diff options
author | Klement Sekera <ksekera@cisco.com> | 2021-02-25 16:47:23 +0100 |
---|---|---|
committer | Klement Sekera <ksekera@cisco.com> | 2021-03-01 13:03:20 +0100 |
commit | dc243ee2bcc4926ec23e71a687bb62b5c52c2fbb (patch) | |
tree | eb4a57e84f45b5bbdfd4385976ce20974b797c5a /src/plugins/nat/test | |
parent | f1af21c9d7c2d4f4e138b5dd0dd40e7f881b46ae (diff) |
nat: pick outside addr based on local addr
Use outside addresses more evenly by using local address to pick from
pool of addresses. This ensures stability from POV of remote host -
an internal host always gets translated using the same outside address,
so it doesn't appear to be "hopping". Also, this avoids all hosts
being translated using the first address, which helps avoid needless
recaptchas and the like.
Exact assignment depends on internal ordering of addresses - local address
is used to pick an offset into internal vector. If that address cannot be
used, a linear search is performed as a fallback mechanism to find a possible
translation.
Type: improvement
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Change-Id: I7ccb1da1dda5537f5d30d2f4cb48024f4b51c1a4
Diffstat (limited to 'src/plugins/nat/test')
-rw-r--r-- | src/plugins/nat/test/test_nat44_ed.py | 39 | ||||
-rw-r--r-- | src/plugins/nat/test/test_nat44_ei.py | 44 |
2 files changed, 83 insertions, 0 deletions
diff --git a/src/plugins/nat/test/test_nat44_ed.py b/src/plugins/nat/test/test_nat44_ed.py index 7e85c938ee8..8c3169e338f 100644 --- a/src/plugins/nat/test/test_nat44_ed.py +++ b/src/plugins/nat/test/test_nat44_ed.py @@ -1903,6 +1903,45 @@ class TestNAT44ED(NAT44EDTestCase): self.logger.error(ppp("Unexpected or invalid packet:", p)) raise + def test_outside_address_distribution(self): + """ Outside address distribution based on source address """ + + x = 100 + nat_addresses = [] + + for i in range(1, x): + a = "10.0.0.%d" % i + nat_addresses.append(a) + + self.nat_add_inside_interface(self.pg0) + self.nat_add_outside_interface(self.pg1) + + self.vapi.nat44_add_del_address_range( + first_ip_address=nat_addresses[0], + last_ip_address=nat_addresses[-1], + vrf_id=0xFFFFFFFF, is_add=1, flags=0) + + self.pg0.generate_remote_hosts(x) + + pkts = [] + for i in range(x): + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IP(src=self.pg0.remote_hosts[i].ip4, + dst=self.pg1.remote_ip4) / + UDP(sport=7000+i, dport=80+i)) + pkts.append(p) + + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + recvd = self.pg1.get_capture(len(pkts)) + for (p_sent, p_recvd) in zip(pkts, recvd): + packed = socket.inet_aton(p_sent[IP].src) + numeric = struct.unpack("!L", packed)[0] + numeric = socket.htonl(numeric) + a = nat_addresses[(numeric-1) % len(nat_addresses)] + self.assertEqual(a, p_recvd[IP].src, "Packet not translated") + class TestNAT44EDMW(TestNAT44ED): """ NAT44ED MW Test Case """ diff --git a/src/plugins/nat/test/test_nat44_ei.py b/src/plugins/nat/test/test_nat44_ei.py index da6ca4293c0..dcd7f46f073 100644 --- a/src/plugins/nat/test/test_nat44_ei.py +++ b/src/plugins/nat/test/test_nat44_ei.py @@ -3719,6 +3719,50 @@ class TestNAT44EI(MethodHolder): self.logger.info( self.vapi.cli("show nat44 ei addr-port-assignment-alg")) + def test_outside_address_distribution(self): + """ Outside address distribution based on source address """ + + x = 100 + nat_addresses = [] + + for i in range(1, x): + a = "10.0.0.%d" % i + nat_addresses.append(a) + + flags = self.config_flags.NAT44_EI_IF_INSIDE + self.vapi.nat44_ei_interface_add_del_feature( + sw_if_index=self.pg0.sw_if_index, + flags=flags, is_add=1) + self.vapi.nat44_ei_interface_add_del_feature( + sw_if_index=self.pg1.sw_if_index, + is_add=1) + + self.vapi.nat44_ei_add_del_address_range( + first_ip_address=nat_addresses[0], + last_ip_address=nat_addresses[-1], + vrf_id=0xFFFFFFFF, is_add=1) + + self.pg0.generate_remote_hosts(x) + + pkts = [] + for i in range(x): + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IP(src=self.pg0.remote_hosts[i].ip4, + dst=self.pg1.remote_ip4) / + UDP(sport=7000+i, dport=80+i)) + pkts.append(p) + + self.pg0.add_stream(pkts) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + recvd = self.pg1.get_capture(len(pkts)) + for (p_sent, p_recvd) in zip(pkts, recvd): + packed = socket.inet_aton(p_sent[IP].src) + numeric = struct.unpack("!L", packed)[0] + numeric = socket.htonl(numeric) + a = nat_addresses[(numeric-1) % len(nat_addresses)] + self.assertEqual(a, p_recvd[IP].src, "Packet not translated") + class TestNAT44Out2InDPO(MethodHolder): """ NAT44EI Test Cases using out2in DPO """ |