diff mbox series

[ovs-dev,1/3] nothd: Unify the priority calculation for NAT flows.

Message ID 20240503072622.2111265-2-amusil@redhat.com
State New
Headers show
Series Arbitrary match for NAT | 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

Ales Musil May 3, 2024, 7:26 a.m. UTC
The priority calculation was scattered in multiple places which
could result in errors when the code is being updated. Move it
to common function that makes it very clear how is the priority
calculated.

Signed-off-by: Ales Musil <amusil@redhat.com>
---
 northd/northd.c | 82 +++++++++++++++++++------------------------------
 1 file changed, 32 insertions(+), 50 deletions(-)
diff mbox series

Patch

diff --git a/northd/northd.c b/northd/northd.c
index 133cddb69..a883c3e08 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -11543,6 +11543,25 @@  lrouter_dnat_and_snat_is_stateless(const struct nbrec_nat *nat)
            !strcmp(nat->type, "dnat_and_snat");
 }
 
+static inline uint16_t
+lrouter_nat_get_priority(const struct ovn_datapath *od, bool is_dnat,
+                         uint16_t prefix_len)
+{
+    if (is_dnat) {
+        return 100;
+    }
+
+    /* The priority here is calculated such that the
+     * nat->logical_ip with the longest mask gets a higher
+     * priority. */
+    uint16_t priority = prefix_len + 1;
+    if (!od->is_gw_router && od->n_l3dgw_ports) {
+        priority += 128;
+    }
+
+    return priority;
+}
+
 /* Handles the match criteria and actions in logical flow
  * based on external ip based NAT rule filter.
  *
@@ -11573,7 +11592,6 @@  lrouter_nat_add_ext_ip_match(const struct ovn_datapath *od,
     } else if (exempted_ext_ips) {
         struct ds match_exempt = DS_EMPTY_INITIALIZER;
         enum ovn_stage stage = is_src ? S_ROUTER_IN_DNAT : S_ROUTER_OUT_SNAT;
-        uint16_t priority;
 
         /* Priority of logical flows corresponding to exempted_ext_ips is
          * +2 of the corresponding regular NAT rule.
@@ -11589,17 +11607,8 @@  lrouter_nat_add_ext_ip_match(const struct ovn_datapath *od,
          * lr_out_snat...priority=161, match=(..), action=(ct_snat(....);)
          *
          */
-        if (is_src) {
-            /* S_ROUTER_IN_DNAT uses priority 100 */
-            priority = 100 + 2;
-        } else {
-            /* S_ROUTER_OUT_SNAT uses priority (mask + 1 + 128 + 1) */
-            priority = cidr_bits + 3;
-
-            if (!od->is_gw_router) {
-                priority += 128;
-           }
-        }
+        uint16_t priority =
+                lrouter_nat_get_priority(od, is_src, cidr_bits) + 2;
 
         ds_clone(&match_exempt, match);
         ds_put_format(&match_exempt, " && ip%s.%s == $%s",
@@ -14598,7 +14607,8 @@  build_lrouter_in_dnat_flow(struct lflow_table *lflows,
         ds_put_format(actions, ");");
     }
 
-    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DNAT, 100,
+    ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DNAT,
+                            lrouter_nat_get_priority(od, true, cidr_bits),
                             ds_cstr(match), ds_cstr(actions),
                             &nat->header_, lflow_ref);
 }
@@ -14741,25 +14751,14 @@  build_lrouter_out_snat_stateless_flow(struct lflow_table *lflows,
 
     ds_clear(actions);
 
-    /* The priority here is calculated such that the
-     * nat->logical_ip with the longest mask gets a higher
-     * priority. */
-    uint16_t priority = cidr_bits + 1;
-
+    uint16_t priority = lrouter_nat_get_priority(od, false, cidr_bits);
     build_lrouter_out_snat_match(lflows, od, nat, match, distributed_nat,
                                  cidr_bits, is_v6, l3dgw_port, lflow_ref,
                                  false);
 
-    if (!od->is_gw_router) {
-        /* Distributed router. */
-        if (od->n_l3dgw_ports) {
-            priority += 128;
-        }
-
-        if (distributed_nat) {
-            ds_put_format(actions, "eth.src = "ETH_ADDR_FMT"; ",
-                          ETH_ADDR_ARGS(mac));
-        }
+    if (!od->is_gw_router && distributed_nat) {
+        ds_put_format(actions, "eth.src = "ETH_ADDR_FMT"; ",
+                      ETH_ADDR_ARGS(mac));
     }
 
     ds_put_format(actions, "ip%c.src=%s; next;",
@@ -14787,20 +14786,13 @@  build_lrouter_out_snat_in_czone_flow(struct lflow_table *lflows,
 
     ds_clear(actions);
 
-    /* The priority here is calculated such that the
-     * nat->logical_ip with the longest mask gets a higher
-     * priority. */
-    uint16_t priority = cidr_bits + 1;
+    uint16_t priority = lrouter_nat_get_priority(od, false, cidr_bits);
     struct ds zone_actions = DS_EMPTY_INITIALIZER;
 
     build_lrouter_out_snat_match(lflows, od, nat, match, distributed_nat,
                                  cidr_bits, is_v6, l3dgw_port,
                                  lflow_ref, false);
 
-    if (od->n_l3dgw_ports) {
-        priority += 128;
-    }
-
     if (distributed_nat) {
         ds_put_format(actions, "eth.src = "ETH_ADDR_FMT"; ",
                       ETH_ADDR_ARGS(mac));
@@ -14853,26 +14845,16 @@  build_lrouter_out_snat_flow(struct lflow_table *lflows,
 
     ds_clear(actions);
 
-    /* The priority here is calculated such that the
-     * nat->logical_ip with the longest mask gets a higher
-     * priority. */
-    uint16_t priority = cidr_bits + 1;
+    uint16_t priority = lrouter_nat_get_priority(od, false, cidr_bits);
 
     build_lrouter_out_snat_match(lflows, od, nat, match, distributed_nat,
                                  cidr_bits, is_v6, l3dgw_port, lflow_ref,
                                  false);
     size_t original_match_len = match->length;
 
-    if (!od->is_gw_router) {
-        /* Distributed router. */
-        if (od->n_l3dgw_ports) {
-            priority += 128;
-        }
-
-        if (distributed_nat) {
-            ds_put_format(actions, "eth.src = "ETH_ADDR_FMT"; ",
-                          ETH_ADDR_ARGS(mac));
-        }
+    if (!od->is_gw_router && distributed_nat) {
+        ds_put_format(actions, "eth.src = "ETH_ADDR_FMT"; ",
+                      ETH_ADDR_ARGS(mac));
     }
     ds_put_cstr(match, " && (!ct.trk || !ct.rpl)");