This patch enables source node replication in OVN for receive from Vxlan
tunnels.  OVN only supports source node replication mode.

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 <dlu...@gmail.com>
---
 ovn/controller-vtep/vtep.c |  4 ++++
 ovn/controller/physical.c  | 25 ++++++++++++++++++++-----
 ovn/lib/logical-fields.h   | 15 +++++++++++++++
 tests/ovn.at               |  3 +++
 4 files changed, 42 insertions(+), 5 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 a104e33..96a9b39 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -472,6 +472,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,
+                              MFF_LOG_FLAGS_RCV_FROM_VXLAN,
+                              MFF_LOG_FLAGS_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);
+
     }
 }
 
@@ -802,11 +817,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;
@@ -826,6 +837,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, 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 24c15c7..022fa18 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_REG10  /* Logical flags (32 bits). */
 #define MFF_LOG_DNAT_ZONE  MFF_REG11  /* conntrack dnat zone for gateway router
                                        * (32 bits). */
 #define MFF_LOG_SNAT_ZONE  MFF_REG12  /* conntrack snat zone for gateway router
@@ -47,4 +48,18 @@
     MFF_LOG_REG(MFF_REG8) \
     MFF_LOG_REG(MFF_REG9)
 
+/* MFF_LOG_FLAGS_REG bit assignments */
+enum mff_log_flags_bits {
+    MFF_LOG_FLAGS_RCV_FROM_VXLAN_BIT =         0,
+};
+
+/* 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 << MFF_LOG_FLAGS_RCV_FROM_VXLAN_BIT),
+};
+
 #endif /* ovn/lib/logical-fields.h */
diff --git a/tests/ovn.at b/tests/ovn.at
index 614a4bb..f1e6320 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1197,6 +1197,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

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to