From: Lucas Alvares Gomes <[email protected]>

In order for the CMS to know which Chassis a distributed gateway port
is bond to, this patch updates the ovn-northd daemon to populate the
Logical_Router_Port table with that information.

A new column called "status" has been added to the Logical_Router_Port
table and a key called "hosting-chassis" will be populated by ovn-northd
with the name of the Chassis that is currently hosting the distributed
port.

The new "status" column uses key-value style so it's more future proof
and can be easily extended.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2107515
Signed-off-by: Lucas Alvares Gomes <[email protected]>
---
v5 -> v6
* Add a new column called "status" to the Logical_Router_Port table
  to host the "hosting-chassis" key
* Enhance test to remove the "hosting-chassis" key from the status
  column and assert that ovn-northd repopulates it

v4 -> v5
* Fix test to remove sleep and assert on the right table

v3 -> v4
* Removed smap_clone for updating the options and replaced it with
  smap_replace/smap_remove
* Updated the test to also assert the removal of the hosting-chassis
  key by northd

v2 -> v3
* Fixed memory leak
* Separate the logic to update the router port into their own function
* Use attribute l3dgw_port to find the GW port

v1 -> v2
* Rebased on the main branch
* Updated the ovnsb_db_run() and handle_port_binding_changes() functions
  to include the LR ports as a parameter

 northd/en-sync-from-sb.c |  2 +-
 northd/northd.c          | 30 ++++++++++++++++++++++++--
 northd/northd.h          |  3 ++-
 ovn-nb.ovsschema         |  7 ++++--
 ovn-nb.xml               | 19 +++++++++++++++++
 tests/ovn-northd.at      | 46 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/northd/en-sync-from-sb.c b/northd/en-sync-from-sb.c
index 55ece2d16..4109aebe4 100644
--- a/northd/en-sync-from-sb.c
+++ b/northd/en-sync-from-sb.c
@@ -60,7 +60,7 @@ en_sync_from_sb_run(struct engine_node *node, void *data 
OVS_UNUSED)
     stopwatch_start(OVNSB_DB_RUN_STOPWATCH_NAME, time_msec());
     ovnsb_db_run(eng_ctx->ovnnb_idl_txn, eng_ctx->ovnsb_idl_txn,
                  sb_pb_table, sb_ha_ch_grp_table, sb_ha_ch_grp_by_name,
-                 &nd->ls_ports);
+                 &nd->ls_ports, &nd->lr_ports);
     stopwatch_stop(OVNSB_DB_RUN_STOPWATCH_NAME, time_msec());
 }

diff --git a/northd/northd.c b/northd/northd.c
index 459aaafb1..9f87099fc 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -17419,6 +17419,22 @@ build_ha_chassis_group_ref_chassis(struct 
ovsdb_idl_index *ha_ch_grp_by_name,
     }
 }

+/* Set the "hosting-chassis" status in the NBDB logical_router_port
+ * table indicating which chassis the distributed port is bond to. */
+static void
+handle_cr_port_binding_changes(const struct sbrec_port_binding *sb,
+                struct ovn_port *orp)
+{
+    if (sb->chassis) {
+        nbrec_logical_router_port_update_status_setkey(
+            orp->l3dgw_port->nbrp, "hosting-chassis",
+            sb->chassis->name);
+    } else {
+        nbrec_logical_router_port_update_status_delkey(
+            orp->l3dgw_port->nbrp, "hosting-chassis");
+    }
+}
+
 /* Handle changes to the 'chassis' column of the 'Port_Binding' table.  When
  * this column is not empty, it means we need to set the corresponding logical
  * port as 'up' in the northbound DB. */
@@ -17428,6 +17444,7 @@ handle_port_binding_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
                 const struct sbrec_ha_chassis_group_table *sb_ha_ch_grp_table,
                 struct ovsdb_idl_index *sb_ha_ch_grp_by_name,
                 struct hmap *ls_ports,
+                struct hmap *lr_ports,
                 struct shash *ha_ref_chassis_map)
 {
     struct hmapx lr_groups = HMAPX_INITIALIZER(&lr_groups);
@@ -17450,6 +17467,14 @@ handle_port_binding_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
     }

     SBREC_PORT_BINDING_TABLE_FOR_EACH (sb, sb_pb_table) {
+
+        struct ovn_port *orp = ovn_port_find(lr_ports, sb->logical_port);
+
+        if (orp && is_cr_port(orp)) {
+            handle_cr_port_binding_changes(sb, orp);
+            continue;
+        }
+
         struct ovn_port *op = ovn_port_find(ls_ports, sb->logical_port);

         if (!op || !op->nbsp) {
@@ -17502,7 +17527,8 @@ ovnsb_db_run(struct ovsdb_idl_txn *ovnnb_txn,
              const struct sbrec_port_binding_table *sb_pb_table,
              const struct sbrec_ha_chassis_group_table *sb_ha_ch_grp_table,
              struct ovsdb_idl_index *sb_ha_ch_grp_by_name,
-             struct hmap *ls_ports)
+             struct hmap *ls_ports,
+             struct hmap *lr_ports)
 {
     if (!ovnnb_txn ||
         !ovsdb_idl_has_ever_connected(ovsdb_idl_txn_get_idl(ovnsb_txn))) {
@@ -17511,7 +17537,7 @@ ovnsb_db_run(struct ovsdb_idl_txn *ovnnb_txn,

     struct shash ha_ref_chassis_map = SHASH_INITIALIZER(&ha_ref_chassis_map);
     handle_port_binding_changes(ovnsb_txn, sb_pb_table, sb_ha_ch_grp_table,
-                                sb_ha_ch_grp_by_name, ls_ports,
+                                sb_ha_ch_grp_by_name, ls_ports, lr_ports,
                                 &ha_ref_chassis_map);
     if (ovnsb_txn) {
         update_sb_ha_group_ref_chassis(sb_ha_ch_grp_table,
diff --git a/northd/northd.h b/northd/northd.h
index dad914b66..224000003 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -317,7 +317,8 @@ void ovnsb_db_run(struct ovsdb_idl_txn *ovnnb_txn,
                   const struct sbrec_port_binding_table *,
                   const struct sbrec_ha_chassis_group_table *,
                   struct ovsdb_idl_index *sb_ha_ch_grp_by_name,
-                  struct hmap *ls_ports);
+                  struct hmap *ls_ports,
+                  struct hmap *lr_ports);
 bool northd_handle_ls_changes(struct ovsdb_idl_txn *,
                               const struct northd_input *,
                               struct northd_data *);
diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema
index f8bac5302..e103360ec 100644
--- a/ovn-nb.ovsschema
+++ b/ovn-nb.ovsschema
@@ -1,7 +1,7 @@
 {
     "name": "OVN_Northbound",
-    "version": "7.0.4",
-    "cksum": "1676649201 33795",
+    "version": "7.1.0",
+    "cksum": "217362582 33949",
     "tables": {
         "NB_Global": {
             "columns": {
@@ -437,6 +437,9 @@
                                       "min": 0,
                                       "max": "unlimited"}},
                 "external_ids": {
+                    "type": {"key": "string", "value": "string",
+                             "min": 0, "max": "unlimited"}},
+                "status": {
                     "type": {"key": "string", "value": "string",
                              "min": 0, "max": "unlimited"}}},
             "indexes": [["name"]],
diff --git a/ovn-nb.xml b/ovn-nb.xml
index 9c44fc834..9131305ea 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -3359,6 +3359,25 @@ or
         </p>
       </column>
     </group>
+
+    <group title="Status">
+      <p>
+        Additional status about the logical router port.
+      </p>
+      <column name="status" key="hosting-chassis">
+        <p>
+          This option is populated by <code>ovn-northd</code>.
+        </p>
+
+        <p>
+          When a distributed gateway port is bound to a location in
+          the OVN Southbound database
+          <ref db="OVN_Southbound" table="Port_Binding"/>
+          <code>ovn-northd</code> will populate this key with the
+          name of the Chassis that is currently hosting this port.
+        </p>
+      </column>
+    </group>
   </table>

   <table name="Logical_Router_Static_Route" title="Logical router static 
routes">
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 3ef92bb3f..46fb62c24 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -172,6 +172,52 @@ AT_CHECK([test x`ovn-nbctl lsp-get-up S1-R1` = xup])
 AT_CLEANUP
 ])

+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([check Logical Router Port hosting-chassis status])
+ovn_start
+
+check ovn-sbctl chassis-add ch1 geneve 127.0.0.2
+
+check ovn-nbctl lr-add lr1
+check ovn-nbctl lrp-add lr1 lrp1 00:00:00:00:00:01 10.0.0.1/24
+check ovn-nbctl ls-add ls1
+check ovn-nbctl lsp-add ls1 lsp1 -- \
+    lsp-set-addresses lsp1 router -- \
+    lsp-set-type lsp1 router -- \
+    lsp-set-options lsp1 router-port=lrp1
+
+# Make lrp a cr-port
+check ovn-nbctl lrp-set-gateway-chassis lrp1 ch1
+
+check ovn-nbctl --wait=sb sync
+
+wait_row_count Port_Binding 1 logical_port=cr-lrp1 \
+    options:always-redirect="true" options:distributed-port="lrp1"
+
+# Simulate cr-port being bound to ch1
+ch1_uuid=`ovn-sbctl --bare --columns _uuid find Chassis name="ch1"`
+check ovn-sbctl set Port_Binding cr-lrp1 chassis=${ch1_uuid}
+
+check ovn-nbctl --wait=sb sync
+
+# Check for the hosting-chassis status being set by northd
+wait_row_count nb:Logical_Router_Port 1 name=lrp1 status:hosting-chassis=ch1
+
+# Clear the hosting-chassis status from LRP and assert northd repopulates it
+check ovn-nbctl remove logical_router_port lrp1 status hosting-chassis
+check ovn-nbctl --wait=sb sync
+wait_row_count nb:Logical_Router_Port 1 name=lrp1 status:hosting-chassis=ch1
+
+# Now remove the chassis from the port binding record and assert that the
+# hosting-chassis status was removed by northd
+check ovn-sbctl clear Port_Binding cr-lrp1 chassis
+check ovn-nbctl --wait=sb sync
+
+wait_row_count nb:Logical_Router_Port 0 name=lrp1 status:hosting-chassis=ch1
+
+AT_CLEANUP
+])
+
 OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([check LRP external id propagation to SBDB])
 ovn_start
--
2.41.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to