@@ -2179,20 +2179,16 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
bool ephemeral_ports_tried = conn->nat_info->nat_action & NAT_ACTION_DST
? true : false;
union ct_addr first_addr = ct_addr;
+ bool pat_enabled = conn->key.nw_proto != IPPROTO_ICMP &&
+ conn->key.nw_proto != IPPROTO_ICMPV6;
while (true) {
+
if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
nat_conn->rev_key.dst.addr = ct_addr;
- } else {
- nat_conn->rev_key.src.addr = ct_addr;
- }
-
- if ((conn->key.nw_proto == IPPROTO_ICMP) ||
- (conn->key.nw_proto == IPPROTO_ICMPV6)) {
- all_ports_tried = true;
- } else if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
nat_conn->rev_key.dst.port = htons(port);
} else {
+ nat_conn->rev_key.src.addr = ct_addr;
nat_conn->rev_key.src.port = htons(port);
}
@@ -2200,7 +2196,7 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
ct->hash_basis);
if (new_insert) {
return true;
- } else if (!all_ports_tried) {
+ } else if (pat_enabled && !all_ports_tried) {
if (min_port == max_port) {
all_ports_tried = true;
} else if (port == max_port) {
@@ -2222,7 +2218,7 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
ct_addr = conn->nat_info->min_addr;
}
if (!memcmp(&ct_addr, &first_addr, sizeof ct_addr)) {
- if (!ephemeral_ports_tried) {
+ if (pat_enabled && !ephemeral_ports_tried) {
ephemeral_ports_tried = true;
ct_addr = conn->nat_info->min_addr;
first_addr = ct_addr;
ICMPv4 and ICMPv6 are not subject to port address translation (PAT), however, a loop increments a local variable unnecessarily for ephemeral ports, resulting in wasted work for ICMPv4 and ICMPv6 packets subject to NAT. Fix this by checking for PAT being enabled before incrementing the local port variable and bail out otherwise. Signed-off-by: Darrell Ball <dlu998@gmail.com> --- v2: Consolidate two selection statements. lib/conntrack.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)