struct xlate_ctx *);
static void xlate_actions__(struct xlate_in *, struct xlate_out *)
OVS_REQ_RDLOCK(xlate_rwlock);
-static void xlate_normal(struct xlate_ctx *);
-static void xlate_report(struct xlate_ctx *, const char *);
-static void xlate_table_action(struct xlate_ctx *, ofp_port_t in_port,
- uint8_t table_id, bool may_packet_in);
+ static void xlate_normal(struct xlate_ctx *);
+ static void xlate_report(struct xlate_ctx *, const char *);
+ static void xlate_table_action(struct xlate_ctx *, ofp_port_t in_port,
+ uint8_t table_id, bool may_packet_in);
static bool input_vid_is_valid(uint16_t vid, struct xbundle *, bool warn);
static uint16_t input_vid_to_vlan(const struct xbundle *, uint16_t vid);
static void output_normal(struct xlate_ctx *, const struct xbundle *,
}
xport = xport_lookup(tnl_port_should_receive(flow)
- ? tnl_port_receive(flow)
- : odp_port_to_ofport(backer, flow->in_port.odp_port));
+ ? tnl_port_receive(flow)
+ : odp_port_to_ofport(backer, flow->in_port.odp_port));
flow->in_port.ofp_port = xport ? xport->ofp_port : OFPP_NONE;
if (!xport) {
/* Make the packet resemble the flow, so that it gets sent to
* an OpenFlow controller properly, so that it looks correct
* for sFlow, and so that flow_extract() will get the correct
- * vlan_tci if it is called on 'packet'.
- *
- * The allocated space inside 'packet' probably also contains
- * 'key', that is, both 'packet' and 'key' are probably part of
- * a struct dpif_upcall (see the large comment on that
- * structure definition), so pushing data on 'packet' is in
- * general not a good idea since it could overwrite 'key' or
- * free it as a side effect. However, it's OK in this special
- * case because we know that 'packet' is inside a Netlink
- * attribute: pushing 4 bytes will just overwrite the 4-byte
- * "struct nlattr", which is fine since we don't need that
- * header anymore. */
+ * vlan_tci if it is called on 'packet'. */
eth_push_vlan(packet, flow->vlan_tci);
}
/* We can't reproduce 'key' from 'flow'. */
}
return !ofputil_bucket_has_liveness(bucket) ||
- (bucket->watch_port != OFPP_ANY &&
- odp_port_is_alive(ctx, bucket->watch_port)) ||
- (bucket->watch_group != OFPG_ANY &&
- group_is_alive(ctx, bucket->watch_group, depth + 1));
+ (bucket->watch_port != OFPP_ANY &&
+ odp_port_is_alive(ctx, bucket->watch_port)) ||
+ (bucket->watch_group != OFPG_ANY &&
+ group_is_alive(ctx, bucket->watch_group, depth + 1));
}
static const struct ofputil_bucket *
return vid ? vid : in_xbundle->vlan;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
return true;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
return vlan == out_xbundle->vlan ? 0 : vlan;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
/* No slaves enabled, so drop packet. */
return;
}
+
+ if (ctx->xin->resubmit_stats) {
+ bond_account(out_xbundle->bond, &ctx->xin->flow, vid,
+ ctx->xin->resubmit_stats->n_bytes);
+ }
}
old_tci = *flow_tci;
const struct flow *flow,
struct flow_wildcards *wc,
int vlan, struct xbundle *in_xbundle)
- OVS_REQ_RDLOCK(ml->rwlock)
+OVS_REQ_RDLOCK(ml->rwlock)
{
struct mac_entry *mac;
update_learning_table__(const struct xbridge *xbridge,
const struct flow *flow, struct flow_wildcards *wc,
int vlan, struct xbundle *in_xbundle)
- OVS_REQ_WRLOCK(xbridge->ml->rwlock)
+OVS_REQ_WRLOCK(xbridge->ml->rwlock)
{
struct mac_entry *mac;
|| mac_entry_is_grat_arp_locked(mac))) {
ovs_rwlock_unlock(&xbridge->ml->rwlock);
xlate_report(ctx, "SLB bond thinks this packet looped back, "
- "dropping");
+ "dropping");
return false;
}
ovs_rwlock_unlock(&xbridge->ml->rwlock);
ofp_port_t in_port, uint8_t table_id, bool may_packet_in)
{
if (xlate_resubmit_resource_check(ctx)) {
- struct rule_dpif *rule;
ofp_port_t old_in_port = ctx->xin->flow.in_port.ofp_port;
+ bool skip_wildcards = ctx->xin->skip_wildcards;
uint8_t old_table_id = ctx->table_id;
+ struct rule_dpif *rule;
ctx->table_id = table_id;
* original input port (otherwise OFPP_NORMAL and OFPP_IN_PORT will
* have surprising behavior). */
ctx->xin->flow.in_port.ofp_port = in_port;
- rule_dpif_lookup_in_table(ctx->xbridge->ofproto,
- &ctx->xin->flow, &ctx->xout->wc,
+ rule_dpif_lookup_in_table(ctx->xbridge->ofproto, &ctx->xin->flow,
+ !skip_wildcards ? &ctx->xout->wc : NULL,
table_id, &rule);
ctx->xin->flow.in_port.ofp_port = old_in_port;
xlate_ff_group(ctx, group);
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
group_dpif_release(group);
}
xin->resubmit_hook = NULL;
xin->report_hook = NULL;
xin->resubmit_stats = NULL;
+ xin->skip_wildcards = false;
}
void
ctx.mpls_depth_delta = 0;
if (!xin->ofpacts && !ctx.rule) {
- rule_dpif_lookup(ctx.xbridge->ofproto, flow, wc, &rule);
+ rule_dpif_lookup(ctx.xbridge->ofproto, flow,
+ !xin->skip_wildcards ? wc : NULL, &rule);
if (ctx.xin->resubmit_stats) {
rule_dpif_credit_stats(rule, ctx.xin->resubmit_stats);
}
ofpacts = actions->ofpacts;
ofpacts_len = actions->ofpacts_len;
} else {
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
ofpbuf_use_stub(&ctx.stack, ctx.init_stack, sizeof ctx.init_stack);
goto out;
case OFPC_FRAG_REASM:
- NOT_REACHED();
+ OVS_NOT_REACHED();
case OFPC_FRAG_NX_MATCH:
/* Nothing to do. */
break;
case OFPC_INVALID_TTL_TO_CONTROLLER:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
in_port = get_ofp_port(ctx.xbridge, flow->in_port.ofp_port);
+ if (in_port && in_port->is_tunnel && ctx.xin->resubmit_stats) {
+ netdev_vport_inc_rx(in_port->netdev, ctx.xin->resubmit_stats);
+ if (in_port->bfd) {
+ bfd_account_rx(in_port->bfd, ctx.xin->resubmit_stats);
+ }
+ }
+
special = process_special(&ctx, flow, in_port, ctx.xin->packet);
if (special) {
ctx.xout->slow |= special;
ctx.xout->slow |= SLOW_ACTION;
}
+ if (ctx.xin->resubmit_stats) {
+ mirror_update_stats(ctx.xbridge->mbridge, xout->mirrors,
+ ctx.xin->resubmit_stats->n_packets,
+ ctx.xin->resubmit_stats->n_bytes);
+
+ if (ctx.xbridge->netflow) {
+ const struct ofpact *ofpacts;
+ size_t ofpacts_len;
+
+ ofpacts_len = actions->ofpacts_len;
+ ofpacts = actions->ofpacts;
+ if (ofpacts_len == 0
+ || ofpacts->type != OFPACT_CONTROLLER
+ || ofpact_next(ofpacts) < ofpact_end(ofpacts, ofpacts_len)) {
+ /* Only update netflow if we don't have controller flow. We don't
+ * report NetFlow expiration messages for such facets because they
+ * are just part of the control logic for the network, not real
+ * traffic. */
+ netflow_flow_update(ctx.xbridge->netflow, flow,
+ xout->nf_output_iface,
+ ctx.xin->resubmit_stats);
+ }
+ }
+ }
+
ofpbuf_uninit(&ctx.stack);
ofpbuf_uninit(&ctx.action_set);