Skip to content

Commit

Permalink
conntrack: Fix wasted work for ICMP NAT.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
darball1 authored and blp committed Feb 26, 2019
1 parent d40533f commit 4cd0481
Showing 1 changed file with 5 additions and 7 deletions.
12 changes: 5 additions & 7 deletions lib/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,18 +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) {
if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
nat_conn->rev_key.dst.port = htons(port);
} else {
nat_conn->rev_key.src.port = htons(port);
Expand All @@ -2200,7 +2198,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) {
Expand All @@ -2222,7 +2220,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;
Expand Down

0 comments on commit 4cd0481

Please sign in to comment.