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

Reply via email to