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 class TestNAT44EDMW(TestNAT44ED):
1910 """ NAT44ED MW Test Case """
1911 worker_config = "workers 1"
1913 def get_stats_counter(self, path, worker=1):
1914 return super(TestNAT44EDMW, self).get_stats_counter(path, worker)
1916 @unittest.skip('MW fix required')
1917 def test_users_dump(self):
1918 """ NAT44ED API test - nat44_user_dump """
1920 @unittest.skip('MW fix required')
1921 def test_frag_out_of_order_do_not_translate(self):
1922 """ NAT44ED don't translate fragments arriving out of order """
1924 @unittest.skip('MW fix required')
1925 def test_forwarding(self):
1926 """ NAT44ED forwarding test """
1928 @unittest.skip('MW fix required')
1929 def test_twice_nat(self):
1930 """ NAT44ED Twice NAT """
1932 @unittest.skip('MW fix required')
1933 def test_twice_nat_lb(self):
1934 """ NAT44ED Twice NAT local service load balancing """
1936 @unittest.skip('MW fix required')
1937 def test_output_feature(self):
1938 """ NAT44ED interface output feature (in2out postrouting) """
1940 @unittest.skip('MW fix required')
1941 def test_static_with_port_out2(self):
1942 """ NAT44ED 1:1 NAPT asymmetrical rule """
1944 @unittest.skip('MW fix required')
1945 def test_output_feature_and_service2(self):
1946 """ NAT44ED interface output feature and service host direct access """
1948 @unittest.skip('MW fix required')
1949 def test_static_lb(self):
1950 """ NAT44ED local service load balancing """
1952 @unittest.skip('MW fix required')
1953 def test_static_lb_2(self):
1954 """ NAT44ED local service load balancing (asymmetrical rule) """
1956 @unittest.skip('MW fix required')
1957 def test_lb_affinity(self):
1958 """ NAT44ED local service load balancing affinity """
1960 @unittest.skip('MW fix required')
1961 def test_multiple_vrf(self):
1962 """ NAT44ED Multiple VRF setup """
1964 @unittest.skip('MW fix required')
1965 def test_self_twice_nat_positive(self):
1966 """ NAT44ED Self Twice NAT (positive test) """
1968 @unittest.skip('MW fix required')
1969 def test_self_twice_nat_lb_positive(self):
1970 """ NAT44ED Self Twice NAT local service load balancing (positive test)
1973 def test_dynamic(self):
1974 """ NAT44ED dynamic translation test """
1976 self.nat_add_address(self.nat_addr)
1977 self.nat_add_inside_interface(self.pg0)
1978 self.nat_add_outside_interface(self.pg1)
1981 tc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/tcp')
1982 uc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/udp')
1983 ic1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/icmp')
1984 dc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/drops')
1986 pkts = self.create_stream_in(self.pg0, self.pg1)
1987 # TODO: specify worker=idx, also stats have to
1988 # know from which worker to take capture
1989 self.pg0.add_stream(pkts)
1990 self.pg_enable_capture(self.pg_interfaces)
1992 capture = self.pg1.get_capture(len(pkts))
1993 self.verify_capture_out(capture, ignore_port=True)
1995 if_idx = self.pg0.sw_if_index
1996 tc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/tcp')
1997 uc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/udp')
1998 ic2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/icmp')
1999 dc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/drops')
2001 self.assertEqual(tc2[if_idx] - tc1[if_idx], 2)
2002 self.assertEqual(uc2[if_idx] - uc1[if_idx], 1)
2003 self.assertEqual(ic2[if_idx] - ic1[if_idx], 1)
2004 self.assertEqual(dc2[if_idx] - dc1[if_idx], 0)
2007 tc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/tcp')
2008 uc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/udp')
2009 ic1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/icmp')
2010 dc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/drops')
2012 pkts = self.create_stream_out(self.pg1)
2013 self.pg1.add_stream(pkts)
2014 self.pg_enable_capture(self.pg_interfaces)
2016 capture = self.pg0.get_capture(len(pkts))
2017 self.verify_capture_in(capture, self.pg0)
2019 if_idx = self.pg1.sw_if_index
2020 tc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/tcp')
2021 uc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/udp')
2022 ic2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/icmp')
2023 dc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/drops')
2025 self.assertEqual(tc2[if_idx] - tc1[if_idx], 2)
2026 self.assertEqual(uc2[if_idx] - uc1[if_idx], 1)
2027 self.assertEqual(ic2[if_idx] - ic1[if_idx], 1)
2028 self.assertEqual(dc2[if_idx] - dc1[if_idx], 0)
2030 sc = self.get_stats_counter('/nat44/total-sessions')
2031 self.assertEqual(sc[0], 3)
2033 def test_frag_in_order(self):
2034 """ NAT44ED translate fragments arriving in order """
2036 self.nat_add_address(self.nat_addr)
2037 self.nat_add_inside_interface(self.pg0)
2038 self.nat_add_outside_interface(self.pg1)
2040 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
2041 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
2042 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
2044 def test_frag_in_order_do_not_translate(self):
2045 """ NAT44ED don't translate fragments arriving in order """
2047 self.nat_add_address(self.nat_addr)
2048 self.nat_add_inside_interface(self.pg0)
2049 self.nat_add_outside_interface(self.pg1)
2050 self.vapi.nat44_forwarding_enable_disable(enable=True)
2052 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
2054 def test_frag_out_of_order(self):
2055 """ NAT44ED translate fragments arriving out of order """
2057 self.nat_add_address(self.nat_addr)
2058 self.nat_add_inside_interface(self.pg0)
2059 self.nat_add_outside_interface(self.pg1)
2061 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
2062 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
2063 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
2065 def test_frag_in_order_in_plus_out(self):
2066 """ NAT44ED in+out interface fragments in order """
2068 in_port = self.random_port()
2069 out_port = self.random_port()
2071 self.nat_add_address(self.nat_addr)
2072 self.nat_add_inside_interface(self.pg0)
2073 self.nat_add_outside_interface(self.pg0)
2074 self.nat_add_inside_interface(self.pg1)
2075 self.nat_add_outside_interface(self.pg1)
2077 # add static mappings for server
2078 self.nat_add_static_mapping(self.server_addr,
2082 proto=IP_PROTOS.tcp)
2083 self.nat_add_static_mapping(self.server_addr,
2087 proto=IP_PROTOS.udp)
2088 self.nat_add_static_mapping(self.server_addr,
2090 proto=IP_PROTOS.icmp)
2092 # run tests for each protocol
2093 self.frag_in_order_in_plus_out(self.server_addr,
2098 self.frag_in_order_in_plus_out(self.server_addr,
2103 self.frag_in_order_in_plus_out(self.server_addr,
2109 def test_frag_out_of_order_in_plus_out(self):
2110 """ NAT44ED in+out interface fragments out of order """
2112 in_port = self.random_port()
2113 out_port = self.random_port()
2115 self.nat_add_address(self.nat_addr)
2116 self.nat_add_inside_interface(self.pg0)
2117 self.nat_add_outside_interface(self.pg0)
2118 self.nat_add_inside_interface(self.pg1)
2119 self.nat_add_outside_interface(self.pg1)
2121 # add static mappings for server
2122 self.nat_add_static_mapping(self.server_addr,
2126 proto=IP_PROTOS.tcp)
2127 self.nat_add_static_mapping(self.server_addr,
2131 proto=IP_PROTOS.udp)
2132 self.nat_add_static_mapping(self.server_addr,
2134 proto=IP_PROTOS.icmp)
2136 # run tests for each protocol
2137 self.frag_out_of_order_in_plus_out(self.server_addr,
2142 self.frag_out_of_order_in_plus_out(self.server_addr,
2147 self.frag_out_of_order_in_plus_out(self.server_addr,
2153 def test_reass_hairpinning(self):
2154 """ NAT44ED fragments hairpinning """
2156 server_addr = self.pg0.remote_hosts[1].ip4
2158 host_in_port = self.random_port()
2159 server_in_port = self.random_port()
2160 server_out_port = self.random_port()
2162 self.nat_add_address(self.nat_addr)
2163 self.nat_add_inside_interface(self.pg0)
2164 self.nat_add_outside_interface(self.pg1)
2166 # add static mapping for server
2167 self.nat_add_static_mapping(server_addr, self.nat_addr,
2168 server_in_port, server_out_port,
2169 proto=IP_PROTOS.tcp)
2170 self.nat_add_static_mapping(server_addr, self.nat_addr,
2171 server_in_port, server_out_port,
2172 proto=IP_PROTOS.udp)
2173 self.nat_add_static_mapping(server_addr, self.nat_addr)
2175 self.reass_hairpinning(server_addr, server_in_port, server_out_port,
2176 host_in_port, proto=IP_PROTOS.tcp,
2178 self.reass_hairpinning(server_addr, server_in_port, server_out_port,
2179 host_in_port, proto=IP_PROTOS.udp,
2181 self.reass_hairpinning(server_addr, server_in_port, server_out_port,
2182 host_in_port, proto=IP_PROTOS.icmp,
2185 def test_session_limit_per_vrf(self):
2186 """ NAT44ED per vrf session limit """
2189 inside_vrf10 = self.pg2
2194 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
2195 # non existing vrf_id makes process core dump
2196 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
2198 self.nat_add_inside_interface(inside)
2199 self.nat_add_inside_interface(inside_vrf10)
2200 self.nat_add_outside_interface(outside)
2203 self.nat_add_interface_address(outside)
2205 # BUG: causing core dump - when bad vrf_id is specified
2206 # self.nat_add_address(outside.local_ip4, vrf_id=20)
2208 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
2209 inside_vrf10.add_stream(stream)
2211 self.pg_enable_capture(self.pg_interfaces)
2214 capture = outside.get_capture(limit)
2216 stream = self.create_tcp_stream(inside, outside, limit * 2)
2217 inside.add_stream(stream)
2219 self.pg_enable_capture(self.pg_interfaces)
2222 capture = outside.get_capture(len(stream))
2224 def test_clear_sessions(self):
2225 """ NAT44ED session clearing test """
2227 self.nat_add_address(self.nat_addr)
2228 self.nat_add_inside_interface(self.pg0)
2229 self.nat_add_outside_interface(self.pg1)
2231 pkts = self.create_stream_in(self.pg0, self.pg1)
2232 self.pg0.add_stream(pkts)
2233 self.pg_enable_capture(self.pg_interfaces)
2235 capture = self.pg1.get_capture(len(pkts))
2236 self.verify_capture_out(capture, ignore_port=True)
2238 sessions = self.get_stats_counter('/nat44/total-sessions')
2239 self.assertTrue(sessions[0] > 0)
2241 self.vapi.cli("clear nat44 sessions")
2243 sessions = self.get_stats_counter('/nat44/total-sessions')
2244 self.assertEqual(sessions[0], 0)
2246 def test_show_max_translations(self):
2247 """ NAT44ED API test - max translations per thread """
2248 nat_config = self.vapi.nat_show_config_2()
2249 self.assertEqual(self.max_sessions,
2250 nat_config.max_translations_per_thread)
2252 def test_lru_cleanup(self):
2253 """ NAT44ED LRU cleanup algorithm """
2255 self.nat_add_address(self.nat_addr)
2256 self.nat_add_inside_interface(self.pg0)
2257 self.nat_add_outside_interface(self.pg1)
2259 self.vapi.nat_set_timeouts(
2260 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
2262 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
2264 for i in range(0, self.max_sessions - 1):
2265 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2266 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
2267 UDP(sport=7000+i, dport=80))
2270 self.pg0.add_stream(pkts)
2271 self.pg_enable_capture(self.pg_interfaces)
2273 self.pg1.get_capture(len(pkts))
2274 self.sleep(1.5, "wait for timeouts")
2277 for i in range(0, self.max_sessions - 1):
2278 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2279 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
2280 ICMP(id=8000+i, type='echo-request'))
2283 self.pg0.add_stream(pkts)
2284 self.pg_enable_capture(self.pg_interfaces)
2286 self.pg1.get_capture(len(pkts))
2288 def test_session_rst_timeout(self):
2289 """ NAT44ED session RST timeouts """
2291 self.nat_add_address(self.nat_addr)
2292 self.nat_add_inside_interface(self.pg0)
2293 self.nat_add_outside_interface(self.pg1)
2295 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
2296 tcp_transitory=5, icmp=60)
2298 self.init_tcp_session(self.pg0, self.pg1, self.tcp_port_in,
2299 self.tcp_external_port)
2300 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2301 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2302 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
2304 self.pg0.add_stream(p)
2305 self.pg_enable_capture(self.pg_interfaces)
2307 self.pg1.get_capture(1)
2311 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2312 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2313 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
2315 self.pg0.add_stream(p)
2316 self.pg_enable_capture(self.pg_interfaces)
2318 self.pg1.get_capture(1)
2320 def test_dynamic_out_of_ports(self):
2321 """ NAT44ED dynamic translation test: out of ports """
2323 self.nat_add_inside_interface(self.pg0)
2324 self.nat_add_outside_interface(self.pg1)
2326 # in2out and no NAT addresses added
2327 err_old = self.statistics.get_err_counter(
2328 '/err/nat44-ed-in2out-slowpath/out of ports')
2330 pkts = self.create_stream_in(self.pg0, self.pg1)
2331 self.pg0.add_stream(pkts)
2332 self.pg_enable_capture(self.pg_interfaces)
2334 self.pg1.get_capture(0, timeout=1)
2336 err_new = self.statistics.get_err_counter(
2337 '/err/nat44-ed-in2out-slowpath/out of ports')
2339 self.assertEqual(err_new - err_old, len(pkts))
2341 # in2out after NAT addresses added
2342 self.nat_add_address(self.nat_addr)
2344 err_old = self.statistics.get_err_counter(
2345 '/err/nat44-ed-in2out-slowpath/out of ports')
2347 pkts = self.create_stream_in(self.pg0, self.pg1)
2348 self.pg0.add_stream(pkts)
2349 self.pg_enable_capture(self.pg_interfaces)
2351 capture = self.pg1.get_capture(len(pkts))
2352 self.verify_capture_out(capture, ignore_port=True)
2354 err_new = self.statistics.get_err_counter(
2355 '/err/nat44-ed-in2out-slowpath/out of ports')
2357 self.assertEqual(err_new, err_old)
2359 def test_unknown_proto(self):
2360 """ NAT44ED translate packet with unknown protocol """
2362 self.nat_add_address(self.nat_addr)
2363 self.nat_add_inside_interface(self.pg0)
2364 self.nat_add_outside_interface(self.pg1)
2367 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2368 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2369 TCP(sport=self.tcp_port_in, dport=20))
2370 self.pg0.add_stream(p)
2371 self.pg_enable_capture(self.pg_interfaces)
2373 p = self.pg1.get_capture(1)
2375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2376 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2378 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2379 TCP(sport=1234, dport=1234))
2380 self.pg0.add_stream(p)
2381 self.pg_enable_capture(self.pg_interfaces)
2383 p = self.pg1.get_capture(1)
2386 self.assertEqual(packet[IP].src, self.nat_addr)
2387 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2388 self.assertEqual(packet.haslayer(GRE), 1)
2389 self.assert_packet_checksums_valid(packet)
2391 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2395 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
2396 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
2398 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2399 TCP(sport=1234, dport=1234))
2400 self.pg1.add_stream(p)
2401 self.pg_enable_capture(self.pg_interfaces)
2403 p = self.pg0.get_capture(1)
2406 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
2407 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
2408 self.assertEqual(packet.haslayer(GRE), 1)
2409 self.assert_packet_checksums_valid(packet)
2411 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2414 def test_hairpinning_unknown_proto(self):
2415 """ NAT44ED translate packet with unknown protocol - hairpinning """
2416 host = self.pg0.remote_hosts[0]
2417 server = self.pg0.remote_hosts[1]
2419 server_out_port = 8765
2420 server_nat_ip = "10.0.0.11"
2422 self.nat_add_address(self.nat_addr)
2423 self.nat_add_inside_interface(self.pg0)
2424 self.nat_add_outside_interface(self.pg1)
2426 # add static mapping for server
2427 self.nat_add_static_mapping(server.ip4, server_nat_ip)
2430 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2431 IP(src=host.ip4, dst=server_nat_ip) /
2432 TCP(sport=host_in_port, dport=server_out_port))
2433 self.pg0.add_stream(p)
2434 self.pg_enable_capture(self.pg_interfaces)
2436 self.pg0.get_capture(1)
2438 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
2439 IP(src=host.ip4, dst=server_nat_ip) /
2441 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2442 TCP(sport=1234, dport=1234))
2443 self.pg0.add_stream(p)
2444 self.pg_enable_capture(self.pg_interfaces)
2446 p = self.pg0.get_capture(1)
2449 self.assertEqual(packet[IP].src, self.nat_addr)
2450 self.assertEqual(packet[IP].dst, server.ip4)
2451 self.assertEqual(packet.haslayer(GRE), 1)
2452 self.assert_packet_checksums_valid(packet)
2454 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2458 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
2459 IP(src=server.ip4, dst=self.nat_addr) /
2461 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
2462 TCP(sport=1234, dport=1234))
2463 self.pg0.add_stream(p)
2464 self.pg_enable_capture(self.pg_interfaces)
2466 p = self.pg0.get_capture(1)
2469 self.assertEqual(packet[IP].src, server_nat_ip)
2470 self.assertEqual(packet[IP].dst, host.ip4)
2471 self.assertEqual(packet.haslayer(GRE), 1)
2472 self.assert_packet_checksums_valid(packet)
2474 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2477 def test_output_feature_and_service(self):
2478 """ NAT44ED interface output feature and services """
2479 external_addr = '1.2.3.4'
2483 self.vapi.nat44_forwarding_enable_disable(enable=1)
2484 self.nat_add_address(self.nat_addr)
2485 flags = self.config_flags.NAT_IS_ADDR_ONLY
2486 self.vapi.nat44_add_del_identity_mapping(
2487 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
2488 flags=flags, is_add=1)
2489 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
2490 self.nat_add_static_mapping(self.pg0.remote_ip4, external_addr,
2491 local_port, external_port,
2492 proto=IP_PROTOS.tcp, flags=flags)
2494 self.nat_add_inside_interface(self.pg0)
2495 self.nat_add_outside_interface(self.pg0)
2496 self.vapi.nat44_interface_add_del_output_feature(
2497 sw_if_index=self.pg1.sw_if_index, is_add=1)
2499 # from client to service
2500 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2501 IP(src=self.pg1.remote_ip4, dst=external_addr) /
2502 TCP(sport=12345, dport=external_port))
2503 self.pg1.add_stream(p)
2504 self.pg_enable_capture(self.pg_interfaces)
2506 capture = self.pg0.get_capture(1)
2511 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2512 self.assertEqual(tcp.dport, local_port)
2513 self.assert_packet_checksums_valid(p)
2515 self.logger.error(ppp("Unexpected or invalid packet:", p))
2518 # from service back to client
2519 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2520 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2521 TCP(sport=local_port, dport=12345))
2522 self.pg0.add_stream(p)
2523 self.pg_enable_capture(self.pg_interfaces)
2525 capture = self.pg1.get_capture(1)
2530 self.assertEqual(ip.src, external_addr)
2531 self.assertEqual(tcp.sport, external_port)
2532 self.assert_packet_checksums_valid(p)
2534 self.logger.error(ppp("Unexpected or invalid packet:", p))
2537 # from local network host to external network
2538 pkts = self.create_stream_in(self.pg0, self.pg1)
2539 self.pg0.add_stream(pkts)
2540 self.pg_enable_capture(self.pg_interfaces)
2542 capture = self.pg1.get_capture(len(pkts))
2543 self.verify_capture_out(capture, ignore_port=True)
2544 pkts = self.create_stream_in(self.pg0, self.pg1)
2545 self.pg0.add_stream(pkts)
2546 self.pg_enable_capture(self.pg_interfaces)
2548 capture = self.pg1.get_capture(len(pkts))
2549 self.verify_capture_out(capture, ignore_port=True)
2551 # from external network back to local network host
2552 pkts = self.create_stream_out(self.pg1)
2553 self.pg1.add_stream(pkts)
2554 self.pg_enable_capture(self.pg_interfaces)
2556 capture = self.pg0.get_capture(len(pkts))
2557 self.verify_capture_in(capture, self.pg0)
2559 def test_output_feature_and_service3(self):
2560 """ NAT44ED interface output feature and DST NAT """
2561 external_addr = '1.2.3.4'
2565 self.vapi.nat44_forwarding_enable_disable(enable=1)
2566 self.nat_add_address(self.nat_addr)
2567 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
2568 self.nat_add_static_mapping(self.pg1.remote_ip4, external_addr,
2569 local_port, external_port,
2570 proto=IP_PROTOS.tcp, flags=flags)
2572 self.nat_add_inside_interface(self.pg0)
2573 self.nat_add_outside_interface(self.pg0)
2574 self.vapi.nat44_interface_add_del_output_feature(
2575 sw_if_index=self.pg1.sw_if_index, is_add=1)
2577 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2578 IP(src=self.pg0.remote_ip4, dst=external_addr) /
2579 TCP(sport=12345, dport=external_port))
2580 self.pg0.add_stream(p)
2581 self.pg_enable_capture(self.pg_interfaces)
2583 capture = self.pg1.get_capture(1)
2588 self.assertEqual(ip.src, self.pg0.remote_ip4)
2589 self.assertEqual(tcp.sport, 12345)
2590 self.assertEqual(ip.dst, self.pg1.remote_ip4)
2591 self.assertEqual(tcp.dport, local_port)
2592 self.assert_packet_checksums_valid(p)
2594 self.logger.error(ppp("Unexpected or invalid packet:", p))
2597 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2598 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2599 TCP(sport=local_port, dport=12345))
2600 self.pg1.add_stream(p)
2601 self.pg_enable_capture(self.pg_interfaces)
2603 capture = self.pg0.get_capture(1)
2608 self.assertEqual(ip.src, external_addr)
2609 self.assertEqual(tcp.sport, external_port)
2610 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2611 self.assertEqual(tcp.dport, 12345)
2612 self.assert_packet_checksums_valid(p)
2614 self.logger.error(ppp("Unexpected or invalid packet:", p))
2617 def test_self_twice_nat_lb_negative(self):
2618 """ NAT44ED Self Twice NAT local service load balancing (negative test)
2620 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
2623 def test_self_twice_nat_negative(self):
2624 """ NAT44ED Self Twice NAT (negative test) """
2625 self.twice_nat_common(self_twice_nat=True)
2627 def test_static_lb_multi_clients(self):
2628 """ NAT44ED local service load balancing - multiple clients"""
2630 external_addr = self.nat_addr
2633 server1 = self.pg0.remote_hosts[0]
2634 server2 = self.pg0.remote_hosts[1]
2635 server3 = self.pg0.remote_hosts[2]
2637 locals = [{'addr': server1.ip4,
2641 {'addr': server2.ip4,
2646 flags = self.config_flags.NAT_IS_INSIDE
2647 self.vapi.nat44_interface_add_del_feature(
2648 sw_if_index=self.pg0.sw_if_index,
2649 flags=flags, is_add=1)
2650 self.vapi.nat44_interface_add_del_feature(
2651 sw_if_index=self.pg1.sw_if_index,
2654 self.nat_add_address(self.nat_addr)
2655 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
2656 external_addr=external_addr,
2657 external_port=external_port,
2658 protocol=IP_PROTOS.tcp,
2659 local_num=len(locals),
2664 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
2666 for client in clients:
2667 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2668 IP(src=client, dst=self.nat_addr) /
2669 TCP(sport=12345, dport=external_port))
2671 self.pg1.add_stream(pkts)
2672 self.pg_enable_capture(self.pg_interfaces)
2674 capture = self.pg0.get_capture(len(pkts))
2676 if p[IP].dst == server1.ip4:
2680 self.assertGreater(server1_n, server2_n)
2683 'addr': server3.ip4,
2690 self.vapi.nat44_lb_static_mapping_add_del_local(
2692 external_addr=external_addr,
2693 external_port=external_port,
2695 protocol=IP_PROTOS.tcp)
2699 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
2701 for client in clients:
2702 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2703 IP(src=client, dst=self.nat_addr) /
2704 TCP(sport=12346, dport=external_port))
2706 self.assertGreater(len(pkts), 0)
2707 self.pg1.add_stream(pkts)
2708 self.pg_enable_capture(self.pg_interfaces)
2710 capture = self.pg0.get_capture(len(pkts))
2712 if p[IP].dst == server1.ip4:
2714 elif p[IP].dst == server2.ip4:
2718 self.assertGreater(server1_n, 0)
2719 self.assertGreater(server2_n, 0)
2720 self.assertGreater(server3_n, 0)
2723 'addr': server2.ip4,
2729 # remove one back-end
2730 self.vapi.nat44_lb_static_mapping_add_del_local(
2732 external_addr=external_addr,
2733 external_port=external_port,
2735 protocol=IP_PROTOS.tcp)
2739 self.pg1.add_stream(pkts)
2740 self.pg_enable_capture(self.pg_interfaces)
2742 capture = self.pg0.get_capture(len(pkts))
2744 if p[IP].dst == server1.ip4:
2746 elif p[IP].dst == server2.ip4:
2750 self.assertGreater(server1_n, 0)
2751 self.assertEqual(server2_n, 0)
2752 self.assertGreater(server3_n, 0)
2754 def test_syslog_sess(self):
2755 """ NAT44ED Test syslog session creation and deletion """
2756 self.vapi.syslog_set_filter(
2757 self.syslog_severity.SYSLOG_API_SEVERITY_INFO)
2758 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2760 self.nat_add_address(self.nat_addr)
2761 self.nat_add_inside_interface(self.pg0)
2762 self.nat_add_outside_interface(self.pg1)
2764 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2765 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2766 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
2767 self.pg0.add_stream(p)
2768 self.pg_enable_capture(self.pg_interfaces)
2770 capture = self.pg1.get_capture(1)
2771 self.tcp_port_out = capture[0][TCP].sport
2772 capture = self.pg3.get_capture(1)
2773 self.verify_syslog_sess(capture[0][Raw].load)
2775 self.pg_enable_capture(self.pg_interfaces)
2777 self.nat_add_address(self.nat_addr, is_add=0)
2778 capture = self.pg3.get_capture(1)
2779 self.verify_syslog_sess(capture[0][Raw].load, False)
2781 def test_twice_nat_interface_addr(self):
2782 """ NAT44ED Acquire twice NAT addresses from interface """
2783 flags = self.config_flags.NAT_IS_TWICE_NAT
2784 self.vapi.nat44_add_del_interface_addr(
2785 sw_if_index=self.pg11.sw_if_index,
2786 flags=flags, is_add=1)
2788 # no address in NAT pool
2789 adresses = self.vapi.nat44_address_dump()
2790 self.assertEqual(0, len(adresses))
2792 # configure interface address and check NAT address pool
2793 self.pg11.config_ip4()
2794 adresses = self.vapi.nat44_address_dump()
2795 self.assertEqual(1, len(adresses))
2796 self.assertEqual(str(adresses[0].ip_address),
2797 self.pg11.local_ip4)
2798 self.assertEqual(adresses[0].flags, flags)
2800 # remove interface address and check NAT address pool
2801 self.pg11.unconfig_ip4()
2802 adresses = self.vapi.nat44_address_dump()
2803 self.assertEqual(0, len(adresses))
2805 def test_output_feature_stateful_acl(self):
2806 """ NAT44ED output feature works with stateful ACL """
2808 self.nat_add_address(self.nat_addr)
2809 self.vapi.nat44_interface_add_del_output_feature(
2810 sw_if_index=self.pg0.sw_if_index,
2811 flags=self.config_flags.NAT_IS_INSIDE, is_add=1)
2812 self.vapi.nat44_interface_add_del_output_feature(
2813 sw_if_index=self.pg1.sw_if_index,
2814 flags=self.config_flags.NAT_IS_OUTSIDE, is_add=1)
2816 # First ensure that the NAT is working sans ACL
2818 # send packets out2in, no sessions yet so packets should drop
2819 pkts_out2in = self.create_stream_out(self.pg1)
2820 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
2822 # send packets into inside intf, ensure received via outside intf
2823 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
2824 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
2826 self.verify_capture_out(capture, ignore_port=True)
2828 # send out2in again, with sessions created it should work now
2829 pkts_out2in = self.create_stream_out(self.pg1)
2830 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
2832 self.verify_capture_in(capture, self.pg0)
2834 # Create an ACL blocking everything
2835 out2in_deny_rule = AclRule(is_permit=0)
2836 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
2837 out2in_acl.add_vpp_config()
2839 # create an ACL to permit/reflect everything
2840 in2out_reflect_rule = AclRule(is_permit=2)
2841 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
2842 in2out_acl.add_vpp_config()
2844 # apply as input acl on interface and confirm it blocks everything
2845 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
2846 n_input=1, acls=[out2in_acl])
2847 acl_if.add_vpp_config()
2848 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
2851 acl_if.acls = [out2in_acl, in2out_acl]
2852 acl_if.add_vpp_config()
2853 # send in2out to generate ACL state (NAT state was created earlier)
2854 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
2856 self.verify_capture_out(capture, ignore_port=True)
2858 # send out2in again. ACL state exists so it should work now.
2859 # TCP packets with the syn flag set also need the ack flag
2860 for p in pkts_out2in:
2861 if p.haslayer(TCP) and p[TCP].flags & 0x02:
2862 p[TCP].flags |= 0x10
2863 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
2865 self.verify_capture_in(capture, self.pg0)
2866 self.logger.info(self.vapi.cli("show trace"))
2868 def test_tcp_close(self):
2869 """ NAT44ED Close TCP session from inside network - output feature """
2870 old_timeouts = self.vapi.nat_get_timeouts()
2872 self.vapi.nat_set_timeouts(
2873 udp=old_timeouts.udp,
2874 tcp_established=old_timeouts.tcp_established,
2875 icmp=old_timeouts.icmp,
2876 tcp_transitory=new_transitory)
2878 self.vapi.nat44_forwarding_enable_disable(enable=1)
2879 self.nat_add_address(self.pg1.local_ip4)
2880 twice_nat_addr = '10.0.1.3'
2881 service_ip = '192.168.16.150'
2882 self.nat_add_address(twice_nat_addr, twice_nat=1)
2884 flags = self.config_flags.NAT_IS_INSIDE
2885 self.vapi.nat44_interface_add_del_feature(
2886 sw_if_index=self.pg0.sw_if_index,
2888 self.vapi.nat44_interface_add_del_feature(
2889 sw_if_index=self.pg0.sw_if_index,
2890 flags=flags, is_add=1)
2891 self.vapi.nat44_interface_add_del_output_feature(
2893 sw_if_index=self.pg1.sw_if_index)
2895 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
2896 self.config_flags.NAT_IS_TWICE_NAT)
2897 self.nat_add_static_mapping(self.pg0.remote_ip4,
2899 proto=IP_PROTOS.tcp,
2901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2902 start_sessnum = len(sessions)
2904 # SYN packet out->in
2905 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2906 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2907 TCP(sport=33898, dport=80, flags="S"))
2908 self.pg1.add_stream(p)
2909 self.pg_enable_capture(self.pg_interfaces)
2911 capture = self.pg0.get_capture(1)
2913 tcp_port = p[TCP].sport
2915 # SYN + ACK packet in->out
2916 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2917 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
2918 TCP(sport=80, dport=tcp_port, flags="SA"))
2919 self.pg0.add_stream(p)
2920 self.pg_enable_capture(self.pg_interfaces)
2922 self.pg1.get_capture(1)
2924 # ACK packet out->in
2925 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2926 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2927 TCP(sport=33898, dport=80, flags="A"))
2928 self.pg1.add_stream(p)
2929 self.pg_enable_capture(self.pg_interfaces)
2931 self.pg0.get_capture(1)
2933 # FIN packet in -> out
2934 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2935 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
2936 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
2937 self.pg0.add_stream(p)
2938 self.pg_enable_capture(self.pg_interfaces)
2940 self.pg1.get_capture(1)
2942 # FIN+ACK packet out -> in
2943 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2944 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2945 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
2946 self.pg1.add_stream(p)
2947 self.pg_enable_capture(self.pg_interfaces)
2949 self.pg0.get_capture(1)
2951 # ACK packet in -> out
2952 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2953 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
2954 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
2955 self.pg0.add_stream(p)
2956 self.pg_enable_capture(self.pg_interfaces)
2958 self.pg1.get_capture(1)
2960 # session now in transitory timeout
2961 # try SYN packet out->in - should be dropped
2962 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2963 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2964 TCP(sport=33898, dport=80, flags="S"))
2965 self.pg1.add_stream(p)
2966 self.pg_enable_capture(self.pg_interfaces)
2969 self.sleep(new_transitory, "wait for transitory timeout")
2970 self.pg0.assert_nothing_captured(0)
2972 # session should still exist
2973 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2974 self.assertEqual(len(sessions) - start_sessnum, 1)
2976 # send FIN+ACK packet out -> in - will cause session to be wiped
2977 # but won't create a new session
2978 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2979 IP(src=self.pg1.remote_ip4, dst=service_ip) /
2980 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
2981 self.pg1.add_stream(p)
2982 self.pg_enable_capture(self.pg_interfaces)
2985 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2986 self.assertEqual(len(sessions) - start_sessnum, 0)
2987 self.pg0.assert_nothing_captured(0)
2989 def test_tcp_session_close_in(self):
2990 """ NAT44ED Close TCP session from inside network """
2992 in_port = self.tcp_port_in
2994 ext_port = self.tcp_external_port
2996 self.nat_add_address(self.nat_addr)
2997 self.nat_add_inside_interface(self.pg0)
2998 self.nat_add_outside_interface(self.pg1)
2999 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
3000 in_port, out_port, proto=IP_PROTOS.tcp,
3001 flags=self.config_flags.NAT_IS_TWICE_NAT)
3003 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3004 session_n = len(sessions)
3006 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
3007 tcp_transitory=2, icmp=5)
3009 self.init_tcp_session(self.pg0, self.pg1, in_port, ext_port)
3011 # FIN packet in -> out
3012 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3013 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3014 TCP(sport=in_port, dport=ext_port,
3015 flags="FA", seq=100, ack=300))
3016 self.pg0.add_stream(p)
3017 self.pg_enable_capture(self.pg_interfaces)
3019 self.pg1.get_capture(1)
3023 # ACK packet out -> in
3024 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3025 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3026 TCP(sport=ext_port, dport=out_port,
3027 flags="A", seq=300, ack=101))
3030 # FIN packet out -> in
3031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3033 TCP(sport=ext_port, dport=out_port,
3034 flags="FA", seq=300, ack=101))
3037 self.pg1.add_stream(pkts)
3038 self.pg_enable_capture(self.pg_interfaces)
3040 self.pg0.get_capture(2)
3042 # ACK packet in -> out
3043 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3044 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3045 TCP(sport=in_port, dport=ext_port,
3046 flags="A", seq=101, ack=301))
3047 self.pg0.add_stream(p)
3048 self.pg_enable_capture(self.pg_interfaces)
3050 self.pg1.get_capture(1)
3052 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3053 self.assertEqual(len(sessions) - session_n, 1)
3055 out2in_drops = self.get_err_counter(
3056 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3057 in2out_drops = self.get_err_counter(
3058 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3060 # extra FIN packet out -> in - this should be dropped
3061 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3062 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3063 TCP(sport=ext_port, dport=out_port,
3064 flags="FA", seq=300, ack=101))
3066 self.pg1.add_stream(p)
3067 self.pg_enable_capture(self.pg_interfaces)
3069 self.pg0.assert_nothing_captured()
3071 # extra ACK packet in -> out - this should be dropped
3072 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3073 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3074 TCP(sport=in_port, dport=ext_port,
3075 flags="A", seq=101, ack=301))
3076 self.pg0.add_stream(p)
3077 self.pg_enable_capture(self.pg_interfaces)
3079 self.pg1.assert_nothing_captured()
3081 stats = self.get_err_counter(
3082 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3083 self.assertEqual(stats - out2in_drops, 1)
3084 stats = self.get_err_counter(
3085 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3086 self.assertEqual(stats - in2out_drops, 1)
3089 # extra ACK packet in -> out - this will cause session to be wiped
3090 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3091 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3092 TCP(sport=in_port, dport=ext_port,
3093 flags="A", seq=101, ack=301))
3094 self.pg0.add_stream(p)
3095 self.pg_enable_capture(self.pg_interfaces)
3097 self.pg1.assert_nothing_captured()
3098 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3099 self.assertEqual(len(sessions) - session_n, 0)
3101 def test_tcp_session_close_out(self):
3102 """ NAT44ED Close TCP session from outside network """
3104 in_port = self.tcp_port_in
3106 ext_port = self.tcp_external_port
3108 self.nat_add_address(self.nat_addr)
3109 self.nat_add_inside_interface(self.pg0)
3110 self.nat_add_outside_interface(self.pg1)
3111 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
3112 in_port, out_port, proto=IP_PROTOS.tcp,
3113 flags=self.config_flags.NAT_IS_TWICE_NAT)
3115 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3116 session_n = len(sessions)
3118 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
3119 tcp_transitory=2, icmp=5)
3121 _ = self.init_tcp_session(self.pg0, self.pg1, in_port, ext_port)
3123 # FIN packet out -> in
3124 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3125 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3126 TCP(sport=ext_port, dport=out_port,
3127 flags="FA", seq=100, ack=300))
3128 self.pg1.add_stream(p)
3129 self.pg_enable_capture(self.pg_interfaces)
3131 self.pg0.get_capture(1)
3133 # FIN+ACK packet in -> out
3134 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3135 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3136 TCP(sport=in_port, dport=ext_port,
3137 flags="FA", seq=300, ack=101))
3139 self.pg0.add_stream(p)
3140 self.pg_enable_capture(self.pg_interfaces)
3142 self.pg1.get_capture(1)
3144 # ACK packet out -> in
3145 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3146 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3147 TCP(sport=ext_port, dport=out_port,
3148 flags="A", seq=101, ack=301))
3149 self.pg1.add_stream(p)
3150 self.pg_enable_capture(self.pg_interfaces)
3152 self.pg0.get_capture(1)
3154 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3155 self.assertEqual(len(sessions) - session_n, 1)
3157 out2in_drops = self.get_err_counter(
3158 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3159 in2out_drops = self.get_err_counter(
3160 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3162 # extra FIN packet out -> in - this should be dropped
3163 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3164 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3165 TCP(sport=ext_port, dport=out_port,
3166 flags="FA", seq=300, ack=101))
3168 self.pg1.add_stream(p)
3169 self.pg_enable_capture(self.pg_interfaces)
3171 self.pg0.assert_nothing_captured()
3173 # extra ACK packet in -> out - this should be dropped
3174 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3175 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3176 TCP(sport=in_port, dport=ext_port,
3177 flags="A", seq=101, ack=301))
3178 self.pg0.add_stream(p)
3179 self.pg_enable_capture(self.pg_interfaces)
3181 self.pg1.assert_nothing_captured()
3183 stats = self.get_err_counter(
3184 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3185 self.assertEqual(stats - out2in_drops, 1)
3186 stats = self.get_err_counter(
3187 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3188 self.assertEqual(stats - in2out_drops, 1)
3191 # extra ACK packet in -> out - this will cause session to be wiped
3192 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3193 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3194 TCP(sport=in_port, dport=ext_port,
3195 flags="A", seq=101, ack=301))
3196 self.pg0.add_stream(p)
3197 self.pg_enable_capture(self.pg_interfaces)
3199 self.pg1.assert_nothing_captured()
3200 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3201 self.assertEqual(len(sessions) - session_n, 0)
3203 def test_tcp_session_close_simultaneous(self):
3204 """ NAT44ED Close TCP session from inside network """
3206 in_port = self.tcp_port_in
3209 self.nat_add_address(self.nat_addr)
3210 self.nat_add_inside_interface(self.pg0)
3211 self.nat_add_outside_interface(self.pg1)
3212 self.nat_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
3213 in_port, ext_port, proto=IP_PROTOS.tcp,
3214 flags=self.config_flags.NAT_IS_TWICE_NAT)
3216 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3217 session_n = len(sessions)
3219 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
3220 tcp_transitory=2, icmp=5)
3222 out_port = self.init_tcp_session(self.pg0, self.pg1, in_port, ext_port)
3224 # FIN packet in -> out
3225 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3226 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3227 TCP(sport=in_port, dport=ext_port,
3228 flags="FA", seq=100, ack=300))
3229 self.pg0.add_stream(p)
3230 self.pg_enable_capture(self.pg_interfaces)
3232 self.pg1.get_capture(1)
3234 # FIN packet out -> in
3235 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3236 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3237 TCP(sport=ext_port, dport=out_port,
3238 flags="FA", seq=300, ack=100))
3239 self.pg1.add_stream(p)
3240 self.pg_enable_capture(self.pg_interfaces)
3242 self.pg0.get_capture(1)
3244 # ACK packet in -> out
3245 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3246 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3247 TCP(sport=in_port, dport=ext_port,
3248 flags="A", seq=101, ack=301))
3249 self.pg0.add_stream(p)
3250 self.pg_enable_capture(self.pg_interfaces)
3252 self.pg1.get_capture(1)
3254 # ACK packet out -> in
3255 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3256 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3257 TCP(sport=ext_port, dport=out_port,
3258 flags="A", seq=301, ack=101))
3259 self.pg1.add_stream(p)
3260 self.pg_enable_capture(self.pg_interfaces)
3262 self.pg0.get_capture(1)
3264 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3265 self.assertEqual(len(sessions) - session_n, 1)
3267 out2in_drops = self.get_err_counter(
3268 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3269 in2out_drops = self.get_err_counter(
3270 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3272 # extra FIN packet out -> in - this should be dropped
3273 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3274 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3275 TCP(sport=ext_port, dport=out_port,
3276 flags="FA", seq=300, ack=101))
3278 self.pg1.add_stream(p)
3279 self.pg_enable_capture(self.pg_interfaces)
3281 self.pg0.assert_nothing_captured()
3283 # extra ACK packet in -> out - this should be dropped
3284 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3285 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3286 TCP(sport=in_port, dport=ext_port,
3287 flags="A", seq=101, ack=301))
3288 self.pg0.add_stream(p)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 self.pg1.assert_nothing_captured()
3293 stats = self.get_err_counter(
3294 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
3295 self.assertEqual(stats - out2in_drops, 1)
3296 stats = self.get_err_counter(
3297 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
3298 self.assertEqual(stats - in2out_drops, 1)
3301 # extra ACK packet in -> out - this will cause session to be wiped
3302 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3303 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3304 TCP(sport=in_port, dport=ext_port,
3305 flags="A", seq=101, ack=301))
3306 self.pg0.add_stream(p)
3307 self.pg_enable_capture(self.pg_interfaces)
3309 self.pg1.assert_nothing_captured()
3310 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3311 self.assertEqual(len(sessions) - session_n, 0)
3313 def test_dynamic_output_feature_vrf(self):
3314 """ NAT44ED dynamic translation test: output-feature, VRF"""
3316 # other then default (0)
3319 self.nat_add_address(self.nat_addr)
3320 flags = self.config_flags.NAT_IS_INSIDE
3321 self.vapi.nat44_interface_add_del_output_feature(
3322 sw_if_index=self.pg7.sw_if_index,
3323 flags=flags, is_add=1)
3324 self.vapi.nat44_interface_add_del_output_feature(
3325 sw_if_index=self.pg8.sw_if_index,
3329 self.configure_ip4_interface(self.pg7, table_id=new_vrf_id)
3330 self.configure_ip4_interface(self.pg8, table_id=new_vrf_id)
3333 tcpn = self.get_stats_counter(
3334 '/nat44/ed/in2out/slowpath/tcp')
3335 udpn = self.get_stats_counter(
3336 '/nat44/ed/in2out/slowpath/udp')
3337 icmpn = self.get_stats_counter(
3338 '/nat44/ed/in2out/slowpath/icmp')
3339 drops = self.get_stats_counter(
3340 '/nat44/ed/in2out/slowpath/drops')
3342 pkts = self.create_stream_in(self.pg7, self.pg8)
3343 self.pg7.add_stream(pkts)
3344 self.pg_enable_capture(self.pg_interfaces)
3346 capture = self.pg8.get_capture(len(pkts))
3347 self.verify_capture_out(capture, ignore_port=True)
3349 if_idx = self.pg7.sw_if_index
3350 cnt = self.get_stats_counter(
3351 '/nat44/ed/in2out/slowpath/tcp')
3352 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
3353 cnt = self.get_stats_counter(
3354 '/nat44/ed/in2out/slowpath/udp')
3355 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
3356 cnt = self.get_stats_counter(
3357 '/nat44/ed/in2out/slowpath/icmp')
3358 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
3359 cnt = self.get_stats_counter(
3360 '/nat44/ed/in2out/slowpath/drops')
3361 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
3364 tcpn = self.get_stats_counter(
3365 '/nat44/ed/out2in/fastpath/tcp')
3366 udpn = self.get_stats_counter(
3367 '/nat44/ed/out2in/fastpath/udp')
3368 icmpn = self.get_stats_counter(
3369 '/nat44/ed/out2in/fastpath/icmp')
3370 drops = self.get_stats_counter(
3371 '/nat44/ed/out2in/fastpath/drops')
3373 pkts = self.create_stream_out(self.pg8)
3374 self.pg8.add_stream(pkts)
3375 self.pg_enable_capture(self.pg_interfaces)
3377 capture = self.pg7.get_capture(len(pkts))
3378 self.verify_capture_in(capture, self.pg7)
3380 if_idx = self.pg8.sw_if_index
3381 cnt = self.get_stats_counter(
3382 '/nat44/ed/out2in/fastpath/tcp')
3383 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
3384 cnt = self.get_stats_counter(
3385 '/nat44/ed/out2in/fastpath/udp')
3386 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
3387 cnt = self.get_stats_counter(
3388 '/nat44/ed/out2in/fastpath/icmp')
3389 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
3390 cnt = self.get_stats_counter(
3391 '/nat44/ed/out2in/fastpath/drops')
3392 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
3394 sessions = self.get_stats_counter('/nat44/total-sessions')
3395 self.assertEqual(sessions[0], 3)
3398 self.configure_ip4_interface(self.pg7, table_id=0)
3399 self.configure_ip4_interface(self.pg8, table_id=0)
3401 self.vapi.ip_table_add_del(is_add=0,
3402 table={'table_id': new_vrf_id})
3404 def test_next_src_nat(self):
3405 """ NAT44ED On way back forward packet to nat44-in2out node. """
3407 twice_nat_addr = '10.0.1.3'
3410 post_twice_nat_port = 0
3412 self.vapi.nat44_forwarding_enable_disable(enable=1)
3413 self.nat_add_address(twice_nat_addr, twice_nat=1)
3414 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
3415 self.config_flags.NAT_IS_SELF_TWICE_NAT)
3416 self.nat_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
3417 local_port, external_port,
3418 proto=IP_PROTOS.tcp, vrf_id=1,
3420 self.vapi.nat44_interface_add_del_feature(
3421 sw_if_index=self.pg6.sw_if_index,
3424 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
3425 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
3426 TCP(sport=12345, dport=external_port))
3427 self.pg6.add_stream(p)
3428 self.pg_enable_capture(self.pg_interfaces)
3430 capture = self.pg6.get_capture(1)
3435 self.assertEqual(ip.src, twice_nat_addr)
3436 self.assertNotEqual(tcp.sport, 12345)
3437 post_twice_nat_port = tcp.sport
3438 self.assertEqual(ip.dst, self.pg6.remote_ip4)
3439 self.assertEqual(tcp.dport, local_port)
3440 self.assert_packet_checksums_valid(p)
3442 self.logger.error(ppp("Unexpected or invalid packet:", p))
3445 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
3446 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
3447 TCP(sport=local_port, dport=post_twice_nat_port))
3448 self.pg6.add_stream(p)
3449 self.pg_enable_capture(self.pg_interfaces)
3451 capture = self.pg6.get_capture(1)
3456 self.assertEqual(ip.src, self.pg1.remote_ip4)
3457 self.assertEqual(tcp.sport, external_port)
3458 self.assertEqual(ip.dst, self.pg6.remote_ip4)
3459 self.assertEqual(tcp.dport, 12345)
3460 self.assert_packet_checksums_valid(p)
3462 self.logger.error(ppp("Unexpected or invalid packet:", p))
3465 def test_one_armed_nat44_static(self):
3466 """ NAT44ED One armed NAT and 1:1 NAPT asymmetrical rule """
3468 remote_host = self.pg4.remote_hosts[0]
3469 local_host = self.pg4.remote_hosts[1]
3474 self.vapi.nat44_forwarding_enable_disable(enable=1)
3475 self.nat_add_address(self.nat_addr, twice_nat=1)
3476 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
3477 self.config_flags.NAT_IS_TWICE_NAT)
3478 self.nat_add_static_mapping(local_host.ip4, self.nat_addr,
3479 local_port, external_port,
3480 proto=IP_PROTOS.tcp, flags=flags)
3481 flags = self.config_flags.NAT_IS_INSIDE
3482 self.vapi.nat44_interface_add_del_feature(
3483 sw_if_index=self.pg4.sw_if_index,
3485 self.vapi.nat44_interface_add_del_feature(
3486 sw_if_index=self.pg4.sw_if_index,
3487 flags=flags, is_add=1)
3489 # from client to service
3490 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
3491 IP(src=remote_host.ip4, dst=self.nat_addr) /
3492 TCP(sport=12345, dport=external_port))
3493 self.pg4.add_stream(p)
3494 self.pg_enable_capture(self.pg_interfaces)
3496 capture = self.pg4.get_capture(1)
3501 self.assertEqual(ip.dst, local_host.ip4)
3502 self.assertEqual(ip.src, self.nat_addr)
3503 self.assertEqual(tcp.dport, local_port)
3504 self.assertNotEqual(tcp.sport, 12345)
3505 eh_port_in = tcp.sport
3506 self.assert_packet_checksums_valid(p)
3508 self.logger.error(ppp("Unexpected or invalid packet:", p))
3511 # from service back to client
3512 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
3513 IP(src=local_host.ip4, dst=self.nat_addr) /
3514 TCP(sport=local_port, dport=eh_port_in))
3515 self.pg4.add_stream(p)
3516 self.pg_enable_capture(self.pg_interfaces)
3518 capture = self.pg4.get_capture(1)
3523 self.assertEqual(ip.src, self.nat_addr)
3524 self.assertEqual(ip.dst, remote_host.ip4)
3525 self.assertEqual(tcp.sport, external_port)
3526 self.assertEqual(tcp.dport, 12345)
3527 self.assert_packet_checksums_valid(p)
3529 self.logger.error(ppp("Unexpected or invalid packet:", p))
3533 if __name__ == '__main__':
3534 unittest.main(testRunner=VppTestRunner)