When vlan-splinter is enabled, ovs receives non-vlan flows from the kernel vlan ports, vlan tag is then added to the incoming flow before xlating, so that they look like those received from a trunk port.
In case megaflow is enabled, xlating may set vlan masks during rule processing as usual. If those vlan masks were serialized and downloaded to the kernel (this bug), those mega flows will be rejected due to unexpected vlan mask encapsulation, since the original kernel flows do not have vlan tags. This bug does not break connectivity, but impacts performance since all traffic received on vlan splinter ports will now be handled by vswitchd, as no datapath flows can be successfully installed. This fix is to make sure no vlan mask encapsulation is generated for the datapath flow if its in_port was re-written by vlan-splinter receiving logic. Bug #22567 Signed-off-by: Andy Zhou <[email protected]> --- ofproto/ofproto-dpif.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 803a2e8..7edb640 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -3825,8 +3825,17 @@ handle_flow_miss_with_facet(struct flow_miss *miss, struct facet *facet, ofpbuf_use_stack(&op->mask, &op->maskbuf, sizeof op->maskbuf); if (enable_megaflows) { + ovs_be16 flow_vlan_tci; + + /* Use the original flow vlan_tci vlaue to generate megaflow + * masks, in case the flow has been modified by vlan splinter.*/ + flow_vlan_tci = miss->flow.vlan_tci; + miss->flow.vlan_tci = miss->initial_vals.vlan_tci; + odp_flow_key_from_mask(&op->mask, &facet->xout.wc.masks, &miss->flow, UINT32_MAX); + + miss->flow.vlan_tci = flow_vlan_tci; } op->xout_garbage = false; @@ -5467,8 +5476,20 @@ subfacet_install(struct subfacet *subfacet, const struct ofpbuf *odp_actions, ofpbuf_use_stack(&mask, &maskbuf, sizeof maskbuf); if (enable_megaflows) { + struct flow *flow = &facet->flow; + struct flow orig_flow; + + /* If the flow was updated by vlan splinter, restore + * vlan_tci that matches the datapath flow for generating + * proper flow masks. */ + if (facet->initial_vals.vlan_tci != facet->flow.vlan_tci) { + orig_flow = facet->flow; + orig_flow.vlan_tci = facet->initial_vals.vlan_tci; + flow = &orig_flow; + } + odp_flow_key_from_mask(&mask, &facet->xout.wc.masks, - &facet->flow, UINT32_MAX); + flow, UINT32_MAX); } ret = dpif_flow_put(ofproto->backer->dpif, flags, subfacet->key, -- 1.7.9.5 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
