diff mbox series

[ovs-dev,v3,6/7] northd: Add distributed route exchange options.

Message ID 20240725140009.413791-6-fnordahl@ubuntu.com
State Changes Requested
Headers show
Series [ovs-dev,v3,1/7] controller: Move address with port parser to lib. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed

Commit Message

Frode Nordahl July 25, 2024, 2 p.m. UTC
Add three new options for Logical Router Ports that control
ovn-controller route exchange for NAT addresses and LB VIPs.

Load Balancers already have structured data in the Southbound
database which the ovn-controller can use directly.

NAT addresses are however currently only expressed as specialized
rules in the Port_Binding table nat_addresses column on LSP peer
records for LRPs, used for (G)ARP processing, as well as
logical flow rules for OpenFlow processing.

Options considered for how to redistribute these addresses to the
ovn-controllers in a structured way:
* Introduce even more conditional processing of the lsp
  nat_addresses column.
* Parse ct_dnat records in the Logical_Flow table.
* Add column to the Port_Binding table.
* Copy the Northbound NAT table over to the Southbound database,
  similar to what is done with Load Balancers.
* Populate Port_Binding table nat_addresses column on LRPs peer
  record (the proposed approach).

The Port_Binding table LRP peer records nat_addresses column is
currently unused, populate it with NAT addresses for route
exchange, when the redistribute-nat LRP option is set to 'true'.

The options are only processed for gateway routers.

Signed-off-by: Frode Nordahl <fnordahl@ubuntu.com>
---
 controller/pinctrl.c |  8 +++++--
 northd/northd.c      | 28 ++++++++++++++++++++++++
 ovn-nb.xml           | 45 ++++++++++++++++++++++++++++++++++++++
 ovn-sb.xml           | 51 +++++++++++++++++++++++++++++++++++++++++++-
 tests/ovn-northd.at  | 42 ++++++++++++++++++++++++++++++++++++
 5 files changed, 171 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 708240e24..d9ef97ce1 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -6428,11 +6428,15 @@  get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_port_binding_by_name,
         const struct sbrec_port_binding *pb;
 
         pb = lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
-        if (!pb) {
+        if (!pb || !pb->datapath) {
             continue;
         }
 
-        if (pb->n_nat_addresses) {
+        /* We only want to consider nat_addresses column for LS datapaths. */
+        const char *logical_switch = smap_get(&pb->datapath->external_ids,
+                                              "logical-switch");
+
+        if (pb->n_nat_addresses && logical_switch) {
             for (int i = 0; i < pb->n_nat_addresses; i++) {
                 consider_nat_address(sbrec_port_binding_by_name,
                                      pb->nat_addresses[i], pb,
diff --git a/northd/northd.c b/northd/northd.c
index d2d557f0b..0c4075847 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3912,6 +3912,8 @@  sync_pb_for_lrp(struct ovn_port *op,
     smap_init(&new);
 
     const char *chassis_name = smap_get(&op->od->nbr->options, "chassis");
+    bool redistribute_nat = smap_get_bool(&op->nbrp->options,
+                                          "redistribute-nat", false);
     if (is_cr_port(op)) {
         const struct lr_stateful_record *lr_stateful_rec =
             lr_stateful_table_find_by_index(lr_stateful_table, op->od->index);
@@ -3950,6 +3952,28 @@  sync_pb_for_lrp(struct ovn_port *op,
         }
         if (chassis_name) {
             smap_add(&new, "l3gateway-chassis", chassis_name);
+            if (smap_get_bool(&op->nbrp->options, "maintain-vrf", false)) {
+                smap_add(&new, "maintain-vrf", "true");
+            }
+            if (redistribute_nat) {
+                smap_add(&new, "redistribute-nat", "true");
+
+                size_t n_nats = 0;
+                char **nats = NULL;
+                nats = get_nat_addresses(op, &n_nats, false, false, NULL,
+                                         true);
+                sbrec_port_binding_set_nat_addresses(op->sb,
+                                                     (const char **) nats,
+                                                     n_nats);
+                for (size_t i = 0; i < n_nats; i++) {
+                    free(nats[i]);
+                }
+                free(nats);
+            }
+            if (smap_get_bool(&op->nbrp->options,
+                              "redistribute-lb-vips", false)) {
+                smap_add(&new, "redistribute-lb-vips", "true");
+            }
         }
     }
 
@@ -3960,6 +3984,10 @@  sync_pb_for_lrp(struct ovn_port *op,
 
     sbrec_port_binding_set_options(op->sb, &new);
     smap_destroy(&new);
+
+    if (!chassis_name || !redistribute_nat) {
+        sbrec_port_binding_set_nat_addresses(op->sb, NULL, 0);
+    }
 }
 
 static void ovn_update_ipv6_options(struct hmap *lr_ports);
diff --git a/ovn-nb.xml b/ovn-nb.xml
index 0f9a1005a..a2681e3c2 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -3467,6 +3467,51 @@  or
           <ref column="options" key="gateway_mtu"/> option.
         </p>
       </column>
+
+      <column name="options" key="redistribute-lb-vips">
+        <p>
+          When configured the <code>ovn-controller</code> will redistribute
+          host routes to Load Balancer VIPs that are local to its chassis and
+          associated with the LR datapath.
+
+          This option only works on gateway routers (routers that have
+          <ref column="options" key="chassis" table="Logical_Router"/> set)
+          when OVN is built on a system with Netlink support.
+        </p>
+      </column>
+
+      <column name="options" key="redistribute-nat">
+        <p>
+          When configured the <code>ovn-controller</code> will redistribute
+          host routes to NAT records associated with logical ports local to
+          its chassis in relateion to the LR datapath.
+
+          This option only works on gateway routers (routers that have
+          <ref column="options" key="chassis" table="Logical_Router"/> set)
+          when OVN is built on a system with Netlink support.
+        </p>
+      </column>
+
+      <column name="options" key="maintain-vrf">
+        <p>
+          When configured the <code>ovn-controller</code> will maintain a VRF
+          in the system for exporting host routes to NAT addresses (see
+          <ref column="options" key="redistribute-nat"/> option) and Load
+          Balancer VIPs (see <ref column="options" key="redistribute-lb-vips"/>
+          option).
+
+          Route table ID to use can be influenced by setting the
+          <ref column="options" key="requested-tnl-key"
+               table="Logical_Router"/> option in the
+          <ref table="Logical_Router"/> table. If not set,
+          <code>ovn-northd</code> will allocate one.
+
+          This option only works on gateway routers (routers that have
+          <ref column="options" key="chassis" table="Logical_Router"/> set)
+          when OVN is built on a system with Netlink support.
+        </p>
+      </column>
+
     </group>
 
     <group title="Attachment">
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 90f113afd..2ee1ea5e1 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -3594,14 +3594,63 @@  tcp.flags = RST;
         The <code>chassis</code> in which the port resides.
       </column>
 
+      <column name="options" key="redistribute-lb-vips">
+        <p>
+          The value is copied from the column
+          <ref table="Logical_Router_Port" column="options"
+               db="OVN_Northbound"/> and when configured the
+          <code>ovn-controller</code> will redistribute host routes to Load
+          Balancer VIPs that are local to its chassis and associated with the
+          LR datapath.
+        </p>
+      </column>
+
+      <column name="options" key="redistribute-nat">
+        <p>
+          The value is copied from the column
+          <ref table="Logical_Router_Port" column="options"
+               db="OVN_Northbound"/> and when configured the
+          <code>ovn-controller</code> will redistribute host routes to
+          <ref table="NAT" db="OVN_Northbound"/> records associated with
+          logical ports local to this chassis in relateion to the LR datapath.
+        </p>
+      </column>
+
+      <column name="options" key="maintain-vrf">
+        <p>
+          The value is copied from the column
+          <ref table="Logical_Router_Port" column="options"
+               db="OVN_Northbound"/> and when configured the
+          <code>ovn-controller</code> will maintain a VRF in the system for
+          exporting host routes to NAT addresses (see
+          <ref column="options" key="redistribute-nat"/> option) and Load
+          Balancer VIPs (see <ref column="options" key="redistribute-lb-vips"/>
+          option).
+        </p>
+      </column>
+
       <column name="nat_addresses">
         MAC address of the <code>l3gateway</code> port followed by a list of
-        SNAT and DNAT external IP addresses.  This is used to send gratuitous
+        SNAT and DNAT external IP addresses.
+
+        Both sides of a LRP-LSP peer relationship have records in the
+        <ref table="Port_Binding"/> table.
+
+        When the record is associated with a
+        <ref table="Datapath_Binding" column="external_ids"
+             key="logical-switch"/> record, this is used to send gratuitous
         ARPs for SNAT and DNAT external IP addresses via <code>localnet</code>.
         Example: <code>80:fa:5b:06:72:b7 158.36.44.22 158.36.44.24</code>.
         This would result in generation of gratuitous ARPs for IP addresses
         158.36.44.22 and 158.36.44.24 with a MAC address of 80:fa:5b:06:72:b7.
         This is used in OVS version 2.8 and later versions.
+
+        When the record is associated with a
+        <ref table="Datapath_Binding" column="external_ids"
+             key="logical-router"/> record, this is used to redistribute host
+        routes to <ref table="NAT" db="OVN_Northbound"/> records associated
+        with logical ports local to this chassis in relateion to the LR
+        datapath.
       </column>
     </group>
 
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 83f91c05c..e303609ed 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -12459,3 +12459,45 @@  AT_CHECK([ovn-sbctl dump-flows lr | grep lr_in_dnat | ovn_strip_lflows], [0], [d
 
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([check route-exchange redistribute-nat option])
+ovn_start
+
+ovn-nbctl lr-add R1
+ovn-nbctl set Logical_Router R1 options:chassis=hv1
+ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
+
+ovn-nbctl ls-add S1
+ovn-nbctl lsp-add S1 S1-R1
+ovn-nbctl lsp-set-type S1-R1 router
+ovn-nbctl lsp-set-addresses S1-R1 02:ac:10:01:00:01
+ovn-nbctl --wait=sb lsp-set-options S1-R1 \
+    router-port=R1-S1 \
+    nat-addresses="router"
+
+ovn-nbctl lr-nat-add R1 snat 172.16.1.1 10.0.0.0/24
+ovn-nbctl lr-nat-add R1 dnat 172.16.1.2 10.0.0.1
+ovn-nbctl --wait=sb sync
+
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding S1-R1 nat_addresses | grep -q 172.16.1.2], [0])
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding R1-S1 nat_addresses | grep -q 172.16.1.2], [1])
+
+ovn-nbctl --wait=sb lrp-set-options R1-S1 redistribute-nat=true
+
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding S1-R1 nat_addresses | grep -q 172.16.1.2], [0])
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding R1-S1 nat_addresses | grep -q 172.16.1.2], [0])
+
+ovn-nbctl --wait=sb lrp-set-options R1-S1 redistribute-nat=false
+
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding S1-R1 nat_addresses | grep -q 172.16.1.2], [0])
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding R1-S1 nat_addresses | grep -q 172.16.1.2], [1])
+
+AT_CLEANUP
+])