On Thu, Sep 08, 2016 at 11:51:10PM -0500, Chandra Sekhar Vejendla wrote: > > > > Chandra Sekhar Vejendla/San Jose/IBM@IBMUS wrote on 09/08/2016 11:31:54 PM: > > > From: Chandra Sekhar Vejendla/San Jose/IBM@IBMUS > > To: dev@openvswitch.org > > Cc: Chandra Sekhar Vejendla/San Jose/IBM@IBMUS, Ryan > Moats/Omaha/IBM@IBMUS > > Date: 09/08/2016 11:32 PM > > Subject: [PATCH v2] ovn-controller: Fix match crieria for dynamic > > mac binding flows > > > > match struct is not initialized before adding flows for each entry in > > mac_bindings table. This results in incorrect match criteria. > > > > Signed-off-by: Chandra Sekhar Vejendla <csvej...@us.ibm.com> > > Signed-off-by: Ryan Moats <rmo...@us.ibm.com> > > Co-authored-by: Ryan Moats <rmo...@us.ibm.com> > > --- > > ovn/controller/lflow.c | 31 ++++++++++++++----------------- > > 1 file changed, 14 insertions(+), 17 deletions(-) > > > > diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c > > index efac5b3..3ea7fc7 100644 > > --- a/ovn/controller/lflow.c > > +++ b/ovn/controller/lflow.c > > @@ -343,10 +343,13 @@ put_load(const uint8_t *data, size_t len, > > static void > > consider_neighbor_flow(const struct lport_index *lports, > > const struct sbrec_mac_binding *b, > > - struct ofpbuf *ofpacts_p, > > - struct match *match_p, > > struct hmap *flow_table) > > { > > + struct ofpbuf ofpacts; > > + struct match match; > > + match_init_catchall(&match); > > + ofpbuf_init(&ofpacts, 0); > > + > > const struct sbrec_port_binding *pb > > = lport_lookup_by_name(lports, b->logical_port); > > if (!pb) { > > @@ -368,7 +371,7 @@ consider_neighbor_flow(const struct lport_index > *lports, > > VLOG_WARN_RL(&rl, "bad 'ip' %s", b->ip); > > return; > > } > > - match_set_reg(match_p, 0, ntohl(ip)); > > + match_set_reg(&match, 0, ntohl(ip)); > > } else { > > struct in6_addr ip6; > > if (!ipv6_parse(b->ip, &ip6)) { > > @@ -378,16 +381,17 @@ consider_neighbor_flow(const struct lport_index > *lports, > > } > > ovs_be128 value; > > memcpy(&value, &ip6, sizeof(value)); > > - match_set_xxreg(match_p, 0, ntoh128(value)); > > + match_set_xxreg(&match, 0, ntoh128(value)); > > } > > > > - match_set_metadata(match_p, htonll(pb->datapath->tunnel_key)); > > - match_set_reg(match_p, MFF_LOG_OUTPORT - MFF_REG0, pb->tunnel_key); > > + match_set_metadata(&match, htonll(pb->datapath->tunnel_key)); > > + match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, pb->tunnel_key); > > > > - ofpbuf_clear(ofpacts_p); > > - put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, ofpacts_p); > > + ofpbuf_clear(&ofpacts); > > + put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, &ofpacts); > > > > - ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, match_p, > > ofpacts_p); > > + ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, &match, > &ofpacts); > > + ofpbuf_uninit(&ofpacts); > > } > > > > /* Adds an OpenFlow flow to flow tables for each MAC binding in the OVN > > @@ -398,17 +402,10 @@ add_neighbor_flows(struct controller_ctx *ctx, > > const struct lport_index *lports, > > struct hmap *flow_table) > > { > > - struct ofpbuf ofpacts; > > - struct match match; > > - match_init_catchall(&match); > > - ofpbuf_init(&ofpacts, 0); > > - > > const struct sbrec_mac_binding *b; > > SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) { > > - consider_neighbor_flow(lports, b, &ofpacts, &match, flow_table); > > + consider_neighbor_flow(lports, b, flow_table); > > } > > - > > - ofpbuf_uninit(&ofpacts); > > } > > > > /* Translates logical flows in the Logical_Flow table in the OVN_SB > database > > -- > > 1.9.1 > > > > I haven't been able to come up with a valid test case that would fail > without > this patch. For the unit test, I tried to add multiple mac_bindings with > ovn-sbctl command and then verify that the flows generated should have only > reg0 and reg15 in the match criteria. When i tested this in a real setup, > without the patch, reg1, reg2 and reg3 will sometimes show up in the match > criteria along with reg0 and reg15. This is not 100% reproducible, though.
I think it's clear enough what the patch fixes. I reworked the code a little bit and applied it to master and branch-2.6 as follows: --8<--------------------------cut here-------------------------->8-- From: Chandra S Vejendla <csvej...@us.ibm.com> Date: Thu, 8 Sep 2016 23:31:54 -0500 Subject: [PATCH] ovn-controller: Fix match crieria for dynamic mac binding flows match struct is not initialized before adding flows for each entry in mac_bindings table. The matches for IPv4 and IPv6 entries don't have exactly the same form (IPv4 uses reg0, IPv6 uses xxreg0), so reusing a match structure can cause problems. Signed-off-by: Chandra Sekhar Vejendla <csvej...@us.ibm.com> Signed-off-by: Ryan Moats <rmo...@us.ibm.com> Co-authored-by: Ryan Moats <rmo...@us.ibm.com> Signed-off-by: Ben Pfaff <b...@ovn.org> --- ovn/controller/lflow.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index efac5b3..0414626 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -343,8 +343,6 @@ put_load(const uint8_t *data, size_t len, static void consider_neighbor_flow(const struct lport_index *lports, const struct sbrec_mac_binding *b, - struct ofpbuf *ofpacts_p, - struct match *match_p, struct hmap *flow_table) { const struct sbrec_port_binding *pb @@ -360,7 +358,7 @@ consider_neighbor_flow(const struct lport_index *lports, return; } - + struct match match = MATCH_CATCHALL_INITIALIZER; if (strchr(b->ip, '.')) { ovs_be32 ip; if (!ip_parse(b->ip, &ip)) { @@ -368,7 +366,7 @@ consider_neighbor_flow(const struct lport_index *lports, VLOG_WARN_RL(&rl, "bad 'ip' %s", b->ip); return; } - match_set_reg(match_p, 0, ntohl(ip)); + match_set_reg(&match, 0, ntohl(ip)); } else { struct in6_addr ip6; if (!ipv6_parse(b->ip, &ip6)) { @@ -378,16 +376,17 @@ consider_neighbor_flow(const struct lport_index *lports, } ovs_be128 value; memcpy(&value, &ip6, sizeof(value)); - match_set_xxreg(match_p, 0, ntoh128(value)); + match_set_xxreg(&match, 0, ntoh128(value)); } - match_set_metadata(match_p, htonll(pb->datapath->tunnel_key)); - match_set_reg(match_p, MFF_LOG_OUTPORT - MFF_REG0, pb->tunnel_key); - - ofpbuf_clear(ofpacts_p); - put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, ofpacts_p); + match_set_metadata(&match, htonll(pb->datapath->tunnel_key)); + match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, pb->tunnel_key); - ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, match_p, ofpacts_p); + uint64_t stub[1024 / 8]; + struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); + put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100, &match, &ofpacts); + ofpbuf_uninit(&ofpacts); } /* Adds an OpenFlow flow to flow tables for each MAC binding in the OVN @@ -398,17 +397,10 @@ add_neighbor_flows(struct controller_ctx *ctx, const struct lport_index *lports, struct hmap *flow_table) { - struct ofpbuf ofpacts; - struct match match; - match_init_catchall(&match); - ofpbuf_init(&ofpacts, 0); - const struct sbrec_mac_binding *b; SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) { - consider_neighbor_flow(lports, b, &ofpacts, &match, flow_table); + consider_neighbor_flow(lports, b, flow_table); } - - ofpbuf_uninit(&ofpacts); } /* Translates logical flows in the Logical_Flow table in the OVN_SB database -- 2.1.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev