When transport node has multiple interfaces (vlans) and
ovn-encap-ip on different hosts need to be configured
from different VLANs source IP for encapsulated packet
can be not the same, which is expected by remote system.

Explicitely setting local_ip resolves such problem.

Signed-off-by: Vladislav Odintsov <odiv...@gmail.com>
---
 controller/chassis.c            | 12 +++++++++++
 controller/encaps.c             | 37 +++++++++++++++++++++------------
 controller/ovn-controller.8.xml |  7 +++++++
 ovn-sb.xml                      |  9 ++++++++
 tests/ovn-controller.at         |  9 ++++++++
 5 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/controller/chassis.c b/controller/chassis.c
index 8a1559653..1a3341079 100644
--- a/controller/chassis.c
+++ b/controller/chassis.c
@@ -64,6 +64,8 @@ struct ovs_chassis_cfg {
     struct ds iface_types;
     /* Is this chassis an interconnection gateway. */
     bool is_interconn;
+    /* Whether we should configure local_ip tunnel port option.*/
+    bool set_local_ip;
 };
 
 static void
@@ -192,6 +194,12 @@ get_is_interconn(const struct smap *ext_ids)
     return smap_get_bool(ext_ids, "ovn-is-interconn", false);
 }
 
+static bool
+get_set_local_ip(const struct smap *ext_ids)
+{
+    return smap_get_bool(ext_ids, "ovn-set-local-ip", false);
+}
+
 static void
 update_chassis_transport_zones(const struct sset *transport_zones,
                                const struct sbrec_chassis *chassis_rec)
@@ -324,6 +332,8 @@ chassis_parse_ovs_config(const struct 
ovsrec_open_vswitch_table *ovs_table,
 
     ovs_cfg->is_interconn = get_is_interconn(&cfg->external_ids);
 
+    ovs_cfg->set_local_ip = get_set_local_ip(&cfg->external_ids);
+
     return true;
 }
 
@@ -350,6 +360,8 @@ chassis_build_other_config(const struct ovs_chassis_cfg 
*ovs_cfg,
     smap_replace(config, "is-interconn",
                  ovs_cfg->is_interconn ? "true" : "false");
     smap_replace(config, OVN_FEATURE_PORT_UP_NOTIF, "true");
+    smap_replace(config, "ovn-set-local-ip",
+                 ovs_cfg->set_local_ip ? "true" : "false");
 }
 
 /*
diff --git a/controller/encaps.c b/controller/encaps.c
index 66e0cd8cd..3b0c92931 100644
--- a/controller/encaps.c
+++ b/controller/encaps.c
@@ -23,6 +23,7 @@
 #include "openvswitch/vlog.h"
 #include "lib/ovn-sb-idl.h"
 #include "ovn-controller.h"
+#include "smap.h"
 
 VLOG_DEFINE_THIS_MODULE(encaps);
 
@@ -176,8 +177,31 @@ tunnel_add(struct tunnel_ctx *tc, const struct 
sbrec_sb_global *sbg,
         smap_add(&options, "dst_port", dst_port);
     }
 
+    const struct ovsrec_open_vswitch *cfg =
+        ovsrec_open_vswitch_table_first(ovs_table);
+
+    bool set_local_ip = false;
+    if (cfg) {
+        /* If the tos option is configured, get it */
+        const char *encap_tos = smap_get_def(&cfg->external_ids,
+           "ovn-encap-tos", "none");
+
+        if (encap_tos && strcmp(encap_tos, "none")) {
+            smap_add(&options, "tos", encap_tos);
+        }
+
+        /* If ovn-set-local-ip option is configured, get it */
+        set_local_ip = smap_get_bool(&cfg->external_ids, "ovn-set-local-ip",
+                                     false);
+    }
+
     /* Add auth info if ipsec is enabled. */
     if (sbg->ipsec) {
+        set_local_ip = true;
+        smap_add(&options, "remote_name", new_chassis_id);
+    }
+
+    if (set_local_ip) {
         const struct sbrec_chassis *this_chassis = tc->this_chassis;
         const char *local_ip = NULL;
 
@@ -200,19 +224,6 @@ tunnel_add(struct tunnel_ctx *tc, const struct 
sbrec_sb_global *sbg,
         if (local_ip) {
             smap_add(&options, "local_ip", local_ip);
         }
-        smap_add(&options, "remote_name", new_chassis_id);
-    }
-
-    const struct ovsrec_open_vswitch *cfg =
-        ovsrec_open_vswitch_table_first(ovs_table);
-    /* If the tos option is configured, get it */
-    if (cfg) {
-        const char *encap_tos = smap_get_def(&cfg->external_ids,
-           "ovn-encap-tos", "none");
-
-        if (encap_tos && strcmp(encap_tos, "none")) {
-            smap_add(&options, "tos", encap_tos);
-        }
     }
 
     /* If there's an existing chassis record that does not need any change,
diff --git a/controller/ovn-controller.8.xml b/controller/ovn-controller.8.xml
index e9708fe64..cc9a7d1c2 100644
--- a/controller/ovn-controller.8.xml
+++ b/controller/ovn-controller.8.xml
@@ -304,6 +304,13 @@
         of how many entries there are in the cache.  By default this is set to
         30000 (30 seconds).
       </dd>
+      <dt><code>external_ids:ovn-set-local-ip</code></dt>
+      <dd>
+        The boolean flag indicates if <code>ovn-controller</code> when create
+        tunnel ports should set <code>local_ip</code> parameter.  Can be
+        heplful to pin source outer IP for the tunnel when multiple interfaces
+        are used on the host for overlay traffic.
+      </dd>
     </dl>
 
     <p>
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 9ddacdf09..46b8192d8 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -300,6 +300,15 @@
       See <code>ovn-controller</code>(8) for more information.
     </column>
 
+    <column name="other_config" key="ovn-set-local-ip">
+      <code>ovn-controller</code> populates this key with the setting
+      configured in the <ref table="Open_vSwitch"
+      column="external_ids:ovn-set-local-ip"/> column of the Open_vSwitch
+      database's <ref table="Open_vSwitch" db="Open_vSwitch"/> table.
+      If set to true, the <code>ovn-controller</code> configures
+      <code>local_ip</code> option on tunnel ports.
+    </column>
+
     <column name="other_config" key="is-remote">
       <code>ovn-ic</code> set this key to true for remote interconnection
       gateway chassises learned from the interconnection southbound database.
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index e99eec1d6..89ae2c9e1 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -298,6 +298,15 @@ OVS_WAIT_UNTIL([check_tunnel_property type geneve])
 ovs-vsctl del-port ovn-fakech-0
 OVS_WAIT_UNTIL([check_tunnel_property type geneve])
 
+# set `ovn-set-local-ip` option to true and check if tunnel parameters
+OVS_WAIT_WHILE([check_tunnel_property options:local_ip "\"192.168.0.1\""])
+ovs-vsctl set open . external_ids:ovn-set-local-ip=true
+OVS_WAIT_UNTIL([check_tunnel_property options:local_ip "\"192.168.0.1\""])
+
+# Change the local_ip on the OVS side and check than OVN fixes it
+ovs-vsctl set interface ovn-fakech-0 options:local_ip="1.1.1.1"
+OVS_WAIT_UNTIL([check_tunnel_property options:local_ip "\"192.168.0.1\""])
+
 # Gracefully terminate daemons
 OVN_CLEANUP_SBOX([hv])
 OVN_CLEANUP_VSWITCH([main])
-- 
2.26.3

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to