From a41d7bf2b8714b580f3e41d8d33deef72a43c7a3 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Mon, 15 Jul 2013 18:53:23 -0700 Subject: [PATCH] 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 --- ofproto/ofproto-dpif.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) 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; -- 2.47.0