If setting the port range in SNAT, we expect that the selected port is in the 
range we set.
At the same time, this behavior is consistent with the kernel-datapath.

The port has no meaning for the icmp/icmpv6 protocol.
If no key is available, it will exit early.

Signed-off-by: LiWei <[email protected]>
---
 lib/conntrack.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/conntrack.c b/lib/conntrack.c
index 4028ba9a0..c3fd7d63d 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -2115,6 +2115,12 @@ nat_range_hash(const struct conn *conn, uint32_t basis)
     return hash_finish(hash, 0);
 }
 
+/* This function selects a unique new connection key based on the ip and port
+ * settings in the nat tuple. For the case where the port range is not
+ * specified, the ephemeral port from 1024 to 65535 can be selected when the
+ * address is exhausted.
+ * However, the ephemeral ports are not enabled by ICMP/ICMPv6 and DNAT.
+ */
 static bool
 nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
                        struct conn *nat_conn)
@@ -2126,12 +2132,14 @@ nat_select_range_tuple(struct conntrack *ct, const 
struct conn *conn,
     uint16_t max_port;
     uint16_t first_port;
     uint32_t hash = nat_range_hash(conn, ct->hash_basis);
+    bool ephemeral_ports_tried = true;
 
     if ((conn->nat_info->nat_action & NAT_ACTION_SRC) &&
         (!(conn->nat_info->nat_action & NAT_ACTION_SRC_PORT))) {
         min_port = ntohs(conn->key.src.port);
         max_port = ntohs(conn->key.src.port);
         first_port = min_port;
+        ephemeral_ports_tried = false;
     } else if ((conn->nat_info->nat_action & NAT_ACTION_DST) &&
                (!(conn->nat_info->nat_action & NAT_ACTION_DST_PORT))) {
         min_port = ntohs(conn->key.dst.port);
@@ -2175,9 +2183,6 @@ nat_select_range_tuple(struct conntrack *ct, const struct 
conn *conn,
 
     uint16_t port = first_port;
     bool all_ports_tried = false;
-    /* For DNAT, we don't use ephemeral ports. */
-    bool ephemeral_ports_tried = conn->nat_info->nat_action & NAT_ACTION_DST
-                                 ? true : false;
     union ct_addr first_addr = ct_addr;
 
     while (true) {
@@ -2190,6 +2195,7 @@ nat_select_range_tuple(struct conntrack *ct, const struct 
conn *conn,
         if ((conn->key.nw_proto == IPPROTO_ICMP) ||
             (conn->key.nw_proto == IPPROTO_ICMPV6)) {
             all_ports_tried = true;
+            ephemeral_ports_tried = true;
         } else if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
             nat_conn->rev_key.dst.port = htons(port);
         } else {
-- 
2.11.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to