[ovs-dev] [patch_v8] ovn: Fix receive from vxlan in ovn-controller.

Darrell Ball dlu998 at gmail.com
Tue Aug 9 02:20:38 UTC 2016


The changes enable source node replication in OVN for receive from Vxlan
tunnels.  OVN only supports source node replication mode.  This is needed
for ovn-controller to interoperate with hardware switches.

Previously hardware vtep interaction, which uses service node
replication by default for multicast/broadcast/unknown unicast traffic
partially "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 with obvious benefits.  This behavior is
newly documented in ovn-architecture.7.xml.

To support keeping state for receipt from a vxlan tunnel, a MFF logical
flags register flag is allocated.

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>
---

v7->v8: A logical flags register was added recently in the 2 months
              since this patch was originally submitted, so there is no need
              for the patch to add such a register.  Recalibrate the patch.

v6->v7: Split out documentation refactoring from this patch.

v5->v6: rebase; facilitate future use of flags register by checking single
               flag for receive from vxlan.

v3->v5: Rebases.

v2->v3:
Change reg0 and reg1 usage column comment to "generic scratch".
Split code change for bug fix and documentation update into two patches.

v1->v2:
Rebased after recent conflicting commit.  Converted some xml
comments ported from the ovn-architecture document. Removed
redundant register initialization and unnecessary bit declaration.

 ovn/controller-vtep/vtep.c |  4 ++++
 ovn/controller/physical.c  | 24 +++++++++++++++++++-----
 ovn/lib/logical-fields.h   | 26 +++++++++++++++++---------
 ovn/ovn-architecture.7.xml | 22 ++++++++++++++++++----
 tests/ovn.at               |  3 +++
 5 files changed, 61 insertions(+), 18 deletions(-)

diff --git a/ovn/controller-vtep/vtep.c b/ovn/controller-vtep/vtep.c
index b529519..ba78a39 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 589b053..43885fd 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -496,6 +496,21 @@ consider_port_binding(enum mf_field_id mff_ovn_geneve,
         ofpact_put_OUTPUT(ofpacts_p)->port = ofport;
         ofctrl_add_flow(OFTABLE_REMOTE_OUTPUT, 100,
                         &match, ofpacts_p, &binding->header_.uuid);
+
+        /* 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_p);
+         match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0,
+                              MLF_RCV_FROM_VXLAN,
+                              MLF_RCV_FROM_VXLAN);
+         /* Resubmit to table 33. */
+         put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p);
+         ofctrl_add_flow(OFTABLE_REMOTE_OUTPUT, 101, &match, ofpacts_p,
+                         &binding->header_.uuid);
+
     }
 }
 
@@ -859,11 +874,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;
@@ -883,6 +894,9 @@ 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(1, MFF_LOG_FLAGS, MLF_RCV_FROM_VXLAN_BIT, 1, &ofpacts);
             put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
 
             ofctrl_add_flow(OFTABLE_PHY_TO_LOG, 100, &match, &ofpacts, hc_uuid);
diff --git a/ovn/lib/logical-fields.h b/ovn/lib/logical-fields.h
index 1ea2e0f..1053c86 100644
--- a/ovn/lib/logical-fields.h
+++ b/ovn/lib/logical-fields.h
@@ -20,15 +20,6 @@
 
 struct shash;
 
-enum {
-    MLF_ALLOW_LOOPBACK_BIT = 0
-};
-
-enum {
-    MLF_ALLOW_LOOPBACK = (1 << MLF_ALLOW_LOOPBACK_BIT) /* Allow outputting
-                                                          back to inport. */
-};
-
 /* Logical fields.
  *
  * These values are documented in ovn-architecture(7), please update the
@@ -52,4 +43,21 @@ enum {
 
 void ovn_init_symtab(struct shash *symtab);
 
+/* MFF_LOG_FLAGS_REG bit assignments */
+enum mff_log_flags_bits {
+    MLF_ALLOW_LOOPBACK_BIT = 0,
+    MLF_RCV_FROM_VXLAN_BIT = 1,
+};
+
+/* MFF_LOG_FLAGS_REG flag assignments */
+enum mff_log_flags {
+    MLF_ALLOW_LOOPBACK = (1 << MLF_ALLOW_LOOPBACK_BIT), /* Allow outputting
+                                                          back to inport. */
+    /* The below 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. */
+    MLF_RCV_FROM_VXLAN = (1 << MLF_RCV_FROM_VXLAN_BIT),
+};
+
 #endif /* ovn/lib/logical-fields.h */
diff --git a/ovn/ovn-architecture.7.xml b/ovn/ovn-architecture.7.xml
index 092e418..9c7166f 100644
--- a/ovn/ovn-architecture.7.xml
+++ b/ovn/ovn-architecture.7.xml
@@ -742,6 +742,13 @@
       <p>
         Geneve and STT tunnels pass this field as part of the tunnel key.
         VXLAN tunnels do not transmit the logical output port field.
+        Since VXLAN tunnels do not carry a logical output port field in
+        the tunnel key, when a packet is received from VXLAN tunnel by
+        an OVN hypervisor, the packet is resubmitted to table 16 to
+        determine the output port(s);  when the packet reaches table 32,
+        these packets are resubmitted to table 33 for local delivery by
+        checking a MLF_RCV_FROM_VXLAN flag, which is set when the packet
+        arrives from a VXLAN tunnel.
       </p>
     </dd>
 
@@ -770,11 +777,13 @@
 
     <dt>logical flow flags</dt>
     <dd>
-      A field used to store flags to be used when transforming logical
+      The logical flags are intended to handle keeping context between
+      tables in order to decide which rules in subsequent tables are
+      matched.  These values only have local significance and are not
+      meaningful between chassis.  OVN stores the logical flags in
         <!-- Keep the following in sync with MFF_LOG_FLAGS in
              ovn/lib/logical-fields.h. -->
-      flows into physical flows.  OVN stores this in Open vSwitch
-      extension register number 10.
+      Open vSwitch extension register number 10.
     </dd>
 
     <dt>VLAN ID</dt>
@@ -928,7 +937,12 @@
         multicast group includes a logical port or ports on the local
         hypervisor, then its actions also resubmit to table 33.  Table 32 also
         includes a fallback flow that resubmits to table 33 if there is no
-        other match.
+        other match.  Table 32 also contains a higher priority rule to match
+        packets received from VXLAN tunnels, based on flag MLF_RCV_FROM_VXLAN
+        and resubmit these packets to table 33 for local delivery. Packets
+        received from VXLAN tunnels reach here because of a lack of logical
+        output port field in the tunnel key and thus these packets needed to
+        be submitted to table 16 to determine the output port.
       </p>
 
       <p>
diff --git a/tests/ovn.at b/tests/ovn.at
index 72868be..a95e0b2 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1271,6 +1271,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