return pkts
def verify_capture_out(self, capture, nat_ip=None, same_port=False,
- dst_ip=None, is_ip6=False):
+ dst_ip=None, is_ip6=False, ignore_port=False):
"""
Verify captured packets on outside network
if dst_ip is not None:
self.assertEqual(packet[IP46].dst, dst_ip)
if packet.haslayer(TCP):
- if same_port:
- self.assertEqual(packet[TCP].sport, self.tcp_port_in)
- else:
- self.assertNotEqual(
- packet[TCP].sport, self.tcp_port_in)
+ if not ignore_port:
+ if same_port:
+ self.assertEqual(
+ packet[TCP].sport, self.tcp_port_in)
+ else:
+ self.assertNotEqual(
+ packet[TCP].sport, self.tcp_port_in)
self.tcp_port_out = packet[TCP].sport
self.assert_packet_checksums_valid(packet)
elif packet.haslayer(UDP):
- if same_port:
- self.assertEqual(packet[UDP].sport, self.udp_port_in)
- else:
- self.assertNotEqual(
- packet[UDP].sport, self.udp_port_in)
+ if not ignore_port:
+ if same_port:
+ self.assertEqual(
+ packet[UDP].sport, self.udp_port_in)
+ else:
+ self.assertNotEqual(
+ packet[UDP].sport, self.udp_port_in)
self.udp_port_out = packet[UDP].sport
else:
- if same_port:
- self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
- else:
- self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
+ if not ignore_port:
+ if same_port:
+ self.assertEqual(
+ packet[ICMP46].id, self.icmp_id_in)
+ else:
+ self.assertNotEqual(
+ packet[ICMP46].id, self.icmp_id_in)
self.icmp_id_out = packet[ICMP46].id
self.assert_packet_checksums_valid(packet)
except:
else:
raise Exception("Unsupported protocol")
- def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
+ def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
+ ignore_port=False):
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
if proto != IP_PROTOS.icmp:
if not dont_translate:
self.assertEqual(p[layer].dport, 20)
- self.assertNotEqual(p[layer].sport, self.port_in)
+ if not ignore_port:
+ self.assertNotEqual(p[layer].sport, self.port_in)
else:
self.assertEqual(p[layer].sport, self.port_in)
else:
- if not dont_translate:
- self.assertNotEqual(p[layer].id, self.port_in)
- else:
- self.assertEqual(p[layer].id, self.port_in)
+ if not ignore_port:
+ if not dont_translate:
+ self.assertNotEqual(p[layer].id, self.port_in)
+ else:
+ self.assertEqual(p[layer].id, self.port_in)
self.assertEqual(data, p[Raw].load)
# out2in
self.assertEqual(p[layer].id, self.port_in)
self.assertEqual(data, p[Raw].load)
- def reass_hairpinning(self, proto=IP_PROTOS.tcp):
+ def reass_hairpinning(self, proto=IP_PROTOS.tcp, ignore_port=False):
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
self.nat_addr,
self.server.ip4)
if proto != IP_PROTOS.icmp:
- self.assertNotEqual(p[layer].sport, self.host_in_port)
+ if not ignore_port:
+ self.assertNotEqual(p[layer].sport, self.host_in_port)
self.assertEqual(p[layer].dport, self.server_in_port)
else:
- self.assertNotEqual(p[layer].id, self.host_in_port)
+ if not ignore_port:
+ self.assertNotEqual(p[layer].id, self.host_in_port)
self.assertEqual(data, p[Raw].load)
- def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
+ def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
+ ignore_port=False):
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
if proto != IP_PROTOS.icmp:
if not dont_translate:
self.assertEqual(p[layer].dport, 20)
- self.assertNotEqual(p[layer].sport, self.port_in)
+ if not ignore_port:
+ self.assertNotEqual(p[layer].sport, self.port_in)
else:
self.assertEqual(p[layer].sport, self.port_in)
else:
- if not dont_translate:
- self.assertNotEqual(p[layer].id, self.port_in)
- else:
- self.assertEqual(p[layer].id, self.port_in)
+ if not ignore_port:
+ if not dont_translate:
+ self.assertNotEqual(p[layer].id, self.port_in)
+ else:
+ self.assertEqual(p[layer].id, self.port_in)
self.assertEqual(data, p[Raw].load)
# out2in
class TestNAT44(MethodHolder):
""" NAT44 Test Cases """
+ max_translations = 10240
+ max_users = 10240
+
+ @classmethod
+ def setUpConstants(cls):
+ super(TestNAT44, cls).setUpConstants()
+ cls.vpp_cmdline.extend([
+ "nat", "{",
+ "max translations per thread %d" % cls.max_translations,
+ "max users per thread %d" % cls.max_users,
+ "}"
+ ])
+
@classmethod
def setUpClass(cls):
super(TestNAT44, cls).setUpClass()
is_add=1)
# in2out
- tcpn = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/TCP packets')
- udpn = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/good in2out packets processed')
+ tcpn = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
+ udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
+ icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
+ drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
capture = self.pg1.get_capture(len(pkts))
self.verify_capture_out(capture)
- err = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-in2out-slowpath/good in2out packets processed')
- self.assertEqual(err - totaln, 4)
+ if_idx = self.pg0.sw_if_index
+ cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
# out2in
- tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
- udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat44-out2in/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat44-out2in/good out2in packets processed')
+ tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
+ udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
+ icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
+ drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
capture = self.pg0.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg0)
- err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-out2in/good out2in packets processed')
- self.assertEqual(err - totaln, 4)
+ if_idx = self.pg1.sw_if_index
+ cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
users = self.statistics.get_counter('/nat44/total-users')
self.assertEqual(users[0][0], 1)
server_in_port, server_out_port,
proto=IP_PROTOS.tcp)
+ cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
+ after = self.statistics.get_counter('/nat44/hairpinning')[0]
+ if_idx = self.pg0.sw_if_index
+ self.assertEqual(after[if_idx] - cnt[if_idx], 1)
+
# send reply from server to host
p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
IP(src=server.ip4, dst=self.nat_addr) /
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
+ after = self.statistics.get_counter('/nat44/hairpinning')[0]
+ if_idx = self.pg0.sw_if_index
+ self.assertEqual(after[if_idx] - cnt[if_idx], 2)
+
def test_hairpinning2(self):
""" NAT44 hairpinning - 1:1 NAT"""
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- nat44_config = self.vapi.nat_show_config()
- max_sessions = 10 * nat44_config.translation_buckets
+ max_sessions = self.max_translations
pkts = []
for i in range(0, max_sessions):
self.vapi.nat44_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.frag_in_order(proto=IP_PROTOS.tcp)
- self.frag_in_order(proto=IP_PROTOS.udp)
- self.frag_in_order(proto=IP_PROTOS.icmp)
+ self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
+ self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
+ self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
def test_frag_in_order_dont_translate(self):
""" NAT44 don't translate fragments arriving in order """
self.vapi.nat44_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.frag_out_of_order(proto=IP_PROTOS.tcp)
- self.frag_out_of_order(proto=IP_PROTOS.udp)
- self.frag_out_of_order(proto=IP_PROTOS.icmp)
+ self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
+ self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
+ self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
def test_frag_out_of_order_dont_translate(self):
""" NAT44 don't translate fragments arriving out of order """
proto=IP_PROTOS.udp)
self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
- self.reass_hairpinning(proto=IP_PROTOS.tcp)
- self.reass_hairpinning(proto=IP_PROTOS.udp)
- self.reass_hairpinning(proto=IP_PROTOS.icmp)
+ self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
+ self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
+ self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
def test_clear_sessions(self):
""" NAT44 ED session clearing test """
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
sessions = self.statistics.get_counter('/nat44/total-sessions')
self.assertTrue(sessions[0][0] > 0)
self.assertEqual(1, nat_config.endpoint_dependent)
# in2out
- tcpn = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/TCP packets')
- udpn = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
+ tcpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
+ udpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
+ icmpn = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/icmp')[0]
+ drops = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/drops')[0]
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture)
-
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
- self.assertEqual(err - totaln, 4)
+ self.verify_capture_out(capture, ignore_port=True)
+
+ if_idx = self.pg0.sw_if_index
+ cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
# out2in
- tcpn = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/TCP packets')
- udpn = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in-slowpath/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/good out2in packets processed')
+ tcpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
+ udpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
+ icmpn = self.statistics.get_counter(
+ '/nat44/ed/out2in/slowpath/icmp')[0]
+ drops = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/drops')[0]
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
capture = self.pg0.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg0)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in-slowpath/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/good out2in packets processed')
- self.assertEqual(err - totaln, 3)
+ if_idx = self.pg1.sw_if_index
+ cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/ed/out2in/slowpath/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
sessions = self.statistics.get_counter('/nat44/total-sessions')
self.assertEqual(sessions[0][0], 3)
+ def test_dynamic_out_of_ports(self):
+ """ NAT44 dynamic translation test: out of ports """
+
+ flags = self.config_flags.NAT_IS_INSIDE
+ self.vapi.nat44_interface_add_del_feature(
+ sw_if_index=self.pg0.sw_if_index,
+ flags=flags, is_add=1)
+ self.vapi.nat44_interface_add_del_feature(
+ sw_if_index=self.pg1.sw_if_index,
+ is_add=1)
+
+ nat_config = self.vapi.nat_show_config()
+ self.assertEqual(1, nat_config.endpoint_dependent)
+
+ # in2out and no NAT addresses added
+ err_old = self.statistics.get_err_counter(
+ '/err/nat44-ed-in2out-slowpath/out of ports')
+
+ pkts = self.create_stream_in(self.pg0, self.pg1)
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.pg1.get_capture(0, timeout=1)
+
+ err_new = self.statistics.get_err_counter(
+ '/err/nat44-ed-in2out-slowpath/out of ports')
+
+ self.assertEqual(err_new - err_old, len(pkts))
+
+ # in2out after NAT addresses added
+ self.nat44_add_address(self.nat_addr)
+
+ err_old = self.statistics.get_err_counter(
+ '/err/nat44-ed-in2out-slowpath/out of ports')
+
+ pkts = self.create_stream_in(self.pg0, self.pg1)
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg1.get_capture(len(pkts))
+ self.verify_capture_out(capture, ignore_port=True)
+
+ err_new = self.statistics.get_err_counter(
+ '/err/nat44-ed-in2out-slowpath/out of ports')
+
+ self.assertEqual(err_new, err_old)
+
def test_dynamic_output_feature_vrf(self):
""" NAT44 dynamic translation test: output-feature, VRF"""
self.assertEqual(1, nat_config.endpoint_dependent)
# in2out
- tcpn = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/TCP packets')
- udpn = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
+ tcpn = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/tcp')[0]
+ udpn = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/udp')[0]
+ icmpn = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/icmp')[0]
+ drops = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/drops')[0]
pkts = self.create_stream_in(self.pg7, self.pg8)
self.pg7.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg8.get_capture(len(pkts))
- self.verify_capture_out(capture)
-
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
- self.assertEqual(err - totaln, 4)
+ self.verify_capture_out(capture, ignore_port=True)
+
+ if_idx = self.pg7.sw_if_index
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/in2out/slowpath/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
# out2in
- tcpn = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/TCP packets')
- udpn = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in-slowpath/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/good out2in packets processed')
+ tcpn = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/tcp')[0]
+ udpn = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/udp')[0]
+ icmpn = self.statistics.get_counter(
+ '/nat44/ed/out2in/slowpath/icmp')[0]
+ drops = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/drops')[0]
pkts = self.create_stream_out(self.pg8)
self.pg8.add_stream(pkts)
capture = self.pg7.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg7)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in-slowpath/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat44-ed-out2in/good out2in packets processed')
- self.assertEqual(err - totaln, 3)
+ if_idx = self.pg8.sw_if_index
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/out2in/slowpath/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter(
+ '/nat44/ed/out2in/fastpath/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
sessions = self.statistics.get_counter('/nat44/total-sessions')
self.assertEqual(sessions[0][0], 3)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
# from external network back to local network host
pkts = self.create_stream_out(self.pg1)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
# out2in
pkts = self.create_stream_out(self.pg1)
pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
len(pkts_in2out))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
# send out2in again, with sessions created it should work now
pkts_out2in = self.create_stream_out(self.pg1)
# send in2out to generate ACL state (NAT state was created earlier)
capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
len(pkts_in2out))
- self.verify_capture_out(capture)
+ self.verify_capture_out(capture, ignore_port=True)
# send out2in again. ACL state exists so it should work now.
# TCP packets with the syn flag set also need the ack flag
ip = p[IP]
tcp = p[TCP]
self.assertEqual(ip.src, self.nat_addr)
- self.assertNotEqual(tcp.sport, 2345)
self.assert_packet_checksums_valid(p)
port = tcp.sport
except:
capture = self.pg2.get_capture(1)
self.verify_syslog_sess(capture[0][Raw].load, False)
+ def test_ed_users_dump(self):
+ """ API test - nat44_user_dump """
+ flags = self.config_flags.NAT_IS_INSIDE
+ self.vapi.nat44_interface_add_del_feature(
+ sw_if_index=self.pg0.sw_if_index,
+ flags=flags, is_add=1)
+ self.vapi.nat44_interface_add_del_feature(
+ sw_if_index=self.pg1.sw_if_index,
+ is_add=1)
+ self.vapi.nat44_forwarding_enable_disable(enable=1)
+
+ real_ip = self.pg0.remote_ip4
+ alias_ip = self.nat_addr
+ flags = self.config_flags.NAT_IS_ADDR_ONLY
+ self.vapi.nat44_add_del_static_mapping(is_add=1,
+ local_ip_address=real_ip,
+ external_ip_address=alias_ip,
+ external_sw_if_index=0xFFFFFFFF,
+ flags=flags)
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 0)
+ try:
+ # in2out - static mapping match
+
+ pkts = self.create_stream_out(self.pg1)
+ self.pg1.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(len(pkts))
+ self.verify_capture_in(capture, self.pg0)
+
+ pkts = self.create_stream_in(self.pg0, self.pg1)
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg1.get_capture(len(pkts))
+ self.verify_capture_out(capture, same_port=True)
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 1)
+ static_user = users[0]
+ self.assertEqual(static_user.nstaticsessions, 3)
+ self.assertEqual(static_user.nsessions, 0)
+
+ # in2out - no static mapping match
+
+ host0 = self.pg0.remote_hosts[0]
+ self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
+ try:
+ pkts = self.create_stream_out(self.pg1,
+ dst_ip=self.pg0.remote_ip4,
+ use_inside_ports=True)
+ self.pg1.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(len(pkts))
+ self.verify_capture_in(capture, self.pg0)
+
+ pkts = self.create_stream_in(self.pg0, self.pg1)
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg1.get_capture(len(pkts))
+ self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
+ same_port=True)
+ finally:
+ self.pg0.remote_hosts[0] = host0
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 2)
+ if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
+ non_static_user = users[1]
+ static_user = users[0]
+ else:
+ non_static_user = users[0]
+ static_user = users[1]
+ self.assertEqual(static_user.nstaticsessions, 3)
+ self.assertEqual(static_user.nsessions, 0)
+ self.assertEqual(non_static_user.nstaticsessions, 0)
+ self.assertEqual(non_static_user.nsessions, 3)
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 2)
+ if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
+ non_static_user = users[1]
+ static_user = users[0]
+ else:
+ non_static_user = users[0]
+ static_user = users[1]
+ self.assertEqual(static_user.nstaticsessions, 3)
+ self.assertEqual(static_user.nsessions, 0)
+ self.assertEqual(non_static_user.nstaticsessions, 0)
+ self.assertEqual(non_static_user.nsessions, 3)
+
+ finally:
+ self.vapi.nat44_forwarding_enable_disable(enable=0)
+ flags = self.config_flags.NAT_IS_ADDR_ONLY
+ self.vapi.nat44_add_del_static_mapping(
+ is_add=0,
+ local_ip_address=real_ip,
+ external_ip_address=alias_ip,
+ external_sw_if_index=0xFFFFFFFF,
+ flags=flags)
+
def tearDown(self):
super(TestNAT44EndpointDependent, self).tearDown()
if not self.vpp_dead:
self.logger.info(self.vapi.cli("show nat timeouts"))
-class TestNAT44EndpointDependent2(MethodHolder):
+class TestNAT44EndpointDependent3(MethodHolder):
""" Endpoint-Dependent mapping and filtering extra test cases """
- translation_buckets = 5
+ max_translations = 50
@classmethod
def setUpConstants(cls):
- super(TestNAT44EndpointDependent2, cls).setUpConstants()
+ super(TestNAT44EndpointDependent3, cls).setUpConstants()
cls.vpp_cmdline.extend([
"nat", "{", "endpoint-dependent",
- "translation hash buckets %d" % cls.translation_buckets,
+ "max translations per thread %d" % cls.max_translations,
"}"
])
@classmethod
def setUpClass(cls):
- super(TestNAT44EndpointDependent2, cls).setUpClass()
+ super(TestNAT44EndpointDependent3, cls).setUpClass()
cls.vapi.cli("set log class nat level debug")
cls.nat_addr = '10.0.0.3'
i.resolve_arp()
def setUp(self):
- super(TestNAT44EndpointDependent2, self).setUp()
+ super(TestNAT44EndpointDependent3, self).setUp()
self.vapi.nat_set_timeouts(
udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
self.nat44_add_address(self.nat_addr)
@classmethod
def tearDownClass(cls):
- super(TestNAT44EndpointDependent2, cls).tearDownClass()
+ super(TestNAT44EndpointDependent3, cls).tearDownClass()
def init_tcp_session(self, in_if, out_if, sport, ext_dport):
# SYN packet in->out
def test_lru_cleanup(self):
""" LRU cleanup algorithm """
tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
- max_translations = 10 * self.translation_buckets
pkts = []
- for i in range(0, max_translations - 1):
+ for i in range(0, self.max_translations - 1):
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
UDP(sport=7000+i, dport=80))
self.sleep(1.5, "wait for timeouts")
pkts = []
- for i in range(0, max_translations - 1):
+ for i in range(0, self.max_translations - 1):
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
ICMP(id=8000+i, type='echo-request'))
sw_if_index=self.pg1.sw_if_index)
# in2out
- tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
- udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat64-in2out/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat64-in2out/good in2out packets processed')
+ tcpn = self.statistics.get_counter('/nat64/in2out/tcp')[0]
+ udpn = self.statistics.get_counter('/nat64/in2out/udp')[0]
+ icmpn = self.statistics.get_counter('/nat64/in2out/icmp')[0]
+ drops = self.statistics.get_counter('/nat64/in2out/drops')[0]
pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.verify_capture_out(capture, nat_ip=self.nat_addr,
dst_ip=self.pg1.remote_ip4)
- err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
- self.assertEqual(err - tcpn, 1)
- err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat64-in2out/good in2out packets processed')
- self.assertEqual(err - totaln, 3)
+ if_idx = self.pg0.sw_if_index
+ cnt = self.statistics.get_counter('/nat64/in2out/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat64/in2out/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat64/in2out/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat64/in2out/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
# out2in
- tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
- udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
- icmpn = self.statistics.get_err_counter(
- '/err/nat64-out2in/ICMP packets')
- totaln = self.statistics.get_err_counter(
- '/err/nat64-out2in/good out2in packets processed')
+ tcpn = self.statistics.get_counter('/nat64/out2in/tcp')[0]
+ udpn = self.statistics.get_counter('/nat64/out2in/udp')[0]
+ icmpn = self.statistics.get_counter('/nat64/out2in/icmp')[0]
+ drops = self.statistics.get_counter('/nat64/out2in/drops')[0]
pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
self.pg1.add_stream(pkts)
ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
- err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
- self.assertEqual(err - tcpn, 2)
- err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
- self.assertEqual(err - udpn, 1)
- err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
- self.assertEqual(err - icmpn, 1)
- err = self.statistics.get_err_counter(
- '/err/nat64-out2in/good out2in packets processed')
- self.assertEqual(err - totaln, 4)
+ if_idx = self.pg1.sw_if_index
+ cnt = self.statistics.get_counter('/nat64/out2in/tcp')[0]
+ self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
+ cnt = self.statistics.get_counter('/nat64/out2in/udp')[0]
+ self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat64/out2in/icmp')[0]
+ self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
+ cnt = self.statistics.get_counter('/nat64/out2in/drops')[0]
+ self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
bibs = self.statistics.get_counter('/nat64/total-bibs')
self.assertEqual(bibs[0][0], 3)
self.logger.info(self.vapi.cli("show nat64 session table all"))
-class TestNAT66(MethodHolder):
- """ NAT66 Test Cases """
-
- @classmethod
- def setUpClass(cls):
- super(TestNAT66, cls).setUpClass()
-
- cls.nat_addr = 'fd01:ff::2'
-
- cls.create_pg_interfaces(range(2))
- cls.interfaces = list(cls.pg_interfaces)
-
- for i in cls.interfaces:
- i.admin_up()
- i.config_ip6()
- i.configure_ipv6_neighbors()
-
- @classmethod
- def tearDownClass(cls):
- super(TestNAT66, cls).tearDownClass()
-
- def test_static(self):
- """ 1:1 NAT66 test """
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
- sw_if_index=self.pg0.sw_if_index)
- self.vapi.nat66_add_del_interface(is_add=1,
- sw_if_index=self.pg1.sw_if_index)
- self.vapi.nat66_add_del_static_mapping(
- local_ip_address=self.pg0.remote_ip6,
- external_ip_address=self.nat_addr,
- is_add=1)
-
- # in2out
- pkts = []
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
- TCP())
- pkts.append(p)
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
- UDP())
- pkts.append(p)
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
- ICMPv6EchoRequest())
- pkts.append(p)
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
- GRE() / IP() / TCP())
- pkts.append(p)
- self.pg0.add_stream(pkts)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
- capture = self.pg1.get_capture(len(pkts))
-
- for packet in capture:
- try:
- self.assertEqual(packet[IPv6].src, self.nat_addr)
- self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
- self.assert_packet_checksums_valid(packet)
- except:
- self.logger.error(ppp("Unexpected or invalid packet:", packet))
- raise
-
- # out2in
- pkts = []
- p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
- IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
- TCP())
- pkts.append(p)
- p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
- IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
- UDP())
- pkts.append(p)
- p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
- IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
- ICMPv6EchoReply())
- pkts.append(p)
- p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
- IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
- GRE() / IP() / TCP())
- pkts.append(p)
- self.pg1.add_stream(pkts)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
- capture = self.pg0.get_capture(len(pkts))
- for packet in capture:
- try:
- self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
- self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
- self.assert_packet_checksums_valid(packet)
- except:
- self.logger.error(ppp("Unexpected or invalid packet:", packet))
- raise
-
- sm = self.vapi.nat66_static_mapping_dump()
- self.assertEqual(len(sm), 1)
- self.assertEqual(sm[0].total_pkts, 8)
-
- def test_check_no_translate(self):
- """ NAT66 translate only when egress interface is outside interface """
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
- sw_if_index=self.pg0.sw_if_index)
- self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
- sw_if_index=self.pg1.sw_if_index)
- self.vapi.nat66_add_del_static_mapping(
- local_ip_address=self.pg0.remote_ip6,
- external_ip_address=self.nat_addr,
- is_add=1)
-
- # in2out
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
- UDP())
- self.pg0.add_stream([p])
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
- capture = self.pg1.get_capture(1)
- packet = capture[0]
- try:
- self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
- self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
- except:
- self.logger.error(ppp("Unexpected or invalid packet:", packet))
- raise
-
- def clear_nat66(self):
- """
- Clear NAT66 configuration.
- """
- interfaces = self.vapi.nat66_interface_dump()
- for intf in interfaces:
- self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
- sw_if_index=intf.sw_if_index)
-
- static_mappings = self.vapi.nat66_static_mapping_dump()
- for sm in static_mappings:
- self.vapi.nat66_add_del_static_mapping(
- local_ip_address=sm.local_ip_address,
- external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
- is_add=0)
-
- def tearDown(self):
- super(TestNAT66, self).tearDown()
- self.clear_nat66()
-
- def show_commands_at_teardown(self):
- self.logger.info(self.vapi.cli("show nat66 interfaces"))
- self.logger.info(self.vapi.cli("show nat66 static mappings"))
-
-
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)