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 <az...@nicira.com> --- ofproto/ofproto-dpif.c | 35 +++++++++++++++++++++++++++++------ ofproto/ofproto-dpif.h | 3 +++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 34c6255..a0ba728 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -3291,8 +3291,8 @@ 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) { - odp_flow_key_from_mask(&op->mask, &facet->xout.wc.masks, - &miss->flow, UINT32_MAX); + mask_to_netlink_attr(&op->mask, facet->ofproto, + &facet->xout.wc.masks, &miss->flow); } op->xout_garbage = false; @@ -4638,8 +4638,8 @@ subfacet_install(struct subfacet *subfacet, const struct ofpbuf *odp_actions, ofpbuf_use_stack(&mask, &maskbuf, sizeof maskbuf); if (enable_megaflows) { - odp_flow_key_from_mask(&mask, &facet->xout.wc.masks, - &facet->flow, UINT32_MAX); + mask_to_netlink_attr(&mask, facet->ofproto, + &facet->xout.wc.masks, &facet->flow); } ret = dpif_flow_put(subfacet->backer->dpif, flags, subfacet->key, @@ -5882,8 +5882,8 @@ ofproto_unixctl_dpif_dump_flows(struct unixctl_conn *conn, ofpbuf_use_stack(&mask, &maskbuf, sizeof maskbuf); if (enable_megaflows) { - odp_flow_key_from_mask(&mask, &facet->xout.wc.masks, - &facet->flow, UINT32_MAX); + mask_to_netlink_attr(&mask, facet->ofproto, + &facet->xout.wc.masks, &facet->flow); } odp_flow_format(subfacet->key, subfacet->key_len, @@ -6278,6 +6278,29 @@ update_moving_averages(struct dpif_backer *backer) } } +/* Appends a representation of 'mask' as OVS_KEY_ATTR_* attributes to 'buf'. + * Ommit vlan mask if the flow's vlan was added by VLAN splinter. */ +void +mask_to_netlink_attr(struct ofpbuf *buf, const struct ofproto_dpif *ofproto, + const struct flow *mask, const struct flow *flow) +{ + ofp_port_t vlandev_port; + struct flow orig_flow; + + vlandev_port = vsp_realdev_to_vlandev(ofproto, flow->in_port.ofp_port, + flow->vlan_tci); + + if (vlandev_port != flow->in_port.ofp_port) { + /* This flow was received from the VLAN port, do not + * generate vlan masks. */ + orig_flow = *flow; + orig_flow.vlan_tci = 0; + flow = &orig_flow; + } + + odp_flow_key_from_mask(buf, mask, flow, UINT32_MAX); +} + const struct ofproto_class ofproto_dpif_class = { init, enumerate_types, diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 14a9669..80add59 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -97,6 +97,9 @@ void ofproto_dpif_send_packet_in(struct ofproto_dpif *, struct ofputil_packet_in *pin); void ofproto_dpif_flow_mod(struct ofproto_dpif *, struct ofputil_flow_mod *); +void mask_to_netlink_attr(struct ofpbuf *buf, const struct ofproto_dpif *, + const struct flow *mask, const struct flow *flow); + struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); #endif /* ofproto-dpif.h */ -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev