From: wenxu <[email protected]>

Splits the nested loop used to search the unique ports for the
reverse tuple.
It affects only the dnat action, giving more precedence to the dnat
range, similarly to the kernel dp, instead of searching through the
default ephemeral source range for each destination port.

Signed-off-by: wenxu <[email protected]>
---
 lib/conntrack.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/lib/conntrack.c b/lib/conntrack.c
index 44f99f3..2a5d72a 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -2411,9 +2411,11 @@ next_addr_in_range_guarded(union ct_addr *curr, union 
ct_addr *min,
  *
  * In case of DNAT:
  *    - For each dst IP address in the range (if any).
- *        - For each dport in range (if any).
- *             - Try to find a source port in the ephemeral range
- *               (after testing the port used by the sender).
+ *        - For each dport in range (if any) tries to find
+ *          an unique tuple.
+ *        - Eventually, if the previous attempt fails,
+ *          tries to find a source port in the ephemeral
+ *          range (after testing the port used by the sender).
  *
  * If none can be found, return exhaustion to the caller. */
 static bool
@@ -2457,10 +2459,9 @@ another_round:
         goto next_addr;
     }
 
-    FOR_EACH_PORT_IN_RANGE(curr_dport, min_dport, max_dport) {
-        nat_conn->rev_key.src.port = htons(curr_dport);
-        FOR_EACH_PORT_IN_RANGE(curr_sport, min_sport, max_sport) {
-            nat_conn->rev_key.dst.port = htons(curr_sport);
+    if (nat_info->nat_action & NAT_ACTION_DST_PORT) {
+        FOR_EACH_PORT_IN_RANGE(curr_dport, min_dport, max_dport) {
+            nat_conn->rev_key.src.port = htons(curr_dport);
             if (!conn_lookup(ct, &nat_conn->rev_key,
                              time_msec(), NULL, NULL)) {
                 return true;
@@ -2468,6 +2469,14 @@ another_round:
         }
     }
 
+    FOR_EACH_PORT_IN_RANGE(curr_sport, min_sport, max_sport) {
+        nat_conn->rev_key.dst.port = htons(curr_sport);
+        if (!conn_lookup(ct, &nat_conn->rev_key,
+                         time_msec(), NULL, NULL)) {
+            return true;
+        }
+    }
+
     /* Check if next IP is in range and respin. Otherwise, notify
      * exhaustion to the caller. */
 next_addr:
-- 
1.8.3.1

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

Reply via email to