diff mbox series

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

Message ID dab5bea663d9422eb99905b5acf71554a086471a.1726765502.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 Sept. 19, 2024, 5:08 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        | 50 +++++++++++++++++++++++++++++--------
 controller/pinctrl.h        |  1 +
 northd/en-northd.c          |  4 +++
 northd/inc-proc-northd.c    |  6 +++++
 northd/northd.c             | 17 +++++++++++++
 northd/northd.h             |  1 +
 7 files changed, 72 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index e72d28731..4dc9bc8cb 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -4939,6 +4939,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
@@ -5645,6 +5648,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 daf0bfa41..092613c4a 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -206,11 +206,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);
+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)
@@ -4160,6 +4164,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,
@@ -4177,7 +4182,8 @@  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,
@@ -4831,13 +4837,9 @@  mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
                       struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
                       const char *logical_port,
                       const struct sbrec_datapath_binding *dp,
-                      struct eth_addr ea, const char *ip,
+                      char *mac_string, const char *ip,
                       bool update_only)
 {
-    /* Convert ethernet argument to string form for database. */
-    char mac_string[ETH_ADDR_STRLEN + 1];
-    snprintf(mac_string, sizeof mac_string, ETH_ADDR_FMT, ETH_ADDR_ARGS(ea));
-
     const struct sbrec_mac_binding *b =
             mac_binding_lookup(sbrec_mac_binding_by_lport_ip,
                                logical_port, ip);
@@ -4896,18 +4898,37 @@  send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
         struct ds ip_s = DS_EMPTY_INITIALIZER;
 
         ip_format_masked(ip, OVS_BE32_MAX, &ip_s);
+        /* Convert ethernet argument to string form for database. */
+        char mac_string[ETH_ADDR_STRLEN + 1];
+        snprintf(mac_string, sizeof mac_string, ETH_ADDR_FMT,
+                 ETH_ADDR_ARGS(ea));
         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);
+                              mac_string, ds_cstr(&ip_s), update_only);
         ds_destroy(&ip_s);
     }
 }
 
+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. */
@@ -4930,8 +4951,13 @@  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,
+                          pb->logical_port, pb->datapath, mac_string,
                           ds_cstr(&ip_s), false);
+    const struct sbrec_ecmp_nexthop *ecmp_nh =
+        ecmp_nexthop_lookup(sbrec_ecmp_by_nexthop, ds_cstr(&ip_s));
+    if (ecmp_nh) {
+        sbrec_ecmp_nexthop_set_mac(ecmp_nh, mac_string);
+    }
     ds_destroy(&ip_s);
 }
 
@@ -4941,7 +4967,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) {
@@ -4956,7 +4983,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);
         }
     }
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 *,
diff --git a/northd/en-northd.c b/northd/en-northd.c
index b8227617b..b3e612958 100644
--- a/northd/en-northd.c
+++ b/northd/en-northd.c
@@ -412,9 +412,13 @@  en_ecmp_nexthop_run(struct engine_node *node, void *data OVS_UNUSED)
         engine_get_input_data("static_routes", node);
     const struct sbrec_ecmp_nexthop_table *sbrec_ecmp_nexthop_table =
         EN_OVSDB_GET(engine_get_input("SB_ecmp_nexthop", node));
+    struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip =
+        engine_ovsdb_node_get_index(engine_get_input("SB_mac_binding", node),
+                                    "sbrec_mac_binding_by_lport_ip");
 
     build_ecmp_nexthop_table(eng_ctx->ovnsb_idl_txn,
                              &static_routes_data->parsed_routes,
+                             sbrec_mac_binding_by_lport_ip,
                              sbrec_ecmp_nexthop_table);
     engine_set_node_state(node, EN_UPDATED);
 }
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index cdc080ef0..d29bdca3e 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -266,6 +266,7 @@  void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_bfd_sync, &en_route_policies, NULL);
     engine_add_input(&en_bfd_sync, &en_northd, bfd_sync_northd_change_handler);
 
+    engine_add_input(&en_ecmp_nexthop, &en_sb_mac_binding, NULL);
     engine_add_input(&en_ecmp_nexthop, &en_sb_ecmp_nexthop, NULL);
     engine_add_input(&en_ecmp_nexthop, &en_static_routes, NULL);
 
@@ -369,6 +370,8 @@  void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
         = static_mac_binding_index_create(sb->idl);
     struct ovsdb_idl_index *sbrec_mac_binding_by_datapath
         = mac_binding_by_datapath_index_create(sb->idl);
+    struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip
+        = mac_binding_by_lport_ip_index_create(sb->idl);
     struct ovsdb_idl_index *fdb_by_dp_key =
         ovsdb_idl_index_create1(sb->idl, &sbrec_fdb_col_dp_key);
 
@@ -395,6 +398,9 @@  void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_ovsdb_node_add_index(&en_sb_mac_binding,
                                 "sbrec_mac_binding_by_datapath",
                                 sbrec_mac_binding_by_datapath);
+    engine_ovsdb_node_add_index(&en_sb_mac_binding,
+                                "sbrec_mac_binding_by_lport_ip",
+                                sbrec_mac_binding_by_lport_ip);
     engine_ovsdb_node_add_index(&en_sb_fdb,
                                 "fdb_by_dp_key",
                                 fdb_by_dp_key);
diff --git a/northd/northd.c b/northd/northd.c
index 3e3bb84ef..4e99e2687 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -10669,6 +10669,7 @@  void
 build_ecmp_nexthop_table(
         struct ovsdb_idl_txn *ovnsb_txn,
         struct hmap *routes,
+        struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
         const struct sbrec_ecmp_nexthop_table *sbrec_ecmp_nexthop_table)
 {
     if (!ovnsb_txn) {
@@ -10699,6 +10700,22 @@  build_ecmp_nexthop_table(
             sb_ecmp_nexthop = sbrec_ecmp_nexthop_insert(ovnsb_txn);
             sbrec_ecmp_nexthop_set_nexthop(sb_ecmp_nexthop, r->nexthop);
             sbrec_ecmp_nexthop_set_port(sb_ecmp_nexthop, pr->out_port->key);
+
+            struct sbrec_mac_binding *mb_index_row =
+                sbrec_mac_binding_index_init_row(
+                        sbrec_mac_binding_by_lport_ip);
+            sbrec_mac_binding_index_set_ip(mb_index_row, r->nexthop);
+            sbrec_mac_binding_index_set_logical_port(mb_index_row,
+                                                     pr->out_port->key);
+
+            const struct sbrec_mac_binding *mb =
+                sbrec_mac_binding_index_find(sbrec_mac_binding_by_lport_ip,
+                                             mb_index_row);
+            if (mb) {
+                sbrec_ecmp_nexthop_set_mac(sb_ecmp_nexthop, mb->mac);
+            }
+
+            sbrec_mac_binding_index_destroy_row(mb_index_row);
         }
         sset_add(&nb_nexthops_sset, r->nexthop);
     }
diff --git a/northd/northd.h b/northd/northd.h
index c4c2a5d7e..83239197f 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -747,6 +747,7 @@  void bfd_sync_init(struct bfd_sync_data *);
 void bfd_sync_destroy(struct bfd_sync_data *);
 
 void build_ecmp_nexthop_table(struct ovsdb_idl_txn *, struct hmap *,
+                              struct ovsdb_idl_index *,
                               const struct sbrec_ecmp_nexthop_table *);
 
 struct lflow_table;