[ovs-dev] [patch_v3 1/2] ovn: Fix receive from vxlan in ovn-controller.

Darrell Ball dlu998 at gmail.com
Mon Jun 27 01:34:01 UTC 2016


OVN only supports source_node replication and previously vtep interaction,
which used service node replication by default for
multicast/broadcast/unknown unicast traffic worked by happenstance.
Because of limited vxlan encapsulation metadata, received packets were
resubmitted to find the egress port(s). This is not correct for multicast,
broadcast and unknown unicast traffic as traffic will get resent on the tunnel
mesh. ovn-controller is changed not to send traffic received from vxlan
tunnels out the tunnel mesh again.  Traffic received from vxlan tunnels is
now only sent locally as intended.

To support keeping state for receipt from a vxlan tunnel a MFF logical
register is allocated for general scratchpad purposes and one bit is used for
receipt from vxlan context.

As part of this change ovn-controller-vtep is hard-coded to set the replication
mode of each logical switch to source node as OVN will only support source
node replication.

Signed-off-by: Darrell Ball <dlu998 at gmail.com>
---
 ovn/controller-vtep/vtep.c |  4 ++++
 ovn/controller/physical.c  | 25 ++++++++++++++++++++-----
 ovn/lib/logical-fields.h   | 13 +++++++++++--
 tests/ovn.at               |  3 +++
 4 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/ovn/controller-vtep/vtep.c b/ovn/controller-vtep/vtep.c
index e412b6b..f9151c2 100644
--- a/ovn/controller-vtep/vtep.c
+++ b/ovn/controller-vtep/vtep.c
@@ -233,6 +233,10 @@ vtep_lswitch_run(struct shash *vtep_pbs, struct sset *vtep_pswitches,
                          vtep_ls->tunnel_key[0], tnl_key);
             }
             vteprec_logical_switch_set_tunnel_key(vtep_ls, &tnl_key, 1);
+            /* OVN is expected to always use source node replication mode,
+             * hence the replication mode is hard-coded for each logical
+             * switch in the context of ovn-controller-vtep. */
+            vteprec_logical_switch_set_replication_mode(vtep_ls, "source_node");
             sset_add(&used_ls, lswitch_name);
         }
     }
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index 85528e0..0dbdd21 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -524,6 +524,21 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
             ofpact_put_OUTPUT(&ofpacts)->port = ofport;
             ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100,
                             &match, &ofpacts);
+
+            /* For packets received from a Vxlan tunnel which get
+             * resubmitted to OFTABLE_LOG_INGRESS_PIPELINE due to lack of
+             * needed metadata in Vxlan, explicitly skip sending back out
+             * any tunnels and resubmit to table 33 for local delivery. */
+            match_init_catchall(&match);
+            ofpbuf_clear(&ofpacts);
+
+            match_set_reg(&match, MFF_LOG_FLAGS - MFF_REG0,
+                          MFF_LOG_FLAGS_RCV_FROM_VXLAN);
+            /* Resubmit to table 33. */
+            put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts);
+            ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 101, &match,
+                            &ofpacts);
+
         }
     }
 
@@ -687,11 +702,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
      * metadata, we only support VXLAN for connections to gateways.  The
      * VNI is used to populate MFF_LOG_DATAPATH.  The gateway's logical
      * port is set to MFF_LOG_INPORT.  Then the packet is resubmitted to
-     * table 16 to determine the logical egress port.
-     *
-     * xxx Due to resubmitting to table 16, broadcasts will be re-sent to
-     * xxx all logical ports, including non-local ones which could cause
-     * xxx duplicate packets to be received by multiply-connected gateways. */
+     * table 16 to determine the logical egress port. */
     HMAP_FOR_EACH (tun, hmap_node, &tunnels) {
         if (tun->type != VXLAN) {
             continue;
@@ -711,6 +722,10 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
             ofpbuf_clear(&ofpacts);
             put_move(MFF_TUN_ID, 0,  MFF_LOG_DATAPATH, 0, 24, &ofpacts);
             put_load(binding->tunnel_key, MFF_LOG_INPORT, 0, 15, &ofpacts);
+            /* For packets received from a vxlan tunnel, set a flag to that
+             * effect. */
+            put_load(MFF_LOG_FLAGS_RCV_FROM_VXLAN, MFF_LOG_FLAGS,
+                     0, 32, &ofpacts);
             put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
 
             ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 100, &match,
diff --git a/ovn/lib/logical-fields.h b/ovn/lib/logical-fields.h
index f0f97a9..b340653 100644
--- a/ovn/lib/logical-fields.h
+++ b/ovn/lib/logical-fields.h
@@ -23,6 +23,7 @@
  * These values are documented in ovn-architecture(7), please update the
  * documentation if you change any of them. */
 #define MFF_LOG_DATAPATH MFF_METADATA /* Logical datapath (64 bits). */
+#define MFF_LOG_FLAGS      MFF_REG2   /* Logical flags (32 bits). */
 #define MFF_LOG_DNAT_ZONE  MFF_REG3   /* conntrack dnat zone for gateway router
                                        * (32 bits). */
 #define MFF_LOG_SNAT_ZONE  MFF_REG4   /* conntrack snat zone for gateway router
@@ -37,7 +38,15 @@
  * Make sure these don't overlap with the logical fields! */
 #define MFF_LOG_REGS \
     MFF_LOG_REG(MFF_REG0) \
-    MFF_LOG_REG(MFF_REG1) \
-    MFF_LOG_REG(MFF_REG2)
+    MFF_LOG_REG(MFF_REG1)
+
+/* MFF_LOG_FLAGS_REG flag assignments */
+enum mff_log_flags {
+    /* This flag is used to indicate that a packet was received from a vxlan
+     * tunnel to compensate for the lack of egress port information available
+     * in Vxlan encapsulation.  Egress port information is available for Geneve
+     * and STT tunnel types. */
+    MFF_LOG_FLAGS_RCV_FROM_VXLAN = (1 << 0),
+};
 
 #endif /* ovn/lib/logical-fields.h */
diff --git a/tests/ovn.at b/tests/ovn.at
index 297070c..4fe536d 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1136,6 +1136,9 @@ sleep 1
 
 vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0
 
+OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
+               grep -- source`"])
+# It takes more time for the update to be processed by ovs-vtep.
 sleep 1
 
 # Add hv3 on the other side of the vtep
-- 
1.9.1




More information about the dev mailing list