diff mbox series

[ovs-dev,RFC,v3,3/4] pinctrl: Update ecmp-nexthop mac resolving L2 address.

Message ID 9a3d81afee3aca22ee5f1c6dce35e2283ca3f4de.1731342268.git.lorenzo.bianconi@redhat.com
State New
Headers show
Series Introduce ECMP_nexthop monitor in ovn-controller | 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 fail github build: failed

Commit Message

Lorenzo Bianconi Nov. 11, 2024, 4:30 p.m. UTC
Set the mac address column in the ECMP_Nexthop table updating
sb MAC_Binding table. This is a preliminary patch to introduce the
capability to flush stale ECMP CT entries.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 controller/ovn-controller.c |  4 ++
 controller/pinctrl.c        | 85 ++++++++++++++++++++++++++++++-------
 controller/pinctrl.h        |  1 +
 3 files changed, 75 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index c93995b94..c319e0d77 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -4963,6 +4963,9 @@  main(int argc, char *argv[])
         = ovsdb_idl_index_create2(ovnsb_idl_loop.idl,
                                   &sbrec_fdb_col_mac,
                                   &sbrec_fdb_col_dp_key);
+    struct ovsdb_idl_index *sbrec_ecmp_by_nexthop
+        = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
+                                  &sbrec_ecmp_nexthop_col_nexthop);
     struct ovsdb_idl_index *sbrec_mac_binding_by_datapath
         = mac_binding_by_datapath_index_create(ovnsb_idl_loop.idl);
     struct ovsdb_idl_index *sbrec_static_mac_binding_by_datapath
@@ -5691,6 +5694,7 @@  main(int argc, char *argv[])
                                     sbrec_igmp_group,
                                     sbrec_ip_multicast,
                                     sbrec_fdb_by_dp_key_mac,
+                                    sbrec_ecmp_by_nexthop,
                                     sbrec_dns_table_get(ovnsb_idl_loop.idl),
                                     sbrec_controller_event_table_get(
                                         ovnsb_idl_loop.idl),
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index d97b10710..a3cfe73bd 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -207,11 +207,15 @@  static void pinctrl_handle_put_mac_binding(const struct flow *md,
     OVS_REQUIRES(pinctrl_mutex);
 static void init_put_mac_bindings(void);
 static void destroy_put_mac_bindings(void);
+static const struct sbrec_ecmp_nexthop *ecmp_nexthop_lookup(
+        struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
+        const char *nexthop);
 static void run_put_mac_bindings(
     struct ovsdb_idl_txn *ovnsb_idl_txn,
     struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
     struct ovsdb_idl_index *sbrec_port_binding_by_key,
-    struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip)
+    struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+    struct ovsdb_idl_index *sbrec_ecmp_by_nexthop)
     OVS_REQUIRES(pinctrl_mutex);
 static void wait_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn);
 static void send_mac_binding_buffered_pkts(struct rconn *swconn)
@@ -243,6 +247,7 @@  static void send_garp_rarp_prepare(
     struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
     struct ovsdb_idl_index *sbrec_port_binding_by_name,
     struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+    struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
     const struct sbrec_ecmp_nexthop_table *ecmp_nh_table,
     const struct ovsrec_bridge *,
     const struct sbrec_chassis *,
@@ -4157,6 +4162,7 @@  pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
             struct ovsdb_idl_index *sbrec_igmp_groups,
             struct ovsdb_idl_index *sbrec_ip_multicast_opts,
             struct ovsdb_idl_index *sbrec_fdb_by_dp_key_mac,
+            struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
             const struct sbrec_dns_table *dns_table,
             const struct sbrec_controller_event_table *ce_table,
             const struct sbrec_service_monitor_table *svc_mon_table,
@@ -4174,12 +4180,14 @@  pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
     ovs_mutex_lock(&pinctrl_mutex);
     run_put_mac_bindings(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
                          sbrec_port_binding_by_key,
-                         sbrec_mac_binding_by_lport_ip);
+                         sbrec_mac_binding_by_lport_ip,
+                         sbrec_ecmp_by_nexthop);
     run_put_vport_bindings(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
                            sbrec_port_binding_by_key, chassis);
     send_garp_rarp_prepare(ovnsb_idl_txn, sbrec_port_binding_by_datapath,
                            sbrec_port_binding_by_name,
-                           sbrec_mac_binding_by_lport_ip, ecmp_nh_table,
+                           sbrec_mac_binding_by_lport_ip,
+                           sbrec_ecmp_by_nexthop, ecmp_nh_table,
                            br_int, chassis, local_datapaths, active_tunnels,
                            ovs_table);
     prepare_ipv6_ras(local_active_ports_ras, sbrec_port_binding_by_name);
@@ -4827,6 +4835,7 @@  send_mac_binding_buffered_pkts(struct rconn *swconn)
 static void
 mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
                       struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+                      struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
                       const char *logical_port,
                       const struct sbrec_datapath_binding *dp,
                       struct eth_addr ea, const char *ip,
@@ -4858,6 +4867,12 @@  mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
             sbrec_mac_binding_set_timestamp(b, time_wall_msec());
         }
     }
+
+    const struct sbrec_ecmp_nexthop *ecmp_nh =
+        ecmp_nexthop_lookup(sbrec_ecmp_by_nexthop, ip);
+    if (ecmp_nh) {
+        sbrec_ecmp_nexthop_set_mac(ecmp_nh, mac_string);
+    }
 }
 
 /* Simulate the effect of a GARP on local datapaths, i.e., create MAC_Bindings
@@ -4866,6 +4881,7 @@  mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
 static void
 send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
                   struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+                  struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
                   const struct hmap *local_datapaths,
                   const struct sbrec_port_binding *in_pb,
                   struct eth_addr ea, ovs_be32 ip)
@@ -4895,17 +4911,33 @@  send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
 
         ip_format_masked(ip, OVS_BE32_MAX, &ip_s);
         mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
-                              remote->logical_port, remote->datapath,
-                              ea, ds_cstr(&ip_s), update_only);
+                              sbrec_ecmp_by_nexthop, remote->logical_port,
+                              remote->datapath, ea, ds_cstr(&ip_s),
+                              update_only);
         ds_destroy(&ip_s);
     }
 }
 
+static const struct sbrec_ecmp_nexthop *
+ecmp_nexthop_lookup(struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
+                    const char *nexthop)
+{
+    struct sbrec_ecmp_nexthop *ecmp_nh =
+            sbrec_ecmp_nexthop_index_init_row(sbrec_ecmp_by_nexthop);
+    sbrec_ecmp_nexthop_set_nexthop(ecmp_nh, nexthop);
+    const struct sbrec_ecmp_nexthop *retval =
+            sbrec_ecmp_nexthop_index_find(sbrec_ecmp_by_nexthop, ecmp_nh);
+    sbrec_ecmp_nexthop_index_destroy_row(ecmp_nh);
+
+    return retval;
+}
+
 static void
 run_put_mac_binding(struct ovsdb_idl_txn *ovnsb_idl_txn,
                     struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
                     struct ovsdb_idl_index *sbrec_port_binding_by_key,
                     struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+                    struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
                     const struct mac_binding *mb)
 {
     /* Convert logical datapath and logical port key into lport. */
@@ -4928,8 +4960,9 @@  run_put_mac_binding(struct ovsdb_idl_txn *ovnsb_idl_txn,
     struct ds ip_s = DS_EMPTY_INITIALIZER;
     ipv6_format_mapped(&mb->data.ip, &ip_s);
     mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
-                          pb->logical_port, pb->datapath, mb->data.mac,
-                          ds_cstr(&ip_s), false);
+                          sbrec_ecmp_by_nexthop, pb->logical_port,
+                          pb->datapath, mb->data.mac, ds_cstr(&ip_s),
+                          false);
     ds_destroy(&ip_s);
 }
 
@@ -4939,7 +4972,8 @@  static void
 run_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn,
                      struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
                      struct ovsdb_idl_index *sbrec_port_binding_by_key,
-                     struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip)
+                     struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+                     struct ovsdb_idl_index *sbrec_ecmp_by_nexthop)
     OVS_REQUIRES(pinctrl_mutex)
 {
     if (!ovnsb_idl_txn) {
@@ -4954,7 +4988,8 @@  run_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn,
             run_put_mac_binding(ovnsb_idl_txn,
                                 sbrec_datapath_binding_by_key,
                                 sbrec_port_binding_by_key,
-                                sbrec_mac_binding_by_lport_ip, mb);
+                                sbrec_mac_binding_by_lport_ip,
+                                sbrec_ecmp_by_nexthop, mb);
             mac_binding_remove(&put_mac_bindings, mb);
         }
     }
@@ -5104,6 +5139,7 @@  add_garp_rarp(const char *name, const struct eth_addr ea, ovs_be32 ip,
 static void
 send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
                       struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+                      struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
                       const struct hmap *local_datapaths,
                       const struct sbrec_port_binding *binding_rec,
                       struct shash *nat_addresses,
@@ -5147,8 +5183,9 @@  send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
                                   binding_rec->tunnel_key);
                     send_garp_locally(ovnsb_idl_txn,
                                       sbrec_mac_binding_by_lport_ip,
-                                      local_datapaths, binding_rec, laddrs->ea,
-                                      laddrs->ipv4_addrs[i].addr);
+                                      sbrec_ecmp_by_nexthop,
+                                      local_datapaths, binding_rec,
+                                      laddrs->ea, laddrs->ipv4_addrs[i].addr);
 
                 }
                 free(name);
@@ -5217,7 +5254,8 @@  send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
                       binding_rec->tunnel_key);
         if (ip) {
             send_garp_locally(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
-                              local_datapaths, binding_rec, laddrs.ea, ip);
+                              sbrec_ecmp_by_nexthop, local_datapaths,
+                              binding_rec, laddrs.ea, ip);
         }
 
         destroy_lport_addresses(&laddrs);
@@ -6824,6 +6862,7 @@  send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
                        struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
                        struct ovsdb_idl_index *sbrec_port_binding_by_name,
                        struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+                       struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
                        const struct sbrec_ecmp_nexthop_table *ecmp_nh_table,
                        const struct ovsrec_bridge *br_int,
                        const struct sbrec_chassis *chassis,
@@ -6885,6 +6924,7 @@  send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
         if (pb && !smap_get_bool(&pb->options, "disable_garp_rarp", false)) {
             send_garp_rarp_update(ovnsb_idl_txn,
                                   sbrec_mac_binding_by_lport_ip,
+                                  sbrec_ecmp_by_nexthop,
                                   local_datapaths, pb, &nat_addresses,
                                   garp_max_timeout, garp_continuous);
         }
@@ -6897,8 +6937,9 @@  send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
             = lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
         if (pb && !smap_get_bool(&pb->options, "disable_garp_rarp", false)) {
             send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
-                                  local_datapaths, pb, &nat_addresses,
-                                  garp_max_timeout, garp_continuous);
+                                  sbrec_ecmp_by_nexthop, local_datapaths, pb,
+                                  &nat_addresses, garp_max_timeout,
+                                  garp_continuous);
         }
     }
 
@@ -6914,7 +6955,21 @@  send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
 
     SBREC_ECMP_NEXTHOP_TABLE_FOR_EACH (sb_ecmp_nexthop, ecmp_nh_table) {
         const struct sbrec_port_binding *pb = sb_ecmp_nexthop->port;
-        if (pb && !strcmp(pb->type, "l3gateway") && pb->chassis == chassis) {
+        if (!pb || pb->chassis != chassis) {
+            continue;
+        }
+
+        /* Update mac binding if not already set. */
+        if (!strcmp(sb_ecmp_nexthop->mac, "")) {
+            const struct sbrec_mac_binding *mb =
+                mac_binding_lookup(sbrec_mac_binding_by_lport_ip,
+                                   pb->logical_port, sb_ecmp_nexthop->nexthop);
+            if (ovnsb_idl_txn && mb) {
+                sbrec_ecmp_nexthop_set_mac(sb_ecmp_nexthop, mb->mac);
+            }
+        }
+
+        if (!strcmp(pb->type, "l3gateway")) {
             send_arp_nd_update(pb, sb_ecmp_nexthop->nexthop,
                                max_arp_nd_timeout, continuous_arp_nd);
         }
diff --git a/controller/pinctrl.h b/controller/pinctrl.h
index 5c8ea7aea..f1968f31c 100644
--- a/controller/pinctrl.h
+++ b/controller/pinctrl.h
@@ -50,6 +50,7 @@  void pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
                  struct ovsdb_idl_index *sbrec_igmp_groups,
                  struct ovsdb_idl_index *sbrec_ip_multicast_opts,
                  struct ovsdb_idl_index *sbrec_fdb_by_dp_key_mac,
+                 struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
                  const struct sbrec_dns_table *,
                  const struct sbrec_controller_event_table *,
                  const struct sbrec_service_monitor_table *,