From: Justin Pettit Date: Tue, 16 Jul 2013 01:53:23 +0000 (-0700) Subject: ofproto-dpif: Don't put new subfacets as result of "userspace" action. X-Git-Tag: sliver-openvswitch-2.0.90-1~36^2~18 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;ds=sidebyside;h=a41d7bf2b8714b580f3e41d8d33deef72a43c7a3;p=sliver-openvswitch.git ofproto-dpif: Don't put new subfacets as result of "userspace" action. Don't install a flow if it's the result of the "userspace" action for an already installed facet. This can occur when a datapath flow with wildcards has a "userspace" action and flows sent to userspace result in a different subfacet, which will then be rejected as overlapping by the datapath. Signed-off-by: Justin Pettit Co-authored-by: Ethan Jackson --- diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 283336c0e..5c9527b69 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -3395,11 +3395,7 @@ handle_flow_miss_with_facet(struct flow_miss *miss, struct facet *facet, struct subfacet *subfacet; struct ofpbuf *packet; - subfacet = subfacet_create(facet, miss, now); want_path = facet->xout.slow ? SF_SLOW_PATH : SF_FAST_PATH; - if (stats) { - subfacet_update_stats(subfacet, stats); - } LIST_FOR_EACH (packet, list_node, &miss->packets) { struct flow_miss_op *op = &ops[*n_ops]; @@ -3426,6 +3422,27 @@ handle_flow_miss_with_facet(struct flow_miss *miss, struct facet *facet, } } + /* Don't install the flow if it's the result of the "userspace" + * action for an already installed facet. This can occur when a + * datapath flow with wildcards has a "userspace" action and flows + * sent to userspace result in a different subfacet, which will then + * be rejected as overlapping by the datapath. */ + if (miss->upcall_type == DPIF_UC_ACTION + && !list_is_empty(&facet->subfacets)) { + if (stats) { + facet->used = MAX(facet->used, stats->used); + facet->packet_count += stats->n_packets; + facet->byte_count += stats->n_bytes; + facet->tcp_flags |= stats->tcp_flags; + } + return; + } + + subfacet = subfacet_create(facet, miss, now); + if (stats) { + subfacet_update_stats(subfacet, stats); + } + if (miss->upcall_type == DPIF_UC_MISS || subfacet->path != want_path) { struct flow_miss_op *op = &ops[(*n_ops)++]; struct dpif_flow_put *put = &op->dpif_op.u.flow_put;