From: Srikar Tati <[email protected]>

Static routes choose the fields that their ECMP group hashes on with
the "selection_fields" column.  The following patches let learned
routes and EVPN FDB entries take the same fields from a string option.

Move the static route handling of tp_src and tp_dst to
ovn_ecmp_selection_fields_add(), so that every user adds ip_proto in
the same way.

Assisted-by: Claude Opus 5.5, Claude Code
Acked-by: Numan Siddique <[email protected]>
Signed-off-by: Srikar Tati <[email protected]>
---
v2:
  - Make 'selection_fields' the last parameter of
    ovn_ecmp_selection_fields_add(). (Numan)
  - Move ovn_ecmp_selection_fields_parse() to the next patch, which
    uses it. (Numan)
  - Rebased on main.

 lib/ovn-util.c  | 13 +++++++++++++
 lib/ovn-util.h  |  3 +++
 northd/northd.c | 17 +++--------------
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/lib/ovn-util.c b/lib/ovn-util.c
index eb1fa8a06..ceec1e563 100644
--- a/lib/ovn-util.c
+++ b/lib/ovn-util.c
@@ -1634,6 +1634,19 @@ ovn_is_valid_vni(int64_t vni)
     return vni >= 0 && (vni <= (1 << 24) - 1);
 }
 
+/* Adds 'field' to the ECMP 'selection_fields'.  If 'field' is tp_src or
+ * tp_dst, also adds ip_proto: the protocol specific port fields are only
+ * valid with a match on the protocol. */
+void
+ovn_ecmp_selection_fields_add(const char *field,
+                              struct sset *selection_fields)
+{
+    if (!strcmp(field, "tp_src") || !strcmp(field, "tp_dst")) {
+        sset_add(selection_fields, "ip_proto");
+    }
+    sset_add(selection_fields, field);
+}
+
 struct sset *
 lrp_network_sset(const char **networks, int n_networks)
 {
diff --git a/lib/ovn-util.h b/lib/ovn-util.h
index 01d21d282..5c5fdceb1 100644
--- a/lib/ovn-util.h
+++ b/lib/ovn-util.h
@@ -735,6 +735,9 @@ void ovn_debug_commands_register(void);
 
 bool ovn_is_valid_vni(int64_t vni);
 
+void ovn_ecmp_selection_fields_add(const char *field,
+                                   struct sset *selection_fields);
+
 const struct sbrec_port_binding *lport_lookup_by_name(
     struct ovsdb_idl_index *sbrec_port_binding_by_name,
     const char *name);
diff --git a/northd/northd.c b/northd/northd.c
index 3f59894bd..1b9e203a3 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -13041,20 +13041,9 @@ parsed_routes_add_static(const struct ovn_datapath *od,
 
     struct sset ecmp_selection_fields =
         SSET_INITIALIZER(&ecmp_selection_fields);
-
-    /* If tp_src or tp_dst is included in the selection_fields, implicitly
-     * include match on ip_proto. */
-    if (route->n_selection_fields) {
-        struct sset field_set = SSET_INITIALIZER(&field_set);
-        for (size_t i = 0; i < route->n_selection_fields; i++) {
-            char *field = route->selection_fields[i];
-            if (!strcmp(field, "tp_src") || !strcmp(field, "tp_dst")) {
-                sset_add(&field_set, "ip_proto");
-            }
-            sset_add(&field_set, field);
-        }
-        sset_clone(&ecmp_selection_fields, &field_set);
-        sset_destroy(&field_set);
+    for (size_t i = 0; i < route->n_selection_fields; i++) {
+        ovn_ecmp_selection_fields_add(route->selection_fields[i],
+                                      &ecmp_selection_fields);
     }
 
     uint32_t route_table_id = get_route_table_id(route_tables,
-- 
2.54.0

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

Reply via email to