Commit acf608 (ofproto-dpif: Use a single underlying datapath across multiple bridges.) causes datapath flows from deleted ports to not be removed. The issue is that the code that bulk deletes old flows doesn't know the datapath port number that makes up the datapath flow definition. This commit keeps track of the datapath port in the facet for use when the datapath flow eventually needs to be removed.
Signed-off-by: Justin Pettit <jpet...@nicira.com> --- ofproto/ofproto-dpif.c | 33 +++++++++++++++++++-------------- 1 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 283917c..10f0b86 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -76,6 +76,7 @@ BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); struct ofport_dpif; struct ofproto_dpif; +struct flow_miss; struct rule_dpif { struct rule up; @@ -467,10 +468,13 @@ struct facet { * overhead. (A facet always has at least one subfacet and in the common * case has exactly one subfacet.) */ struct subfacet one_subfacet; + + /* Datapath port packet arrived on. */ + uint32_t odp_in_port; }; static struct facet *facet_create(struct rule_dpif *, - const struct flow *, uint32_t hash); + const struct flow_miss *, uint32_t hash); static void facet_remove(struct facet *); static void facet_free(struct facet *); @@ -3065,6 +3069,7 @@ struct flow_miss { ovs_be16 initial_tci; struct list packets; enum dpif_upcall_type upcall_type; + uint32_t odp_in_port; }; struct flow_miss_op { @@ -3371,7 +3376,7 @@ handle_flow_miss(struct flow_miss *miss, struct flow_miss_op *ops, return; } - facet = facet_create(rule, &miss->flow, hash); + facet = facet_create(rule, miss, hash); now = facet->used; } else { now = time_msec(); @@ -3463,6 +3468,7 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls, enum odp_key_fitness fitness; struct ofproto_dpif *ofproto; struct ofport_dpif *port; + uint32_t odp_in_port; struct flow flow; uint32_t hash; @@ -3478,6 +3484,7 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls, continue; } ofproto = ofproto_dpif_cast(port->up.ofproto); + odp_in_port = flow.in_port; flow.in_port = port->up.ofp_port; /* Obtain metadata and check userspace/kernel agreement on flow match, @@ -3499,6 +3506,7 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls, miss->key = upcall->key; miss->key_len = upcall->key_len; miss->upcall_type = upcall->type; + miss->odp_in_port = odp_in_port; list_init(&miss->packets); n_misses++; @@ -3824,11 +3832,8 @@ update_stats(struct dpif_backer *backer) if (!port) { /* This flow is for a port for which we couldn't associate an * ofproto. This can happen if a port is removed while - * traffic is being received. Print a rate-limited message - * in case it happens frequently. */ - VLOG_INFO_RL(&rl, - "stats update for flow with unassociated port %"PRIu32, - flow.in_port); + * traffic is being received. Ignore this flow, since it + * will get timed out. */ continue; } @@ -4023,7 +4028,8 @@ rule_expire(struct rule_dpif *rule) /* Facets. */ -/* Creates and returns a new facet owned by 'rule', given a 'flow'. +/* Creates and returns a new facet owned by 'rule', given the 'flow' + * member in 'miss'. * * The caller must already have determined that no facet with an identical * 'flow' exists in 'ofproto' and that 'flow' is the best match for 'rule' in @@ -4034,7 +4040,8 @@ rule_expire(struct rule_dpif *rule) * The facet will initially have no subfacets. The caller should create (at * least) one subfacet with subfacet_create(). */ static struct facet * -facet_create(struct rule_dpif *rule, const struct flow *flow, uint32_t hash) +facet_create(struct rule_dpif *rule, const struct flow_miss *miss, + uint32_t hash) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto); struct facet *facet; @@ -4044,7 +4051,8 @@ facet_create(struct rule_dpif *rule, const struct flow *flow, uint32_t hash) hmap_insert(&ofproto->facets, &facet->hmap_node, hash); list_push_back(&rule->facets, &facet->list_node); facet->rule = rule; - facet->flow = *flow; + facet->flow = miss->flow; + facet->odp_in_port = miss->odp_in_port; list_init(&facet->subfacets); netflow_flow_init(&facet->nf_flow); netflow_flow_update_time(ofproto->netflow, &facet->nf_flow, facet->used); @@ -4781,13 +4789,10 @@ subfacet_get_key(struct subfacet *subfacet, struct odputil_keybuf *keybuf, { if (!subfacet->key) { - struct ofproto_dpif *ofproto; struct flow *flow = &subfacet->facet->flow; ofpbuf_use_stack(key, keybuf, sizeof *keybuf); - ofproto = ofproto_dpif_cast(subfacet->facet->rule->up.ofproto); - odp_flow_key_from_flow(key, flow, - ofp_port_to_odp_port(ofproto, flow->in_port)); + odp_flow_key_from_flow(key, flow, subfacet->facet->odp_in_port); } else { ofpbuf_use_const(key, subfacet->key, subfacet->key_len); } -- 1.7.5.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev