The patch, when 'persistent' flag is specified, makes the IP selection
in a range persistent across reboots.

Signed-off-by: Paolo Valerio <pvale...@redhat.com>
Acked-by: Simon Horman <ho...@ovn.org>
---
v3:
- rearranged branches in nat_get_unique_tuple() (Simon)
---
 NEWS              |  3 ++-
 lib/conntrack.c   | 25 +++++++++++++++++++------
 lib/conntrack.h   |  1 +
 lib/dpif-netdev.c |  2 ++
 4 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/NEWS b/NEWS
index 93046b963..0c86bba81 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,8 @@ Post-v3.3.0
 --------------------
    - Userspace datapath:
      * Conntrack now supports 'random' flag for selecting ports in a range
-       while natting.
+       while natting and 'persistent' flag for selection of the IP address
+       from a range.
 
 
 v3.3.0 - xx xxx xxxx
diff --git a/lib/conntrack.c b/lib/conntrack.c
index e09ecdf33..8a7056bac 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -2202,17 +2202,21 @@ nat_range_hash(const struct conn_key *key, uint32_t 
basis,
 {
     uint32_t hash = basis;
 
+    if (!basis) {
+        hash = ct_addr_hash_add(hash, &key->src.addr);
+    } else {
+        hash = ct_endpoint_hash_add(hash, &key->src);
+        hash = ct_endpoint_hash_add(hash, &key->dst);
+    }
+
     hash = ct_addr_hash_add(hash, &nat_info->min_addr);
     hash = ct_addr_hash_add(hash, &nat_info->max_addr);
     hash = hash_add(hash,
                     ((uint32_t) nat_info->max_port << 16)
                     | nat_info->min_port);
-    hash = ct_endpoint_hash_add(hash, &key->src);
-    hash = ct_endpoint_hash_add(hash, &key->dst);
     hash = hash_add(hash, (OVS_FORCE uint32_t) key->dl_type);
     hash = hash_add(hash, key->nw_proto);
     hash = hash_add(hash, key->zone);
-
     /* The purpose of the second parameter is to distinguish hashes of data of
      * different length; our data always has the same length so there is no
      * value in counting. */
@@ -2388,10 +2392,19 @@ nat_get_unique_tuple(struct conntrack *ct, struct conn 
*conn,
                      fwd_key->nw_proto == IPPROTO_SCTP;
     uint16_t min_dport, max_dport, curr_dport;
     uint16_t min_sport, max_sport, curr_sport;
-    uint32_t hash, port_off;
+    uint32_t hash, port_off, basis;
+
+    basis = (nat_info->nat_flags & NAT_PERSISTENT) ? 0 : ct->hash_basis;
+    hash = nat_range_hash(fwd_key, basis, nat_info);
+
+    if (nat_info->nat_flags & NAT_RANGE_RANDOM) {
+        port_off = random_uint32();
+    } else if (basis) {
+        port_off = hash;
+    } else {
+        port_off = nat_range_hash(fwd_key, ct->hash_basis, nat_info);
+    }
 
-    hash = nat_range_hash(fwd_key, ct->hash_basis, nat_info);
-    port_off = nat_info->nat_flags & NAT_RANGE_RANDOM ? random_uint32() : hash;
     min_addr = nat_info->min_addr;
     max_addr = nat_info->max_addr;
 
diff --git a/lib/conntrack.h b/lib/conntrack.h
index 9b0c6aa88..ee7da099e 100644
--- a/lib/conntrack.h
+++ b/lib/conntrack.h
@@ -79,6 +79,7 @@ enum nat_action_e {
 
 enum nat_flags_e {
     NAT_RANGE_RANDOM = 1 << 0,
+    NAT_PERSISTENT = 1 << 1,
 };
 
 struct nat_action_info_t {
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index c3334c667..fbf7ccabd 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -9413,6 +9413,8 @@ dp_execute_cb(void *aux_, struct dp_packet_batch 
*packets_,
                         nat_action_info.nat_flags |= NAT_RANGE_RANDOM;
                         break;
                     case OVS_NAT_ATTR_PERSISTENT:
+                        nat_action_info.nat_flags |= NAT_PERSISTENT;
+                        break;
                     case OVS_NAT_ATTR_PROTO_HASH:
                         break;
                     case OVS_NAT_ATTR_UNSPEC:
-- 
2.43.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to