5 from random import randint
8 from framework import tag_fixme_vpp_workers
9 from framework import VppTestCase, VppTestRunner
10 from scapy.data import IP_PROTOS
11 from scapy.layers.inet import IP, TCP, UDP, ICMP, GRE
12 from scapy.layers.inet import IPerror, TCPerror
13 from scapy.layers.l2 import Ether
14 from scapy.packet import Raw
15 from syslog_rfc5424_parser import SyslogMessage, ParseError
16 from syslog_rfc5424_parser.constants import SyslogSeverity
17 from util import ppp, ip4_range
18 from vpp_acl import AclRule, VppAcl, VppAclInterface
19 from vpp_ip_route import VppIpRoute, VppRoutePath
20 from vpp_papi import VppEnum
23 class NAT44EDTestCase(VppTestCase):
36 tcp_external_port = 80
41 super(NAT44EDTestCase, self).setUp()
45 super(NAT44EDTestCase, self).tearDown()
49 def plugin_enable(self):
50 self.vapi.nat44_plugin_enable_disable(
51 flags=self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT,
52 sessions=self.max_sessions, enable=1)
54 def plugin_disable(self):
55 self.vapi.nat44_plugin_enable_disable(enable=0)
58 def config_flags(self):
59 return VppEnum.vl_api_nat_config_flags_t
62 def nat44_config_flags(self):
63 return VppEnum.vl_api_nat44_config_flags_t
66 def syslog_severity(self):
67 return VppEnum.vl_api_syslog_severity_t
70 def server_addr(self):
71 return self.pg1.remote_hosts[0].ip4
75 return randint(1025, 65535)
78 def proto2layer(proto):
79 if proto == IP_PROTOS.tcp:
81 elif proto == IP_PROTOS.udp:
83 elif proto == IP_PROTOS.icmp:
86 raise Exception("Unsupported protocol")
89 def create_and_add_ip4_table(cls, i, table_id=0):
90 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
91 i.set_table_ip4(table_id)
94 def configure_ip4_interface(cls, i, hosts=0, table_id=None):
96 cls.create_and_add_ip4_table(i, table_id)
104 i.generate_remote_hosts(hosts)
105 i.configure_ipv4_neighbors()
108 def nat_add_interface_address(cls, i):
109 cls.vapi.nat44_add_del_interface_addr(
110 sw_if_index=i.sw_if_index, is_add=1)
112 def nat_add_inside_interface(self, i):
113 self.vapi.nat44_interface_add_del_feature(
114 flags=self.config_flags.NAT_IS_INSIDE,
115 sw_if_index=i.sw_if_index, is_add=1)
117 def nat_add_outside_interface(self, i):
118 self.vapi.nat44_interface_add_del_feature(
119 flags=self.config_flags.NAT_IS_OUTSIDE,
120 sw_if_index=i.sw_if_index, is_add=1)
122 def nat_add_address(self, address, twice_nat=0,
123 vrf_id=0xFFFFFFFF, is_add=1):
124 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
125 self.vapi.nat44_add_del_address_range(first_ip_address=address,
126 last_ip_address=address,
131 def nat_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
132 local_port=0, external_port=0, vrf_id=0,
133 is_add=1, external_sw_if_index=0xFFFFFFFF,
134 proto=0, tag="", flags=0):
136 if not (local_port and external_port):
137 flags |= self.config_flags.NAT_IS_ADDR_ONLY
139 self.vapi.nat44_add_del_static_mapping(
141 local_ip_address=local_ip,
142 external_ip_address=external_ip,
143 external_sw_if_index=external_sw_if_index,
144 local_port=local_port,
145 external_port=external_port,
146 vrf_id=vrf_id, protocol=proto,
152 super(NAT44EDTestCase, cls).setUpClass()
153 cls.vapi.cli("set log class nat level debug")
155 cls.create_pg_interfaces(range(12))
156 cls.interfaces = list(cls.pg_interfaces[:4])
158 cls.create_and_add_ip4_table(cls.pg2, 10)
160 for i in cls.interfaces:
161 cls.configure_ip4_interface(i, hosts=3)
163 # test specific (test-multiple-vrf)
164 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
166 # test specific (test-one-armed-nat44-static)
167 cls.pg4.generate_remote_hosts(2)
169 cls.vapi.sw_interface_add_del_address(
170 sw_if_index=cls.pg4.sw_if_index,
171 prefix="10.0.0.1/24")
173 cls.pg4.resolve_arp()
174 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
175 cls.pg4.resolve_arp()
177 # test specific interface (pg5)
178 cls.pg5._local_ip4 = "10.1.1.1"
179 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
180 cls.pg5.set_table_ip4(1)
183 cls.pg5.resolve_arp()
185 # test specific interface (pg6)
186 cls.pg6._local_ip4 = "10.1.2.1"
187 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
188 cls.pg6.set_table_ip4(1)
191 cls.pg6.resolve_arp()
195 rl.append(VppIpRoute(cls, "0.0.0.0", 0,
196 [VppRoutePath("0.0.0.0", 0xffffffff,
198 register=False, table_id=1))
199 rl.append(VppIpRoute(cls, "0.0.0.0", 0,
200 [VppRoutePath(cls.pg1.local_ip4,
201 cls.pg1.sw_if_index)],
203 rl.append(VppIpRoute(cls, cls.pg5.remote_ip4, 32,
204 [VppRoutePath("0.0.0.0",
205 cls.pg5.sw_if_index)],
206 register=False, table_id=1))
207 rl.append(VppIpRoute(cls, cls.pg6.remote_ip4, 32,
208 [VppRoutePath("0.0.0.0",
209 cls.pg6.sw_if_index)],
210 register=False, table_id=1))
211 rl.append(VppIpRoute(cls, cls.pg6.remote_ip4, 16,
212 [VppRoutePath("0.0.0.0", 0xffffffff,
214 register=False, table_id=0))
219 def get_err_counter(self, path):
220 return self.statistics.get_err_counter(path)
222 def get_stats_counter(self, path, worker=0):
223 return self.statistics.get_counter(path)[worker]
225 def reass_hairpinning(self, server_addr, server_in_port, server_out_port,
226 host_in_port, proto=IP_PROTOS.tcp,
228 layer = self.proto2layer(proto)
230 if proto == IP_PROTOS.tcp:
231 data = b"A" * 4 + b"B" * 16 + b"C" * 3
233 data = b"A" * 16 + b"B" * 16 + b"C" * 3
235 # send packet from host to server
236 pkts = self.create_stream_frag(self.pg0,
242 self.pg0.add_stream(pkts)
243 self.pg_enable_capture(self.pg_interfaces)
245 frags = self.pg0.get_capture(len(pkts))
246 p = self.reass_frags_and_verify(frags,
249 if proto != IP_PROTOS.icmp:
251 self.assertNotEqual(p[layer].sport, host_in_port)
252 self.assertEqual(p[layer].dport, server_in_port)
255 self.assertNotEqual(p[layer].id, host_in_port)
256 self.assertEqual(data, p[Raw].load)
258 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
260 layer = self.proto2layer(proto)
262 if proto == IP_PROTOS.tcp:
263 data = b"A" * 4 + b"B" * 16 + b"C" * 3
265 data = b"A" * 16 + b"B" * 16 + b"C" * 3
266 self.port_in = self.random_port()
270 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
271 self.port_in, 20, data, proto)
273 self.pg0.add_stream(pkts)
274 self.pg_enable_capture(self.pg_interfaces)
276 frags = self.pg1.get_capture(len(pkts))
277 if not dont_translate:
278 p = self.reass_frags_and_verify(frags,
282 p = self.reass_frags_and_verify(frags,
285 if proto != IP_PROTOS.icmp:
286 if not dont_translate:
287 self.assertEqual(p[layer].dport, 20)
289 self.assertNotEqual(p[layer].sport, self.port_in)
291 self.assertEqual(p[layer].sport, self.port_in)
294 if not dont_translate:
295 self.assertNotEqual(p[layer].id, self.port_in)
297 self.assertEqual(p[layer].id, self.port_in)
298 self.assertEqual(data, p[Raw].load)
301 if not dont_translate:
302 dst_addr = self.nat_addr
304 dst_addr = self.pg0.remote_ip4
305 if proto != IP_PROTOS.icmp:
307 dport = p[layer].sport
311 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
312 data, proto, echo_reply=True)
314 self.pg1.add_stream(pkts)
315 self.pg_enable_capture(self.pg_interfaces)
317 frags = self.pg0.get_capture(len(pkts))
318 p = self.reass_frags_and_verify(frags,
321 if proto != IP_PROTOS.icmp:
322 self.assertEqual(p[layer].sport, 20)
323 self.assertEqual(p[layer].dport, self.port_in)
325 self.assertEqual(p[layer].id, self.port_in)
326 self.assertEqual(data, p[Raw].load)
328 def reass_frags_and_verify(self, frags, src, dst):
331 self.assertEqual(p[IP].src, src)
332 self.assertEqual(p[IP].dst, dst)
333 self.assert_ip_checksum_valid(p)
334 buffer.seek(p[IP].frag * 8)
335 buffer.write(bytes(p[IP].payload))
336 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
337 proto=frags[0][IP].proto)
338 if ip.proto == IP_PROTOS.tcp:
339 p = (ip / TCP(buffer.getvalue()))
340 self.logger.debug(ppp("Reassembled:", p))
341 self.assert_tcp_checksum_valid(p)
342 elif ip.proto == IP_PROTOS.udp:
343 p = (ip / UDP(buffer.getvalue()[:8]) /
344 Raw(buffer.getvalue()[8:]))
345 elif ip.proto == IP_PROTOS.icmp:
346 p = (ip / ICMP(buffer.getvalue()))
349 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
351 layer = self.proto2layer(proto)
353 if proto == IP_PROTOS.tcp:
354 data = b"A" * 4 + b"B" * 16 + b"C" * 3
356 data = b"A" * 16 + b"B" * 16 + b"C" * 3
357 self.port_in = self.random_port()
360 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
361 self.port_in, 20, data, proto)
362 self.pg0.add_stream(pkts)
363 self.pg_enable_capture(self.pg_interfaces)
365 frags = self.pg1.get_capture(len(pkts))
366 if not dont_translate:
367 p = self.reass_frags_and_verify(frags,
371 p = self.reass_frags_and_verify(frags,
374 if proto != IP_PROTOS.icmp:
375 if not dont_translate:
376 self.assertEqual(p[layer].dport, 20)
378 self.assertNotEqual(p[layer].sport, self.port_in)
380 self.assertEqual(p[layer].sport, self.port_in)
383 if not dont_translate:
384 self.assertNotEqual(p[layer].id, self.port_in)
386 self.assertEqual(p[layer].id, self.port_in)
387 self.assertEqual(data, p[Raw].load)
390 if not dont_translate:
391 dst_addr = self.nat_addr
393 dst_addr = self.pg0.remote_ip4
394 if proto != IP_PROTOS.icmp:
396 dport = p[layer].sport
400 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
401 proto, echo_reply=True)
402 self.pg1.add_stream(pkts)
403 self.pg_enable_capture(self.pg_interfaces)
405 frags = self.pg0.get_capture(len(pkts))
406 p = self.reass_frags_and_verify(frags,
409 if proto != IP_PROTOS.icmp:
410 self.assertEqual(p[layer].sport, 20)
411 self.assertEqual(p[layer].dport, self.port_in)
413 self.assertEqual(p[layer].id, self.port_in)
414 self.assertEqual(data, p[Raw].load)
416 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
417 dst_ip=None, ignore_port=False):
419 nat_ip = self.nat_addr
420 for packet in capture:
422 self.assert_packet_checksums_valid(packet)
423 self.assertEqual(packet[IP].src, nat_ip)
424 if dst_ip is not None:
425 self.assertEqual(packet[IP].dst, dst_ip)
426 if packet.haslayer(TCP):
430 packet[TCP].sport, self.tcp_port_in)
433 packet[TCP].sport, self.tcp_port_in)
434 self.tcp_port_out = packet[TCP].sport
435 self.assert_packet_checksums_valid(packet)
436 elif packet.haslayer(UDP):
440 packet[UDP].sport, self.udp_port_in)
443 packet[UDP].sport, self.udp_port_in)
444 self.udp_port_out = packet[UDP].sport
449 packet[ICMP].id, self.icmp_id_in)
452 packet[ICMP].id, self.icmp_id_in)
453 self.icmp_id_out = packet[ICMP].id
454 self.assert_packet_checksums_valid(packet)
456 self.logger.error(ppp("Unexpected or invalid packet "
457 "(outside network):", packet))
460 def verify_capture_in(self, capture, in_if):
461 for packet in capture:
463 self.assert_packet_checksums_valid(packet)
464 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
465 if packet.haslayer(TCP):
466 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
467 elif packet.haslayer(UDP):
468 self.assertEqual(packet[UDP].dport, self.udp_port_in)
470 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
472 self.logger.error(ppp("Unexpected or invalid packet "
473 "(inside network):", packet))
476 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
478 dst_ip = out_if.remote_ip4
482 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
483 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
484 TCP(sport=self.tcp_port_in, dport=20))
488 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
489 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
490 UDP(sport=self.udp_port_in, dport=20))
494 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
495 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
496 ICMP(id=self.icmp_id_in, type='echo-request'))
501 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
502 use_inside_ports=False):
504 dst_ip = self.nat_addr
505 if not use_inside_ports:
506 tcp_port = self.tcp_port_out
507 udp_port = self.udp_port_out
508 icmp_id = self.icmp_id_out
510 tcp_port = self.tcp_port_in
511 udp_port = self.udp_port_in
512 icmp_id = self.icmp_id_in
515 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
516 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
517 TCP(dport=tcp_port, sport=20))
521 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
522 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
523 UDP(dport=udp_port, sport=20))
527 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
528 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
529 ICMP(id=icmp_id, type='echo-reply'))
534 def create_tcp_stream(self, in_if, out_if, count):
538 for i in range(count):
539 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
540 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
541 TCP(sport=port + i, dport=20))
546 def create_stream_frag(self, src_if, dst, sport, dport, data,
547 proto=IP_PROTOS.tcp, echo_reply=False):
548 if proto == IP_PROTOS.tcp:
549 p = (IP(src=src_if.remote_ip4, dst=dst) /
550 TCP(sport=sport, dport=dport) /
552 p = p.__class__(scapy.compat.raw(p))
553 chksum = p[TCP].chksum
554 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
555 elif proto == IP_PROTOS.udp:
556 proto_header = UDP(sport=sport, dport=dport)
557 elif proto == IP_PROTOS.icmp:
559 proto_header = ICMP(id=sport, type='echo-request')
561 proto_header = ICMP(id=sport, type='echo-reply')
563 raise Exception("Unsupported protocol")
564 id = self.random_port()
566 if proto == IP_PROTOS.tcp:
569 raw = Raw(data[0:16])
570 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
571 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
575 if proto == IP_PROTOS.tcp:
576 raw = Raw(data[4:20])
578 raw = Raw(data[16:32])
579 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
580 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
584 if proto == IP_PROTOS.tcp:
588 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
589 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
595 def frag_in_order_in_plus_out(self, in_addr, out_addr, in_port, out_port,
596 proto=IP_PROTOS.tcp):
598 layer = self.proto2layer(proto)
600 if proto == IP_PROTOS.tcp:
601 data = b"A" * 4 + b"B" * 16 + b"C" * 3
603 data = b"A" * 16 + b"B" * 16 + b"C" * 3
604 port_in = self.random_port()
608 pkts = self.create_stream_frag(self.pg0, out_addr,
611 self.pg0.add_stream(pkts)
612 self.pg_enable_capture(self.pg_interfaces)
614 frags = self.pg1.get_capture(len(pkts))
615 p = self.reass_frags_and_verify(frags,
618 if proto != IP_PROTOS.icmp:
619 self.assertEqual(p[layer].sport, port_in)
620 self.assertEqual(p[layer].dport, in_port)
622 self.assertEqual(p[layer].id, port_in)
623 self.assertEqual(data, p[Raw].load)
626 if proto != IP_PROTOS.icmp:
627 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
629 p[layer].sport, data, proto)
631 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
632 p[layer].id, 0, data, proto,
634 self.pg1.add_stream(pkts)
635 self.pg_enable_capture(self.pg_interfaces)
637 frags = self.pg0.get_capture(len(pkts))
638 p = self.reass_frags_and_verify(frags,
641 if proto != IP_PROTOS.icmp:
642 self.assertEqual(p[layer].sport, out_port)
643 self.assertEqual(p[layer].dport, port_in)
645 self.assertEqual(p[layer].id, port_in)
646 self.assertEqual(data, p[Raw].load)
648 def frag_out_of_order_in_plus_out(self, in_addr, out_addr, in_port,
649 out_port, proto=IP_PROTOS.tcp):
651 layer = self.proto2layer(proto)
653 if proto == IP_PROTOS.tcp:
654 data = b"A" * 4 + b"B" * 16 + b"C" * 3
656 data = b"A" * 16 + b"B" * 16 + b"C" * 3
657 port_in = self.random_port()
661 pkts = self.create_stream_frag(self.pg0, out_addr,
665 self.pg0.add_stream(pkts)
666 self.pg_enable_capture(self.pg_interfaces)
668 frags = self.pg1.get_capture(len(pkts))
669 p = self.reass_frags_and_verify(frags,
672 if proto != IP_PROTOS.icmp:
673 self.assertEqual(p[layer].dport, in_port)
674 self.assertEqual(p[layer].sport, port_in)
675 self.assertEqual(p[layer].dport, in_port)
677 self.assertEqual(p[layer].id, port_in)
678 self.assertEqual(data, p[Raw].load)
681 if proto != IP_PROTOS.icmp:
682 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
684 p[layer].sport, data, proto)
686 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
687 p[layer].id, 0, data, proto,
690 self.pg1.add_stream(pkts)
691 self.pg_enable_capture(self.pg_interfaces)
693 frags = self.pg0.get_capture(len(pkts))
694 p = self.reass_frags_and_verify(frags,
697 if proto != IP_PROTOS.icmp:
698 self.assertEqual(p[layer].sport, out_port)
699 self.assertEqual(p[layer].dport, port_in)
701 self.assertEqual(p[layer].id, port_in)
702 self.assertEqual(data, p[Raw].load)
704 def init_tcp_session(self, in_if, out_if, in_port, ext_port):
706 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
707 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
708 TCP(sport=in_port, dport=ext_port, flags="S"))
710 self.pg_enable_capture(self.pg_interfaces)
712 capture = out_if.get_capture(1)
714 out_port = p[TCP].sport
716 # SYN + ACK packet out->in
717 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
718 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
719 TCP(sport=ext_port, dport=out_port, flags="SA"))
721 self.pg_enable_capture(self.pg_interfaces)
726 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
727 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
728 TCP(sport=in_port, dport=ext_port, flags="A"))
730 self.pg_enable_capture(self.pg_interfaces)
732 out_if.get_capture(1)
736 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
738 twice_nat_addr = '10.0.1.3'
746 port_in1 = port_in + 1
747 port_in2 = port_in + 2
752 server1 = self.pg0.remote_hosts[0]
753 server2 = self.pg0.remote_hosts[1]
765 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
768 self.nat_add_address(self.nat_addr)
769 self.nat_add_address(twice_nat_addr, twice_nat=1)
773 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
775 flags |= self.config_flags.NAT_IS_TWICE_NAT
778 self.nat_add_static_mapping(pg0.remote_ip4, self.nat_addr,
783 locals = [{'addr': server1.ip4,
787 {'addr': server2.ip4,
791 out_addr = self.nat_addr
793 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
794 external_addr=out_addr,
795 external_port=port_out,
796 protocol=IP_PROTOS.tcp,
797 local_num=len(locals),
799 self.nat_add_inside_interface(pg0)
800 self.nat_add_outside_interface(pg1)
806 assert client_id is not None
808 client = self.pg0.remote_hosts[0]
810 client = self.pg0.remote_hosts[1]
812 client = pg1.remote_hosts[0]
813 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
814 IP(src=client.ip4, dst=self.nat_addr) /
815 TCP(sport=eh_port_out, dport=port_out))
817 self.pg_enable_capture(self.pg_interfaces)
819 capture = pg0.get_capture(1)
825 if ip.dst == server1.ip4:
831 self.assertEqual(ip.dst, server.ip4)
833 self.assertIn(tcp.dport, [port_in1, port_in2])
835 self.assertEqual(tcp.dport, port_in)
837 self.assertEqual(ip.src, twice_nat_addr)
838 self.assertNotEqual(tcp.sport, eh_port_out)
840 self.assertEqual(ip.src, client.ip4)
841 self.assertEqual(tcp.sport, eh_port_out)
843 eh_port_in = tcp.sport
844 saved_port_in = tcp.dport
845 self.assert_packet_checksums_valid(p)
847 self.logger.error(ppp("Unexpected or invalid packet:", p))
850 p = (Ether(src=server.mac, dst=pg0.local_mac) /
851 IP(src=server.ip4, dst=eh_addr_in) /
852 TCP(sport=saved_port_in, dport=eh_port_in))
854 self.pg_enable_capture(self.pg_interfaces)
856 capture = pg1.get_capture(1)
861 self.assertEqual(ip.dst, client.ip4)
862 self.assertEqual(ip.src, self.nat_addr)
863 self.assertEqual(tcp.dport, eh_port_out)
864 self.assertEqual(tcp.sport, port_out)
865 self.assert_packet_checksums_valid(p)
867 self.logger.error(ppp("Unexpected or invalid packet:", p))
871 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
872 self.assertEqual(len(sessions), 1)
873 self.assertTrue(sessions[0].flags &
874 self.config_flags.NAT_IS_EXT_HOST_VALID)
875 self.assertTrue(sessions[0].flags &
876 self.config_flags.NAT_IS_TWICE_NAT)
877 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
878 self.vapi.nat44_del_session(
879 address=sessions[0].inside_ip_address,
880 port=sessions[0].inside_port,
881 protocol=sessions[0].protocol,
882 flags=(self.config_flags.NAT_IS_INSIDE |
883 self.config_flags.NAT_IS_EXT_HOST_VALID),
884 ext_host_address=sessions[0].ext_host_nat_address,
885 ext_host_port=sessions[0].ext_host_nat_port)
886 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
887 self.assertEqual(len(sessions), 0)
889 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
890 message = data.decode('utf-8')
892 message = SyslogMessage.parse(message)
893 except ParseError as e:
897 self.assertEqual(message.severity, SyslogSeverity.info)
898 self.assertEqual(message.appname, 'NAT')
899 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
900 sd_params = message.sd.get('nsess')
901 self.assertTrue(sd_params is not None)
903 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
904 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
906 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
907 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
908 self.assertTrue(sd_params.get('SSUBIX') is not None)
909 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
910 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
911 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
912 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
913 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
914 self.assertEqual(sd_params.get('SVLAN'), '0')
915 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
916 self.assertEqual(sd_params.get('XDPORT'),
917 "%d" % self.tcp_external_port)
920 @tag_fixme_vpp_workers
921 class TestNAT44ED(NAT44EDTestCase):
922 """ NAT44ED Test Case """
924 def test_users_dump(self):
925 """ NAT44ED API test - nat44_user_dump """
927 self.nat_add_address(self.nat_addr)
928 self.nat_add_inside_interface(self.pg0)
929 self.nat_add_outside_interface(self.pg1)
931 self.vapi.nat44_forwarding_enable_disable(enable=1)
933 local_ip = self.pg0.remote_ip4
934 external_ip = self.nat_addr
935 self.nat_add_static_mapping(local_ip, external_ip)
937 users = self.vapi.nat44_user_dump()
938 self.assertEqual(len(users), 0)
940 # in2out - static mapping match
942 pkts = self.create_stream_out(self.pg1)
943 self.pg1.add_stream(pkts)
944 self.pg_enable_capture(self.pg_interfaces)
946 capture = self.pg0.get_capture(len(pkts))
947 self.verify_capture_in(capture, self.pg0)
949 pkts = self.create_stream_in(self.pg0, self.pg1)
950 self.pg0.add_stream(pkts)
951 self.pg_enable_capture(self.pg_interfaces)
953 capture = self.pg1.get_capture(len(pkts))
954 self.verify_capture_out(capture, same_port=True)
956 users = self.vapi.nat44_user_dump()
957 self.assertEqual(len(users), 1)
958 static_user = users[0]
959 self.assertEqual(static_user.nstaticsessions, 3)
960 self.assertEqual(static_user.nsessions, 0)
962 # in2out - no static mapping match (forwarding test)
964 host0 = self.pg0.remote_hosts[0]
965 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
967 pkts = self.create_stream_out(self.pg1,
968 dst_ip=self.pg0.remote_ip4,
969 use_inside_ports=True)
970 self.pg1.add_stream(pkts)
971 self.pg_enable_capture(self.pg_interfaces)
973 capture = self.pg0.get_capture(len(pkts))
974 self.verify_capture_in(capture, self.pg0)
976 pkts = self.create_stream_in(self.pg0, self.pg1)
977 self.pg0.add_stream(pkts)
978 self.pg_enable_capture(self.pg_interfaces)
980 capture = self.pg1.get_capture(len(pkts))
981 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
984 self.pg0.remote_hosts[0] = host0
986 users = self.vapi.nat44_user_dump()
987 self.assertEqual(len(users), 2)
988 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
989 non_static_user = users[1]
990 static_user = users[0]
992 non_static_user = users[0]
993 static_user = users[1]
994 self.assertEqual(static_user.nstaticsessions, 3)
995 self.assertEqual(static_user.nsessions, 0)
996 self.assertEqual(non_static_user.nstaticsessions, 0)
997 self.assertEqual(non_static_user.nsessions, 3)
999 users = self.vapi.nat44_user_dump()
1000 self.assertEqual(len(users), 2)
1001 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
1002 non_static_user = users[1]
1003 static_user = users[0]
1005 non_static_user = users[0]
1006 static_user = users[1]
1007 self.assertEqual(static_user.nstaticsessions, 3)
1008 self.assertEqual(static_user.nsessions, 0)
1009 self.assertEqual(non_static_user.nstaticsessions, 0)
1010 self.assertEqual(non_static_user.nsessions, 3)
1012 def test_frag_out_of_order_do_not_translate(self):
1013 """ NAT44ED don't translate fragments arriving out of order """
1014 self.nat_add_inside_interface(self.pg0)
1015 self.nat_add_outside_interface(self.pg1)
1016 self.vapi.nat44_forwarding_enable_disable(enable=True)
1017 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
1019 def test_forwarding(self):
1020 """ NAT44ED forwarding test """
1022 self.nat_add_inside_interface(self.pg0)
1023 self.nat_add_outside_interface(self.pg1)
1024 self.vapi.nat44_forwarding_enable_disable(enable=1)
1026 real_ip = self.pg0.remote_ip4
1027 alias_ip = self.nat_addr
1028 flags = self.config_flags.NAT_IS_ADDR_ONLY
1029 self.vapi.nat44_add_del_static_mapping(is_add=1,
1030 local_ip_address=real_ip,
1031 external_ip_address=alias_ip,
1032 external_sw_if_index=0xFFFFFFFF,
1036 # in2out - static mapping match
1038 pkts = self.create_stream_out(self.pg1)
1039 self.pg1.add_stream(pkts)
1040 self.pg_enable_capture(self.pg_interfaces)
1042 capture = self.pg0.get_capture(len(pkts))
1043 self.verify_capture_in(capture, self.pg0)
1045 pkts = self.create_stream_in(self.pg0, self.pg1)
1046 self.pg0.add_stream(pkts)
1047 self.pg_enable_capture(self.pg_interfaces)
1049 capture = self.pg1.get_capture(len(pkts))
1050 self.verify_capture_out(capture, same_port=True)
1052 # in2out - no static mapping match
1054 host0 = self.pg0.remote_hosts[0]
1055 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1057 pkts = self.create_stream_out(self.pg1,
1058 dst_ip=self.pg0.remote_ip4,
1059 use_inside_ports=True)
1060 self.pg1.add_stream(pkts)
1061 self.pg_enable_capture(self.pg_interfaces)
1063 capture = self.pg0.get_capture(len(pkts))
1064 self.verify_capture_in(capture, self.pg0)
1066 pkts = self.create_stream_in(self.pg0, self.pg1)
1067 self.pg0.add_stream(pkts)
1068 self.pg_enable_capture(self.pg_interfaces)
1070 capture = self.pg1.get_capture(len(pkts))
1071 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1074 self.pg0.remote_hosts[0] = host0
1076 user = self.pg0.remote_hosts[1]
1077 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
1078 self.assertEqual(len(sessions), 3)
1079 self.assertTrue(sessions[0].flags &
1080 self.config_flags.NAT_IS_EXT_HOST_VALID)
1081 self.vapi.nat44_del_session(
1082 address=sessions[0].inside_ip_address,
1083 port=sessions[0].inside_port,
1084 protocol=sessions[0].protocol,
1085 flags=(self.config_flags.NAT_IS_INSIDE |
1086 self.config_flags.NAT_IS_EXT_HOST_VALID),
1087 ext_host_address=sessions[0].ext_host_address,
1088 ext_host_port=sessions[0].ext_host_port)
1089 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
1090 self.assertEqual(len(sessions), 2)
1093 self.vapi.nat44_forwarding_enable_disable(enable=0)
1094 flags = self.config_flags.NAT_IS_ADDR_ONLY
1095 self.vapi.nat44_add_del_static_mapping(
1097 local_ip_address=real_ip,
1098 external_ip_address=alias_ip,
1099 external_sw_if_index=0xFFFFFFFF,
1102 def test_output_feature_and_service2(self):
1103 """ NAT44ED interface output feature and service host direct access """
1104 self.vapi.nat44_forwarding_enable_disable(enable=1)
1105 self.nat_add_address(self.nat_addr)
1107 self.vapi.nat44_interface_add_del_output_feature(
1108 sw_if_index=self.pg1.sw_if_index, is_add=1,)
1110 # session initiated from service host - translate
1111 pkts = self.create_stream_in(self.pg0, self.pg1)
1112 self.pg0.add_stream(pkts)
1113 self.pg_enable_capture(self.pg_interfaces)
1115 capture = self.pg1.get_capture(len(pkts))
1116 self.verify_capture_out(capture, ignore_port=True)
1118 pkts = self.create_stream_out(self.pg1)
1119 self.pg1.add_stream(pkts)
1120 self.pg_enable_capture(self.pg_interfaces)
1122 capture = self.pg0.get_capture(len(pkts))
1123 self.verify_capture_in(capture, self.pg0)
1125 # session initiated from remote host - do not translate
1126 tcp_port_in = self.tcp_port_in
1127 udp_port_in = self.udp_port_in
1128 icmp_id_in = self.icmp_id_in
1130 self.tcp_port_in = 60303
1131 self.udp_port_in = 60304
1132 self.icmp_id_in = 60305
1135 pkts = self.create_stream_out(self.pg1,
1136 self.pg0.remote_ip4,
1137 use_inside_ports=True)
1138 self.pg1.add_stream(pkts)
1139 self.pg_enable_capture(self.pg_interfaces)
1141 capture = self.pg0.get_capture(len(pkts))
1142 self.verify_capture_in(capture, self.pg0)
1144 pkts = self.create_stream_in(self.pg0, self.pg1)
1145 self.pg0.add_stream(pkts)
1146 self.pg_enable_capture(self.pg_interfaces)
1148 capture = self.pg1.get_capture(len(pkts))
1149 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1152 self.tcp_port_in = tcp_port_in
1153 self.udp_port_in = udp_port_in
1154 self.icmp_id_in = icmp_id_in
1156 def test_twice_nat(self):
1157 """ NAT44ED Twice NAT """
1158 self.twice_nat_common()
1160 def test_self_twice_nat_positive(self):
1161 """ NAT44ED Self Twice NAT (positive test) """
1162 self.twice_nat_common(self_twice_nat=True, same_pg=True)
1164 def test_self_twice_nat_lb_positive(self):
1165 """ NAT44ED Self Twice NAT local service load balancing (positive test)
1167 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
1170 def test_twice_nat_lb(self):
1171 """ NAT44ED Twice NAT local service load balancing """
1172 self.twice_nat_common(lb=True)
1174 def test_output_feature(self):
1175 """ NAT44ED interface output feature (in2out postrouting) """
1176 self.vapi.nat44_forwarding_enable_disable(enable=1)
1177 self.nat_add_address(self.nat_addr)
1179 self.nat_add_outside_interface(self.pg0)
1180 self.vapi.nat44_interface_add_del_output_feature(
1181 sw_if_index=self.pg1.sw_if_index, is_add=1)
1184 pkts = self.create_stream_in(self.pg0, self.pg1)
1185 self.pg0.add_stream(pkts)
1186 self.pg_enable_capture(self.pg_interfaces)
1188 capture = self.pg1.get_capture(len(pkts))
1189 self.verify_capture_out(capture, ignore_port=True)
1192 pkts = self.create_stream_out(self.pg1)
1193 self.pg1.add_stream(pkts)
1194 self.pg_enable_capture(self.pg_interfaces)
1196 capture = self.pg0.get_capture(len(pkts))
1197 self.verify_capture_in(capture, self.pg0)
1199 def test_static_with_port_out2(self):
1200 """ NAT44ED 1:1 NAPT asymmetrical rule """
1205 self.vapi.nat44_forwarding_enable_disable(enable=1)
1206 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
1207 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1208 local_port, external_port,
1209 proto=IP_PROTOS.tcp, flags=flags)
1211 self.nat_add_inside_interface(self.pg0)
1212 self.nat_add_outside_interface(self.pg1)
1214 # from client to service
1215 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1216 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1217 TCP(sport=12345, dport=external_port))
1218 self.pg1.add_stream(p)
1219 self.pg_enable_capture(self.pg_interfaces)
1221 capture = self.pg0.get_capture(1)
1226 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1227 self.assertEqual(tcp.dport, local_port)
1228 self.assert_packet_checksums_valid(p)
1230 self.logger.error(ppp("Unexpected or invalid packet:", p))
1234 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1235 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1236 ICMP(type=11) / capture[0][IP])
1237 self.pg0.add_stream(p)
1238 self.pg_enable_capture(self.pg_interfaces)
1240 capture = self.pg1.get_capture(1)
1243 self.assertEqual(p[IP].src, self.nat_addr)
1245 self.assertEqual(inner.dst, self.nat_addr)
1246 self.assertEqual(inner[TCPerror].dport, external_port)
1248 self.logger.error(ppp("Unexpected or invalid packet:", p))
1251 # from service back to client
1252 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1253 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1254 TCP(sport=local_port, dport=12345))
1255 self.pg0.add_stream(p)
1256 self.pg_enable_capture(self.pg_interfaces)
1258 capture = self.pg1.get_capture(1)
1263 self.assertEqual(ip.src, self.nat_addr)
1264 self.assertEqual(tcp.sport, external_port)
1265 self.assert_packet_checksums_valid(p)
1267 self.logger.error(ppp("Unexpected or invalid packet:", p))
1271 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1272 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1273 ICMP(type=11) / capture[0][IP])
1274 self.pg1.add_stream(p)
1275 self.pg_enable_capture(self.pg_interfaces)
1277 capture = self.pg0.get_capture(1)
1280 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
1282 self.assertEqual(inner.src, self.pg0.remote_ip4)
1283 self.assertEqual(inner[TCPerror].sport, local_port)
1285 self.logger.error(ppp("Unexpected or invalid packet:", p))
1288 # from client to server (no translation)
1289 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1290 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1291 TCP(sport=12346, dport=local_port))
1292 self.pg1.add_stream(p)
1293 self.pg_enable_capture(self.pg_interfaces)
1295 capture = self.pg0.get_capture(1)
1300 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1301 self.assertEqual(tcp.dport, local_port)
1302 self.assert_packet_checksums_valid(p)
1304 self.logger.error(ppp("Unexpected or invalid packet:", p))
1307 # from service back to client (no translation)
1308 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1309 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1310 TCP(sport=local_port, dport=12346))
1311 self.pg0.add_stream(p)
1312 self.pg_enable_capture(self.pg_interfaces)
1314 capture = self.pg1.get_capture(1)
1319 self.assertEqual(ip.src, self.pg0.remote_ip4)
1320 self.assertEqual(tcp.sport, local_port)
1321 self.assert_packet_checksums_valid(p)
1323 self.logger.error(ppp("Unexpected or invalid packet:", p))
1326 def test_static_lb(self):
1327 """ NAT44ED local service load balancing """
1328 external_addr_n = self.nat_addr
1331 server1 = self.pg0.remote_hosts[0]
1332 server2 = self.pg0.remote_hosts[1]
1334 locals = [{'addr': server1.ip4,
1338 {'addr': server2.ip4,
1343 self.nat_add_address(self.nat_addr)
1344 self.vapi.nat44_add_del_lb_static_mapping(
1346 external_addr=external_addr_n,
1347 external_port=external_port,
1348 protocol=IP_PROTOS.tcp,
1349 local_num=len(locals),
1351 flags = self.config_flags.NAT_IS_INSIDE
1352 self.vapi.nat44_interface_add_del_feature(
1353 sw_if_index=self.pg0.sw_if_index,
1354 flags=flags, is_add=1)
1355 self.vapi.nat44_interface_add_del_feature(
1356 sw_if_index=self.pg1.sw_if_index,
1359 # from client to service
1360 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1361 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1362 TCP(sport=12345, dport=external_port))
1363 self.pg1.add_stream(p)
1364 self.pg_enable_capture(self.pg_interfaces)
1366 capture = self.pg0.get_capture(1)
1372 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
1373 if ip.dst == server1.ip4:
1377 self.assertEqual(tcp.dport, local_port)
1378 self.assert_packet_checksums_valid(p)
1380 self.logger.error(ppp("Unexpected or invalid packet:", p))
1383 # from service back to client
1384 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
1385 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
1386 TCP(sport=local_port, dport=12345))
1387 self.pg0.add_stream(p)
1388 self.pg_enable_capture(self.pg_interfaces)
1390 capture = self.pg1.get_capture(1)
1395 self.assertEqual(ip.src, self.nat_addr)
1396 self.assertEqual(tcp.sport, external_port)
1397 self.assert_packet_checksums_valid(p)
1399 self.logger.error(ppp("Unexpected or invalid packet:", p))
1402 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
1403 self.assertEqual(len(sessions), 1)
1404 self.assertTrue(sessions[0].flags &
1405 self.config_flags.NAT_IS_EXT_HOST_VALID)
1406 self.vapi.nat44_del_session(
1407 address=sessions[0].inside_ip_address,
1408 port=sessions[0].inside_port,
1409 protocol=sessions[0].protocol,
1410 flags=(self.config_flags.NAT_IS_INSIDE |
1411 self.config_flags.NAT_IS_EXT_HOST_VALID),
1412 ext_host_address=sessions[0].ext_host_address,
1413 ext_host_port=sessions[0].ext_host_port)
1414 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
1415 self.assertEqual(len(sessions), 0)
1417 def test_static_lb_2(self):
1418 """ NAT44ED local service load balancing (asymmetrical rule) """
1419 external_addr = self.nat_addr
1422 server1 = self.pg0.remote_hosts[0]
1423 server2 = self.pg0.remote_hosts[1]
1425 locals = [{'addr': server1.ip4,
1429 {'addr': server2.ip4,
1434 self.vapi.nat44_forwarding_enable_disable(enable=1)
1435 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
1436 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
1437 external_addr=external_addr,
1438 external_port=external_port,
1439 protocol=IP_PROTOS.tcp,
1440 local_num=len(locals),
1442 flags = self.config_flags.NAT_IS_INSIDE
1443 self.vapi.nat44_interface_add_del_feature(
1444 sw_if_index=self.pg0.sw_if_index,
1445 flags=flags, is_add=1)
1446 self.vapi.nat44_interface_add_del_feature(
1447 sw_if_index=self.pg1.sw_if_index,
1450 # from client to service
1451 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1452 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1453 TCP(sport=12345, dport=external_port))
1454 self.pg1.add_stream(p)
1455 self.pg_enable_capture(self.pg_interfaces)
1457 capture = self.pg0.get_capture(1)
1463 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
1464 if ip.dst == server1.ip4:
1468 self.assertEqual(tcp.dport, local_port)
1469 self.assert_packet_checksums_valid(p)
1471 self.logger.error(ppp("Unexpected or invalid packet:", p))
1474 # from service back to client
1475 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
1476 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
1477 TCP(sport=local_port, dport=12345))
1478 self.pg0.add_stream(p)
1479 self.pg_enable_capture(self.pg_interfaces)
1481 capture = self.pg1.get_capture(1)
1486 self.assertEqual(ip.src, self.nat_addr)
1487 self.assertEqual(tcp.sport, external_port)
1488 self.assert_packet_checksums_valid(p)
1490 self.logger.error(ppp("Unexpected or invalid packet:", p))
1493 # from client to server (no translation)
1494 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1495 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
1496 TCP(sport=12346, dport=local_port))
1497 self.pg1.add_stream(p)
1498 self.pg_enable_capture(self.pg_interfaces)
1500 capture = self.pg0.get_capture(1)
1506 self.assertEqual(ip.dst, server1.ip4)
1507 self.assertEqual(tcp.dport, local_port)
1508 self.assert_packet_checksums_valid(p)
1510 self.logger.error(ppp("Unexpected or invalid packet:", p))
1513 # from service back to client (no translation)
1514 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
1515 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
1516 TCP(sport=local_port, dport=12346))
1517 self.pg0.add_stream(p)
1518 self.pg_enable_capture(self.pg_interfaces)
1520 capture = self.pg1.get_capture(1)
1525 self.assertEqual(ip.src, server1.ip4)
1526 self.assertEqual(tcp.sport, local_port)
1527 self.assert_packet_checksums_valid(p)
1529 self.logger.error(ppp("Unexpected or invalid packet:", p))
1532 def test_lb_affinity(self):
1533 """ NAT44ED local service load balancing affinity """
1534 external_addr = self.nat_addr
1537 server1 = self.pg0.remote_hosts[0]
1538 server2 = self.pg0.remote_hosts[1]
1540 locals = [{'addr': server1.ip4,
1544 {'addr': server2.ip4,
1549 self.nat_add_address(self.nat_addr)
1550 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
1551 external_addr=external_addr,
1552 external_port=external_port,
1553 protocol=IP_PROTOS.tcp,
1555 local_num=len(locals),
1557 flags = self.config_flags.NAT_IS_INSIDE
1558 self.vapi.nat44_interface_add_del_feature(
1559 sw_if_index=self.pg0.sw_if_index,
1560 flags=flags, is_add=1)
1561 self.vapi.nat44_interface_add_del_feature(
1562 sw_if_index=self.pg1.sw_if_index,
1565 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1566 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1567 TCP(sport=1025, dport=external_port))
1568 self.pg1.add_stream(p)
1569 self.pg_enable_capture(self.pg_interfaces)
1571 capture = self.pg0.get_capture(1)
1572 backend = capture[0][IP].dst
1574 sessions = self.vapi.nat44_user_session_dump(backend, 0)
1575 self.assertEqual(len(sessions), 1)
1576 self.assertTrue(sessions[0].flags &
1577 self.config_flags.NAT_IS_EXT_HOST_VALID)
1578 self.vapi.nat44_del_session(
1579 address=sessions[0].inside_ip_address,
1580 port=sessions[0].inside_port,
1581 protocol=sessions[0].protocol,
1582 flags=(self.config_flags.NAT_IS_INSIDE |
1583 self.config_flags.NAT_IS_EXT_HOST_VALID),
1584 ext_host_address=sessions[0].ext_host_address,
1585 ext_host_port=sessions[0].ext_host_port)
1588 for port in range(1030, 1100):
1589 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1590 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1591 TCP(sport=port, dport=external_port))
1593 self.pg1.add_stream(pkts)
1594 self.pg_enable_capture(self.pg_interfaces)
1596 capture = self.pg0.get_capture(len(pkts))
1598 self.assertEqual(p[IP].dst, backend)
1600 def test_multiple_vrf(self):
1601 """ NAT44ED Multiple VRF setup """
1603 external_addr = '1.2.3.4'
1608 self.vapi.nat44_forwarding_enable_disable(enable=1)
1609 self.nat_add_address(self.nat_addr)
1610 flags = self.config_flags.NAT_IS_INSIDE
1611 self.vapi.nat44_interface_add_del_feature(
1612 sw_if_index=self.pg0.sw_if_index,
1614 self.vapi.nat44_interface_add_del_feature(
1615 sw_if_index=self.pg0.sw_if_index,
1616 is_add=1, flags=flags)
1617 self.vapi.nat44_interface_add_del_output_feature(
1618 sw_if_index=self.pg1.sw_if_index,
1620 self.vapi.nat44_interface_add_del_feature(
1621 sw_if_index=self.pg5.sw_if_index,
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg5.sw_if_index,
1625 is_add=1, flags=flags)
1626 self.vapi.nat44_interface_add_del_feature(
1627 sw_if_index=self.pg6.sw_if_index,
1629 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
1630 self.nat_add_static_mapping(self.pg5.remote_ip4, external_addr,
1631 local_port, external_port, vrf_id=1,
1632 proto=IP_PROTOS.tcp, flags=flags)
1633 self.nat_add_static_mapping(
1634 self.pg0.remote_ip4,
1635 external_sw_if_index=self.pg0.sw_if_index,
1636 local_port=local_port,
1638 external_port=external_port,
1639 proto=IP_PROTOS.tcp,
1643 # from client to service (both VRF1)
1644 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
1645 IP(src=self.pg6.remote_ip4, dst=external_addr) /
1646 TCP(sport=12345, dport=external_port))
1647 self.pg6.add_stream(p)
1648 self.pg_enable_capture(self.pg_interfaces)
1650 capture = self.pg5.get_capture(1)
1655 self.assertEqual(ip.dst, self.pg5.remote_ip4)
1656 self.assertEqual(tcp.dport, local_port)
1657 self.assert_packet_checksums_valid(p)
1659 self.logger.error(ppp("Unexpected or invalid packet:", p))
1662 # from service back to client (both VRF1)
1663 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
1664 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
1665 TCP(sport=local_port, dport=12345))
1666 self.pg5.add_stream(p)
1667 self.pg_enable_capture(self.pg_interfaces)
1669 capture = self.pg6.get_capture(1)
1674 self.assertEqual(ip.src, external_addr)
1675 self.assertEqual(tcp.sport, external_port)
1676 self.assert_packet_checksums_valid(p)
1678 self.logger.error(ppp("Unexpected or invalid packet:", p))
1681 # dynamic NAT from VRF1 to VRF0 (output-feature)
1682 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
1683 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
1684 TCP(sport=2345, dport=22))
1685 self.pg5.add_stream(p)
1686 self.pg_enable_capture(self.pg_interfaces)
1688 capture = self.pg1.get_capture(1)
1693 self.assertEqual(ip.src, self.nat_addr)
1694 self.assert_packet_checksums_valid(p)
1697 self.logger.error(ppp("Unexpected or invalid packet:", p))
1700 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1701 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1702 TCP(sport=22, dport=port))
1703 self.pg1.add_stream(p)
1704 self.pg_enable_capture(self.pg_interfaces)
1706 capture = self.pg5.get_capture(1)
1711 self.assertEqual(ip.dst, self.pg5.remote_ip4)
1712 self.assertEqual(tcp.dport, 2345)
1713 self.assert_packet_checksums_valid(p)
1715 self.logger.error(ppp("Unexpected or invalid packet:", p))
1718 # from client VRF1 to service VRF0
1719 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
1720 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
1721 TCP(sport=12346, dport=external_port))
1722 self.pg6.add_stream(p)
1723 self.pg_enable_capture(self.pg_interfaces)
1725 capture = self.pg0.get_capture(1)
1730 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1731 self.assertEqual(tcp.dport, local_port)
1732 self.assert_packet_checksums_valid(p)
1734 self.logger.error(ppp("Unexpected or invalid packet:", p))
1737 # from service VRF0 back to client VRF1
1738 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1739 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
1740 TCP(sport=local_port, dport=12346))
1741 self.pg0.add_stream(p)
1742 self.pg_enable_capture(self.pg_interfaces)
1744 capture = self.pg6.get_capture(1)
1749 self.assertEqual(ip.src, self.pg0.local_ip4)
1750 self.assertEqual(tcp.sport, external_port)
1751 self.assert_packet_checksums_valid(p)
1753 self.logger.error(ppp("Unexpected or invalid packet:", p))
1756 # from client VRF0 to service VRF1
1757 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1758 IP(src=self.pg0.remote_ip4, dst=external_addr) /
1759 TCP(sport=12347, dport=external_port))
1760 self.pg0.add_stream(p)
1761 self.pg_enable_capture(self.pg_interfaces)
1763 capture = self.pg5.get_capture(1)
1768 self.assertEqual(ip.dst, self.pg5.remote_ip4)
1769 self.assertEqual(tcp.dport, local_port)
1770 self.assert_packet_checksums_valid(p)
1772 self.logger.error(ppp("Unexpected or invalid packet:", p))
1775 # from service VRF1 back to client VRF0
1776 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
1777 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
1778 TCP(sport=local_port, dport=12347))
1779 self.pg5.add_stream(p)
1780 self.pg_enable_capture(self.pg_interfaces)
1782 capture = self.pg0.get_capture(1)
1787 self.assertEqual(ip.src, external_addr)
1788 self.assertEqual(tcp.sport, external_port)
1789 self.assert_packet_checksums_valid(p)
1791 self.logger.error(ppp("Unexpected or invalid packet:", p))
1794 # from client to server (both VRF1, no translation)
1795 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
1796 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
1797 TCP(sport=12348, dport=local_port))
1798 self.pg6.add_stream(p)
1799 self.pg_enable_capture(self.pg_interfaces)
1801 capture = self.pg5.get_capture(1)
1806 self.assertEqual(ip.dst, self.pg5.remote_ip4)
1807 self.assertEqual(tcp.dport, local_port)
1808 self.assert_packet_checksums_valid(p)
1810 self.logger.error(ppp("Unexpected or invalid packet:", p))
1813 # from server back to client (both VRF1, no translation)
1814 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
1815 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
1816 TCP(sport=local_port, dport=12348))
1817 self.pg5.add_stream(p)
1818 self.pg_enable_capture(self.pg_interfaces)
1820 capture = self.pg6.get_capture(1)
1825 self.assertEqual(ip.src, self.pg5.remote_ip4)
1826 self.assertEqual(tcp.sport, local_port)
1827 self.assert_packet_checksums_valid(p)
1829 self.logger.error(ppp("Unexpected or invalid packet:", p))
1832 # from client VRF1 to server VRF0 (no translation)
1833 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1834 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
1835 TCP(sport=local_port, dport=12349))
1836 self.pg0.add_stream(p)
1837 self.pg_enable_capture(self.pg_interfaces)
1839 capture = self.pg6.get_capture(1)
1844 self.assertEqual(ip.src, self.pg0.remote_ip4)
1845 self.assertEqual(tcp.sport, local_port)
1846 self.assert_packet_checksums_valid(p)
1848 self.logger.error(ppp("Unexpected or invalid packet:", p))
1851 # from server VRF0 back to client VRF1 (no translation)
1852 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1853 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
1854 TCP(sport=local_port, dport=12349))
1855 self.pg0.add_stream(p)
1856 self.pg_enable_capture(self.pg_interfaces)
1858 capture = self.pg6.get_capture(1)
1863 self.assertEqual(ip.src, self.pg0.remote_ip4)
1864 self.assertEqual(tcp.sport, local_port)
1865 self.assert_packet_checksums_valid(p)
1867 self.logger.error(ppp("Unexpected or invalid packet:", p))
1870 # from client VRF0 to server VRF1 (no translation)
1871 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
1872 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
1873 TCP(sport=12344, dport=local_port))
1874 self.pg0.add_stream(p)
1875 self.pg_enable_capture(self.pg_interfaces)
1877 capture = self.pg5.get_capture(1)
1882 self.assertEqual(ip.dst, self.pg5.remote_ip4)
1883 self.assertEqual(tcp.dport, local_port)
1884 self.assert_packet_checksums_valid(p)
1886 self.logger.error(ppp("Unexpected or invalid packet:", p))
1889 # from server VRF1 back to client VRF0 (no translation)
1890 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
1891 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
1892 TCP(sport=local_port, dport=12344))
1893 self.pg5.add_stream(p)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg0.get_capture(1)
1901 self.assertEqual(ip.src, self.pg5.remote_ip4)
1902 self.assertEqual(tcp.sport, local_port)
1903 self.assert_packet_checksums_valid(p)
1905 self.logger.error(ppp("Unexpected or invalid packet:", p))
1909 @tag_fixme_vpp_workers
1910 class TestNAT44EDMW(TestNAT44ED):
1911 """ NAT44ED MW Test Case """
1912 worker_config = "workers 1"
1914 def get_stats_counter(self, path, worker=1):
1915 return super(TestNAT44EDMW, self).get_stats_counter(path, worker)
1917 @unittest.skip('MW fix required')
1918 def test_users_dump(self):
1919 """ NAT44ED API test - nat44_user_dump """
1921 @unittest.skip('MW fix required')
1922 def test_frag_out_of_order_do_not_translate(self):
1923 """ NAT44ED don't translate fragments arriving out of order """
1925 @unittest.skip('MW fix required')
1926 def test_forwarding(self):
1927 """ NAT44ED forwarding test """
1929 @unittest.skip('MW fix required')
1930 def test_twice_nat(self):
1931 """ NAT44ED Twice NAT """
1933 @unittest.skip('MW fix required')
1934 def test_twice_nat_lb(self):
1935 """ NAT44ED Twice NAT local service load balancing """
1937 @unittest.skip('MW fix required')
1938 def test_output_feature(self):
1939 """ NAT44ED interface output feature (in2out postrouting) """
1941 @unittest.skip('MW fix required')
1942 def test_static_with_port_out2(self):
1943 """ NAT44ED 1:1 NAPT asymmetrical rule """
1945 @unittest.skip('MW fix required')
1946 def test_output_feature_and_service2(self):
1947 """ NAT44ED interface output feature and service host direct access """
1949 @unittest.skip('MW fix required')
1950 def test_static_lb(self):
1951 """ NAT44ED local service load balancing """
1953 @unittest.skip('MW fix required')
1954 def test_static_lb_2(self):
1955 """ NAT44ED local service load balancing (asymmetrical rule) """
1957 @unittest.skip('MW fix required')
1958 def test_lb_affinity(self):
1959 """ NAT44ED local service load balancing affinity """
1961 @unittest.skip('MW fix required')
1962 def test_multiple_vrf(self):
1963 """ NAT44ED Multiple VRF setup """
1965 @unittest.skip('MW fix required')
1966 def test_self_twice_nat_positive(self):
1967 """ NAT44ED Self Twice NAT (positive test) """
1969 @unittest.skip('MW fix required')
1970 def test_self_twice_nat_lb_positive(self):
1971 """ NAT44ED Self Twice NAT local service load balancing (positive test)
1974 def test_dynamic(self):
1975 """ NAT44ED dynamic translation test """
1977 self.nat_add_address(self.nat_addr)
1978 self.nat_add_inside_interface(self.pg0)
1979 self.nat_add_outside_interface(self.pg1)
1982 tc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/tcp')
1983 uc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/udp')
1984 ic1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/icmp')
1985 dc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/drops')
1987 pkts = self.create_stream_in(self.pg0, self.pg1)
1988 # TODO: specify worker=idx, also stats have to
1989 # know from which worker to take capture
1990 self.pg0.add_stream(pkts)
1991 self.pg_enable_capture(self.pg_interfaces)
1993 capture = self.pg1.get_capture(len(pkts))
1994 self.verify_capture_out(capture, ignore_port=True)
1996 if_idx = self.pg0.sw_if_index
1997 tc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/tcp')
1998 uc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/udp')
1999 ic2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/icmp')
2000 dc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/drops')
2002 self.assertEqual(tc2[if_idx] - tc1[if_idx], 2)
2003 self.assertEqual(uc2[if_idx] - uc1[if_idx], 1)
2004 self.assertEqual(ic2[if_idx] - ic1[if_idx], 1)
2005 self.assertEqual(dc2[if_idx] - dc1[if_idx], 0)
2008 tc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/tcp')
2009 uc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/udp')
2010 ic1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/icmp')
2011 dc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/drops')
2013 pkts = self.create_stream_out(self.pg1)
2014 self.pg1.add_stream(pkts)
2015 self.pg_enable_capture(self.pg_interfaces)
2017 capture = self.pg0.get_capture(len(pkts))
2018 self.verify_capture_in(capture, self.pg0)
2020 if_idx = self.pg1.sw_if_index
2021 tc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/tcp')
2022 uc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/udp')
2023 ic2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/icmp')
2024 dc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/drops')
2026 self.assertEqual(tc2[if_idx] - tc1[if_idx], 2)
2027 self.assertEqual(uc2[if_idx] - uc1[if_idx], 1)
2028 self.assertEqual(ic2[if_idx] - ic1[if_idx], 1)
2029 self.assertEqual(dc2[if_idx] - dc1[if_idx], 0)
2031 sc = self.get_stats_counter('/nat44/total-sessions')
2032 self.assertEqual(sc[0], 3)
2034 def test_frag_in_order(self):
2035 """ NAT44ED translate fragments arriving in order """
2037 self.nat_add_address(self.nat_addr)
2038 self.nat_add_inside_interface(self.pg0)
2039 self.nat_add_outside_interface(self.pg1)
2041 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
2042 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
2043 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
2045 def test_frag_in_order_do_not_translate(self):
2046 """ NAT44ED don't translate fragments arriving in order """
2048 self.nat_add_address(self.nat_addr)
2049 self.nat_add_inside_interface(self.pg0)
2050 self.nat_add_outside_interface(self.pg1)
2051 self.vapi.nat44_forwarding_enable_disable(enable=True)
2053 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
2055 def test_frag_out_of_order(self):
2056 """ NAT44ED translate fragments arriving out of order """
2058 self.nat_add_address(self.nat_addr)
2059 self.nat_add_inside_interface(self.pg0)
2060 self.nat_add_outside_interface(self.pg1)
2062 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
2063 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
2064 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
2066 def test_frag_in_order_in_plus_out(self):
2067 """ NAT44ED in+out interface fragments in order """
2069 in_port = self.random_port()
2070 out_port = self.random_port()
2072 self.nat_add_address(self.nat_addr)
2073 self.nat_add_inside_interface(self.pg0)
2074 self.nat_add_outside_interface(self.pg0)
2075 self.nat_add_inside_interface(self.pg1)
2076 self.nat_add_outside_interface(self.pg1)
2078 # add static mappings for server
2079 self.nat_add_static_mapping(self.server_addr,
2083 proto=IP_PROTOS.tcp)
2084 self.nat_add_static_mapping(self.server_addr,
2088 proto=IP_PROTOS.udp)
2089 self.nat_add_static_mapping(self.server_addr,
2091 proto=IP_PROTOS.icmp)
2093 # run tests for each protocol
2094 self.frag_in_order_in_plus_out(self.server_addr,
2099 self.frag_in_order_in_plus_out(self.server_addr,
2104 self.frag_in_order_in_plus_out(self.server_addr,
2110 def test_frag_out_of_order_in_plus_out(self):
2111 """ NAT44ED in+out interface fragments out of order """
2113 in_port = self.random_port()
2114 out_port = self.random_port()
2116 self.nat_add_address(self.nat_addr)
2117 self.nat_add_inside_interface(self.pg0)
2118 self.nat_add_outside_interface(self.pg0)
2119 self.nat_add_inside_interface(self.pg1)
2120 self.nat_add_outside_interface(self.pg1)
2122 # add static mappings for server
2123 self.nat_add_static_mapping(self.server_addr,
2127 proto=IP_PROTOS.tcp)
2128 self.nat_add_static_mapping(self.server_addr,
2132 proto=IP_PROTOS.udp)
2133 self.nat_add_static_mapping(self.server_addr,
2135 proto=IP_PROTOS.icmp)
2137 # run tests for each protocol
2138 self.frag_out_of_order_in_plus_out(self.server_addr,
2143 self.frag_out_of_order_in_plus_out(self.server_addr,
2148 self.frag_out_of_order_in_plus_out(self.server_addr,
2154 def test_reass_hairpinning(self):
2155 """ NAT44ED fragments hairpinning """
2157 server_addr = self.pg0.remote_hosts[1].ip4
2159 host_in_port = self.random_port()
2160 server_in_port = self.random_port()
2161 server_out_port = self.random_port()
2163 self.nat_add_address(self.nat_addr)
2164 self.nat_add_inside_interface(self.pg0)
2165 self.nat_add_outside_interface(self.pg1)
2167 # add static mapping for server
2168 self.nat_add_static_mapping(server_addr, self.nat_addr,
2169 server_in_port, server_out_port,
2170 proto=IP_PROTOS.tcp)
2171 self.nat_add_static_mapping(server_addr, self.nat_addr,
2172 server_in_port, server_out_port,
2173 proto=IP_PROTOS.udp)
2174 self.nat_add_static_mapping(server_addr, self.nat_addr)
2176 self.reass_hairpinning(server_addr, server_in_port, server_out_port,
2177 host_in_port, proto=IP_PROTOS.tcp,
2179 self.reass_hairpinning(server_addr, server_in_port, server_out_port,
2180 host_in_port, proto=IP_PROTOS.udp,
2182 self.reass_hairpinning(server_addr, server_in_port, server_out_port,
2183 host_in_port, proto=IP_PROTOS.icmp,
2186 def test_session_limit_per_vrf(self):
2187 """ NAT44ED per vrf session limit """
2190 inside_vrf10 = self.pg2
2195 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
2196 # non existing vrf_id makes process core dump
2197 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
2199 self.nat_add_inside_interface(inside)
2200 self.nat_add_inside_interface(inside_vrf10)
2201 self.nat_add_outside_interface(outside)
2204 self.nat_add_interface_address(outside)
2206 # BUG: causing core dump - when bad vrf_id is specified
2207 # self.nat_add_address(outside.local_ip4, vrf_id=20)
2209 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
2210 inside_vrf10.add_stream(stream)
2212 self.pg_enable_capture(self.pg_interfaces)
2215 capture = outside.get_capture(limit)
2217 stream = self.create_tcp_stream(inside, outside, limit * 2)
2218 inside.add_stream(stream)
2220 self.pg_enable_capture(self.pg_interfaces)
2223 capture = outside.get_capture(len(stream))
2225 def test_clear_sessions(self):
2226 """ NAT44ED session clearing test """
2228 self.nat_add_address(self.nat_addr)
2229 self.nat_add_inside_interface(self.pg0)
2230 self.nat_add_outside_interface(self.pg1)
2232 pkts = self.create_stream_in(self.pg0, self.pg1)
2233 self.pg0.add_stream(pkts)
2234 self.pg_enable_capture(self.pg_interfaces)
2236 capture = self.pg1.get_capture(len(pkts))
2237 self.verify_capture_out(capture, ignore_port=True)
2239 sessions = self.get_stats_counter('/nat44/total-sessions')
2240 self.assertTrue(sessions[0] > 0)
2242 self.vapi.cli("clear nat44 sessions")
2244 sessions = self.get_stats_counter('/nat44/total-sessions')
2245 self.assertEqual(sessions[0], 0)
2247 def test_show_max_translations(self):
2248 """ NAT44ED API test - max translations per thread """
2249 nat_config = self.vapi.nat_show_config_2()
2250 self.assertEqual(self.max_sessions,
2251 nat_config.max_translations_per_thread)
2253 def test_lru_cleanup(self):
2254 """ NAT44ED LRU cleanup algorithm """
2256 self.nat_add_address(self.nat_addr)
2257 self.nat_add_inside_interface(self.pg0)
2258 self.nat_add_outside_interface(self.pg1)
2260 self.vapi.nat_set_timeouts(
2261 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
2263 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
2265 for i in range(0, self.max_sessions - 1):
2266 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2267 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
2268 UDP(sport=7000+i, dport=80))
2271 self.pg0.add_stream(pkts)
2272 self.pg_enable_capture(self.pg_interfaces)
2274 self.pg1.get_capture(len(pkts))
2275 self.sleep(1.5, "wait for timeouts")
2278 for i in range(0, self.max_sessions - 1):
2279 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2280 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
2281 ICMP(id=8000+i, type='echo-request'))
2284 self.pg0.add_stream(pkts)
2285 self.pg_enable_capture(self.pg_interfaces)
2287 self.pg1.get_capture(len(pkts))
2289 def test_session_rst_timeout(self):
2290 """ NAT44ED session RST timeouts """
2292 self.nat_add_address(self.nat_addr)
2293 self.nat_add_inside_interface(self.pg0)
2294 self.nat_add_outside_interface(self.pg1)
2296 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
2297 tcp_transitory=5, icmp=60)
2299 self.init_tcp_session(self.pg0, self.pg1, self.tcp_port_in,
2300 self.tcp_external_port)
2301 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2302 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2303 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
2305 self.pg0.add_stream(p)
2306 self.pg_enable_capture(self.pg_interfaces)
2308 self.pg1.get_capture(1)
2312 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2313 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2314 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
2316 self.pg0.add_stream(p)
2317 self.pg_enable_capture(self.pg_interfaces)
2319 self.pg1.get_capture(1)
2321 def test_dynamic_out_of_ports(self):
2322 """ NAT44ED dynamic translation test: out of ports """
2324 self.nat_add_inside_interface(self.pg0)
2325 self.nat_add_outside_interface(self.pg1)
2327 # in2out and no NAT addresses added
2328 err_old = self.statistics.get_err_counter(
2329 '/err/nat44-ed-in2out-slowpath/out of ports')
2331 pkts = self.create_stream_in(self.pg0, self.pg1)
2332 self.pg0.add_stream(pkts)
2333 self.pg_enable_capture(self.pg_interfaces)
2335 self.pg1.get_capture(0, timeout=1)
2337 err_new = self.statistics.get_err_counter(
2338 '/err/nat44-ed-in2out-slowpath/out of ports')
2340 self.assertEqual(err_new - err_old, len(pkts))
2342 # in2out after NAT addresses added
2343 self.nat_add_address(self.nat_addr)
2345 err_old = self.statistics.get_err_counter(
2346 '/err/nat44-ed-in2out-slowpath/out of ports')
2348 pkts = self.create_stream_in(self.pg0, self.pg1)
2349 self.pg0.add_stream(pkts)
2350 self.pg_enable_capture(self.pg_interfaces)
2352 capture = self.pg1.get_capture(len(pkts))
2353 self.verify_capture_out(capture, ignore_port=True)
2355 err_new = self.statistics.get_err_counter(
2356 '/err/nat44-ed-in2out-slowpath/out of ports')
2358 self.assertEqual(err_new, err_old)
2360 def test_unknown_proto(self):
2361 """ NAT44ED translate packet with unknown protocol """
2363 self.nat_add_address(self.nat_addr)
2364 self.nat_add_inside_interface(self.pg0)
2365 self.nat_add_outside_interface(self.pg1)
2368 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2369 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2370 TCP(sport=self.tcp_port_in, dport=20))
2371 self.pg0.add_stream(p)
2372 self.pg_enable_capture(self.pg_interfaces)
2374 p = self.pg1.get_capture(1)
2376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2377 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2379 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2380 TCP(sport=1234, dport=1234))
2381 self.pg0.add_stream(p)
2382 self.pg_enable_capture(self.pg_interfaces)
2384 p = self.pg1.get_capture(1)
2387 self.assertEqual(packet[IP].src, self.nat_addr)
2388 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2389 self.assertEqual(packet.haslayer(GRE), 1)
2390 self.assert_packet_checksums_valid(packet)
2392 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2396 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
2397 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
2399 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2400 TCP(sport=1234, dport=1234))
2401 self.pg1.add_stream(p)
2402 self.pg_enable_capture(self.pg_interfaces)
2404 p = self.pg0.get_capture(1)
2407 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
2408 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
2409 self.assertEqual(packet.haslayer(GRE), 1)
2410 self.assert_packet_checksums_valid(packet)
2412 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2415 def test_hairpinning_unknown_proto(self):
2416 """ NAT44ED translate packet with unknown protocol - hairpinning """
2417 host = self.pg0.remote_hosts[0]
2418 server = self.pg0.remote_hosts[1]
2420 server_out_port = 8765
2421 server_nat_ip = "10.0.0.11"
2423 self.nat_add_address(self.nat_addr)
2424 self.nat_add_inside_interface(self.pg0)
2425 self.nat_add_outside_interface(self.pg1)
2427 # add static mapping for server
2428 self.nat_add_static_mapping(server.ip4, server_nat_ip)
2431 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2432 IP(src=host.ip4, dst=server_nat_ip) /
2433 TCP(sport=host_in_port, dport=server_out_port))
2434 self.pg0.add_stream(p)
2435 self.pg_enable_capture(self.pg_interfaces)
2437 self.pg0.get_capture(1)
2439 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
2440 IP(src=host.ip4, dst=server_nat_ip) /
2442 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2443 TCP(sport=1234, dport=1234))
2444 self.pg0.add_stream(p)
2445 self.pg_enable_capture(self.pg_interfaces)
2447 p = self.pg0.get_capture(1)
2450 self.assertEqual(packet[IP].src, self.nat_addr)
2451 self.assertEqual(packet[IP].dst, server.ip4)
2452 self.assertEqual(packet.haslayer(GRE), 1)
2453 self.assert_packet_checksums_valid(packet)
2455 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2459 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
2460 IP(src=server.ip4, dst=self.nat_addr) /
2462 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2463 TCP(sport=1234, dport=1234))
2464 self.pg0.add_stream(p)
2465 self.pg_enable_capture(self.pg_interfaces)
2467 p = self.pg0.get_capture(1)
2470 self.assertEqual(packet[IP].src, server_nat_ip)
2471 self.assertEqual(packet[IP].dst, host.ip4)
2472 self.assertEqual(packet.haslayer(GRE), 1)
2473 self.assert_packet_checksums_valid(packet)
2475 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2478 def test_output_feature_and_service(self):
2479 """ NAT44ED interface output feature and services """
2480 external_addr = '1.2.3.4'
2484 self.vapi.nat44_forwarding_enable_disable(enable=1)
2485 self.nat_add_address(self.nat_addr)
2486 flags = self.config_flags.NAT_IS_ADDR_ONLY
2487 self.vapi.nat44_add_del_identity_mapping(
2488 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
2489 flags=flags, is_add=1)
2490 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
2491 self.nat_add_static_mapping(self.pg0.remote_ip4, external_addr,
2492 local_port, external_port,
2493 proto=IP_PROTOS.tcp, flags=flags)
2495 self.nat_add_inside_interface(self.pg0)
2496 self.nat_add_outside_interface(self.pg0)
2497 self.vapi.nat44_interface_add_del_output_feature(
2498 sw_if_index=self.pg1.sw_if_index, is_add=1)
2500 # from client to service
2501 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2502 IP(src=self.pg1.remote_ip4, dst=external_addr) /
2503 TCP(sport=12345, dport=external_port))
2504 self.pg1.add_stream(p)
2505 self.pg_enable_capture(self.pg_interfaces)
2507 capture = self.pg0.get_capture(1)
2512 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2513 self.assertEqual(tcp.dport, local_port)
2514 self.assert_packet_checksums_valid(p)
2516 self.logger.error(ppp("Unexpected or invalid packet:", p))
2519 # from service back to client
2520 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2521 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2522 TCP(sport=local_port, dport=12345))
2523 self.pg0.add_stream(p)
2524 self.pg_enable_capture(self.pg_interfaces)
2526 capture = self.pg1.get_capture(1)
2531 self.assertEqual(ip.src, external_addr)
2532 self.assertEqual(tcp.sport, external_port)
2533 self.assert_packet_checksums_valid(p)
2535 self.logger.error(ppp("Unexpected or invalid packet:", p))
2538 # from local network host to external network
2539 pkts = self.create_stream_in(self.pg0, self.pg1)
2540 self.pg0.add_stream(pkts)
2541 self.pg_enable_capture(self.pg_interfaces)
2543 capture = self.pg1.get_capture(len(pkts))
2544 self.verify_capture_out(capture, ignore_port=True)
2545 pkts = self.create_stream_in(self.pg0, self.pg1)
2546 self.pg0.add_stream(pkts)
2547 self.pg_enable_capture(self.pg_interfaces)
2549 capture = self.pg1.get_capture(len(pkts))
2550 self.verify_capture_out(capture, ignore_port=True)
2552 # from external network back to local network host
2553 pkts = self.create_stream_out(self.pg1)
2554 self.pg1.add_stream(pkts)
2555 self.pg_enable_capture(self.pg_interfaces)
2557 capture = self.pg0.get_capture(len(pkts))
2558 self.verify_capture_in(capture, self.pg0)
2560 def test_output_feature_and_service3(self):
2561 """ NAT44ED interface output feature and DST NAT """
2562 external_addr = '1.2.3.4'
2566 self.vapi.nat44_forwarding_enable_disable(enable=1)
2567 self.nat_add_address(self.nat_addr)
2568 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
2569 self.nat_add_static_mapping(self.pg1.remote_ip4, external_addr,
2570 local_port, external_port,
2571 proto=IP_PROTOS.tcp, flags=flags)
2573 self.nat_add_inside_interface(self.pg0)
2574 self.nat_add_outside_interface(self.pg0)
2575 self.vapi.nat44_interface_add_del_output_feature(
2576 sw_if_index=self.pg1.sw_if_index, is_add=1)
2578 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2579 IP(src=self.pg0.remote_ip4, dst=external_addr) /
2580 TCP(sport=12345, dport=external_port))
2581 self.pg0.add_stream(p)
2582 self.pg_enable_capture(self.pg_interfaces)
2584 capture = self.pg1.get_capture(1)
2589 self.assertEqual(ip.src, self.pg0.remote_ip4)
2590 self.assertEqual(tcp.sport, 12345)
2591 self.assertEqual(ip.dst, self.pg1.remote_ip4)
2592 self.assertEqual(tcp.dport, local_port)
2593 self.assert_packet_checksums_valid(p)
2595 self.logger.error(ppp("Unexpected or invalid packet:", p))
2598 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2599 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2600 TCP(sport=local_port, dport=12345))
2601 self.pg1.add_stream(p)
2602 self.pg_enable_capture(self.pg_interfaces)
2604 capture = self.pg0.get_capture(1)
2609 self.assertEqual(ip.src, external_addr)
2610 self.assertEqual(tcp.sport, external_port)
2611 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2612 self.assertEqual(tcp.dport, 12345)
2613 self.assert_packet_checksums_valid(p)
2615 self.logger.error(ppp("Unexpected or invalid packet:", p))
2618 def test_self_twice_nat_lb_negative(self):
2619 """ NAT44ED Self Twice NAT local service load balancing (negative test)
2621 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
2624 def test_self_twice_nat_negative(self):
2625 """ NAT44ED Self Twice NAT (negative test) """
2626 self.twice_nat_common(self_twice_nat=True)
2628 def test_static_lb_multi_clients(self):
2629 """ NAT44ED local service load balancing - multiple clients"""
2631 external_addr = self.nat_addr
2634 server1 = self.pg0.remote_hosts[0]
2635 server2 = self.pg0.remote_hosts[1]
2636 server3 = self.pg0.remote_hosts[2]
2638 locals = [{'addr': server1.ip4,
2642 {'addr': server2.ip4,
2647 flags = self.config_flags.NAT_IS_INSIDE
2648 self.vapi.nat44_interface_add_del_feature(
2649 sw_if_index=self.pg0.sw_if_index,
2650 flags=flags, is_add=1)
2651 self.vapi.nat44_interface_add_del_feature(
2652 sw_if_index=self.pg1.sw_if_index,
2655 self.nat_add_address(self.nat_addr)
2656 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
2657 external_addr=external_addr,
2658 external_port=external_port,
2659 protocol=IP_PROTOS.tcp,
2660 local_num=len(locals),
2665 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
2667 for client in clients:
2668 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2669 IP(src=client, dst=self.nat_addr) /
2670 TCP(sport=12345, dport=external_port))
2672 self.pg1.add_stream(pkts)
2673 self.pg_enable_capture(self.pg_interfaces)
2675 capture = self.pg0.get_capture(len(pkts))
2677 if p[IP].dst == server1.ip4:
2681 self.assertGreater(server1_n, server2_n)
2684 'addr': server3.ip4,
2691 self.vapi.nat44_lb_static_mapping_add_del_local(
2693 external_addr=external_addr,
2694 external_port=external_port,
2696 protocol=IP_PROTOS.tcp)
2700 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
2702 for client in clients:
2703 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2704 IP(src=client, dst=self.nat_addr) /
2705 TCP(sport=12346, dport=external_port))
2707 self.assertGreater(len(pkts), 0)
2708 self.pg1.add_stream(pkts)
2709 self.pg_enable_capture(self.pg_interfaces)
2711 capture = self.pg0.get_capture(len(pkts))
2713 if p[IP].dst == server1.ip4:
2715 elif p[IP].dst == server2.ip4:
2719 self.assertGreater(server1_n, 0)
2720 self.assertGreater(server2_n, 0)
2721 self.assertGreater(server3_n, 0)
2724 'addr': server2.ip4,
2730 # remove one back-end
2731 self.vapi.nat44_lb_static_mapping_add_del_local(
2733 external_addr=external_addr,
2734 external_port=external_port,
2736 protocol=IP_PROTOS.tcp)
2740 self.pg1.add_stream(pkts)
2741 self.pg_enable_capture(self.pg_interfaces)
2743 capture = self.pg0.get_capture(len(pkts))
2745 if p[IP].dst == server1.ip4:
2747 elif p[IP].dst == server2.ip4:
2751 self.assertGreater(server1_n, 0)
2752 self.assertEqual(server2_n, 0)
2753 self.assertGreater(server3_n, 0)
2755 def test_syslog_sess(self):
2756 """ NAT44ED Test syslog session creation and deletion """
2757 self.vapi.syslog_set_filter(
2758 self.syslog_severity.SYSLOG_API_SEVERITY_INFO)
2759 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2761 self.nat_add_address(self.nat_addr)
2762 self.nat_add_inside_interface(self.pg0)
2763 self.nat_add_outside_interface(self.pg1)
2765 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2766 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2767 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
2768 self.pg0.add_stream(p)
2769 self.pg_enable_capture(self.pg_interfaces)
2771 capture = self.pg1.get_capture(1)
2772 self.tcp_port_out = capture[0][TCP].sport
2773 capture = self.pg3.get_capture(1)
2774 self.verify_syslog_sess(capture[0][Raw].load)
2776 self.pg_enable_capture(self.pg_interfaces)
2778 self.nat_add_address(self.nat_addr, is_add=0)
2779 capture = self.pg3.get_capture(1)
2780 self.verify_syslog_sess(capture[0][Raw].load, False)
2782 def test_twice_nat_interface_addr(self):
2783 """ NAT44ED Acquire twice NAT addresses from interface """
2784 flags = self.config_flags.NAT_IS_TWICE_NAT
2785 self.vapi.nat44_add_del_interface_addr(
2786 sw_if_index=self.pg11.sw_if_index,
2787 flags=flags, is_add=1)
2789 # no address in NAT pool
2790 adresses = self.vapi.nat44_address_dump()
2791 self.assertEqual(0, len(adresses))
2793 # configure interface address and check NAT address pool
2794 self.pg11.config_ip4()
2795 adresses = self.vapi.nat44_address_dump()
2796 self.assertEqual(1, len(adresses))
2797 self.assertEqual(str(adresses[0].ip_address),
2798 self.pg11.local_ip4)
2799 self.assertEqual(adresses[0].flags, flags)
2801 # remove interface address and check NAT address pool
2802 self.pg11.unconfig_ip4()
2803 adresses = self.vapi.nat44_address_dump()
2804 self.assertEqual(0, len(adresses))
2806 def test_output_feature_stateful_acl(self):
2807 """ NAT44ED output feature works with stateful ACL """
2809 self.nat_add_address(self.nat_addr)
2810 self.vapi.nat44_interface_add_del_output_feature(
2811 sw_if_index=self.pg0.sw_if_index,
2812 flags=self.config_flags.NAT_IS_INSIDE, is_add=1)
2813 self.vapi.nat44_interface_add_del_output_feature(
2814 sw_if_index=self.pg1.sw_if_index,
2815 flags=self.config_flags.NAT_IS_OUTSIDE, is_add=1)
2817 # First ensure that the NAT is working sans ACL
2819 # send packets out2in, no sessions yet so packets should drop
2820 pkts_out2in = self.create_stream_out(self.pg1)
2821 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
2823 # send packets into inside intf, ensure received via outside intf
2824 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
2825 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
2827 self.verify_capture_out(capture, ignore_port=True)
2829 # send out2in again, with sessions created it should work now
2830 pkts_out2in = self.create_stream_out(self.pg1)
2831 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
2833 self.verify_capture_in(capture, self.pg0)
2835 # Create an ACL blocking everything
2836 out2in_deny_rule = AclRule(is_permit=0)
2837 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
2838 out2in_acl.add_vpp_config()
2840 # create an ACL to permit/reflect everything
2841 in2out_reflect_rule = AclRule(is_permit=2)
2842 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
2843 in2out_acl.add_vpp_config()
2845 # apply as input acl on interface and confirm it blocks everything
2846 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
2847 n_input=1, acls=[out2in_acl])
2848 acl_if.add_vpp_config()
2849 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
2852 acl_if.acls = [out2in_acl, in2out_acl]
2853 acl_if.add_vpp_config()
2854 # send in2out to generate ACL state (NAT state was created earlier)
2855 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
2857 self.verify_capture_out(capture, ignore_port=True)
2859 # send out2in again. ACL state exists so it should work now.
2860 # TCP packets with the syn flag set also need the ack flag
2861 for p in pkts_out2in:
2862 if p.haslayer(TCP) and p[TCP].flags & 0x02:
2863 p[TCP].flags |= 0x10
2864 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
2866 self.verify_capture_in(capture, self.pg0)
2867 self.logger.info(self.vapi.cli("show trace"))
2869 def test_tcp_close(self):
2870 """ NAT44ED Close TCP session from inside network - output feature """
2871 old_timeouts = self.vapi.nat_get_timeouts()
2873 self.vapi.nat_set_timeouts(
2874 udp=old_timeouts.udp,
2875 tcp_established=old_timeouts.tcp_established,
2876 icmp=old_timeouts.icmp,
2877 tcp_transitory=new_transitory)
2879 self.vapi.nat44_forwarding_enable_disable(enable=1)
2880 self.nat_add_address(self.pg1.local_ip4)
2881 twice_nat_addr = '10.0.1.3'
2882 service_ip = '192.168.16.150'
2883 self.nat_add_address(twice_nat_addr, twice_nat=1)
2885 flags = self.config_flags.NAT_IS_INSIDE
2886 self.vapi.nat44_interface_add_del_feature(
2887 sw_if_index=self.pg0.sw_if_index,
2889 self.vapi.nat44_interface_add_del_feature(
2890 sw_if_index=self.pg0.sw_if_index,
2891 flags=flags, is_add=1)
2892 self.vapi.nat44_interface_add_del_output_feature(
2894 sw_if_index=self.pg1.sw_if_index)
2896 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
2897 self.config_flags.NAT_IS_TWICE_NAT)
2898 self.nat_add_static_mapping(self.pg0.remote_ip4,
2900 proto=IP_PROTOS.tcp,
2902 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2903 start_sessnum = len(sessions)
2905 # SYN packet out->in
2906 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2907 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2908 TCP(sport=33898, dport=80, flags="S"))
2909 self.pg1.add_stream(p)
2910 self.pg_enable_capture(self.pg_interfaces)
2912 capture = self.pg0.get_capture(1)
2914 tcp_port = p[TCP].sport
2916 # SYN + ACK packet in->out
2917 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2918 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
2919 TCP(sport=80, dport=tcp_port, flags="SA"))
2920 self.pg0.add_stream(p)
2921 self.pg_enable_capture(self.pg_interfaces)
2923 self.pg1.get_capture(1)
2925 # ACK packet out->in
2926 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2927 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2928 TCP(sport=33898, dport=80, flags="A"))
2929 self.pg1.add_stream(p)
2930 self.pg_enable_capture(self.pg_interfaces)
2932 self.pg0.get_capture(1)
2934 # FIN packet in -> out
2935 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2936 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
2937 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
2938 self.pg0.add_stream(p)
2939 self.pg_enable_capture(self.pg_interfaces)
2941 self.pg1.get_capture(1)
2943 # FIN+ACK packet out -> in
2944 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2945 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2946 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
2947 self.pg1.add_stream(p)
2948 self.pg_enable_capture(self.pg_interfaces)
2950 self.pg0.get_capture(1)
2952 # ACK packet in -> out
2953 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2954 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
2955 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
2956 self.pg0.add_stream(p)
2957 self.pg_enable_capture(self.pg_interfaces)
2959 self.pg1.get_capture(1)
2961 # session now in transitory timeout
2962 # try SYN packet out->in - should be dropped
2963 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2964 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2965 TCP(sport=33898, dport=80, flags="S"))
2966 self.pg1.add_stream(p)
2967 self.pg_enable_capture(self.pg_interfaces)
2970 self.sleep(new_transitory, "wait for transitory timeout")
2971 self.pg0.assert_nothing_captured(0)
2973 # session should still exist
2974 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2975 self.assertEqual(len(sessions) - start_sessnum, 1)
2977 # send FIN+ACK packet out -> in - will cause session to be wiped
2978 # but won't create a new session
2979 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2980 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2981 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
2982 self.pg1.add_stream(p)
2983 self.pg_enable_capture(self.pg_interfaces)
2986 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2987 self.assertEqual(len(sessions) - start_sessnum, 0)
2988 self.pg0.assert_nothing_captured(0)
2990 def test_tcp_session_close_in(self):
2991 """ NAT44ED Close TCP session from inside network """
2993 in_port = self.tcp_port_in
2995 ext_port = self.tcp_external_port
2997 self.nat_add_address(self.nat_addr)
2998 self.nat_add_inside_interface(self.pg0)
2999 self.nat_add_outside_interface(self.pg1)
3000 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
3001 in_port, out_port, proto=IP_PROTOS.tcp,
3002 flags=self.config_flags.NAT_IS_TWICE_NAT)
3004 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3005 session_n = len(sessions)
3007 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
3008 tcp_transitory=2, icmp=5)
3010 self.init_tcp_session(self.pg0, self.pg1, in_port, ext_port)
3012 # FIN packet in -> out
3013 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3014 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3015 TCP(sport=in_port, dport=ext_port,
3016 flags="FA", seq=100, ack=300))
3017 self.pg0.add_stream(p)
3018 self.pg_enable_capture(self.pg_interfaces)
3020 self.pg1.get_capture(1)
3024 # ACK packet out -> in
3025 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3026 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3027 TCP(sport=ext_port, dport=out_port,
3028 flags="A", seq=300, ack=101))
3031 # FIN packet out -> in
3032 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3033 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3034 TCP(sport=ext_port, dport=out_port,
3035 flags="FA", seq=300, ack=101))
3038 self.pg1.add_stream(pkts)
3039 self.pg_enable_capture(self.pg_interfaces)
3041 self.pg0.get_capture(2)
3043 # ACK packet in -> out
3044 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3045 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3046 TCP(sport=in_port, dport=ext_port,
3047 flags="A", seq=101, ack=301))
3048 self.pg0.add_stream(p)
3049 self.pg_enable_capture(self.pg_interfaces)
3051 self.pg1.get_capture(1)
3053 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3054 self.assertEqual(len(sessions) - session_n, 1)
3056 out2in_drops = self.get_err_counter(
3057 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3058 in2out_drops = self.get_err_counter(
3059 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3061 # extra FIN packet out -> in - this should be dropped
3062 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3063 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3064 TCP(sport=ext_port, dport=out_port,
3065 flags="FA", seq=300, ack=101))
3067 self.pg1.add_stream(p)
3068 self.pg_enable_capture(self.pg_interfaces)
3070 self.pg0.assert_nothing_captured()
3072 # extra ACK packet in -> out - this should be dropped
3073 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3074 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3075 TCP(sport=in_port, dport=ext_port,
3076 flags="A", seq=101, ack=301))
3077 self.pg0.add_stream(p)
3078 self.pg_enable_capture(self.pg_interfaces)
3080 self.pg1.assert_nothing_captured()
3082 stats = self.get_err_counter(
3083 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3084 self.assertEqual(stats - out2in_drops, 1)
3085 stats = self.get_err_counter(
3086 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3087 self.assertEqual(stats - in2out_drops, 1)
3090 # extra ACK packet in -> out - this will cause session to be wiped
3091 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3092 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3093 TCP(sport=in_port, dport=ext_port,
3094 flags="A", seq=101, ack=301))
3095 self.pg0.add_stream(p)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 self.pg1.assert_nothing_captured()
3099 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3100 self.assertEqual(len(sessions) - session_n, 0)
3102 def test_tcp_session_close_out(self):
3103 """ NAT44ED Close TCP session from outside network """
3105 in_port = self.tcp_port_in
3107 ext_port = self.tcp_external_port
3109 self.nat_add_address(self.nat_addr)
3110 self.nat_add_inside_interface(self.pg0)
3111 self.nat_add_outside_interface(self.pg1)
3112 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
3113 in_port, out_port, proto=IP_PROTOS.tcp,
3114 flags=self.config_flags.NAT_IS_TWICE_NAT)
3116 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3117 session_n = len(sessions)
3119 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
3120 tcp_transitory=2, icmp=5)
3122 _ = self.init_tcp_session(self.pg0, self.pg1, in_port, ext_port)
3124 # FIN packet out -> in
3125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3126 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3127 TCP(sport=ext_port, dport=out_port,
3128 flags="FA", seq=100, ack=300))
3129 self.pg1.add_stream(p)
3130 self.pg_enable_capture(self.pg_interfaces)
3132 self.pg0.get_capture(1)
3134 # FIN+ACK packet in -> out
3135 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3136 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3137 TCP(sport=in_port, dport=ext_port,
3138 flags="FA", seq=300, ack=101))
3140 self.pg0.add_stream(p)
3141 self.pg_enable_capture(self.pg_interfaces)
3143 self.pg1.get_capture(1)
3145 # ACK packet out -> in
3146 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3147 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3148 TCP(sport=ext_port, dport=out_port,
3149 flags="A", seq=101, ack=301))
3150 self.pg1.add_stream(p)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 self.pg0.get_capture(1)
3155 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3156 self.assertEqual(len(sessions) - session_n, 1)
3158 out2in_drops = self.get_err_counter(
3159 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3160 in2out_drops = self.get_err_counter(
3161 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3163 # extra FIN packet out -> in - this should be dropped
3164 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3165 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3166 TCP(sport=ext_port, dport=out_port,
3167 flags="FA", seq=300, ack=101))
3169 self.pg1.add_stream(p)
3170 self.pg_enable_capture(self.pg_interfaces)
3172 self.pg0.assert_nothing_captured()
3174 # extra ACK packet in -> out - this should be dropped
3175 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3176 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3177 TCP(sport=in_port, dport=ext_port,
3178 flags="A", seq=101, ack=301))
3179 self.pg0.add_stream(p)
3180 self.pg_enable_capture(self.pg_interfaces)
3182 self.pg1.assert_nothing_captured()
3184 stats = self.get_err_counter(
3185 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3186 self.assertEqual(stats - out2in_drops, 1)
3187 stats = self.get_err_counter(
3188 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3189 self.assertEqual(stats - in2out_drops, 1)
3192 # extra ACK packet in -> out - this will cause session to be wiped
3193 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3194 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3195 TCP(sport=in_port, dport=ext_port,
3196 flags="A", seq=101, ack=301))
3197 self.pg0.add_stream(p)
3198 self.pg_enable_capture(self.pg_interfaces)
3200 self.pg1.assert_nothing_captured()
3201 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3202 self.assertEqual(len(sessions) - session_n, 0)
3204 def test_tcp_session_close_simultaneous(self):
3205 """ NAT44ED Close TCP session from inside network """
3207 in_port = self.tcp_port_in
3210 self.nat_add_address(self.nat_addr)
3211 self.nat_add_inside_interface(self.pg0)
3212 self.nat_add_outside_interface(self.pg1)
3213 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
3214 in_port, ext_port, proto=IP_PROTOS.tcp,
3215 flags=self.config_flags.NAT_IS_TWICE_NAT)
3217 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3218 session_n = len(sessions)
3220 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
3221 tcp_transitory=2, icmp=5)
3223 out_port = self.init_tcp_session(self.pg0, self.pg1, in_port, ext_port)
3225 # FIN packet in -> out
3226 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3227 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3228 TCP(sport=in_port, dport=ext_port,
3229 flags="FA", seq=100, ack=300))
3230 self.pg0.add_stream(p)
3231 self.pg_enable_capture(self.pg_interfaces)
3233 self.pg1.get_capture(1)
3235 # FIN packet out -> in
3236 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3237 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3238 TCP(sport=ext_port, dport=out_port,
3239 flags="FA", seq=300, ack=100))
3240 self.pg1.add_stream(p)
3241 self.pg_enable_capture(self.pg_interfaces)
3243 self.pg0.get_capture(1)
3245 # ACK packet in -> out
3246 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3247 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3248 TCP(sport=in_port, dport=ext_port,
3249 flags="A", seq=101, ack=301))
3250 self.pg0.add_stream(p)
3251 self.pg_enable_capture(self.pg_interfaces)
3253 self.pg1.get_capture(1)
3255 # ACK packet out -> in
3256 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3257 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3258 TCP(sport=ext_port, dport=out_port,
3259 flags="A", seq=301, ack=101))
3260 self.pg1.add_stream(p)
3261 self.pg_enable_capture(self.pg_interfaces)
3263 self.pg0.get_capture(1)
3265 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3266 self.assertEqual(len(sessions) - session_n, 1)
3268 out2in_drops = self.get_err_counter(
3269 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3270 in2out_drops = self.get_err_counter(
3271 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3273 # extra FIN packet out -> in - this should be dropped
3274 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3275 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3276 TCP(sport=ext_port, dport=out_port,
3277 flags="FA", seq=300, ack=101))
3279 self.pg1.add_stream(p)
3280 self.pg_enable_capture(self.pg_interfaces)
3282 self.pg0.assert_nothing_captured()
3284 # extra ACK packet in -> out - this should be dropped
3285 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3286 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3287 TCP(sport=in_port, dport=ext_port,
3288 flags="A", seq=101, ack=301))
3289 self.pg0.add_stream(p)
3290 self.pg_enable_capture(self.pg_interfaces)
3292 self.pg1.assert_nothing_captured()
3294 stats = self.get_err_counter(
3295 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3296 self.assertEqual(stats - out2in_drops, 1)
3297 stats = self.get_err_counter(
3298 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3299 self.assertEqual(stats - in2out_drops, 1)
3302 # extra ACK packet in -> out - this will cause session to be wiped
3303 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3304 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3305 TCP(sport=in_port, dport=ext_port,
3306 flags="A", seq=101, ack=301))
3307 self.pg0.add_stream(p)
3308 self.pg_enable_capture(self.pg_interfaces)
3310 self.pg1.assert_nothing_captured()
3311 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3312 self.assertEqual(len(sessions) - session_n, 0)
3314 def test_dynamic_output_feature_vrf(self):
3315 """ NAT44ED dynamic translation test: output-feature, VRF"""
3317 # other then default (0)
3320 self.nat_add_address(self.nat_addr)
3321 flags = self.config_flags.NAT_IS_INSIDE
3322 self.vapi.nat44_interface_add_del_output_feature(
3323 sw_if_index=self.pg7.sw_if_index,
3324 flags=flags, is_add=1)
3325 self.vapi.nat44_interface_add_del_output_feature(
3326 sw_if_index=self.pg8.sw_if_index,
3330 self.configure_ip4_interface(self.pg7, table_id=new_vrf_id)
3331 self.configure_ip4_interface(self.pg8, table_id=new_vrf_id)
3334 tcpn = self.get_stats_counter(
3335 '/nat44/ed/in2out/slowpath/tcp')
3336 udpn = self.get_stats_counter(
3337 '/nat44/ed/in2out/slowpath/udp')
3338 icmpn = self.get_stats_counter(
3339 '/nat44/ed/in2out/slowpath/icmp')
3340 drops = self.get_stats_counter(
3341 '/nat44/ed/in2out/slowpath/drops')
3343 pkts = self.create_stream_in(self.pg7, self.pg8)
3344 self.pg7.add_stream(pkts)
3345 self.pg_enable_capture(self.pg_interfaces)
3347 capture = self.pg8.get_capture(len(pkts))
3348 self.verify_capture_out(capture, ignore_port=True)
3350 if_idx = self.pg7.sw_if_index
3351 cnt = self.get_stats_counter(
3352 '/nat44/ed/in2out/slowpath/tcp')
3353 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
3354 cnt = self.get_stats_counter(
3355 '/nat44/ed/in2out/slowpath/udp')
3356 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
3357 cnt = self.get_stats_counter(
3358 '/nat44/ed/in2out/slowpath/icmp')
3359 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
3360 cnt = self.get_stats_counter(
3361 '/nat44/ed/in2out/slowpath/drops')
3362 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
3365 tcpn = self.get_stats_counter(
3366 '/nat44/ed/out2in/fastpath/tcp')
3367 udpn = self.get_stats_counter(
3368 '/nat44/ed/out2in/fastpath/udp')
3369 icmpn = self.get_stats_counter(
3370 '/nat44/ed/out2in/fastpath/icmp')
3371 drops = self.get_stats_counter(
3372 '/nat44/ed/out2in/fastpath/drops')
3374 pkts = self.create_stream_out(self.pg8)
3375 self.pg8.add_stream(pkts)
3376 self.pg_enable_capture(self.pg_interfaces)
3378 capture = self.pg7.get_capture(len(pkts))
3379 self.verify_capture_in(capture, self.pg7)
3381 if_idx = self.pg8.sw_if_index
3382 cnt = self.get_stats_counter(
3383 '/nat44/ed/out2in/fastpath/tcp')
3384 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
3385 cnt = self.get_stats_counter(
3386 '/nat44/ed/out2in/fastpath/udp')
3387 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
3388 cnt = self.get_stats_counter(
3389 '/nat44/ed/out2in/fastpath/icmp')
3390 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
3391 cnt = self.get_stats_counter(
3392 '/nat44/ed/out2in/fastpath/drops')
3393 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
3395 sessions = self.get_stats_counter('/nat44/total-sessions')
3396 self.assertEqual(sessions[0], 3)
3399 self.configure_ip4_interface(self.pg7, table_id=0)
3400 self.configure_ip4_interface(self.pg8, table_id=0)
3402 self.vapi.ip_table_add_del(is_add=0,
3403 table={'table_id': new_vrf_id})
3405 def test_next_src_nat(self):
3406 """ NAT44ED On way back forward packet to nat44-in2out node. """
3408 twice_nat_addr = '10.0.1.3'
3411 post_twice_nat_port = 0
3413 self.vapi.nat44_forwarding_enable_disable(enable=1)
3414 self.nat_add_address(twice_nat_addr, twice_nat=1)
3415 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
3416 self.config_flags.NAT_IS_SELF_TWICE_NAT)
3417 self.nat_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
3418 local_port, external_port,
3419 proto=IP_PROTOS.tcp, vrf_id=1,
3421 self.vapi.nat44_interface_add_del_feature(
3422 sw_if_index=self.pg6.sw_if_index,
3425 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
3426 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
3427 TCP(sport=12345, dport=external_port))
3428 self.pg6.add_stream(p)
3429 self.pg_enable_capture(self.pg_interfaces)
3431 capture = self.pg6.get_capture(1)
3436 self.assertEqual(ip.src, twice_nat_addr)
3437 self.assertNotEqual(tcp.sport, 12345)
3438 post_twice_nat_port = tcp.sport
3439 self.assertEqual(ip.dst, self.pg6.remote_ip4)
3440 self.assertEqual(tcp.dport, local_port)
3441 self.assert_packet_checksums_valid(p)
3443 self.logger.error(ppp("Unexpected or invalid packet:", p))
3446 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
3447 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
3448 TCP(sport=local_port, dport=post_twice_nat_port))
3449 self.pg6.add_stream(p)
3450 self.pg_enable_capture(self.pg_interfaces)
3452 capture = self.pg6.get_capture(1)
3457 self.assertEqual(ip.src, self.pg1.remote_ip4)
3458 self.assertEqual(tcp.sport, external_port)
3459 self.assertEqual(ip.dst, self.pg6.remote_ip4)
3460 self.assertEqual(tcp.dport, 12345)
3461 self.assert_packet_checksums_valid(p)
3463 self.logger.error(ppp("Unexpected or invalid packet:", p))
3466 def test_one_armed_nat44_static(self):
3467 """ NAT44ED One armed NAT and 1:1 NAPT asymmetrical rule """
3469 remote_host = self.pg4.remote_hosts[0]
3470 local_host = self.pg4.remote_hosts[1]
3475 self.vapi.nat44_forwarding_enable_disable(enable=1)
3476 self.nat_add_address(self.nat_addr, twice_nat=1)
3477 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
3478 self.config_flags.NAT_IS_TWICE_NAT)
3479 self.nat_add_static_mapping(local_host.ip4, self.nat_addr,
3480 local_port, external_port,
3481 proto=IP_PROTOS.tcp, flags=flags)
3482 flags = self.config_flags.NAT_IS_INSIDE
3483 self.vapi.nat44_interface_add_del_feature(
3484 sw_if_index=self.pg4.sw_if_index,
3486 self.vapi.nat44_interface_add_del_feature(
3487 sw_if_index=self.pg4.sw_if_index,
3488 flags=flags, is_add=1)
3490 # from client to service
3491 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
3492 IP(src=remote_host.ip4, dst=self.nat_addr) /
3493 TCP(sport=12345, dport=external_port))
3494 self.pg4.add_stream(p)
3495 self.pg_enable_capture(self.pg_interfaces)
3497 capture = self.pg4.get_capture(1)
3502 self.assertEqual(ip.dst, local_host.ip4)
3503 self.assertEqual(ip.src, self.nat_addr)
3504 self.assertEqual(tcp.dport, local_port)
3505 self.assertNotEqual(tcp.sport, 12345)
3506 eh_port_in = tcp.sport
3507 self.assert_packet_checksums_valid(p)
3509 self.logger.error(ppp("Unexpected or invalid packet:", p))
3512 # from service back to client
3513 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
3514 IP(src=local_host.ip4, dst=self.nat_addr) /
3515 TCP(sport=local_port, dport=eh_port_in))
3516 self.pg4.add_stream(p)
3517 self.pg_enable_capture(self.pg_interfaces)
3519 capture = self.pg4.get_capture(1)
3524 self.assertEqual(ip.src, self.nat_addr)
3525 self.assertEqual(ip.dst, remote_host.ip4)
3526 self.assertEqual(tcp.sport, external_port)
3527 self.assertEqual(tcp.dport, 12345)
3528 self.assert_packet_checksums_valid(p)
3530 self.logger.error(ppp("Unexpected or invalid packet:", p))
3534 if __name__ == '__main__':
3535 unittest.main(testRunner=VppTestRunner)