9 from framework import VppTestCase, VppTestRunner, running_extended_tests
10 from scapy.layers.inet import IP, TCP, UDP, ICMP
11 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
12 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
13 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr
14 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
15 from scapy.layers.l2 import Ether, ARP, GRE
16 from scapy.data import IP_PROTOS
17 from scapy.packet import bind_layers, Raw
18 from scapy.all import fragment6
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from util import mactobinary
26 class MethodHolder(VppTestCase):
27 """ NAT create capture and verify method holder """
29 def clear_nat44(self):
31 Clear NAT44 configuration.
33 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
34 # I found no elegant way to do this
35 self.vapi.ip_add_del_route(
36 dst_address=self.pg7.remote_ip4n,
37 dst_address_length=32,
38 next_hop_address=self.pg7.remote_ip4n,
39 next_hop_sw_if_index=self.pg7.sw_if_index,
41 self.vapi.ip_add_del_route(
42 dst_address=self.pg8.remote_ip4n,
43 dst_address_length=32,
44 next_hop_address=self.pg8.remote_ip4n,
45 next_hop_sw_if_index=self.pg8.sw_if_index,
48 for intf in [self.pg7, self.pg8]:
49 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
51 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
56 if self.pg7.has_ip4_config:
57 self.pg7.unconfig_ip4()
59 self.vapi.nat44_forwarding_enable_disable(0)
61 interfaces = self.vapi.nat44_interface_addr_dump()
62 for intf in interfaces:
63 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
64 twice_nat=intf.twice_nat,
67 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
68 domain_id=self.ipfix_domain_id)
69 self.ipfix_src_port = 4739
70 self.ipfix_domain_id = 1
72 interfaces = self.vapi.nat44_interface_dump()
73 for intf in interfaces:
74 if intf.is_inside > 1:
75 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
78 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
82 interfaces = self.vapi.nat44_interface_output_feature_dump()
83 for intf in interfaces:
84 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
88 static_mappings = self.vapi.nat44_static_mapping_dump()
89 for sm in static_mappings:
90 self.vapi.nat44_add_del_static_mapping(
92 sm.external_ip_address,
93 local_port=sm.local_port,
94 external_port=sm.external_port,
95 addr_only=sm.addr_only,
98 twice_nat=sm.twice_nat,
99 self_twice_nat=sm.self_twice_nat,
100 out2in_only=sm.out2in_only,
102 external_sw_if_index=sm.external_sw_if_index,
105 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
106 for lb_sm in lb_static_mappings:
107 self.vapi.nat44_add_del_lb_static_mapping(
111 twice_nat=lb_sm.twice_nat,
112 self_twice_nat=lb_sm.self_twice_nat,
113 out2in_only=lb_sm.out2in_only,
119 identity_mappings = self.vapi.nat44_identity_mapping_dump()
120 for id_m in identity_mappings:
121 self.vapi.nat44_add_del_identity_mapping(
122 addr_only=id_m.addr_only,
125 sw_if_index=id_m.sw_if_index,
127 protocol=id_m.protocol,
130 adresses = self.vapi.nat44_address_dump()
131 for addr in adresses:
132 self.vapi.nat44_add_del_address_range(addr.ip_address,
134 twice_nat=addr.twice_nat,
137 self.vapi.nat_set_reass()
138 self.vapi.nat_set_reass(is_ip6=1)
139 self.verify_no_nat44_user()
140 self.vapi.nat_set_timeouts()
141 self.vapi.nat_set_addr_and_port_alloc_alg()
142 self.vapi.nat_set_mss_clamping()
144 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
145 local_port=0, external_port=0, vrf_id=0,
146 is_add=1, external_sw_if_index=0xFFFFFFFF,
147 proto=0, twice_nat=0, self_twice_nat=0,
148 out2in_only=0, tag=""):
150 Add/delete NAT44 static mapping
152 :param local_ip: Local IP address
153 :param external_ip: External IP address
154 :param local_port: Local port number (Optional)
155 :param external_port: External port number (Optional)
156 :param vrf_id: VRF ID (Default 0)
157 :param is_add: 1 if add, 0 if delete (Default add)
158 :param external_sw_if_index: External interface instead of IP address
159 :param proto: IP protocol (Mandatory if port specified)
160 :param twice_nat: 1 if translate external host address and port
161 :param self_twice_nat: 1 if translate external host address and port
162 whenever external host address equals
163 local address of internal host
164 :param out2in_only: if 1 rule is matching only out2in direction
165 :param tag: Opaque string tag
168 if local_port and external_port:
170 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
171 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
172 self.vapi.nat44_add_del_static_mapping(
175 external_sw_if_index,
187 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
189 Add/delete NAT44 address
191 :param ip: IP address
192 :param is_add: 1 if add, 0 if delete (Default add)
193 :param twice_nat: twice NAT address for extenal hosts
195 nat_addr = socket.inet_pton(socket.AF_INET, ip)
196 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
200 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
202 Create packet stream for inside network
204 :param in_if: Inside interface
205 :param out_if: Outside interface
206 :param dst_ip: Destination address
207 :param ttl: TTL of generated packets
210 dst_ip = out_if.remote_ip4
214 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
215 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
216 TCP(sport=self.tcp_port_in, dport=20))
220 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
221 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
222 UDP(sport=self.udp_port_in, dport=20))
226 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
227 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
228 ICMP(id=self.icmp_id_in, type='echo-request'))
233 def compose_ip6(self, ip4, pref, plen):
235 Compose IPv4-embedded IPv6 addresses
237 :param ip4: IPv4 address
238 :param pref: IPv6 prefix
239 :param plen: IPv6 prefix length
240 :returns: IPv4-embedded IPv6 addresses
242 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
243 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
258 pref_n[10] = ip4_n[3]
262 pref_n[10] = ip4_n[2]
263 pref_n[11] = ip4_n[3]
266 pref_n[10] = ip4_n[1]
267 pref_n[11] = ip4_n[2]
268 pref_n[12] = ip4_n[3]
270 pref_n[12] = ip4_n[0]
271 pref_n[13] = ip4_n[1]
272 pref_n[14] = ip4_n[2]
273 pref_n[15] = ip4_n[3]
274 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
276 def extract_ip4(self, ip6, plen):
278 Extract IPv4 address embedded in IPv6 addresses
280 :param ip6: IPv6 address
281 :param plen: IPv6 prefix length
282 :returns: extracted IPv4 address
284 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
316 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
318 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
320 Create IPv6 packet stream for inside network
322 :param in_if: Inside interface
323 :param out_if: Outside interface
324 :param ttl: Hop Limit of generated packets
325 :param pref: NAT64 prefix
326 :param plen: NAT64 prefix length
330 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
332 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
335 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
336 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
337 TCP(sport=self.tcp_port_in, dport=20))
341 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
342 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
343 UDP(sport=self.udp_port_in, dport=20))
347 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
348 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
349 ICMPv6EchoRequest(id=self.icmp_id_in))
354 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
355 use_inside_ports=False):
357 Create packet stream for outside network
359 :param out_if: Outside interface
360 :param dst_ip: Destination IP address (Default use global NAT address)
361 :param ttl: TTL of generated packets
362 :param use_inside_ports: Use inside NAT ports as destination ports
363 instead of outside ports
366 dst_ip = self.nat_addr
367 if not use_inside_ports:
368 tcp_port = self.tcp_port_out
369 udp_port = self.udp_port_out
370 icmp_id = self.icmp_id_out
372 tcp_port = self.tcp_port_in
373 udp_port = self.udp_port_in
374 icmp_id = self.icmp_id_in
377 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
378 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
379 TCP(dport=tcp_port, sport=20))
383 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
384 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
385 UDP(dport=udp_port, sport=20))
389 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
390 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
391 ICMP(id=icmp_id, type='echo-reply'))
396 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
398 Create packet stream for outside network
400 :param out_if: Outside interface
401 :param dst_ip: Destination IP address (Default use global NAT address)
402 :param hl: HL of generated packets
406 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
407 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
408 TCP(dport=self.tcp_port_out, sport=20))
412 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
413 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
414 UDP(dport=self.udp_port_out, sport=20))
418 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
419 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
420 ICMPv6EchoReply(id=self.icmp_id_out))
425 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
426 dst_ip=None, is_ip6=False):
428 Verify captured packets on outside network
430 :param capture: Captured packets
431 :param nat_ip: Translated IP address (Default use global NAT address)
432 :param same_port: Sorce port number is not translated (Default False)
433 :param dst_ip: Destination IP address (Default do not verify)
434 :param is_ip6: If L3 protocol is IPv6 (Default False)
438 ICMP46 = ICMPv6EchoRequest
443 nat_ip = self.nat_addr
444 for packet in capture:
447 self.assert_packet_checksums_valid(packet)
448 self.assertEqual(packet[IP46].src, nat_ip)
449 if dst_ip is not None:
450 self.assertEqual(packet[IP46].dst, dst_ip)
451 if packet.haslayer(TCP):
453 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
456 packet[TCP].sport, self.tcp_port_in)
457 self.tcp_port_out = packet[TCP].sport
458 self.assert_packet_checksums_valid(packet)
459 elif packet.haslayer(UDP):
461 self.assertEqual(packet[UDP].sport, self.udp_port_in)
464 packet[UDP].sport, self.udp_port_in)
465 self.udp_port_out = packet[UDP].sport
468 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
470 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
471 self.icmp_id_out = packet[ICMP46].id
472 self.assert_packet_checksums_valid(packet)
474 self.logger.error(ppp("Unexpected or invalid packet "
475 "(outside network):", packet))
478 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
481 Verify captured packets on outside network
483 :param capture: Captured packets
484 :param nat_ip: Translated IP address
485 :param same_port: Sorce port number is not translated (Default False)
486 :param dst_ip: Destination IP address (Default do not verify)
488 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
491 def verify_capture_in(self, capture, in_if):
493 Verify captured packets on inside network
495 :param capture: Captured packets
496 :param in_if: Inside interface
498 for packet in capture:
500 self.assert_packet_checksums_valid(packet)
501 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
502 if packet.haslayer(TCP):
503 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
504 elif packet.haslayer(UDP):
505 self.assertEqual(packet[UDP].dport, self.udp_port_in)
507 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
509 self.logger.error(ppp("Unexpected or invalid packet "
510 "(inside network):", packet))
513 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
515 Verify captured IPv6 packets on inside network
517 :param capture: Captured packets
518 :param src_ip: Source IP
519 :param dst_ip: Destination IP address
521 for packet in capture:
523 self.assertEqual(packet[IPv6].src, src_ip)
524 self.assertEqual(packet[IPv6].dst, dst_ip)
525 self.assert_packet_checksums_valid(packet)
526 if packet.haslayer(TCP):
527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
528 elif packet.haslayer(UDP):
529 self.assertEqual(packet[UDP].dport, self.udp_port_in)
531 self.assertEqual(packet[ICMPv6EchoReply].id,
534 self.logger.error(ppp("Unexpected or invalid packet "
535 "(inside network):", packet))
538 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
540 Verify captured packet that don't have to be translated
542 :param capture: Captured packets
543 :param ingress_if: Ingress interface
544 :param egress_if: Egress interface
546 for packet in capture:
548 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
549 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
550 if packet.haslayer(TCP):
551 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
552 elif packet.haslayer(UDP):
553 self.assertEqual(packet[UDP].sport, self.udp_port_in)
555 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
557 self.logger.error(ppp("Unexpected or invalid packet "
558 "(inside network):", packet))
561 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
564 Verify captured packets with ICMP errors on outside network
566 :param capture: Captured packets
567 :param src_ip: Translated IP address or IP address of VPP
568 (Default use global NAT address)
569 :param icmp_type: Type of error ICMP packet
570 we are expecting (Default 11)
573 src_ip = self.nat_addr
574 for packet in capture:
576 self.assertEqual(packet[IP].src, src_ip)
577 self.assertTrue(packet.haslayer(ICMP))
579 self.assertEqual(icmp.type, icmp_type)
580 self.assertTrue(icmp.haslayer(IPerror))
581 inner_ip = icmp[IPerror]
582 if inner_ip.haslayer(TCPerror):
583 self.assertEqual(inner_ip[TCPerror].dport,
585 elif inner_ip.haslayer(UDPerror):
586 self.assertEqual(inner_ip[UDPerror].dport,
589 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
591 self.logger.error(ppp("Unexpected or invalid packet "
592 "(outside network):", packet))
595 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
597 Verify captured packets with ICMP errors on inside network
599 :param capture: Captured packets
600 :param in_if: Inside interface
601 :param icmp_type: Type of error ICMP packet
602 we are expecting (Default 11)
604 for packet in capture:
606 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
607 self.assertTrue(packet.haslayer(ICMP))
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].sport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].sport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(inside network):", packet))
625 def create_stream_frag(self, src_if, dst, sport, dport, data,
626 proto=IP_PROTOS.tcp, echo_reply=False):
628 Create fragmented packet stream
630 :param src_if: Source interface
631 :param dst: Destination IPv4 address
632 :param sport: Source port
633 :param dport: Destination port
634 :param data: Payload data
635 :param proto: protocol (TCP, UDP, ICMP)
636 :param echo_reply: use echo_reply if protocol is ICMP
639 if proto == IP_PROTOS.tcp:
640 p = (IP(src=src_if.remote_ip4, dst=dst) /
641 TCP(sport=sport, dport=dport) /
643 p = p.__class__(str(p))
644 chksum = p['TCP'].chksum
645 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
646 elif proto == IP_PROTOS.udp:
647 proto_header = UDP(sport=sport, dport=dport)
648 elif proto == IP_PROTOS.icmp:
650 proto_header = ICMP(id=sport, type='echo-request')
652 proto_header = ICMP(id=sport, type='echo-reply')
654 raise Exception("Unsupported protocol")
655 id = random.randint(0, 65535)
657 if proto == IP_PROTOS.tcp:
660 raw = Raw(data[0:16])
661 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
662 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
666 if proto == IP_PROTOS.tcp:
667 raw = Raw(data[4:20])
669 raw = Raw(data[16:32])
670 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
671 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
675 if proto == IP_PROTOS.tcp:
679 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
680 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
686 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
687 pref=None, plen=0, frag_size=128):
689 Create fragmented packet stream
691 :param src_if: Source interface
692 :param dst: Destination IPv4 address
693 :param sport: Source TCP port
694 :param dport: Destination TCP port
695 :param data: Payload data
696 :param pref: NAT64 prefix
697 :param plen: NAT64 prefix length
698 :param fragsize: size of fragments
702 dst_ip6 = ''.join(['64:ff9b::', dst])
704 dst_ip6 = self.compose_ip6(dst, pref, plen)
706 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
707 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
708 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
709 TCP(sport=sport, dport=dport) /
712 return fragment6(p, frag_size)
714 def reass_frags_and_verify(self, frags, src, dst):
716 Reassemble and verify fragmented packet
718 :param frags: Captured fragments
719 :param src: Source IPv4 address to verify
720 :param dst: Destination IPv4 address to verify
722 :returns: Reassembled IPv4 packet
724 buffer = StringIO.StringIO()
726 self.assertEqual(p[IP].src, src)
727 self.assertEqual(p[IP].dst, dst)
728 self.assert_ip_checksum_valid(p)
729 buffer.seek(p[IP].frag * 8)
730 buffer.write(p[IP].payload)
731 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
732 proto=frags[0][IP].proto)
733 if ip.proto == IP_PROTOS.tcp:
734 p = (ip / TCP(buffer.getvalue()))
735 self.assert_tcp_checksum_valid(p)
736 elif ip.proto == IP_PROTOS.udp:
737 p = (ip / UDP(buffer.getvalue()[:8]) /
738 Raw(buffer.getvalue()[8:]))
739 elif ip.proto == IP_PROTOS.icmp:
740 p = (ip / ICMP(buffer.getvalue()))
743 def reass_frags_and_verify_ip6(self, frags, src, dst):
745 Reassemble and verify fragmented packet
747 :param frags: Captured fragments
748 :param src: Source IPv6 address to verify
749 :param dst: Destination IPv6 address to verify
751 :returns: Reassembled IPv6 packet
753 buffer = StringIO.StringIO()
755 self.assertEqual(p[IPv6].src, src)
756 self.assertEqual(p[IPv6].dst, dst)
757 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
758 buffer.write(p[IPv6ExtHdrFragment].payload)
759 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
760 nh=frags[0][IPv6ExtHdrFragment].nh)
761 if ip.nh == IP_PROTOS.tcp:
762 p = (ip / TCP(buffer.getvalue()))
763 elif ip.nh == IP_PROTOS.udp:
764 p = (ip / UDP(buffer.getvalue()))
765 self.assert_packet_checksums_valid(p)
768 def initiate_tcp_session(self, in_if, out_if):
770 Initiates TCP session
772 :param in_if: Inside interface
773 :param out_if: Outside interface
777 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
778 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
779 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
782 self.pg_enable_capture(self.pg_interfaces)
784 capture = out_if.get_capture(1)
786 self.tcp_port_out = p[TCP].sport
788 # SYN + ACK packet out->in
789 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
790 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
791 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
794 self.pg_enable_capture(self.pg_interfaces)
799 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
800 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
801 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
804 self.pg_enable_capture(self.pg_interfaces)
806 out_if.get_capture(1)
809 self.logger.error("TCP 3 way handshake failed")
812 def verify_ipfix_nat44_ses(self, data):
814 Verify IPFIX NAT44 session create/delete event
816 :param data: Decoded IPFIX data records
818 nat44_ses_create_num = 0
819 nat44_ses_delete_num = 0
820 self.assertEqual(6, len(data))
823 self.assertIn(ord(record[230]), [4, 5])
824 if ord(record[230]) == 4:
825 nat44_ses_create_num += 1
827 nat44_ses_delete_num += 1
829 self.assertEqual(self.pg0.remote_ip4n, record[8])
830 # postNATSourceIPv4Address
831 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
834 self.assertEqual(struct.pack("!I", 0), record[234])
835 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
836 if IP_PROTOS.icmp == ord(record[4]):
837 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
838 self.assertEqual(struct.pack("!H", self.icmp_id_out),
840 elif IP_PROTOS.tcp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.tcp_port_in),
843 self.assertEqual(struct.pack("!H", self.tcp_port_out),
845 elif IP_PROTOS.udp == ord(record[4]):
846 self.assertEqual(struct.pack("!H", self.udp_port_in),
848 self.assertEqual(struct.pack("!H", self.udp_port_out),
851 self.fail("Invalid protocol")
852 self.assertEqual(3, nat44_ses_create_num)
853 self.assertEqual(3, nat44_ses_delete_num)
855 def verify_ipfix_addr_exhausted(self, data):
857 Verify IPFIX NAT addresses event
859 :param data: Decoded IPFIX data records
861 self.assertEqual(1, len(data))
864 self.assertEqual(ord(record[230]), 3)
866 self.assertEqual(struct.pack("!I", 0), record[283])
868 def verify_ipfix_max_sessions(self, data, limit):
870 Verify IPFIX maximum session entries exceeded event
872 :param data: Decoded IPFIX data records
873 :param limit: Number of maximum session entries that can be created.
875 self.assertEqual(1, len(data))
878 self.assertEqual(ord(record[230]), 13)
879 # natQuotaExceededEvent
880 self.assertEqual(struct.pack("I", 1), record[466])
882 self.assertEqual(struct.pack("I", limit), record[471])
884 def verify_ipfix_max_bibs(self, data, limit):
886 Verify IPFIX maximum BIB entries exceeded event
888 :param data: Decoded IPFIX data records
889 :param limit: Number of maximum BIB entries that can be created.
891 self.assertEqual(1, len(data))
894 self.assertEqual(ord(record[230]), 13)
895 # natQuotaExceededEvent
896 self.assertEqual(struct.pack("I", 2), record[466])
898 self.assertEqual(struct.pack("I", limit), record[472])
900 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
902 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum fragments pending reassembly
906 :param src_addr: IPv6 source address
908 self.assertEqual(1, len(data))
911 self.assertEqual(ord(record[230]), 13)
912 # natQuotaExceededEvent
913 self.assertEqual(struct.pack("I", 5), record[466])
914 # maxFragmentsPendingReassembly
915 self.assertEqual(struct.pack("I", limit), record[475])
917 self.assertEqual(src_addr, record[27])
919 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
921 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
923 :param data: Decoded IPFIX data records
924 :param limit: Number of maximum fragments pending reassembly
925 :param src_addr: IPv4 source address
927 self.assertEqual(1, len(data))
930 self.assertEqual(ord(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 5), record[466])
933 # maxFragmentsPendingReassembly
934 self.assertEqual(struct.pack("I", limit), record[475])
936 self.assertEqual(src_addr, record[8])
938 def verify_ipfix_bib(self, data, is_create, src_addr):
940 Verify IPFIX NAT64 BIB create and delete events
942 :param data: Decoded IPFIX data records
943 :param is_create: Create event if nonzero value otherwise delete event
944 :param src_addr: IPv6 source address
946 self.assertEqual(1, len(data))
950 self.assertEqual(ord(record[230]), 10)
952 self.assertEqual(ord(record[230]), 11)
954 self.assertEqual(src_addr, record[27])
955 # postNATSourceIPv4Address
956 self.assertEqual(self.nat_addr_n, record[225])
958 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
960 self.assertEqual(struct.pack("!I", 0), record[234])
961 # sourceTransportPort
962 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
963 # postNAPTSourceTransportPort
964 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
966 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
969 Verify IPFIX NAT64 session create and delete events
971 :param data: Decoded IPFIX data records
972 :param is_create: Create event if nonzero value otherwise delete event
973 :param src_addr: IPv6 source address
974 :param dst_addr: IPv4 destination address
975 :param dst_port: destination TCP port
977 self.assertEqual(1, len(data))
981 self.assertEqual(ord(record[230]), 6)
983 self.assertEqual(ord(record[230]), 7)
985 self.assertEqual(src_addr, record[27])
986 # destinationIPv6Address
987 self.assertEqual(socket.inet_pton(socket.AF_INET6,
988 self.compose_ip6(dst_addr,
992 # postNATSourceIPv4Address
993 self.assertEqual(self.nat_addr_n, record[225])
994 # postNATDestinationIPv4Address
995 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
998 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1000 self.assertEqual(struct.pack("!I", 0), record[234])
1001 # sourceTransportPort
1002 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1003 # postNAPTSourceTransportPort
1004 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1005 # destinationTransportPort
1006 self.assertEqual(struct.pack("!H", dst_port), record[11])
1007 # postNAPTDestinationTransportPort
1008 self.assertEqual(struct.pack("!H", dst_port), record[228])
1010 def verify_no_nat44_user(self):
1011 """ Verify that there is no NAT44 user """
1012 users = self.vapi.nat44_user_dump()
1013 self.assertEqual(len(users), 0)
1015 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1017 Verify IPFIX maximum entries per user exceeded event
1019 :param data: Decoded IPFIX data records
1020 :param limit: Number of maximum entries per user
1021 :param src_addr: IPv4 source address
1023 self.assertEqual(1, len(data))
1026 self.assertEqual(ord(record[230]), 13)
1027 # natQuotaExceededEvent
1028 self.assertEqual(struct.pack("I", 3), record[466])
1030 self.assertEqual(struct.pack("I", limit), record[473])
1032 self.assertEqual(src_addr, record[8])
1034 def verify_mss_value(self, pkt, mss):
1036 Verify TCP MSS value
1041 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1042 raise TypeError("Not a TCP/IP packet")
1044 for option in pkt[TCP].options:
1045 if option[0] == 'MSS':
1046 self.assertEqual(option[1], mss)
1047 self.assert_tcp_checksum_valid(pkt)
1050 def proto2layer(proto):
1051 if proto == IP_PROTOS.tcp:
1053 elif proto == IP_PROTOS.udp:
1055 elif proto == IP_PROTOS.icmp:
1058 raise Exception("Unsupported protocol")
1060 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1061 layer = self.proto2layer(proto)
1063 if proto == IP_PROTOS.tcp:
1064 data = "A" * 4 + "B" * 16 + "C" * 3
1066 data = "A" * 16 + "B" * 16 + "C" * 3
1067 self.port_in = random.randint(1025, 65535)
1069 reass = self.vapi.nat_reass_dump()
1070 reass_n_start = len(reass)
1073 pkts = self.create_stream_frag(self.pg0,
1074 self.pg1.remote_ip4,
1079 self.pg0.add_stream(pkts)
1080 self.pg_enable_capture(self.pg_interfaces)
1082 frags = self.pg1.get_capture(len(pkts))
1083 if not dont_translate:
1084 p = self.reass_frags_and_verify(frags,
1086 self.pg1.remote_ip4)
1088 p = self.reass_frags_and_verify(frags,
1089 self.pg0.remote_ip4,
1090 self.pg1.remote_ip4)
1091 if proto != IP_PROTOS.icmp:
1092 if not dont_translate:
1093 self.assertEqual(p[layer].dport, 20)
1094 self.assertNotEqual(p[layer].sport, self.port_in)
1096 self.assertEqual(p[layer].sport, self.port_in)
1098 if not dont_translate:
1099 self.assertNotEqual(p[layer].id, self.port_in)
1101 self.assertEqual(p[layer].id, self.port_in)
1102 self.assertEqual(data, p[Raw].load)
1105 if not dont_translate:
1106 dst_addr = self.nat_addr
1108 dst_addr = self.pg0.remote_ip4
1109 if proto != IP_PROTOS.icmp:
1111 dport = p[layer].sport
1115 pkts = self.create_stream_frag(self.pg1,
1122 self.pg1.add_stream(pkts)
1123 self.pg_enable_capture(self.pg_interfaces)
1125 frags = self.pg0.get_capture(len(pkts))
1126 p = self.reass_frags_and_verify(frags,
1127 self.pg1.remote_ip4,
1128 self.pg0.remote_ip4)
1129 if proto != IP_PROTOS.icmp:
1130 self.assertEqual(p[layer].sport, 20)
1131 self.assertEqual(p[layer].dport, self.port_in)
1133 self.assertEqual(p[layer].id, self.port_in)
1134 self.assertEqual(data, p[Raw].load)
1136 reass = self.vapi.nat_reass_dump()
1137 reass_n_end = len(reass)
1139 self.assertEqual(reass_n_end - reass_n_start, 2)
1141 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1142 layer = self.proto2layer(proto)
1144 if proto == IP_PROTOS.tcp:
1145 data = "A" * 4 + "B" * 16 + "C" * 3
1147 data = "A" * 16 + "B" * 16 + "C" * 3
1148 self.port_in = random.randint(1025, 65535)
1151 reass = self.vapi.nat_reass_dump()
1152 reass_n_start = len(reass)
1155 pkts = self.create_stream_frag(self.pg0,
1156 self.server_out_addr,
1158 self.server_out_port,
1161 self.pg0.add_stream(pkts)
1162 self.pg_enable_capture(self.pg_interfaces)
1164 frags = self.pg1.get_capture(len(pkts))
1165 p = self.reass_frags_and_verify(frags,
1166 self.pg0.remote_ip4,
1167 self.server_in_addr)
1168 if proto != IP_PROTOS.icmp:
1169 self.assertEqual(p[layer].sport, self.port_in)
1170 self.assertEqual(p[layer].dport, self.server_in_port)
1172 self.assertEqual(p[layer].id, self.port_in)
1173 self.assertEqual(data, p[Raw].load)
1176 if proto != IP_PROTOS.icmp:
1177 pkts = self.create_stream_frag(self.pg1,
1178 self.pg0.remote_ip4,
1179 self.server_in_port,
1184 pkts = self.create_stream_frag(self.pg1,
1185 self.pg0.remote_ip4,
1191 self.pg1.add_stream(pkts)
1192 self.pg_enable_capture(self.pg_interfaces)
1194 frags = self.pg0.get_capture(len(pkts))
1195 p = self.reass_frags_and_verify(frags,
1196 self.server_out_addr,
1197 self.pg0.remote_ip4)
1198 if proto != IP_PROTOS.icmp:
1199 self.assertEqual(p[layer].sport, self.server_out_port)
1200 self.assertEqual(p[layer].dport, self.port_in)
1202 self.assertEqual(p[layer].id, self.port_in)
1203 self.assertEqual(data, p[Raw].load)
1205 reass = self.vapi.nat_reass_dump()
1206 reass_n_end = len(reass)
1208 self.assertEqual(reass_n_end - reass_n_start, 2)
1210 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1211 layer = self.proto2layer(proto)
1213 if proto == IP_PROTOS.tcp:
1214 data = "A" * 4 + "B" * 16 + "C" * 3
1216 data = "A" * 16 + "B" * 16 + "C" * 3
1218 # send packet from host to server
1219 pkts = self.create_stream_frag(self.pg0,
1222 self.server_out_port,
1225 self.pg0.add_stream(pkts)
1226 self.pg_enable_capture(self.pg_interfaces)
1228 frags = self.pg0.get_capture(len(pkts))
1229 p = self.reass_frags_and_verify(frags,
1232 if proto != IP_PROTOS.icmp:
1233 self.assertNotEqual(p[layer].sport, self.host_in_port)
1234 self.assertEqual(p[layer].dport, self.server_in_port)
1236 self.assertNotEqual(p[layer].id, self.host_in_port)
1237 self.assertEqual(data, p[Raw].load)
1239 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1240 layer = self.proto2layer(proto)
1242 if proto == IP_PROTOS.tcp:
1243 data = "A" * 4 + "B" * 16 + "C" * 3
1245 data = "A" * 16 + "B" * 16 + "C" * 3
1246 self.port_in = random.randint(1025, 65535)
1250 pkts = self.create_stream_frag(self.pg0,
1251 self.pg1.remote_ip4,
1257 self.pg0.add_stream(pkts)
1258 self.pg_enable_capture(self.pg_interfaces)
1260 frags = self.pg1.get_capture(len(pkts))
1261 if not dont_translate:
1262 p = self.reass_frags_and_verify(frags,
1264 self.pg1.remote_ip4)
1266 p = self.reass_frags_and_verify(frags,
1267 self.pg0.remote_ip4,
1268 self.pg1.remote_ip4)
1269 if proto != IP_PROTOS.icmp:
1270 if not dont_translate:
1271 self.assertEqual(p[layer].dport, 20)
1272 self.assertNotEqual(p[layer].sport, self.port_in)
1274 self.assertEqual(p[layer].sport, self.port_in)
1276 if not dont_translate:
1277 self.assertNotEqual(p[layer].id, self.port_in)
1279 self.assertEqual(p[layer].id, self.port_in)
1280 self.assertEqual(data, p[Raw].load)
1283 if not dont_translate:
1284 dst_addr = self.nat_addr
1286 dst_addr = self.pg0.remote_ip4
1287 if proto != IP_PROTOS.icmp:
1289 dport = p[layer].sport
1293 pkts = self.create_stream_frag(self.pg1,
1301 self.pg1.add_stream(pkts)
1302 self.pg_enable_capture(self.pg_interfaces)
1304 frags = self.pg0.get_capture(len(pkts))
1305 p = self.reass_frags_and_verify(frags,
1306 self.pg1.remote_ip4,
1307 self.pg0.remote_ip4)
1308 if proto != IP_PROTOS.icmp:
1309 self.assertEqual(p[layer].sport, 20)
1310 self.assertEqual(p[layer].dport, self.port_in)
1312 self.assertEqual(p[layer].id, self.port_in)
1313 self.assertEqual(data, p[Raw].load)
1315 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1316 layer = self.proto2layer(proto)
1318 if proto == IP_PROTOS.tcp:
1319 data = "A" * 4 + "B" * 16 + "C" * 3
1321 data = "A" * 16 + "B" * 16 + "C" * 3
1322 self.port_in = random.randint(1025, 65535)
1326 pkts = self.create_stream_frag(self.pg0,
1327 self.server_out_addr,
1329 self.server_out_port,
1333 self.pg0.add_stream(pkts)
1334 self.pg_enable_capture(self.pg_interfaces)
1336 frags = self.pg1.get_capture(len(pkts))
1337 p = self.reass_frags_and_verify(frags,
1338 self.pg0.remote_ip4,
1339 self.server_in_addr)
1340 if proto != IP_PROTOS.icmp:
1341 self.assertEqual(p[layer].dport, self.server_in_port)
1342 self.assertEqual(p[layer].sport, self.port_in)
1343 self.assertEqual(p[layer].dport, self.server_in_port)
1345 self.assertEqual(p[layer].id, self.port_in)
1346 self.assertEqual(data, p[Raw].load)
1349 if proto != IP_PROTOS.icmp:
1350 pkts = self.create_stream_frag(self.pg1,
1351 self.pg0.remote_ip4,
1352 self.server_in_port,
1357 pkts = self.create_stream_frag(self.pg1,
1358 self.pg0.remote_ip4,
1365 self.pg1.add_stream(pkts)
1366 self.pg_enable_capture(self.pg_interfaces)
1368 frags = self.pg0.get_capture(len(pkts))
1369 p = self.reass_frags_and_verify(frags,
1370 self.server_out_addr,
1371 self.pg0.remote_ip4)
1372 if proto != IP_PROTOS.icmp:
1373 self.assertEqual(p[layer].sport, self.server_out_port)
1374 self.assertEqual(p[layer].dport, self.port_in)
1376 self.assertEqual(p[layer].id, self.port_in)
1377 self.assertEqual(data, p[Raw].load)
1380 class TestNAT44(MethodHolder):
1381 """ NAT44 Test Cases """
1384 def setUpClass(cls):
1385 super(TestNAT44, cls).setUpClass()
1386 cls.vapi.cli("set log class nat level debug")
1389 cls.tcp_port_in = 6303
1390 cls.tcp_port_out = 6303
1391 cls.udp_port_in = 6304
1392 cls.udp_port_out = 6304
1393 cls.icmp_id_in = 6305
1394 cls.icmp_id_out = 6305
1395 cls.nat_addr = '10.0.0.3'
1396 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1397 cls.ipfix_src_port = 4739
1398 cls.ipfix_domain_id = 1
1399 cls.tcp_external_port = 80
1401 cls.create_pg_interfaces(range(10))
1402 cls.interfaces = list(cls.pg_interfaces[0:4])
1404 for i in cls.interfaces:
1409 cls.pg0.generate_remote_hosts(3)
1410 cls.pg0.configure_ipv4_neighbors()
1412 cls.pg1.generate_remote_hosts(1)
1413 cls.pg1.configure_ipv4_neighbors()
1415 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1416 cls.vapi.ip_table_add_del(10, is_add=1)
1417 cls.vapi.ip_table_add_del(20, is_add=1)
1419 cls.pg4._local_ip4 = "172.16.255.1"
1420 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1421 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1422 cls.pg4.set_table_ip4(10)
1423 cls.pg5._local_ip4 = "172.17.255.3"
1424 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1425 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1426 cls.pg5.set_table_ip4(10)
1427 cls.pg6._local_ip4 = "172.16.255.1"
1428 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1429 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1430 cls.pg6.set_table_ip4(20)
1431 for i in cls.overlapping_interfaces:
1439 cls.pg9.generate_remote_hosts(2)
1440 cls.pg9.config_ip4()
1441 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1442 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1446 cls.pg9.resolve_arp()
1447 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1448 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1449 cls.pg9.resolve_arp()
1452 super(TestNAT44, cls).tearDownClass()
1455 def test_dynamic(self):
1456 """ NAT44 dynamic translation test """
1458 self.nat44_add_address(self.nat_addr)
1459 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1460 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1464 pkts = self.create_stream_in(self.pg0, self.pg1)
1465 self.pg0.add_stream(pkts)
1466 self.pg_enable_capture(self.pg_interfaces)
1468 capture = self.pg1.get_capture(len(pkts))
1469 self.verify_capture_out(capture)
1472 pkts = self.create_stream_out(self.pg1)
1473 self.pg1.add_stream(pkts)
1474 self.pg_enable_capture(self.pg_interfaces)
1476 capture = self.pg0.get_capture(len(pkts))
1477 self.verify_capture_in(capture, self.pg0)
1479 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1480 """ NAT44 handling of client packets with TTL=1 """
1482 self.nat44_add_address(self.nat_addr)
1483 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1484 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1487 # Client side - generate traffic
1488 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1489 self.pg0.add_stream(pkts)
1490 self.pg_enable_capture(self.pg_interfaces)
1493 # Client side - verify ICMP type 11 packets
1494 capture = self.pg0.get_capture(len(pkts))
1495 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1497 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1498 """ NAT44 handling of server packets with TTL=1 """
1500 self.nat44_add_address(self.nat_addr)
1501 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1502 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1505 # Client side - create sessions
1506 pkts = self.create_stream_in(self.pg0, self.pg1)
1507 self.pg0.add_stream(pkts)
1508 self.pg_enable_capture(self.pg_interfaces)
1511 # Server side - generate traffic
1512 capture = self.pg1.get_capture(len(pkts))
1513 self.verify_capture_out(capture)
1514 pkts = self.create_stream_out(self.pg1, ttl=1)
1515 self.pg1.add_stream(pkts)
1516 self.pg_enable_capture(self.pg_interfaces)
1519 # Server side - verify ICMP type 11 packets
1520 capture = self.pg1.get_capture(len(pkts))
1521 self.verify_capture_out_with_icmp_errors(capture,
1522 src_ip=self.pg1.local_ip4)
1524 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1525 """ NAT44 handling of error responses to client packets with TTL=2 """
1527 self.nat44_add_address(self.nat_addr)
1528 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1529 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1532 # Client side - generate traffic
1533 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1534 self.pg0.add_stream(pkts)
1535 self.pg_enable_capture(self.pg_interfaces)
1538 # Server side - simulate ICMP type 11 response
1539 capture = self.pg1.get_capture(len(pkts))
1540 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1541 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1542 ICMP(type=11) / packet[IP] for packet in capture]
1543 self.pg1.add_stream(pkts)
1544 self.pg_enable_capture(self.pg_interfaces)
1547 # Client side - verify ICMP type 11 packets
1548 capture = self.pg0.get_capture(len(pkts))
1549 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1551 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1552 """ NAT44 handling of error responses to server packets with TTL=2 """
1554 self.nat44_add_address(self.nat_addr)
1555 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1556 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1559 # Client side - create sessions
1560 pkts = self.create_stream_in(self.pg0, self.pg1)
1561 self.pg0.add_stream(pkts)
1562 self.pg_enable_capture(self.pg_interfaces)
1565 # Server side - generate traffic
1566 capture = self.pg1.get_capture(len(pkts))
1567 self.verify_capture_out(capture)
1568 pkts = self.create_stream_out(self.pg1, ttl=2)
1569 self.pg1.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1573 # Client side - simulate ICMP type 11 response
1574 capture = self.pg0.get_capture(len(pkts))
1575 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1576 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1577 ICMP(type=11) / packet[IP] for packet in capture]
1578 self.pg0.add_stream(pkts)
1579 self.pg_enable_capture(self.pg_interfaces)
1582 # Server side - verify ICMP type 11 packets
1583 capture = self.pg1.get_capture(len(pkts))
1584 self.verify_capture_out_with_icmp_errors(capture)
1586 def test_ping_out_interface_from_outside(self):
1587 """ Ping NAT44 out interface from outside network """
1589 self.nat44_add_address(self.nat_addr)
1590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1594 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1595 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1596 ICMP(id=self.icmp_id_out, type='echo-request'))
1598 self.pg1.add_stream(pkts)
1599 self.pg_enable_capture(self.pg_interfaces)
1601 capture = self.pg1.get_capture(len(pkts))
1604 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1605 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1606 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1607 self.assertEqual(packet[ICMP].type, 0) # echo reply
1609 self.logger.error(ppp("Unexpected or invalid packet "
1610 "(outside network):", packet))
1613 def test_ping_internal_host_from_outside(self):
1614 """ Ping internal host from outside network """
1616 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1617 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1618 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1622 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1623 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1624 ICMP(id=self.icmp_id_out, type='echo-request'))
1625 self.pg1.add_stream(pkt)
1626 self.pg_enable_capture(self.pg_interfaces)
1628 capture = self.pg0.get_capture(1)
1629 self.verify_capture_in(capture, self.pg0)
1630 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1633 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1634 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1635 ICMP(id=self.icmp_id_in, type='echo-reply'))
1636 self.pg0.add_stream(pkt)
1637 self.pg_enable_capture(self.pg_interfaces)
1639 capture = self.pg1.get_capture(1)
1640 self.verify_capture_out(capture, same_port=True)
1641 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1643 def test_forwarding(self):
1644 """ NAT44 forwarding test """
1646 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1647 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1649 self.vapi.nat44_forwarding_enable_disable(1)
1651 real_ip = self.pg0.remote_ip4n
1652 alias_ip = self.nat_addr_n
1653 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1654 external_ip=alias_ip)
1657 # static mapping match
1659 pkts = self.create_stream_out(self.pg1)
1660 self.pg1.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1663 capture = self.pg0.get_capture(len(pkts))
1664 self.verify_capture_in(capture, self.pg0)
1666 pkts = self.create_stream_in(self.pg0, self.pg1)
1667 self.pg0.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1670 capture = self.pg1.get_capture(len(pkts))
1671 self.verify_capture_out(capture, same_port=True)
1673 # no static mapping match
1675 host0 = self.pg0.remote_hosts[0]
1676 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1678 pkts = self.create_stream_out(self.pg1,
1679 dst_ip=self.pg0.remote_ip4,
1680 use_inside_ports=True)
1681 self.pg1.add_stream(pkts)
1682 self.pg_enable_capture(self.pg_interfaces)
1684 capture = self.pg0.get_capture(len(pkts))
1685 self.verify_capture_in(capture, self.pg0)
1687 pkts = self.create_stream_in(self.pg0, self.pg1)
1688 self.pg0.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1691 capture = self.pg1.get_capture(len(pkts))
1692 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1695 self.pg0.remote_hosts[0] = host0
1698 self.vapi.nat44_forwarding_enable_disable(0)
1699 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1700 external_ip=alias_ip,
1703 def test_static_in(self):
1704 """ 1:1 NAT initialized from inside network """
1706 nat_ip = "10.0.0.10"
1707 self.tcp_port_out = 6303
1708 self.udp_port_out = 6304
1709 self.icmp_id_out = 6305
1711 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1712 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1713 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1715 sm = self.vapi.nat44_static_mapping_dump()
1716 self.assertEqual(len(sm), 1)
1717 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1718 self.assertEqual(sm[0].protocol, 0)
1719 self.assertEqual(sm[0].local_port, 0)
1720 self.assertEqual(sm[0].external_port, 0)
1723 pkts = self.create_stream_in(self.pg0, self.pg1)
1724 self.pg0.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1727 capture = self.pg1.get_capture(len(pkts))
1728 self.verify_capture_out(capture, nat_ip, True)
1731 pkts = self.create_stream_out(self.pg1, nat_ip)
1732 self.pg1.add_stream(pkts)
1733 self.pg_enable_capture(self.pg_interfaces)
1735 capture = self.pg0.get_capture(len(pkts))
1736 self.verify_capture_in(capture, self.pg0)
1738 def test_static_out(self):
1739 """ 1:1 NAT initialized from outside network """
1741 nat_ip = "10.0.0.20"
1742 self.tcp_port_out = 6303
1743 self.udp_port_out = 6304
1744 self.icmp_id_out = 6305
1747 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1748 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1749 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1751 sm = self.vapi.nat44_static_mapping_dump()
1752 self.assertEqual(len(sm), 1)
1753 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1756 pkts = self.create_stream_out(self.pg1, nat_ip)
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg0.get_capture(len(pkts))
1761 self.verify_capture_in(capture, self.pg0)
1764 pkts = self.create_stream_in(self.pg0, self.pg1)
1765 self.pg0.add_stream(pkts)
1766 self.pg_enable_capture(self.pg_interfaces)
1768 capture = self.pg1.get_capture(len(pkts))
1769 self.verify_capture_out(capture, nat_ip, True)
1771 def test_static_with_port_in(self):
1772 """ 1:1 NAPT initialized from inside network """
1774 self.tcp_port_out = 3606
1775 self.udp_port_out = 3607
1776 self.icmp_id_out = 3608
1778 self.nat44_add_address(self.nat_addr)
1779 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1780 self.tcp_port_in, self.tcp_port_out,
1781 proto=IP_PROTOS.tcp)
1782 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1783 self.udp_port_in, self.udp_port_out,
1784 proto=IP_PROTOS.udp)
1785 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1786 self.icmp_id_in, self.icmp_id_out,
1787 proto=IP_PROTOS.icmp)
1788 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1789 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1793 pkts = self.create_stream_in(self.pg0, self.pg1)
1794 self.pg0.add_stream(pkts)
1795 self.pg_enable_capture(self.pg_interfaces)
1797 capture = self.pg1.get_capture(len(pkts))
1798 self.verify_capture_out(capture)
1801 pkts = self.create_stream_out(self.pg1)
1802 self.pg1.add_stream(pkts)
1803 self.pg_enable_capture(self.pg_interfaces)
1805 capture = self.pg0.get_capture(len(pkts))
1806 self.verify_capture_in(capture, self.pg0)
1808 def test_static_with_port_out(self):
1809 """ 1:1 NAPT initialized from outside network """
1811 self.tcp_port_out = 30606
1812 self.udp_port_out = 30607
1813 self.icmp_id_out = 30608
1815 self.nat44_add_address(self.nat_addr)
1816 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1817 self.tcp_port_in, self.tcp_port_out,
1818 proto=IP_PROTOS.tcp)
1819 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1820 self.udp_port_in, self.udp_port_out,
1821 proto=IP_PROTOS.udp)
1822 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1823 self.icmp_id_in, self.icmp_id_out,
1824 proto=IP_PROTOS.icmp)
1825 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1826 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1838 pkts = self.create_stream_in(self.pg0, self.pg1)
1839 self.pg0.add_stream(pkts)
1840 self.pg_enable_capture(self.pg_interfaces)
1842 capture = self.pg1.get_capture(len(pkts))
1843 self.verify_capture_out(capture)
1845 def test_static_vrf_aware(self):
1846 """ 1:1 NAT VRF awareness """
1848 nat_ip1 = "10.0.0.30"
1849 nat_ip2 = "10.0.0.40"
1850 self.tcp_port_out = 6303
1851 self.udp_port_out = 6304
1852 self.icmp_id_out = 6305
1854 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1856 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1858 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1861 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1863 # inside interface VRF match NAT44 static mapping VRF
1864 pkts = self.create_stream_in(self.pg4, self.pg3)
1865 self.pg4.add_stream(pkts)
1866 self.pg_enable_capture(self.pg_interfaces)
1868 capture = self.pg3.get_capture(len(pkts))
1869 self.verify_capture_out(capture, nat_ip1, True)
1871 # inside interface VRF don't match NAT44 static mapping VRF (packets
1873 pkts = self.create_stream_in(self.pg0, self.pg3)
1874 self.pg0.add_stream(pkts)
1875 self.pg_enable_capture(self.pg_interfaces)
1877 self.pg3.assert_nothing_captured()
1879 def test_dynamic_to_static(self):
1880 """ Switch from dynamic translation to 1:1NAT """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_address(self.nat_addr)
1887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg1.get_capture(len(pkts))
1897 self.verify_capture_out(capture)
1900 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1902 self.assertEqual(len(sessions), 0)
1903 pkts = self.create_stream_in(self.pg0, self.pg1)
1904 self.pg0.add_stream(pkts)
1905 self.pg_enable_capture(self.pg_interfaces)
1907 capture = self.pg1.get_capture(len(pkts))
1908 self.verify_capture_out(capture, nat_ip, True)
1910 def test_identity_nat(self):
1911 """ Identity NAT """
1913 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1915 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1918 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1919 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1920 TCP(sport=12345, dport=56789))
1921 self.pg1.add_stream(p)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg0.get_capture(1)
1929 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1930 self.assertEqual(ip.src, self.pg1.remote_ip4)
1931 self.assertEqual(tcp.dport, 56789)
1932 self.assertEqual(tcp.sport, 12345)
1933 self.assert_packet_checksums_valid(p)
1935 self.logger.error(ppp("Unexpected or invalid packet:", p))
1938 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1939 self.assertEqual(len(sessions), 0)
1940 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
1942 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1943 self.assertEqual(len(identity_mappings), 2)
1945 def test_multiple_inside_interfaces(self):
1946 """ NAT44 multiple non-overlapping address space inside interfaces """
1948 self.nat44_add_address(self.nat_addr)
1949 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1950 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1951 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1954 # between two NAT44 inside interfaces (no translation)
1955 pkts = self.create_stream_in(self.pg0, self.pg1)
1956 self.pg0.add_stream(pkts)
1957 self.pg_enable_capture(self.pg_interfaces)
1959 capture = self.pg1.get_capture(len(pkts))
1960 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1962 # from NAT44 inside to interface without NAT44 feature (no translation)
1963 pkts = self.create_stream_in(self.pg0, self.pg2)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 capture = self.pg2.get_capture(len(pkts))
1968 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1970 # in2out 1st interface
1971 pkts = self.create_stream_in(self.pg0, self.pg3)
1972 self.pg0.add_stream(pkts)
1973 self.pg_enable_capture(self.pg_interfaces)
1975 capture = self.pg3.get_capture(len(pkts))
1976 self.verify_capture_out(capture)
1978 # out2in 1st interface
1979 pkts = self.create_stream_out(self.pg3)
1980 self.pg3.add_stream(pkts)
1981 self.pg_enable_capture(self.pg_interfaces)
1983 capture = self.pg0.get_capture(len(pkts))
1984 self.verify_capture_in(capture, self.pg0)
1986 # in2out 2nd interface
1987 pkts = self.create_stream_in(self.pg1, self.pg3)
1988 self.pg1.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1991 capture = self.pg3.get_capture(len(pkts))
1992 self.verify_capture_out(capture)
1994 # out2in 2nd interface
1995 pkts = self.create_stream_out(self.pg3)
1996 self.pg3.add_stream(pkts)
1997 self.pg_enable_capture(self.pg_interfaces)
1999 capture = self.pg1.get_capture(len(pkts))
2000 self.verify_capture_in(capture, self.pg1)
2002 def test_inside_overlapping_interfaces(self):
2003 """ NAT44 multiple inside interfaces with overlapping address space """
2005 static_nat_ip = "10.0.0.10"
2006 self.nat44_add_address(self.nat_addr)
2007 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2009 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2010 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2011 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2012 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2015 # between NAT44 inside interfaces with same VRF (no translation)
2016 pkts = self.create_stream_in(self.pg4, self.pg5)
2017 self.pg4.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2020 capture = self.pg5.get_capture(len(pkts))
2021 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2023 # between NAT44 inside interfaces with different VRF (hairpinning)
2024 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2025 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2026 TCP(sport=1234, dport=5678))
2027 self.pg4.add_stream(p)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg6.get_capture(1)
2035 self.assertEqual(ip.src, self.nat_addr)
2036 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2037 self.assertNotEqual(tcp.sport, 1234)
2038 self.assertEqual(tcp.dport, 5678)
2040 self.logger.error(ppp("Unexpected or invalid packet:", p))
2043 # in2out 1st interface
2044 pkts = self.create_stream_in(self.pg4, self.pg3)
2045 self.pg4.add_stream(pkts)
2046 self.pg_enable_capture(self.pg_interfaces)
2048 capture = self.pg3.get_capture(len(pkts))
2049 self.verify_capture_out(capture)
2051 # out2in 1st interface
2052 pkts = self.create_stream_out(self.pg3)
2053 self.pg3.add_stream(pkts)
2054 self.pg_enable_capture(self.pg_interfaces)
2056 capture = self.pg4.get_capture(len(pkts))
2057 self.verify_capture_in(capture, self.pg4)
2059 # in2out 2nd interface
2060 pkts = self.create_stream_in(self.pg5, self.pg3)
2061 self.pg5.add_stream(pkts)
2062 self.pg_enable_capture(self.pg_interfaces)
2064 capture = self.pg3.get_capture(len(pkts))
2065 self.verify_capture_out(capture)
2067 # out2in 2nd interface
2068 pkts = self.create_stream_out(self.pg3)
2069 self.pg3.add_stream(pkts)
2070 self.pg_enable_capture(self.pg_interfaces)
2072 capture = self.pg5.get_capture(len(pkts))
2073 self.verify_capture_in(capture, self.pg5)
2076 addresses = self.vapi.nat44_address_dump()
2077 self.assertEqual(len(addresses), 1)
2078 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2079 self.assertEqual(len(sessions), 3)
2080 for session in sessions:
2081 self.assertFalse(session.is_static)
2082 self.assertEqual(session.inside_ip_address[0:4],
2083 self.pg5.remote_ip4n)
2084 self.assertEqual(session.outside_ip_address,
2085 addresses[0].ip_address)
2086 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2087 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2088 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2089 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2090 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2091 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2092 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2093 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2094 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2096 # in2out 3rd interface
2097 pkts = self.create_stream_in(self.pg6, self.pg3)
2098 self.pg6.add_stream(pkts)
2099 self.pg_enable_capture(self.pg_interfaces)
2101 capture = self.pg3.get_capture(len(pkts))
2102 self.verify_capture_out(capture, static_nat_ip, True)
2104 # out2in 3rd interface
2105 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2106 self.pg3.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg6.get_capture(len(pkts))
2110 self.verify_capture_in(capture, self.pg6)
2112 # general user and session dump verifications
2113 users = self.vapi.nat44_user_dump()
2114 self.assertTrue(len(users) >= 3)
2115 addresses = self.vapi.nat44_address_dump()
2116 self.assertEqual(len(addresses), 1)
2118 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2120 for session in sessions:
2121 self.assertEqual(user.ip_address, session.inside_ip_address)
2122 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2123 self.assertTrue(session.protocol in
2124 [IP_PROTOS.tcp, IP_PROTOS.udp,
2126 self.assertFalse(session.ext_host_valid)
2129 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2130 self.assertTrue(len(sessions) >= 4)
2131 for session in sessions:
2132 self.assertFalse(session.is_static)
2133 self.assertEqual(session.inside_ip_address[0:4],
2134 self.pg4.remote_ip4n)
2135 self.assertEqual(session.outside_ip_address,
2136 addresses[0].ip_address)
2139 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2140 self.assertTrue(len(sessions) >= 3)
2141 for session in sessions:
2142 self.assertTrue(session.is_static)
2143 self.assertEqual(session.inside_ip_address[0:4],
2144 self.pg6.remote_ip4n)
2145 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2146 map(int, static_nat_ip.split('.')))
2147 self.assertTrue(session.inside_port in
2148 [self.tcp_port_in, self.udp_port_in,
2151 def test_hairpinning(self):
2152 """ NAT44 hairpinning - 1:1 NAPT """
2154 host = self.pg0.remote_hosts[0]
2155 server = self.pg0.remote_hosts[1]
2158 server_in_port = 5678
2159 server_out_port = 8765
2161 self.nat44_add_address(self.nat_addr)
2162 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2163 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2165 # add static mapping for server
2166 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2167 server_in_port, server_out_port,
2168 proto=IP_PROTOS.tcp)
2170 # send packet from host to server
2171 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2172 IP(src=host.ip4, dst=self.nat_addr) /
2173 TCP(sport=host_in_port, dport=server_out_port))
2174 self.pg0.add_stream(p)
2175 self.pg_enable_capture(self.pg_interfaces)
2177 capture = self.pg0.get_capture(1)
2182 self.assertEqual(ip.src, self.nat_addr)
2183 self.assertEqual(ip.dst, server.ip4)
2184 self.assertNotEqual(tcp.sport, host_in_port)
2185 self.assertEqual(tcp.dport, server_in_port)
2186 self.assert_packet_checksums_valid(p)
2187 host_out_port = tcp.sport
2189 self.logger.error(ppp("Unexpected or invalid packet:", p))
2192 # send reply from server to host
2193 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2194 IP(src=server.ip4, dst=self.nat_addr) /
2195 TCP(sport=server_in_port, dport=host_out_port))
2196 self.pg0.add_stream(p)
2197 self.pg_enable_capture(self.pg_interfaces)
2199 capture = self.pg0.get_capture(1)
2204 self.assertEqual(ip.src, self.nat_addr)
2205 self.assertEqual(ip.dst, host.ip4)
2206 self.assertEqual(tcp.sport, server_out_port)
2207 self.assertEqual(tcp.dport, host_in_port)
2208 self.assert_packet_checksums_valid(p)
2210 self.logger.error(ppp("Unexpected or invalid packet:", p))
2213 def test_hairpinning2(self):
2214 """ NAT44 hairpinning - 1:1 NAT"""
2216 server1_nat_ip = "10.0.0.10"
2217 server2_nat_ip = "10.0.0.11"
2218 host = self.pg0.remote_hosts[0]
2219 server1 = self.pg0.remote_hosts[1]
2220 server2 = self.pg0.remote_hosts[2]
2221 server_tcp_port = 22
2222 server_udp_port = 20
2224 self.nat44_add_address(self.nat_addr)
2225 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2226 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2229 # add static mapping for servers
2230 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2231 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2235 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2236 IP(src=host.ip4, dst=server1_nat_ip) /
2237 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2240 IP(src=host.ip4, dst=server1_nat_ip) /
2241 UDP(sport=self.udp_port_in, dport=server_udp_port))
2243 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2244 IP(src=host.ip4, dst=server1_nat_ip) /
2245 ICMP(id=self.icmp_id_in, type='echo-request'))
2247 self.pg0.add_stream(pkts)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg0.get_capture(len(pkts))
2251 for packet in capture:
2253 self.assertEqual(packet[IP].src, self.nat_addr)
2254 self.assertEqual(packet[IP].dst, server1.ip4)
2255 if packet.haslayer(TCP):
2256 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2257 self.assertEqual(packet[TCP].dport, server_tcp_port)
2258 self.tcp_port_out = packet[TCP].sport
2259 self.assert_packet_checksums_valid(packet)
2260 elif packet.haslayer(UDP):
2261 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2262 self.assertEqual(packet[UDP].dport, server_udp_port)
2263 self.udp_port_out = packet[UDP].sport
2265 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2266 self.icmp_id_out = packet[ICMP].id
2268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2274 IP(src=server1.ip4, dst=self.nat_addr) /
2275 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2278 IP(src=server1.ip4, dst=self.nat_addr) /
2279 UDP(sport=server_udp_port, dport=self.udp_port_out))
2281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2282 IP(src=server1.ip4, dst=self.nat_addr) /
2283 ICMP(id=self.icmp_id_out, type='echo-reply'))
2285 self.pg0.add_stream(pkts)
2286 self.pg_enable_capture(self.pg_interfaces)
2288 capture = self.pg0.get_capture(len(pkts))
2289 for packet in capture:
2291 self.assertEqual(packet[IP].src, server1_nat_ip)
2292 self.assertEqual(packet[IP].dst, host.ip4)
2293 if packet.haslayer(TCP):
2294 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2295 self.assertEqual(packet[TCP].sport, server_tcp_port)
2296 self.assert_packet_checksums_valid(packet)
2297 elif packet.haslayer(UDP):
2298 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2299 self.assertEqual(packet[UDP].sport, server_udp_port)
2301 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2306 # server2 to server1
2308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2309 IP(src=server2.ip4, dst=server1_nat_ip) /
2310 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2313 IP(src=server2.ip4, dst=server1_nat_ip) /
2314 UDP(sport=self.udp_port_in, dport=server_udp_port))
2316 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2317 IP(src=server2.ip4, dst=server1_nat_ip) /
2318 ICMP(id=self.icmp_id_in, type='echo-request'))
2320 self.pg0.add_stream(pkts)
2321 self.pg_enable_capture(self.pg_interfaces)
2323 capture = self.pg0.get_capture(len(pkts))
2324 for packet in capture:
2326 self.assertEqual(packet[IP].src, server2_nat_ip)
2327 self.assertEqual(packet[IP].dst, server1.ip4)
2328 if packet.haslayer(TCP):
2329 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2330 self.assertEqual(packet[TCP].dport, server_tcp_port)
2331 self.tcp_port_out = packet[TCP].sport
2332 self.assert_packet_checksums_valid(packet)
2333 elif packet.haslayer(UDP):
2334 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2335 self.assertEqual(packet[UDP].dport, server_udp_port)
2336 self.udp_port_out = packet[UDP].sport
2338 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2339 self.icmp_id_out = packet[ICMP].id
2341 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2344 # server1 to server2
2346 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2347 IP(src=server1.ip4, dst=server2_nat_ip) /
2348 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2350 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2351 IP(src=server1.ip4, dst=server2_nat_ip) /
2352 UDP(sport=server_udp_port, dport=self.udp_port_out))
2354 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2355 IP(src=server1.ip4, dst=server2_nat_ip) /
2356 ICMP(id=self.icmp_id_out, type='echo-reply'))
2358 self.pg0.add_stream(pkts)
2359 self.pg_enable_capture(self.pg_interfaces)
2361 capture = self.pg0.get_capture(len(pkts))
2362 for packet in capture:
2364 self.assertEqual(packet[IP].src, server1_nat_ip)
2365 self.assertEqual(packet[IP].dst, server2.ip4)
2366 if packet.haslayer(TCP):
2367 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2368 self.assertEqual(packet[TCP].sport, server_tcp_port)
2369 self.assert_packet_checksums_valid(packet)
2370 elif packet.haslayer(UDP):
2371 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2372 self.assertEqual(packet[UDP].sport, server_udp_port)
2374 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2376 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2379 def test_max_translations_per_user(self):
2380 """ MAX translations per user - recycle the least recently used """
2382 self.nat44_add_address(self.nat_addr)
2383 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2384 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2387 # get maximum number of translations per user
2388 nat44_config = self.vapi.nat_show_config()
2390 # send more than maximum number of translations per user packets
2391 pkts_num = nat44_config.max_translations_per_user + 5
2393 for port in range(0, pkts_num):
2394 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2395 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2396 TCP(sport=1025 + port))
2398 self.pg0.add_stream(pkts)
2399 self.pg_enable_capture(self.pg_interfaces)
2402 # verify number of translated packet
2403 self.pg1.get_capture(pkts_num)
2405 users = self.vapi.nat44_user_dump()
2407 if user.ip_address == self.pg0.remote_ip4n:
2408 self.assertEqual(user.nsessions,
2409 nat44_config.max_translations_per_user)
2410 self.assertEqual(user.nstaticsessions, 0)
2413 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2415 proto=IP_PROTOS.tcp)
2416 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2417 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2418 TCP(sport=tcp_port))
2419 self.pg0.add_stream(p)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 self.pg1.get_capture(1)
2423 users = self.vapi.nat44_user_dump()
2425 if user.ip_address == self.pg0.remote_ip4n:
2426 self.assertEqual(user.nsessions,
2427 nat44_config.max_translations_per_user - 1)
2428 self.assertEqual(user.nstaticsessions, 1)
2430 def test_interface_addr(self):
2431 """ Acquire NAT44 addresses from interface """
2432 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2434 # no address in NAT pool
2435 adresses = self.vapi.nat44_address_dump()
2436 self.assertEqual(0, len(adresses))
2438 # configure interface address and check NAT address pool
2439 self.pg7.config_ip4()
2440 adresses = self.vapi.nat44_address_dump()
2441 self.assertEqual(1, len(adresses))
2442 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2444 # remove interface address and check NAT address pool
2445 self.pg7.unconfig_ip4()
2446 adresses = self.vapi.nat44_address_dump()
2447 self.assertEqual(0, len(adresses))
2449 def test_interface_addr_static_mapping(self):
2450 """ Static mapping with addresses from interface """
2453 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2454 self.nat44_add_static_mapping(
2456 external_sw_if_index=self.pg7.sw_if_index,
2459 # static mappings with external interface
2460 static_mappings = self.vapi.nat44_static_mapping_dump()
2461 self.assertEqual(1, len(static_mappings))
2462 self.assertEqual(self.pg7.sw_if_index,
2463 static_mappings[0].external_sw_if_index)
2464 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2466 # configure interface address and check static mappings
2467 self.pg7.config_ip4()
2468 static_mappings = self.vapi.nat44_static_mapping_dump()
2469 self.assertEqual(2, len(static_mappings))
2471 for sm in static_mappings:
2472 if sm.external_sw_if_index == 0xFFFFFFFF:
2473 self.assertEqual(sm.external_ip_address[0:4],
2474 self.pg7.local_ip4n)
2475 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2477 self.assertTrue(resolved)
2479 # remove interface address and check static mappings
2480 self.pg7.unconfig_ip4()
2481 static_mappings = self.vapi.nat44_static_mapping_dump()
2482 self.assertEqual(1, len(static_mappings))
2483 self.assertEqual(self.pg7.sw_if_index,
2484 static_mappings[0].external_sw_if_index)
2485 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2487 # configure interface address again and check static mappings
2488 self.pg7.config_ip4()
2489 static_mappings = self.vapi.nat44_static_mapping_dump()
2490 self.assertEqual(2, len(static_mappings))
2492 for sm in static_mappings:
2493 if sm.external_sw_if_index == 0xFFFFFFFF:
2494 self.assertEqual(sm.external_ip_address[0:4],
2495 self.pg7.local_ip4n)
2496 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2498 self.assertTrue(resolved)
2500 # remove static mapping
2501 self.nat44_add_static_mapping(
2503 external_sw_if_index=self.pg7.sw_if_index,
2506 static_mappings = self.vapi.nat44_static_mapping_dump()
2507 self.assertEqual(0, len(static_mappings))
2509 def test_interface_addr_identity_nat(self):
2510 """ Identity NAT with addresses from interface """
2513 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2514 self.vapi.nat44_add_del_identity_mapping(
2515 sw_if_index=self.pg7.sw_if_index,
2517 protocol=IP_PROTOS.tcp,
2520 # identity mappings with external interface
2521 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2522 self.assertEqual(1, len(identity_mappings))
2523 self.assertEqual(self.pg7.sw_if_index,
2524 identity_mappings[0].sw_if_index)
2526 # configure interface address and check identity mappings
2527 self.pg7.config_ip4()
2528 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2530 self.assertEqual(2, len(identity_mappings))
2531 for sm in identity_mappings:
2532 if sm.sw_if_index == 0xFFFFFFFF:
2533 self.assertEqual(identity_mappings[0].ip_address,
2534 self.pg7.local_ip4n)
2535 self.assertEqual(port, identity_mappings[0].port)
2536 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2538 self.assertTrue(resolved)
2540 # remove interface address and check identity mappings
2541 self.pg7.unconfig_ip4()
2542 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2543 self.assertEqual(1, len(identity_mappings))
2544 self.assertEqual(self.pg7.sw_if_index,
2545 identity_mappings[0].sw_if_index)
2547 def test_ipfix_nat44_sess(self):
2548 """ IPFIX logging NAT44 session created/delted """
2549 self.ipfix_domain_id = 10
2550 self.ipfix_src_port = 20202
2551 colector_port = 30303
2552 bind_layers(UDP, IPFIX, dport=30303)
2553 self.nat44_add_address(self.nat_addr)
2554 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2555 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2557 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2558 src_address=self.pg3.local_ip4n,
2560 template_interval=10,
2561 collector_port=colector_port)
2562 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2563 src_port=self.ipfix_src_port)
2565 pkts = self.create_stream_in(self.pg0, self.pg1)
2566 self.pg0.add_stream(pkts)
2567 self.pg_enable_capture(self.pg_interfaces)
2569 capture = self.pg1.get_capture(len(pkts))
2570 self.verify_capture_out(capture)
2571 self.nat44_add_address(self.nat_addr, is_add=0)
2572 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2573 capture = self.pg3.get_capture(9)
2574 ipfix = IPFIXDecoder()
2575 # first load template
2577 self.assertTrue(p.haslayer(IPFIX))
2578 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2579 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2580 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2581 self.assertEqual(p[UDP].dport, colector_port)
2582 self.assertEqual(p[IPFIX].observationDomainID,
2583 self.ipfix_domain_id)
2584 if p.haslayer(Template):
2585 ipfix.add_template(p.getlayer(Template))
2586 # verify events in data set
2588 if p.haslayer(Data):
2589 data = ipfix.decode_data_set(p.getlayer(Set))
2590 self.verify_ipfix_nat44_ses(data)
2592 def test_ipfix_addr_exhausted(self):
2593 """ IPFIX logging NAT addresses exhausted """
2594 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2595 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2597 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2598 src_address=self.pg3.local_ip4n,
2600 template_interval=10)
2601 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2602 src_port=self.ipfix_src_port)
2604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2605 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2607 self.pg0.add_stream(p)
2608 self.pg_enable_capture(self.pg_interfaces)
2610 self.pg1.assert_nothing_captured()
2612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2613 capture = self.pg3.get_capture(9)
2614 ipfix = IPFIXDecoder()
2615 # first load template
2617 self.assertTrue(p.haslayer(IPFIX))
2618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2621 self.assertEqual(p[UDP].dport, 4739)
2622 self.assertEqual(p[IPFIX].observationDomainID,
2623 self.ipfix_domain_id)
2624 if p.haslayer(Template):
2625 ipfix.add_template(p.getlayer(Template))
2626 # verify events in data set
2628 if p.haslayer(Data):
2629 data = ipfix.decode_data_set(p.getlayer(Set))
2630 self.verify_ipfix_addr_exhausted(data)
2632 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2633 def test_ipfix_max_sessions(self):
2634 """ IPFIX logging maximum session entries exceeded """
2635 self.nat44_add_address(self.nat_addr)
2636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2640 nat44_config = self.vapi.nat_show_config()
2641 max_sessions = 10 * nat44_config.translation_buckets
2644 for i in range(0, max_sessions):
2645 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2647 IP(src=src, dst=self.pg1.remote_ip4) /
2650 self.pg0.add_stream(pkts)
2651 self.pg_enable_capture(self.pg_interfaces)
2654 self.pg1.get_capture(max_sessions)
2655 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2656 src_address=self.pg3.local_ip4n,
2658 template_interval=10)
2659 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2660 src_port=self.ipfix_src_port)
2662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2663 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2665 self.pg0.add_stream(p)
2666 self.pg_enable_capture(self.pg_interfaces)
2668 self.pg1.assert_nothing_captured()
2670 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2671 capture = self.pg3.get_capture(9)
2672 ipfix = IPFIXDecoder()
2673 # first load template
2675 self.assertTrue(p.haslayer(IPFIX))
2676 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2677 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2678 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2679 self.assertEqual(p[UDP].dport, 4739)
2680 self.assertEqual(p[IPFIX].observationDomainID,
2681 self.ipfix_domain_id)
2682 if p.haslayer(Template):
2683 ipfix.add_template(p.getlayer(Template))
2684 # verify events in data set
2686 if p.haslayer(Data):
2687 data = ipfix.decode_data_set(p.getlayer(Set))
2688 self.verify_ipfix_max_sessions(data, max_sessions)
2690 def test_pool_addr_fib(self):
2691 """ NAT44 add pool addresses to FIB """
2692 static_addr = '10.0.0.10'
2693 self.nat44_add_address(self.nat_addr)
2694 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2695 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2697 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2700 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2701 ARP(op=ARP.who_has, pdst=self.nat_addr,
2702 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2703 self.pg1.add_stream(p)
2704 self.pg_enable_capture(self.pg_interfaces)
2706 capture = self.pg1.get_capture(1)
2707 self.assertTrue(capture[0].haslayer(ARP))
2708 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2711 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2712 ARP(op=ARP.who_has, pdst=static_addr,
2713 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2714 self.pg1.add_stream(p)
2715 self.pg_enable_capture(self.pg_interfaces)
2717 capture = self.pg1.get_capture(1)
2718 self.assertTrue(capture[0].haslayer(ARP))
2719 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2721 # send ARP to non-NAT44 interface
2722 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2723 ARP(op=ARP.who_has, pdst=self.nat_addr,
2724 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2725 self.pg2.add_stream(p)
2726 self.pg_enable_capture(self.pg_interfaces)
2728 self.pg1.assert_nothing_captured()
2730 # remove addresses and verify
2731 self.nat44_add_address(self.nat_addr, is_add=0)
2732 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2735 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2736 ARP(op=ARP.who_has, pdst=self.nat_addr,
2737 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2738 self.pg1.add_stream(p)
2739 self.pg_enable_capture(self.pg_interfaces)
2741 self.pg1.assert_nothing_captured()
2743 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2744 ARP(op=ARP.who_has, pdst=static_addr,
2745 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2746 self.pg1.add_stream(p)
2747 self.pg_enable_capture(self.pg_interfaces)
2749 self.pg1.assert_nothing_captured()
2751 def test_vrf_mode(self):
2752 """ NAT44 tenant VRF aware address pool mode """
2756 nat_ip1 = "10.0.0.10"
2757 nat_ip2 = "10.0.0.11"
2759 self.pg0.unconfig_ip4()
2760 self.pg1.unconfig_ip4()
2761 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2762 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2763 self.pg0.set_table_ip4(vrf_id1)
2764 self.pg1.set_table_ip4(vrf_id2)
2765 self.pg0.config_ip4()
2766 self.pg1.config_ip4()
2767 self.pg0.resolve_arp()
2768 self.pg1.resolve_arp()
2770 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2771 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2772 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2773 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2774 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2779 pkts = self.create_stream_in(self.pg0, self.pg2)
2780 self.pg0.add_stream(pkts)
2781 self.pg_enable_capture(self.pg_interfaces)
2783 capture = self.pg2.get_capture(len(pkts))
2784 self.verify_capture_out(capture, nat_ip1)
2787 pkts = self.create_stream_in(self.pg1, self.pg2)
2788 self.pg1.add_stream(pkts)
2789 self.pg_enable_capture(self.pg_interfaces)
2791 capture = self.pg2.get_capture(len(pkts))
2792 self.verify_capture_out(capture, nat_ip2)
2795 self.pg0.unconfig_ip4()
2796 self.pg1.unconfig_ip4()
2797 self.pg0.set_table_ip4(0)
2798 self.pg1.set_table_ip4(0)
2799 self.pg0.config_ip4()
2800 self.pg1.config_ip4()
2801 self.pg0.resolve_arp()
2802 self.pg1.resolve_arp()
2803 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2804 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2806 def test_vrf_feature_independent(self):
2807 """ NAT44 tenant VRF independent address pool mode """
2809 nat_ip1 = "10.0.0.10"
2810 nat_ip2 = "10.0.0.11"
2812 self.nat44_add_address(nat_ip1)
2813 self.nat44_add_address(nat_ip2, vrf_id=99)
2814 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2815 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2816 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2820 pkts = self.create_stream_in(self.pg0, self.pg2)
2821 self.pg0.add_stream(pkts)
2822 self.pg_enable_capture(self.pg_interfaces)
2824 capture = self.pg2.get_capture(len(pkts))
2825 self.verify_capture_out(capture, nat_ip1)
2828 pkts = self.create_stream_in(self.pg1, self.pg2)
2829 self.pg1.add_stream(pkts)
2830 self.pg_enable_capture(self.pg_interfaces)
2832 capture = self.pg2.get_capture(len(pkts))
2833 self.verify_capture_out(capture, nat_ip1)
2835 def test_dynamic_ipless_interfaces(self):
2836 """ NAT44 interfaces without configured IP address """
2838 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2839 mactobinary(self.pg7.remote_mac),
2840 self.pg7.remote_ip4n,
2842 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2843 mactobinary(self.pg8.remote_mac),
2844 self.pg8.remote_ip4n,
2847 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2848 dst_address_length=32,
2849 next_hop_address=self.pg7.remote_ip4n,
2850 next_hop_sw_if_index=self.pg7.sw_if_index)
2851 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2852 dst_address_length=32,
2853 next_hop_address=self.pg8.remote_ip4n,
2854 next_hop_sw_if_index=self.pg8.sw_if_index)
2856 self.nat44_add_address(self.nat_addr)
2857 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2858 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2862 pkts = self.create_stream_in(self.pg7, self.pg8)
2863 self.pg7.add_stream(pkts)
2864 self.pg_enable_capture(self.pg_interfaces)
2866 capture = self.pg8.get_capture(len(pkts))
2867 self.verify_capture_out(capture)
2870 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2871 self.pg8.add_stream(pkts)
2872 self.pg_enable_capture(self.pg_interfaces)
2874 capture = self.pg7.get_capture(len(pkts))
2875 self.verify_capture_in(capture, self.pg7)
2877 def test_static_ipless_interfaces(self):
2878 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2880 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2881 mactobinary(self.pg7.remote_mac),
2882 self.pg7.remote_ip4n,
2884 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2885 mactobinary(self.pg8.remote_mac),
2886 self.pg8.remote_ip4n,
2889 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2890 dst_address_length=32,
2891 next_hop_address=self.pg7.remote_ip4n,
2892 next_hop_sw_if_index=self.pg7.sw_if_index)
2893 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2894 dst_address_length=32,
2895 next_hop_address=self.pg8.remote_ip4n,
2896 next_hop_sw_if_index=self.pg8.sw_if_index)
2898 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2899 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2900 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2904 pkts = self.create_stream_out(self.pg8)
2905 self.pg8.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2908 capture = self.pg7.get_capture(len(pkts))
2909 self.verify_capture_in(capture, self.pg7)
2912 pkts = self.create_stream_in(self.pg7, self.pg8)
2913 self.pg7.add_stream(pkts)
2914 self.pg_enable_capture(self.pg_interfaces)
2916 capture = self.pg8.get_capture(len(pkts))
2917 self.verify_capture_out(capture, self.nat_addr, True)
2919 def test_static_with_port_ipless_interfaces(self):
2920 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2922 self.tcp_port_out = 30606
2923 self.udp_port_out = 30607
2924 self.icmp_id_out = 30608
2926 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2927 mactobinary(self.pg7.remote_mac),
2928 self.pg7.remote_ip4n,
2930 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2931 mactobinary(self.pg8.remote_mac),
2932 self.pg8.remote_ip4n,
2935 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2936 dst_address_length=32,
2937 next_hop_address=self.pg7.remote_ip4n,
2938 next_hop_sw_if_index=self.pg7.sw_if_index)
2939 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2940 dst_address_length=32,
2941 next_hop_address=self.pg8.remote_ip4n,
2942 next_hop_sw_if_index=self.pg8.sw_if_index)
2944 self.nat44_add_address(self.nat_addr)
2945 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2946 self.tcp_port_in, self.tcp_port_out,
2947 proto=IP_PROTOS.tcp)
2948 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2949 self.udp_port_in, self.udp_port_out,
2950 proto=IP_PROTOS.udp)
2951 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2952 self.icmp_id_in, self.icmp_id_out,
2953 proto=IP_PROTOS.icmp)
2954 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2955 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2959 pkts = self.create_stream_out(self.pg8)
2960 self.pg8.add_stream(pkts)
2961 self.pg_enable_capture(self.pg_interfaces)
2963 capture = self.pg7.get_capture(len(pkts))
2964 self.verify_capture_in(capture, self.pg7)
2967 pkts = self.create_stream_in(self.pg7, self.pg8)
2968 self.pg7.add_stream(pkts)
2969 self.pg_enable_capture(self.pg_interfaces)
2971 capture = self.pg8.get_capture(len(pkts))
2972 self.verify_capture_out(capture)
2974 def test_static_unknown_proto(self):
2975 """ 1:1 NAT translate packet with unknown protocol """
2976 nat_ip = "10.0.0.10"
2977 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2979 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2983 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2986 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2987 TCP(sport=1234, dport=1234))
2988 self.pg0.add_stream(p)
2989 self.pg_enable_capture(self.pg_interfaces)
2991 p = self.pg1.get_capture(1)
2994 self.assertEqual(packet[IP].src, nat_ip)
2995 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2996 self.assertTrue(packet.haslayer(GRE))
2997 self.assert_packet_checksums_valid(packet)
2999 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3003 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3004 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3006 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3007 TCP(sport=1234, dport=1234))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 p = self.pg0.get_capture(1)
3014 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3015 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3016 self.assertTrue(packet.haslayer(GRE))
3017 self.assert_packet_checksums_valid(packet)
3019 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3022 def test_hairpinning_static_unknown_proto(self):
3023 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3025 host = self.pg0.remote_hosts[0]
3026 server = self.pg0.remote_hosts[1]
3028 host_nat_ip = "10.0.0.10"
3029 server_nat_ip = "10.0.0.11"
3031 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3032 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3033 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3034 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3038 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3039 IP(src=host.ip4, dst=server_nat_ip) /
3041 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3042 TCP(sport=1234, dport=1234))
3043 self.pg0.add_stream(p)
3044 self.pg_enable_capture(self.pg_interfaces)
3046 p = self.pg0.get_capture(1)
3049 self.assertEqual(packet[IP].src, host_nat_ip)
3050 self.assertEqual(packet[IP].dst, server.ip4)
3051 self.assertTrue(packet.haslayer(GRE))
3052 self.assert_packet_checksums_valid(packet)
3054 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3058 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3059 IP(src=server.ip4, dst=host_nat_ip) /
3061 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3062 TCP(sport=1234, dport=1234))
3063 self.pg0.add_stream(p)
3064 self.pg_enable_capture(self.pg_interfaces)
3066 p = self.pg0.get_capture(1)
3069 self.assertEqual(packet[IP].src, server_nat_ip)
3070 self.assertEqual(packet[IP].dst, host.ip4)
3071 self.assertTrue(packet.haslayer(GRE))
3072 self.assert_packet_checksums_valid(packet)
3074 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3077 def test_output_feature(self):
3078 """ NAT44 interface output feature (in2out postrouting) """
3079 self.nat44_add_address(self.nat_addr)
3080 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3081 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3082 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3086 pkts = self.create_stream_in(self.pg0, self.pg3)
3087 self.pg0.add_stream(pkts)
3088 self.pg_enable_capture(self.pg_interfaces)
3090 capture = self.pg3.get_capture(len(pkts))
3091 self.verify_capture_out(capture)
3094 pkts = self.create_stream_out(self.pg3)
3095 self.pg3.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg0.get_capture(len(pkts))
3099 self.verify_capture_in(capture, self.pg0)
3101 # from non-NAT interface to NAT inside interface
3102 pkts = self.create_stream_in(self.pg2, self.pg0)
3103 self.pg2.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg0.get_capture(len(pkts))
3107 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3109 def test_output_feature_vrf_aware(self):
3110 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3111 nat_ip_vrf10 = "10.0.0.10"
3112 nat_ip_vrf20 = "10.0.0.20"
3114 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3115 dst_address_length=32,
3116 next_hop_address=self.pg3.remote_ip4n,
3117 next_hop_sw_if_index=self.pg3.sw_if_index,
3119 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3120 dst_address_length=32,
3121 next_hop_address=self.pg3.remote_ip4n,
3122 next_hop_sw_if_index=self.pg3.sw_if_index,
3125 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3126 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3127 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3128 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3129 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3133 pkts = self.create_stream_in(self.pg4, self.pg3)
3134 self.pg4.add_stream(pkts)
3135 self.pg_enable_capture(self.pg_interfaces)
3137 capture = self.pg3.get_capture(len(pkts))
3138 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3141 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3142 self.pg3.add_stream(pkts)
3143 self.pg_enable_capture(self.pg_interfaces)
3145 capture = self.pg4.get_capture(len(pkts))
3146 self.verify_capture_in(capture, self.pg4)
3149 pkts = self.create_stream_in(self.pg6, self.pg3)
3150 self.pg6.add_stream(pkts)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 capture = self.pg3.get_capture(len(pkts))
3154 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3157 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3158 self.pg3.add_stream(pkts)
3159 self.pg_enable_capture(self.pg_interfaces)
3161 capture = self.pg6.get_capture(len(pkts))
3162 self.verify_capture_in(capture, self.pg6)
3164 def test_output_feature_hairpinning(self):
3165 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3166 host = self.pg0.remote_hosts[0]
3167 server = self.pg0.remote_hosts[1]
3170 server_in_port = 5678
3171 server_out_port = 8765
3173 self.nat44_add_address(self.nat_addr)
3174 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3175 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3178 # add static mapping for server
3179 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3180 server_in_port, server_out_port,
3181 proto=IP_PROTOS.tcp)
3183 # send packet from host to server
3184 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3185 IP(src=host.ip4, dst=self.nat_addr) /
3186 TCP(sport=host_in_port, dport=server_out_port))
3187 self.pg0.add_stream(p)
3188 self.pg_enable_capture(self.pg_interfaces)
3190 capture = self.pg0.get_capture(1)
3195 self.assertEqual(ip.src, self.nat_addr)
3196 self.assertEqual(ip.dst, server.ip4)
3197 self.assertNotEqual(tcp.sport, host_in_port)
3198 self.assertEqual(tcp.dport, server_in_port)
3199 self.assert_packet_checksums_valid(p)
3200 host_out_port = tcp.sport
3202 self.logger.error(ppp("Unexpected or invalid packet:", p))
3205 # send reply from server to host
3206 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3207 IP(src=server.ip4, dst=self.nat_addr) /
3208 TCP(sport=server_in_port, dport=host_out_port))
3209 self.pg0.add_stream(p)
3210 self.pg_enable_capture(self.pg_interfaces)
3212 capture = self.pg0.get_capture(1)
3217 self.assertEqual(ip.src, self.nat_addr)
3218 self.assertEqual(ip.dst, host.ip4)
3219 self.assertEqual(tcp.sport, server_out_port)
3220 self.assertEqual(tcp.dport, host_in_port)
3221 self.assert_packet_checksums_valid(p)
3223 self.logger.error(ppp("Unexpected or invalid packet:", p))
3226 def test_one_armed_nat44(self):
3227 """ One armed NAT44 """
3228 remote_host = self.pg9.remote_hosts[0]
3229 local_host = self.pg9.remote_hosts[1]
3232 self.nat44_add_address(self.nat_addr)
3233 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3234 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3238 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3239 IP(src=local_host.ip4, dst=remote_host.ip4) /
3240 TCP(sport=12345, dport=80))
3241 self.pg9.add_stream(p)
3242 self.pg_enable_capture(self.pg_interfaces)
3244 capture = self.pg9.get_capture(1)
3249 self.assertEqual(ip.src, self.nat_addr)
3250 self.assertEqual(ip.dst, remote_host.ip4)
3251 self.assertNotEqual(tcp.sport, 12345)
3252 external_port = tcp.sport
3253 self.assertEqual(tcp.dport, 80)
3254 self.assert_packet_checksums_valid(p)
3256 self.logger.error(ppp("Unexpected or invalid packet:", p))
3260 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3261 IP(src=remote_host.ip4, dst=self.nat_addr) /
3262 TCP(sport=80, dport=external_port))
3263 self.pg9.add_stream(p)
3264 self.pg_enable_capture(self.pg_interfaces)
3266 capture = self.pg9.get_capture(1)
3271 self.assertEqual(ip.src, remote_host.ip4)
3272 self.assertEqual(ip.dst, local_host.ip4)
3273 self.assertEqual(tcp.sport, 80)
3274 self.assertEqual(tcp.dport, 12345)
3275 self.assert_packet_checksums_valid(p)
3277 self.logger.error(ppp("Unexpected or invalid packet:", p))
3280 def test_del_session(self):
3281 """ Delete NAT44 session """
3282 self.nat44_add_address(self.nat_addr)
3283 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3284 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3287 pkts = self.create_stream_in(self.pg0, self.pg1)
3288 self.pg0.add_stream(pkts)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 self.pg1.get_capture(len(pkts))
3293 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3294 nsessions = len(sessions)
3296 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3297 sessions[0].inside_port,
3298 sessions[0].protocol)
3299 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3300 sessions[1].outside_port,
3301 sessions[1].protocol,
3304 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3305 self.assertEqual(nsessions - len(sessions), 2)
3307 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3308 sessions[0].inside_port,
3309 sessions[0].protocol)
3311 self.verify_no_nat44_user()
3313 def test_set_get_reass(self):
3314 """ NAT44 set/get virtual fragmentation reassembly """
3315 reas_cfg1 = self.vapi.nat_get_reass()
3317 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3318 max_reass=reas_cfg1.ip4_max_reass * 2,
3319 max_frag=reas_cfg1.ip4_max_frag * 2)
3321 reas_cfg2 = self.vapi.nat_get_reass()
3323 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3324 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3325 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3327 self.vapi.nat_set_reass(drop_frag=1)
3328 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3330 def test_frag_in_order(self):
3331 """ NAT44 translate fragments arriving in order """
3333 self.nat44_add_address(self.nat_addr)
3334 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3335 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3338 self.frag_in_order(proto=IP_PROTOS.tcp)
3339 self.frag_in_order(proto=IP_PROTOS.udp)
3340 self.frag_in_order(proto=IP_PROTOS.icmp)
3342 def test_reass_hairpinning(self):
3343 """ NAT44 fragments hairpinning """
3345 self.server = self.pg0.remote_hosts[1]
3346 self.host_in_port = random.randint(1025, 65535)
3347 self.server_in_port = random.randint(1025, 65535)
3348 self.server_out_port = random.randint(1025, 65535)
3350 self.nat44_add_address(self.nat_addr)
3351 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3352 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3354 # add static mapping for server
3355 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3356 self.server_in_port,
3357 self.server_out_port,
3358 proto=IP_PROTOS.tcp)
3359 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3360 self.server_in_port,
3361 self.server_out_port,
3362 proto=IP_PROTOS.udp)
3363 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3365 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3366 self.reass_hairpinning(proto=IP_PROTOS.udp)
3367 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3369 def test_frag_out_of_order(self):
3370 """ NAT44 translate fragments arriving out of order """
3372 self.nat44_add_address(self.nat_addr)
3373 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3374 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3377 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3378 self.frag_out_of_order(proto=IP_PROTOS.udp)
3379 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3381 def test_port_restricted(self):
3382 """ Port restricted NAT44 (MAP-E CE) """
3383 self.nat44_add_address(self.nat_addr)
3384 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3385 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3387 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3392 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3393 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3394 TCP(sport=4567, dport=22))
3395 self.pg0.add_stream(p)
3396 self.pg_enable_capture(self.pg_interfaces)
3398 capture = self.pg1.get_capture(1)
3403 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3404 self.assertEqual(ip.src, self.nat_addr)
3405 self.assertEqual(tcp.dport, 22)
3406 self.assertNotEqual(tcp.sport, 4567)
3407 self.assertEqual((tcp.sport >> 6) & 63, 10)
3408 self.assert_packet_checksums_valid(p)
3410 self.logger.error(ppp("Unexpected or invalid packet:", p))
3413 def test_port_range(self):
3414 """ External address port range """
3415 self.nat44_add_address(self.nat_addr)
3416 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3417 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3419 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3424 for port in range(0, 5):
3425 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3426 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3427 TCP(sport=1125 + port))
3429 self.pg0.add_stream(pkts)
3430 self.pg_enable_capture(self.pg_interfaces)
3432 capture = self.pg1.get_capture(3)
3435 self.assertGreaterEqual(tcp.sport, 1025)
3436 self.assertLessEqual(tcp.sport, 1027)
3438 def test_ipfix_max_frags(self):
3439 """ IPFIX logging maximum fragments pending reassembly exceeded """
3440 self.nat44_add_address(self.nat_addr)
3441 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3442 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3444 self.vapi.nat_set_reass(max_frag=1)
3445 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3446 src_address=self.pg3.local_ip4n,
3448 template_interval=10)
3449 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3450 src_port=self.ipfix_src_port)
3452 data = "A" * 4 + "B" * 16 + "C" * 3
3453 self.tcp_port_in = random.randint(1025, 65535)
3454 pkts = self.create_stream_frag(self.pg0,
3455 self.pg1.remote_ip4,
3460 self.pg0.add_stream(pkts)
3461 self.pg_enable_capture(self.pg_interfaces)
3463 self.pg1.assert_nothing_captured()
3465 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3466 capture = self.pg3.get_capture(9)
3467 ipfix = IPFIXDecoder()
3468 # first load template
3470 self.assertTrue(p.haslayer(IPFIX))
3471 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3472 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3473 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3474 self.assertEqual(p[UDP].dport, 4739)
3475 self.assertEqual(p[IPFIX].observationDomainID,
3476 self.ipfix_domain_id)
3477 if p.haslayer(Template):
3478 ipfix.add_template(p.getlayer(Template))
3479 # verify events in data set
3481 if p.haslayer(Data):
3482 data = ipfix.decode_data_set(p.getlayer(Set))
3483 self.verify_ipfix_max_fragments_ip4(data, 1,
3484 self.pg0.remote_ip4n)
3486 def test_multiple_outside_vrf(self):
3487 """ Multiple outside VRF """
3491 self.pg1.unconfig_ip4()
3492 self.pg2.unconfig_ip4()
3493 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3494 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3495 self.pg1.set_table_ip4(vrf_id1)
3496 self.pg2.set_table_ip4(vrf_id2)
3497 self.pg1.config_ip4()
3498 self.pg2.config_ip4()
3499 self.pg1.resolve_arp()
3500 self.pg2.resolve_arp()
3502 self.nat44_add_address(self.nat_addr)
3503 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3504 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3506 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3511 pkts = self.create_stream_in(self.pg0, self.pg1)
3512 self.pg0.add_stream(pkts)
3513 self.pg_enable_capture(self.pg_interfaces)
3515 capture = self.pg1.get_capture(len(pkts))
3516 self.verify_capture_out(capture, self.nat_addr)
3518 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3519 self.pg1.add_stream(pkts)
3520 self.pg_enable_capture(self.pg_interfaces)
3522 capture = self.pg0.get_capture(len(pkts))
3523 self.verify_capture_in(capture, self.pg0)
3525 self.tcp_port_in = 60303
3526 self.udp_port_in = 60304
3527 self.icmp_id_in = 60305
3530 pkts = self.create_stream_in(self.pg0, self.pg2)
3531 self.pg0.add_stream(pkts)
3532 self.pg_enable_capture(self.pg_interfaces)
3534 capture = self.pg2.get_capture(len(pkts))
3535 self.verify_capture_out(capture, self.nat_addr)
3537 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3538 self.pg2.add_stream(pkts)
3539 self.pg_enable_capture(self.pg_interfaces)
3541 capture = self.pg0.get_capture(len(pkts))
3542 self.verify_capture_in(capture, self.pg0)
3545 self.pg1.unconfig_ip4()
3546 self.pg2.unconfig_ip4()
3547 self.pg1.set_table_ip4(0)
3548 self.pg2.set_table_ip4(0)
3549 self.pg1.config_ip4()
3550 self.pg2.config_ip4()
3551 self.pg1.resolve_arp()
3552 self.pg2.resolve_arp()
3554 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3555 def test_session_timeout(self):
3556 """ NAT44 session timeouts """
3557 self.nat44_add_address(self.nat_addr)
3558 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3559 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3561 self.vapi.nat_set_timeouts(udp=5)
3565 for i in range(0, max_sessions):
3566 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3567 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3568 IP(src=src, dst=self.pg1.remote_ip4) /
3569 UDP(sport=1025, dport=53))
3571 self.pg0.add_stream(pkts)
3572 self.pg_enable_capture(self.pg_interfaces)
3574 self.pg1.get_capture(max_sessions)
3579 for i in range(0, max_sessions):
3580 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3581 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3582 IP(src=src, dst=self.pg1.remote_ip4) /
3583 UDP(sport=1026, dport=53))
3585 self.pg0.add_stream(pkts)
3586 self.pg_enable_capture(self.pg_interfaces)
3588 self.pg1.get_capture(max_sessions)
3591 users = self.vapi.nat44_user_dump()
3593 nsessions = nsessions + user.nsessions
3594 self.assertLess(nsessions, 2 * max_sessions)
3596 def test_mss_clamping(self):
3597 """ TCP MSS clamping """
3598 self.nat44_add_address(self.nat_addr)
3599 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3600 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3603 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3604 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3605 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3606 flags="S", options=[('MSS', 1400)]))
3608 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3609 self.pg0.add_stream(p)
3610 self.pg_enable_capture(self.pg_interfaces)
3612 capture = self.pg1.get_capture(1)
3613 # Negotiated MSS value greater than configured - changed
3614 self.verify_mss_value(capture[0], 1000)
3616 self.vapi.nat_set_mss_clamping(enable=0)
3617 self.pg0.add_stream(p)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 capture = self.pg1.get_capture(1)
3621 # MSS clamping disabled - negotiated MSS unchanged
3622 self.verify_mss_value(capture[0], 1400)
3624 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3625 self.pg0.add_stream(p)
3626 self.pg_enable_capture(self.pg_interfaces)
3628 capture = self.pg1.get_capture(1)
3629 # Negotiated MSS value smaller than configured - unchanged
3630 self.verify_mss_value(capture[0], 1400)
3633 super(TestNAT44, self).tearDown()
3634 if not self.vpp_dead:
3635 self.logger.info(self.vapi.cli("show nat44 addresses"))
3636 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3637 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3638 self.logger.info(self.vapi.cli("show nat44 interface address"))
3639 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3640 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3641 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3642 self.logger.info(self.vapi.cli("show nat timeouts"))
3644 self.vapi.cli("show nat addr-port-assignment-alg"))
3646 self.vapi.cli("clear logging")
3649 class TestNAT44EndpointDependent(MethodHolder):
3650 """ Endpoint-Dependent mapping and filtering test cases """
3653 def setUpConstants(cls):
3654 super(TestNAT44EndpointDependent, cls).setUpConstants()
3655 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3658 def setUpClass(cls):
3659 super(TestNAT44EndpointDependent, cls).setUpClass()
3660 cls.vapi.cli("set log class nat level debug")
3662 cls.tcp_port_in = 6303
3663 cls.tcp_port_out = 6303
3664 cls.udp_port_in = 6304
3665 cls.udp_port_out = 6304
3666 cls.icmp_id_in = 6305
3667 cls.icmp_id_out = 6305
3668 cls.nat_addr = '10.0.0.3'
3669 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3670 cls.ipfix_src_port = 4739
3671 cls.ipfix_domain_id = 1
3672 cls.tcp_external_port = 80
3674 cls.create_pg_interfaces(range(7))
3675 cls.interfaces = list(cls.pg_interfaces[0:3])
3677 for i in cls.interfaces:
3682 cls.pg0.generate_remote_hosts(3)
3683 cls.pg0.configure_ipv4_neighbors()
3687 cls.pg4.generate_remote_hosts(2)
3688 cls.pg4.config_ip4()
3689 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3690 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3694 cls.pg4.resolve_arp()
3695 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3696 cls.pg4.resolve_arp()
3698 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3699 cls.vapi.ip_table_add_del(1, is_add=1)
3701 cls.pg5._local_ip4 = "10.1.1.1"
3702 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3704 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3705 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3706 socket.AF_INET, cls.pg5.remote_ip4)
3707 cls.pg5.set_table_ip4(1)
3708 cls.pg5.config_ip4()
3710 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3711 dst_address_length=32,
3713 next_hop_sw_if_index=cls.pg5.sw_if_index,
3714 next_hop_address=zero_ip4n)
3716 cls.pg6._local_ip4 = "10.1.2.1"
3717 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3719 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3720 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3721 socket.AF_INET, cls.pg6.remote_ip4)
3722 cls.pg6.set_table_ip4(1)
3723 cls.pg6.config_ip4()
3725 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3726 dst_address_length=32,
3728 next_hop_sw_if_index=cls.pg6.sw_if_index,
3729 next_hop_address=zero_ip4n)
3731 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3732 dst_address_length=16,
3733 next_hop_address=zero_ip4n,
3735 next_hop_table_id=1)
3736 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3737 dst_address_length=0,
3738 next_hop_address=zero_ip4n,
3740 next_hop_table_id=0)
3741 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3742 dst_address_length=0,
3744 next_hop_sw_if_index=cls.pg1.sw_if_index,
3745 next_hop_address=cls.pg1.local_ip4n)
3747 cls.pg5.resolve_arp()
3748 cls.pg6.resolve_arp()
3751 super(TestNAT44EndpointDependent, cls).tearDownClass()
3754 def test_frag_in_order(self):
3755 """ NAT44 translate fragments arriving in order """
3756 self.nat44_add_address(self.nat_addr)
3757 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3758 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3760 self.frag_in_order(proto=IP_PROTOS.tcp)
3761 self.frag_in_order(proto=IP_PROTOS.udp)
3762 self.frag_in_order(proto=IP_PROTOS.icmp)
3764 def test_frag_in_order_dont_translate(self):
3765 """ NAT44 don't translate fragments arriving in order """
3766 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3767 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3769 self.vapi.nat44_forwarding_enable_disable(enable=True)
3770 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3772 def test_frag_out_of_order(self):
3773 """ NAT44 translate fragments arriving out of order """
3774 self.nat44_add_address(self.nat_addr)
3775 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3776 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3778 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3779 self.frag_out_of_order(proto=IP_PROTOS.udp)
3780 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3782 def test_frag_out_of_order_dont_translate(self):
3783 """ NAT44 don't translate fragments arriving out of order """
3784 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3785 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3787 self.vapi.nat44_forwarding_enable_disable(enable=True)
3788 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3790 def test_frag_in_order_in_plus_out(self):
3791 """ in+out interface fragments in order """
3792 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3793 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3795 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3796 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3799 self.server = self.pg1.remote_hosts[0]
3801 self.server_in_addr = self.server.ip4
3802 self.server_out_addr = '11.11.11.11'
3803 self.server_in_port = random.randint(1025, 65535)
3804 self.server_out_port = random.randint(1025, 65535)
3806 self.nat44_add_address(self.server_out_addr)
3808 # add static mappings for server
3809 self.nat44_add_static_mapping(self.server_in_addr,
3810 self.server_out_addr,
3811 self.server_in_port,
3812 self.server_out_port,
3813 proto=IP_PROTOS.tcp)
3814 self.nat44_add_static_mapping(self.server_in_addr,
3815 self.server_out_addr,
3816 self.server_in_port,
3817 self.server_out_port,
3818 proto=IP_PROTOS.udp)
3819 self.nat44_add_static_mapping(self.server_in_addr,
3820 self.server_out_addr,
3821 proto=IP_PROTOS.icmp)
3823 self.vapi.nat_set_reass(timeout=10)
3825 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3826 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3827 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3829 def test_frag_out_of_order_in_plus_out(self):
3830 """ in+out interface fragments out of order """
3831 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3832 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3834 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3835 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3838 self.server = self.pg1.remote_hosts[0]
3840 self.server_in_addr = self.server.ip4
3841 self.server_out_addr = '11.11.11.11'
3842 self.server_in_port = random.randint(1025, 65535)
3843 self.server_out_port = random.randint(1025, 65535)
3845 self.nat44_add_address(self.server_out_addr)
3847 # add static mappings for server
3848 self.nat44_add_static_mapping(self.server_in_addr,
3849 self.server_out_addr,
3850 self.server_in_port,
3851 self.server_out_port,
3852 proto=IP_PROTOS.tcp)
3853 self.nat44_add_static_mapping(self.server_in_addr,
3854 self.server_out_addr,
3855 self.server_in_port,
3856 self.server_out_port,
3857 proto=IP_PROTOS.udp)
3858 self.nat44_add_static_mapping(self.server_in_addr,
3859 self.server_out_addr,
3860 proto=IP_PROTOS.icmp)
3862 self.vapi.nat_set_reass(timeout=10)
3864 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3865 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3866 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3868 def test_reass_hairpinning(self):
3869 """ NAT44 fragments hairpinning """
3870 self.server = self.pg0.remote_hosts[1]
3871 self.host_in_port = random.randint(1025, 65535)
3872 self.server_in_port = random.randint(1025, 65535)
3873 self.server_out_port = random.randint(1025, 65535)
3875 self.nat44_add_address(self.nat_addr)
3876 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3877 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3879 # add static mapping for server
3880 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3881 self.server_in_port,
3882 self.server_out_port,
3883 proto=IP_PROTOS.tcp)
3884 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3885 self.server_in_port,
3886 self.server_out_port,
3887 proto=IP_PROTOS.udp)
3888 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3890 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3891 self.reass_hairpinning(proto=IP_PROTOS.udp)
3892 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3894 def test_dynamic(self):
3895 """ NAT44 dynamic translation test """
3897 self.nat44_add_address(self.nat_addr)
3898 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3899 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3902 nat_config = self.vapi.nat_show_config()
3903 self.assertEqual(1, nat_config.endpoint_dependent)
3906 pkts = self.create_stream_in(self.pg0, self.pg1)
3907 self.pg0.add_stream(pkts)
3908 self.pg_enable_capture(self.pg_interfaces)
3910 capture = self.pg1.get_capture(len(pkts))
3911 self.verify_capture_out(capture)
3914 pkts = self.create_stream_out(self.pg1)
3915 self.pg1.add_stream(pkts)
3916 self.pg_enable_capture(self.pg_interfaces)
3918 capture = self.pg0.get_capture(len(pkts))
3919 self.verify_capture_in(capture, self.pg0)
3921 def test_forwarding(self):
3922 """ NAT44 forwarding test """
3924 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3925 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3927 self.vapi.nat44_forwarding_enable_disable(1)
3929 real_ip = self.pg0.remote_ip4n
3930 alias_ip = self.nat_addr_n
3931 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3932 external_ip=alias_ip)
3935 # in2out - static mapping match
3937 pkts = self.create_stream_out(self.pg1)
3938 self.pg1.add_stream(pkts)
3939 self.pg_enable_capture(self.pg_interfaces)
3941 capture = self.pg0.get_capture(len(pkts))
3942 self.verify_capture_in(capture, self.pg0)
3944 pkts = self.create_stream_in(self.pg0, self.pg1)
3945 self.pg0.add_stream(pkts)
3946 self.pg_enable_capture(self.pg_interfaces)
3948 capture = self.pg1.get_capture(len(pkts))
3949 self.verify_capture_out(capture, same_port=True)
3951 # in2out - no static mapping match
3953 host0 = self.pg0.remote_hosts[0]
3954 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3956 pkts = self.create_stream_out(self.pg1,
3957 dst_ip=self.pg0.remote_ip4,
3958 use_inside_ports=True)
3959 self.pg1.add_stream(pkts)
3960 self.pg_enable_capture(self.pg_interfaces)
3962 capture = self.pg0.get_capture(len(pkts))
3963 self.verify_capture_in(capture, self.pg0)
3965 pkts = self.create_stream_in(self.pg0, self.pg1)
3966 self.pg0.add_stream(pkts)
3967 self.pg_enable_capture(self.pg_interfaces)
3969 capture = self.pg1.get_capture(len(pkts))
3970 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3973 self.pg0.remote_hosts[0] = host0
3975 user = self.pg0.remote_hosts[1]
3976 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3977 self.assertEqual(len(sessions), 3)
3978 self.assertTrue(sessions[0].ext_host_valid)
3979 self.vapi.nat44_del_session(
3980 sessions[0].inside_ip_address,
3981 sessions[0].inside_port,
3982 sessions[0].protocol,
3983 ext_host_address=sessions[0].ext_host_address,
3984 ext_host_port=sessions[0].ext_host_port)
3985 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3986 self.assertEqual(len(sessions), 2)
3989 self.vapi.nat44_forwarding_enable_disable(0)
3990 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3991 external_ip=alias_ip,
3994 def test_static_lb(self):
3995 """ NAT44 local service load balancing """
3996 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3999 server1 = self.pg0.remote_hosts[0]
4000 server2 = self.pg0.remote_hosts[1]
4002 locals = [{'addr': server1.ip4n,
4006 {'addr': server2.ip4n,
4011 self.nat44_add_address(self.nat_addr)
4012 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4015 local_num=len(locals),
4017 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4018 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4021 # from client to service
4022 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4023 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4024 TCP(sport=12345, dport=external_port))
4025 self.pg1.add_stream(p)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 capture = self.pg0.get_capture(1)
4034 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4035 if ip.dst == server1.ip4:
4039 self.assertEqual(tcp.dport, local_port)
4040 self.assert_packet_checksums_valid(p)
4042 self.logger.error(ppp("Unexpected or invalid packet:", p))
4045 # from service back to client
4046 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4047 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4048 TCP(sport=local_port, dport=12345))
4049 self.pg0.add_stream(p)
4050 self.pg_enable_capture(self.pg_interfaces)
4052 capture = self.pg1.get_capture(1)
4057 self.assertEqual(ip.src, self.nat_addr)
4058 self.assertEqual(tcp.sport, external_port)
4059 self.assert_packet_checksums_valid(p)
4061 self.logger.error(ppp("Unexpected or invalid packet:", p))
4064 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4065 self.assertEqual(len(sessions), 1)
4066 self.assertTrue(sessions[0].ext_host_valid)
4067 self.vapi.nat44_del_session(
4068 sessions[0].inside_ip_address,
4069 sessions[0].inside_port,
4070 sessions[0].protocol,
4071 ext_host_address=sessions[0].ext_host_address,
4072 ext_host_port=sessions[0].ext_host_port)
4073 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4074 self.assertEqual(len(sessions), 0)
4076 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4077 def test_static_lb_multi_clients(self):
4078 """ NAT44 local service load balancing - multiple clients"""
4080 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4083 server1 = self.pg0.remote_hosts[0]
4084 server2 = self.pg0.remote_hosts[1]
4086 locals = [{'addr': server1.ip4n,
4090 {'addr': server2.ip4n,
4095 self.nat44_add_address(self.nat_addr)
4096 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4099 local_num=len(locals),
4101 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4102 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4107 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4109 for client in clients:
4110 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4111 IP(src=client, dst=self.nat_addr) /
4112 TCP(sport=12345, dport=external_port))
4114 self.pg1.add_stream(pkts)
4115 self.pg_enable_capture(self.pg_interfaces)
4117 capture = self.pg0.get_capture(len(pkts))
4119 if p[IP].dst == server1.ip4:
4123 self.assertTrue(server1_n > server2_n)
4125 def test_static_lb_2(self):
4126 """ NAT44 local service load balancing (asymmetrical rule) """
4127 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4130 server1 = self.pg0.remote_hosts[0]
4131 server2 = self.pg0.remote_hosts[1]
4133 locals = [{'addr': server1.ip4n,
4137 {'addr': server2.ip4n,
4142 self.vapi.nat44_forwarding_enable_disable(1)
4143 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4147 local_num=len(locals),
4149 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4150 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4153 # from client to service
4154 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4156 TCP(sport=12345, dport=external_port))
4157 self.pg1.add_stream(p)
4158 self.pg_enable_capture(self.pg_interfaces)
4160 capture = self.pg0.get_capture(1)
4166 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4167 if ip.dst == server1.ip4:
4171 self.assertEqual(tcp.dport, local_port)
4172 self.assert_packet_checksums_valid(p)
4174 self.logger.error(ppp("Unexpected or invalid packet:", p))
4177 # from service back to client
4178 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4179 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4180 TCP(sport=local_port, dport=12345))
4181 self.pg0.add_stream(p)
4182 self.pg_enable_capture(self.pg_interfaces)
4184 capture = self.pg1.get_capture(1)
4189 self.assertEqual(ip.src, self.nat_addr)
4190 self.assertEqual(tcp.sport, external_port)
4191 self.assert_packet_checksums_valid(p)
4193 self.logger.error(ppp("Unexpected or invalid packet:", p))
4196 # from client to server (no translation)
4197 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4198 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4199 TCP(sport=12346, dport=local_port))
4200 self.pg1.add_stream(p)
4201 self.pg_enable_capture(self.pg_interfaces)
4203 capture = self.pg0.get_capture(1)
4209 self.assertEqual(ip.dst, server1.ip4)
4210 self.assertEqual(tcp.dport, local_port)
4211 self.assert_packet_checksums_valid(p)
4213 self.logger.error(ppp("Unexpected or invalid packet:", p))
4216 # from service back to client (no translation)
4217 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4218 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4219 TCP(sport=local_port, dport=12346))
4220 self.pg0.add_stream(p)
4221 self.pg_enable_capture(self.pg_interfaces)
4223 capture = self.pg1.get_capture(1)
4228 self.assertEqual(ip.src, server1.ip4)
4229 self.assertEqual(tcp.sport, local_port)
4230 self.assert_packet_checksums_valid(p)
4232 self.logger.error(ppp("Unexpected or invalid packet:", p))
4235 def test_lb_affinity(self):
4236 """ NAT44 local service load balancing affinity """
4237 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4240 server1 = self.pg0.remote_hosts[0]
4241 server2 = self.pg0.remote_hosts[1]
4243 locals = [{'addr': server1.ip4n,
4247 {'addr': server2.ip4n,
4252 self.nat44_add_address(self.nat_addr)
4253 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4257 local_num=len(locals),
4259 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4260 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4263 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4264 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4265 TCP(sport=1025, dport=external_port))
4266 self.pg1.add_stream(p)
4267 self.pg_enable_capture(self.pg_interfaces)
4269 capture = self.pg0.get_capture(1)
4270 backend = capture[0][IP].dst
4272 sessions = self.vapi.nat44_user_session_dump(
4273 socket.inet_pton(socket.AF_INET, backend), 0)
4274 self.assertEqual(len(sessions), 1)
4275 self.assertTrue(sessions[0].ext_host_valid)
4276 self.vapi.nat44_del_session(
4277 sessions[0].inside_ip_address,
4278 sessions[0].inside_port,
4279 sessions[0].protocol,
4280 ext_host_address=sessions[0].ext_host_address,
4281 ext_host_port=sessions[0].ext_host_port)
4284 for port in range(1030, 1100):
4285 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4286 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4287 TCP(sport=port, dport=external_port))
4289 self.pg1.add_stream(pkts)
4290 self.pg_enable_capture(self.pg_interfaces)
4292 capture = self.pg0.get_capture(len(pkts))
4294 self.assertEqual(p[IP].dst, backend)
4296 def test_unknown_proto(self):
4297 """ NAT44 translate packet with unknown protocol """
4298 self.nat44_add_address(self.nat_addr)
4299 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4300 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4304 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4305 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4306 TCP(sport=self.tcp_port_in, dport=20))
4307 self.pg0.add_stream(p)
4308 self.pg_enable_capture(self.pg_interfaces)
4310 p = self.pg1.get_capture(1)
4312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4313 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4315 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4316 TCP(sport=1234, dport=1234))
4317 self.pg0.add_stream(p)
4318 self.pg_enable_capture(self.pg_interfaces)
4320 p = self.pg1.get_capture(1)
4323 self.assertEqual(packet[IP].src, self.nat_addr)
4324 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4325 self.assertTrue(packet.haslayer(GRE))
4326 self.assert_packet_checksums_valid(packet)
4328 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4332 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4333 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4335 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4336 TCP(sport=1234, dport=1234))
4337 self.pg1.add_stream(p)
4338 self.pg_enable_capture(self.pg_interfaces)
4340 p = self.pg0.get_capture(1)
4343 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4344 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4345 self.assertTrue(packet.haslayer(GRE))
4346 self.assert_packet_checksums_valid(packet)
4348 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4351 def test_hairpinning_unknown_proto(self):
4352 """ NAT44 translate packet with unknown protocol - hairpinning """
4353 host = self.pg0.remote_hosts[0]
4354 server = self.pg0.remote_hosts[1]
4356 server_out_port = 8765
4357 server_nat_ip = "10.0.0.11"
4359 self.nat44_add_address(self.nat_addr)
4360 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4361 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4364 # add static mapping for server
4365 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4368 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4369 IP(src=host.ip4, dst=server_nat_ip) /
4370 TCP(sport=host_in_port, dport=server_out_port))
4371 self.pg0.add_stream(p)
4372 self.pg_enable_capture(self.pg_interfaces)
4374 self.pg0.get_capture(1)
4376 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4377 IP(src=host.ip4, dst=server_nat_ip) /
4379 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4380 TCP(sport=1234, dport=1234))
4381 self.pg0.add_stream(p)
4382 self.pg_enable_capture(self.pg_interfaces)
4384 p = self.pg0.get_capture(1)
4387 self.assertEqual(packet[IP].src, self.nat_addr)
4388 self.assertEqual(packet[IP].dst, server.ip4)
4389 self.assertTrue(packet.haslayer(GRE))
4390 self.assert_packet_checksums_valid(packet)
4392 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4396 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4397 IP(src=server.ip4, dst=self.nat_addr) /
4399 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4400 TCP(sport=1234, dport=1234))
4401 self.pg0.add_stream(p)
4402 self.pg_enable_capture(self.pg_interfaces)
4404 p = self.pg0.get_capture(1)
4407 self.assertEqual(packet[IP].src, server_nat_ip)
4408 self.assertEqual(packet[IP].dst, host.ip4)
4409 self.assertTrue(packet.haslayer(GRE))
4410 self.assert_packet_checksums_valid(packet)
4412 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4415 def test_output_feature_and_service(self):
4416 """ NAT44 interface output feature and services """
4417 external_addr = '1.2.3.4'
4421 self.vapi.nat44_forwarding_enable_disable(1)
4422 self.nat44_add_address(self.nat_addr)
4423 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4424 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4425 local_port, external_port,
4426 proto=IP_PROTOS.tcp, out2in_only=1)
4427 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4428 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4430 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4433 # from client to service
4434 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4435 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4436 TCP(sport=12345, dport=external_port))
4437 self.pg1.add_stream(p)
4438 self.pg_enable_capture(self.pg_interfaces)
4440 capture = self.pg0.get_capture(1)
4445 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4446 self.assertEqual(tcp.dport, local_port)
4447 self.assert_packet_checksums_valid(p)
4449 self.logger.error(ppp("Unexpected or invalid packet:", p))
4452 # from service back to client
4453 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4454 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4455 TCP(sport=local_port, dport=12345))
4456 self.pg0.add_stream(p)
4457 self.pg_enable_capture(self.pg_interfaces)
4459 capture = self.pg1.get_capture(1)
4464 self.assertEqual(ip.src, external_addr)
4465 self.assertEqual(tcp.sport, external_port)
4466 self.assert_packet_checksums_valid(p)
4468 self.logger.error(ppp("Unexpected or invalid packet:", p))
4471 # from local network host to external network
4472 pkts = self.create_stream_in(self.pg0, self.pg1)
4473 self.pg0.add_stream(pkts)
4474 self.pg_enable_capture(self.pg_interfaces)
4476 capture = self.pg1.get_capture(len(pkts))
4477 self.verify_capture_out(capture)
4478 pkts = self.create_stream_in(self.pg0, self.pg1)
4479 self.pg0.add_stream(pkts)
4480 self.pg_enable_capture(self.pg_interfaces)
4482 capture = self.pg1.get_capture(len(pkts))
4483 self.verify_capture_out(capture)
4485 # from external network back to local network host
4486 pkts = self.create_stream_out(self.pg1)
4487 self.pg1.add_stream(pkts)
4488 self.pg_enable_capture(self.pg_interfaces)
4490 capture = self.pg0.get_capture(len(pkts))
4491 self.verify_capture_in(capture, self.pg0)
4493 def test_output_feature_and_service2(self):
4494 """ NAT44 interface output feature and service host direct access """
4495 self.vapi.nat44_forwarding_enable_disable(1)
4496 self.nat44_add_address(self.nat_addr)
4497 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4500 # session initiaded from service host - translate
4501 pkts = self.create_stream_in(self.pg0, self.pg1)
4502 self.pg0.add_stream(pkts)
4503 self.pg_enable_capture(self.pg_interfaces)
4505 capture = self.pg1.get_capture(len(pkts))
4506 self.verify_capture_out(capture)
4508 pkts = self.create_stream_out(self.pg1)
4509 self.pg1.add_stream(pkts)
4510 self.pg_enable_capture(self.pg_interfaces)
4512 capture = self.pg0.get_capture(len(pkts))
4513 self.verify_capture_in(capture, self.pg0)
4515 # session initiaded from remote host - do not translate
4516 self.tcp_port_in = 60303
4517 self.udp_port_in = 60304
4518 self.icmp_id_in = 60305
4519 pkts = self.create_stream_out(self.pg1,
4520 self.pg0.remote_ip4,
4521 use_inside_ports=True)
4522 self.pg1.add_stream(pkts)
4523 self.pg_enable_capture(self.pg_interfaces)
4525 capture = self.pg0.get_capture(len(pkts))
4526 self.verify_capture_in(capture, self.pg0)
4528 pkts = self.create_stream_in(self.pg0, self.pg1)
4529 self.pg0.add_stream(pkts)
4530 self.pg_enable_capture(self.pg_interfaces)
4532 capture = self.pg1.get_capture(len(pkts))
4533 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4536 def test_output_feature_and_service3(self):
4537 """ NAT44 interface output feature and DST NAT """
4538 external_addr = '1.2.3.4'
4542 self.vapi.nat44_forwarding_enable_disable(1)
4543 self.nat44_add_address(self.nat_addr)
4544 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4545 local_port, external_port,
4546 proto=IP_PROTOS.tcp, out2in_only=1)
4547 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4548 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4550 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4553 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4554 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4555 TCP(sport=12345, dport=external_port))
4556 self.pg0.add_stream(p)
4557 self.pg_enable_capture(self.pg_interfaces)
4559 capture = self.pg1.get_capture(1)
4564 self.assertEqual(ip.src, self.pg0.remote_ip4)
4565 self.assertEqual(tcp.sport, 12345)
4566 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4567 self.assertEqual(tcp.dport, local_port)
4568 self.assert_packet_checksums_valid(p)
4570 self.logger.error(ppp("Unexpected or invalid packet:", p))
4573 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4574 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4575 TCP(sport=local_port, dport=12345))
4576 self.pg1.add_stream(p)
4577 self.pg_enable_capture(self.pg_interfaces)
4579 capture = self.pg0.get_capture(1)
4584 self.assertEqual(ip.src, external_addr)
4585 self.assertEqual(tcp.sport, external_port)
4586 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4587 self.assertEqual(tcp.dport, 12345)
4588 self.assert_packet_checksums_valid(p)
4590 self.logger.error(ppp("Unexpected or invalid packet:", p))
4593 def test_next_src_nat(self):
4594 """ On way back forward packet to nat44-in2out node. """
4595 twice_nat_addr = '10.0.1.3'
4598 post_twice_nat_port = 0
4600 self.vapi.nat44_forwarding_enable_disable(1)
4601 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4602 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4603 local_port, external_port,
4604 proto=IP_PROTOS.tcp, out2in_only=1,
4605 self_twice_nat=1, vrf_id=1)
4606 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4609 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4610 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4611 TCP(sport=12345, dport=external_port))
4612 self.pg6.add_stream(p)
4613 self.pg_enable_capture(self.pg_interfaces)
4615 capture = self.pg6.get_capture(1)
4620 self.assertEqual(ip.src, twice_nat_addr)
4621 self.assertNotEqual(tcp.sport, 12345)
4622 post_twice_nat_port = tcp.sport
4623 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4624 self.assertEqual(tcp.dport, local_port)
4625 self.assert_packet_checksums_valid(p)
4627 self.logger.error(ppp("Unexpected or invalid packet:", p))
4630 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4631 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4632 TCP(sport=local_port, dport=post_twice_nat_port))
4633 self.pg6.add_stream(p)
4634 self.pg_enable_capture(self.pg_interfaces)
4636 capture = self.pg6.get_capture(1)
4641 self.assertEqual(ip.src, self.pg1.remote_ip4)
4642 self.assertEqual(tcp.sport, external_port)
4643 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4644 self.assertEqual(tcp.dport, 12345)
4645 self.assert_packet_checksums_valid(p)
4647 self.logger.error(ppp("Unexpected or invalid packet:", p))
4650 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4652 twice_nat_addr = '10.0.1.3'
4660 port_in1 = port_in+1
4661 port_in2 = port_in+2
4666 server1 = self.pg0.remote_hosts[0]
4667 server2 = self.pg0.remote_hosts[1]
4679 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4682 self.nat44_add_address(self.nat_addr)
4683 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4685 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4687 proto=IP_PROTOS.tcp,
4688 twice_nat=int(not self_twice_nat),
4689 self_twice_nat=int(self_twice_nat))
4691 locals = [{'addr': server1.ip4n,
4695 {'addr': server2.ip4n,
4699 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4700 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4704 not self_twice_nat),
4707 local_num=len(locals),
4709 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4710 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4717 assert client_id is not None
4719 client = self.pg0.remote_hosts[0]
4720 elif client_id == 2:
4721 client = self.pg0.remote_hosts[1]
4723 client = pg1.remote_hosts[0]
4724 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4725 IP(src=client.ip4, dst=self.nat_addr) /
4726 TCP(sport=eh_port_out, dport=port_out))
4728 self.pg_enable_capture(self.pg_interfaces)
4730 capture = pg0.get_capture(1)
4736 if ip.dst == server1.ip4:
4742 self.assertEqual(ip.dst, server.ip4)
4744 self.assertIn(tcp.dport, [port_in1, port_in2])
4746 self.assertEqual(tcp.dport, port_in)
4748 self.assertEqual(ip.src, twice_nat_addr)
4749 self.assertNotEqual(tcp.sport, eh_port_out)
4751 self.assertEqual(ip.src, client.ip4)
4752 self.assertEqual(tcp.sport, eh_port_out)
4754 eh_port_in = tcp.sport
4755 saved_port_in = tcp.dport
4756 self.assert_packet_checksums_valid(p)
4758 self.logger.error(ppp("Unexpected or invalid packet:", p))
4761 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4762 IP(src=server.ip4, dst=eh_addr_in) /
4763 TCP(sport=saved_port_in, dport=eh_port_in))
4765 self.pg_enable_capture(self.pg_interfaces)
4767 capture = pg1.get_capture(1)
4772 self.assertEqual(ip.dst, client.ip4)
4773 self.assertEqual(ip.src, self.nat_addr)
4774 self.assertEqual(tcp.dport, eh_port_out)
4775 self.assertEqual(tcp.sport, port_out)
4776 self.assert_packet_checksums_valid(p)
4778 self.logger.error(ppp("Unexpected or invalid packet:", p))
4782 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4783 self.assertEqual(len(sessions), 1)
4784 self.assertTrue(sessions[0].ext_host_valid)
4785 self.assertTrue(sessions[0].is_twicenat)
4786 self.vapi.nat44_del_session(
4787 sessions[0].inside_ip_address,
4788 sessions[0].inside_port,
4789 sessions[0].protocol,
4790 ext_host_address=sessions[0].ext_host_nat_address,
4791 ext_host_port=sessions[0].ext_host_nat_port)
4792 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4793 self.assertEqual(len(sessions), 0)
4795 def test_twice_nat(self):
4797 self.twice_nat_common()
4799 def test_self_twice_nat_positive(self):
4800 """ Self Twice NAT44 (positive test) """
4801 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4803 def test_self_twice_nat_negative(self):
4804 """ Self Twice NAT44 (negative test) """
4805 self.twice_nat_common(self_twice_nat=True)
4807 def test_twice_nat_lb(self):
4808 """ Twice NAT44 local service load balancing """
4809 self.twice_nat_common(lb=True)
4811 def test_self_twice_nat_lb_positive(self):
4812 """ Self Twice NAT44 local service load balancing (positive test) """
4813 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4816 def test_self_twice_nat_lb_negative(self):
4817 """ Self Twice NAT44 local service load balancing (negative test) """
4818 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4821 def test_twice_nat_interface_addr(self):
4822 """ Acquire twice NAT44 addresses from interface """
4823 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4825 # no address in NAT pool
4826 adresses = self.vapi.nat44_address_dump()
4827 self.assertEqual(0, len(adresses))
4829 # configure interface address and check NAT address pool
4830 self.pg3.config_ip4()
4831 adresses = self.vapi.nat44_address_dump()
4832 self.assertEqual(1, len(adresses))
4833 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4834 self.assertEqual(adresses[0].twice_nat, 1)
4836 # remove interface address and check NAT address pool
4837 self.pg3.unconfig_ip4()
4838 adresses = self.vapi.nat44_address_dump()
4839 self.assertEqual(0, len(adresses))
4841 def test_tcp_close(self):
4842 """ Close TCP session from inside network - output feature """
4843 self.vapi.nat44_forwarding_enable_disable(1)
4844 self.nat44_add_address(self.pg1.local_ip4)
4845 twice_nat_addr = '10.0.1.3'
4846 service_ip = '192.168.16.150'
4847 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4848 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4849 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4851 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4853 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4857 proto=IP_PROTOS.tcp,
4860 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4861 start_sessnum = len(sessions)
4863 # SYN packet out->in
4864 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4865 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4866 TCP(sport=33898, dport=80, flags="S"))
4867 self.pg1.add_stream(p)
4868 self.pg_enable_capture(self.pg_interfaces)
4870 capture = self.pg0.get_capture(1)
4872 tcp_port = p[TCP].sport
4874 # SYN + ACK packet in->out
4875 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4876 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4877 TCP(sport=80, dport=tcp_port, flags="SA"))
4878 self.pg0.add_stream(p)
4879 self.pg_enable_capture(self.pg_interfaces)
4881 self.pg1.get_capture(1)
4883 # ACK packet out->in
4884 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4885 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4886 TCP(sport=33898, dport=80, flags="A"))
4887 self.pg1.add_stream(p)
4888 self.pg_enable_capture(self.pg_interfaces)
4890 self.pg0.get_capture(1)
4892 # FIN packet in -> out
4893 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4894 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4895 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
4896 self.pg0.add_stream(p)
4897 self.pg_enable_capture(self.pg_interfaces)
4899 self.pg1.get_capture(1)
4901 # FIN+ACK packet out -> in
4902 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4903 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4904 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
4905 self.pg1.add_stream(p)
4906 self.pg_enable_capture(self.pg_interfaces)
4908 self.pg0.get_capture(1)
4910 # ACK packet in -> out
4911 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4912 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4913 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
4914 self.pg0.add_stream(p)
4915 self.pg_enable_capture(self.pg_interfaces)
4917 self.pg1.get_capture(1)
4919 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4921 self.assertEqual(len(sessions) - start_sessnum, 0)
4923 def test_tcp_session_close_in(self):
4924 """ Close TCP session from inside network """
4925 self.tcp_port_out = 10505
4926 self.nat44_add_address(self.nat_addr)
4927 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4931 proto=IP_PROTOS.tcp,
4933 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4934 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4937 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4938 start_sessnum = len(sessions)
4940 self.initiate_tcp_session(self.pg0, self.pg1)
4942 # FIN packet in -> out
4943 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4944 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4945 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4946 flags="FA", seq=100, ack=300))
4947 self.pg0.add_stream(p)
4948 self.pg_enable_capture(self.pg_interfaces)
4950 self.pg1.get_capture(1)
4954 # ACK packet out -> in
4955 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4956 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4957 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4958 flags="A", seq=300, ack=101))
4961 # FIN packet out -> in
4962 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4963 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4964 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4965 flags="FA", seq=300, ack=101))
4968 self.pg1.add_stream(pkts)
4969 self.pg_enable_capture(self.pg_interfaces)
4971 self.pg0.get_capture(2)
4973 # ACK packet in -> out
4974 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4975 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4976 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4977 flags="A", seq=101, ack=301))
4978 self.pg0.add_stream(p)
4979 self.pg_enable_capture(self.pg_interfaces)
4981 self.pg1.get_capture(1)
4983 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4985 self.assertEqual(len(sessions) - start_sessnum, 0)
4987 def test_tcp_session_close_out(self):
4988 """ Close TCP session from outside network """
4989 self.tcp_port_out = 10505
4990 self.nat44_add_address(self.nat_addr)
4991 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4995 proto=IP_PROTOS.tcp,
4997 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4998 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5001 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5002 start_sessnum = len(sessions)
5004 self.initiate_tcp_session(self.pg0, self.pg1)
5006 # FIN packet out -> in
5007 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5008 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5009 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5010 flags="FA", seq=100, ack=300))
5011 self.pg1.add_stream(p)
5012 self.pg_enable_capture(self.pg_interfaces)
5014 self.pg0.get_capture(1)
5016 # FIN+ACK packet in -> out
5017 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5018 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5019 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5020 flags="FA", seq=300, ack=101))
5022 self.pg0.add_stream(p)
5023 self.pg_enable_capture(self.pg_interfaces)
5025 self.pg1.get_capture(1)
5027 # ACK packet out -> in
5028 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5029 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5030 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5031 flags="A", seq=101, ack=301))
5032 self.pg1.add_stream(p)
5033 self.pg_enable_capture(self.pg_interfaces)
5035 self.pg0.get_capture(1)
5037 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5039 self.assertEqual(len(sessions) - start_sessnum, 0)
5041 def test_tcp_session_close_simultaneous(self):
5042 """ Close TCP session from inside network """
5043 self.tcp_port_out = 10505
5044 self.nat44_add_address(self.nat_addr)
5045 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5049 proto=IP_PROTOS.tcp,
5051 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5052 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5055 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5056 start_sessnum = len(sessions)
5058 self.initiate_tcp_session(self.pg0, self.pg1)
5060 # FIN packet in -> out
5061 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5062 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5063 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5064 flags="FA", seq=100, ack=300))
5065 self.pg0.add_stream(p)
5066 self.pg_enable_capture(self.pg_interfaces)
5068 self.pg1.get_capture(1)
5070 # FIN packet out -> in
5071 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5072 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5073 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5074 flags="FA", seq=300, ack=100))
5075 self.pg1.add_stream(p)
5076 self.pg_enable_capture(self.pg_interfaces)
5078 self.pg0.get_capture(1)
5080 # ACK packet in -> out
5081 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5082 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5083 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5084 flags="A", seq=101, ack=301))
5085 self.pg0.add_stream(p)
5086 self.pg_enable_capture(self.pg_interfaces)
5088 self.pg1.get_capture(1)
5090 # ACK packet out -> in
5091 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5092 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5093 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5094 flags="A", seq=301, ack=101))
5095 self.pg1.add_stream(p)
5096 self.pg_enable_capture(self.pg_interfaces)
5098 self.pg0.get_capture(1)
5100 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5102 self.assertEqual(len(sessions) - start_sessnum, 0)
5104 def test_one_armed_nat44_static(self):
5105 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5106 remote_host = self.pg4.remote_hosts[0]
5107 local_host = self.pg4.remote_hosts[1]
5112 self.vapi.nat44_forwarding_enable_disable(1)
5113 self.nat44_add_address(self.nat_addr, twice_nat=1)
5114 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5115 local_port, external_port,
5116 proto=IP_PROTOS.tcp, out2in_only=1,
5118 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5119 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5122 # from client to service
5123 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5124 IP(src=remote_host.ip4, dst=self.nat_addr) /
5125 TCP(sport=12345, dport=external_port))
5126 self.pg4.add_stream(p)
5127 self.pg_enable_capture(self.pg_interfaces)
5129 capture = self.pg4.get_capture(1)
5134 self.assertEqual(ip.dst, local_host.ip4)
5135 self.assertEqual(ip.src, self.nat_addr)
5136 self.assertEqual(tcp.dport, local_port)
5137 self.assertNotEqual(tcp.sport, 12345)
5138 eh_port_in = tcp.sport
5139 self.assert_packet_checksums_valid(p)
5141 self.logger.error(ppp("Unexpected or invalid packet:", p))
5144 # from service back to client
5145 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5146 IP(src=local_host.ip4, dst=self.nat_addr) /
5147 TCP(sport=local_port, dport=eh_port_in))
5148 self.pg4.add_stream(p)
5149 self.pg_enable_capture(self.pg_interfaces)
5151 capture = self.pg4.get_capture(1)
5156 self.assertEqual(ip.src, self.nat_addr)
5157 self.assertEqual(ip.dst, remote_host.ip4)
5158 self.assertEqual(tcp.sport, external_port)
5159 self.assertEqual(tcp.dport, 12345)
5160 self.assert_packet_checksums_valid(p)
5162 self.logger.error(ppp("Unexpected or invalid packet:", p))
5165 def test_static_with_port_out2(self):
5166 """ 1:1 NAPT asymmetrical rule """
5171 self.vapi.nat44_forwarding_enable_disable(1)
5172 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5173 local_port, external_port,
5174 proto=IP_PROTOS.tcp, out2in_only=1)
5175 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5176 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5179 # from client to service
5180 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5181 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5182 TCP(sport=12345, dport=external_port))
5183 self.pg1.add_stream(p)
5184 self.pg_enable_capture(self.pg_interfaces)
5186 capture = self.pg0.get_capture(1)
5191 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5192 self.assertEqual(tcp.dport, local_port)
5193 self.assert_packet_checksums_valid(p)
5195 self.logger.error(ppp("Unexpected or invalid packet:", p))
5199 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5200 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5201 ICMP(type=11) / capture[0][IP])
5202 self.pg0.add_stream(p)
5203 self.pg_enable_capture(self.pg_interfaces)
5205 capture = self.pg1.get_capture(1)
5208 self.assertEqual(p[IP].src, self.nat_addr)
5210 self.assertEqual(inner.dst, self.nat_addr)
5211 self.assertEqual(inner[TCPerror].dport, external_port)
5213 self.logger.error(ppp("Unexpected or invalid packet:", p))
5216 # from service back to client
5217 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5218 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5219 TCP(sport=local_port, dport=12345))
5220 self.pg0.add_stream(p)
5221 self.pg_enable_capture(self.pg_interfaces)
5223 capture = self.pg1.get_capture(1)
5228 self.assertEqual(ip.src, self.nat_addr)
5229 self.assertEqual(tcp.sport, external_port)
5230 self.assert_packet_checksums_valid(p)
5232 self.logger.error(ppp("Unexpected or invalid packet:", p))
5236 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5237 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5238 ICMP(type=11) / capture[0][IP])
5239 self.pg1.add_stream(p)
5240 self.pg_enable_capture(self.pg_interfaces)
5242 capture = self.pg0.get_capture(1)
5245 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5247 self.assertEqual(inner.src, self.pg0.remote_ip4)
5248 self.assertEqual(inner[TCPerror].sport, local_port)
5250 self.logger.error(ppp("Unexpected or invalid packet:", p))
5253 # from client to server (no translation)
5254 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5255 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5256 TCP(sport=12346, dport=local_port))
5257 self.pg1.add_stream(p)
5258 self.pg_enable_capture(self.pg_interfaces)
5260 capture = self.pg0.get_capture(1)
5265 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5266 self.assertEqual(tcp.dport, local_port)
5267 self.assert_packet_checksums_valid(p)
5269 self.logger.error(ppp("Unexpected or invalid packet:", p))
5272 # from service back to client (no translation)
5273 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5274 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5275 TCP(sport=local_port, dport=12346))
5276 self.pg0.add_stream(p)
5277 self.pg_enable_capture(self.pg_interfaces)
5279 capture = self.pg1.get_capture(1)
5284 self.assertEqual(ip.src, self.pg0.remote_ip4)
5285 self.assertEqual(tcp.sport, local_port)
5286 self.assert_packet_checksums_valid(p)
5288 self.logger.error(ppp("Unexpected or invalid packet:", p))
5291 def test_output_feature(self):
5292 """ NAT44 interface output feature (in2out postrouting) """
5293 self.vapi.nat44_forwarding_enable_disable(1)
5294 self.nat44_add_address(self.nat_addr)
5295 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5297 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5301 pkts = self.create_stream_in(self.pg0, self.pg1)
5302 self.pg0.add_stream(pkts)
5303 self.pg_enable_capture(self.pg_interfaces)
5305 capture = self.pg1.get_capture(len(pkts))
5306 self.verify_capture_out(capture)
5309 pkts = self.create_stream_out(self.pg1)
5310 self.pg1.add_stream(pkts)
5311 self.pg_enable_capture(self.pg_interfaces)
5313 capture = self.pg0.get_capture(len(pkts))
5314 self.verify_capture_in(capture, self.pg0)
5316 def test_multiple_vrf(self):
5317 """ Multiple VRF setup """
5318 external_addr = '1.2.3.4'
5323 self.vapi.nat44_forwarding_enable_disable(1)
5324 self.nat44_add_address(self.nat_addr)
5325 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5326 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5328 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5330 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5331 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5333 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5335 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5336 local_port, external_port, vrf_id=1,
5337 proto=IP_PROTOS.tcp, out2in_only=1)
5338 self.nat44_add_static_mapping(
5339 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5340 local_port=local_port, vrf_id=0, external_port=external_port,
5341 proto=IP_PROTOS.tcp, out2in_only=1)
5343 # from client to service (both VRF1)
5344 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5345 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5346 TCP(sport=12345, dport=external_port))
5347 self.pg6.add_stream(p)
5348 self.pg_enable_capture(self.pg_interfaces)
5350 capture = self.pg5.get_capture(1)
5355 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5356 self.assertEqual(tcp.dport, local_port)
5357 self.assert_packet_checksums_valid(p)
5359 self.logger.error(ppp("Unexpected or invalid packet:", p))
5362 # from service back to client (both VRF1)
5363 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5364 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5365 TCP(sport=local_port, dport=12345))
5366 self.pg5.add_stream(p)
5367 self.pg_enable_capture(self.pg_interfaces)
5369 capture = self.pg6.get_capture(1)
5374 self.assertEqual(ip.src, external_addr)
5375 self.assertEqual(tcp.sport, external_port)
5376 self.assert_packet_checksums_valid(p)
5378 self.logger.error(ppp("Unexpected or invalid packet:", p))
5381 # dynamic NAT from VRF1 to VRF0 (output-feature)
5382 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5383 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5384 TCP(sport=2345, dport=22))
5385 self.pg5.add_stream(p)
5386 self.pg_enable_capture(self.pg_interfaces)
5388 capture = self.pg1.get_capture(1)
5393 self.assertEqual(ip.src, self.nat_addr)
5394 self.assertNotEqual(tcp.sport, 2345)
5395 self.assert_packet_checksums_valid(p)
5398 self.logger.error(ppp("Unexpected or invalid packet:", p))
5401 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5402 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5403 TCP(sport=22, dport=port))
5404 self.pg1.add_stream(p)
5405 self.pg_enable_capture(self.pg_interfaces)
5407 capture = self.pg5.get_capture(1)
5412 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5413 self.assertEqual(tcp.dport, 2345)
5414 self.assert_packet_checksums_valid(p)
5416 self.logger.error(ppp("Unexpected or invalid packet:", p))
5419 # from client VRF1 to service VRF0
5420 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5421 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5422 TCP(sport=12346, dport=external_port))
5423 self.pg6.add_stream(p)
5424 self.pg_enable_capture(self.pg_interfaces)
5426 capture = self.pg0.get_capture(1)
5431 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5432 self.assertEqual(tcp.dport, local_port)
5433 self.assert_packet_checksums_valid(p)
5435 self.logger.error(ppp("Unexpected or invalid packet:", p))
5438 # from service VRF0 back to client VRF1
5439 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5440 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5441 TCP(sport=local_port, dport=12346))
5442 self.pg0.add_stream(p)
5443 self.pg_enable_capture(self.pg_interfaces)
5445 capture = self.pg6.get_capture(1)
5450 self.assertEqual(ip.src, self.pg0.local_ip4)
5451 self.assertEqual(tcp.sport, external_port)
5452 self.assert_packet_checksums_valid(p)
5454 self.logger.error(ppp("Unexpected or invalid packet:", p))
5457 # from client VRF0 to service VRF1
5458 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5459 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5460 TCP(sport=12347, dport=external_port))
5461 self.pg0.add_stream(p)
5462 self.pg_enable_capture(self.pg_interfaces)
5464 capture = self.pg5.get_capture(1)
5469 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5470 self.assertEqual(tcp.dport, local_port)
5471 self.assert_packet_checksums_valid(p)
5473 self.logger.error(ppp("Unexpected or invalid packet:", p))
5476 # from service VRF1 back to client VRF0
5477 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5478 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5479 TCP(sport=local_port, dport=12347))
5480 self.pg5.add_stream(p)
5481 self.pg_enable_capture(self.pg_interfaces)
5483 capture = self.pg0.get_capture(1)
5488 self.assertEqual(ip.src, external_addr)
5489 self.assertEqual(tcp.sport, external_port)
5490 self.assert_packet_checksums_valid(p)
5492 self.logger.error(ppp("Unexpected or invalid packet:", p))
5495 # from client to server (both VRF1, no translation)
5496 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5497 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5498 TCP(sport=12348, dport=local_port))
5499 self.pg6.add_stream(p)
5500 self.pg_enable_capture(self.pg_interfaces)
5502 capture = self.pg5.get_capture(1)
5507 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5508 self.assertEqual(tcp.dport, local_port)
5509 self.assert_packet_checksums_valid(p)
5511 self.logger.error(ppp("Unexpected or invalid packet:", p))
5514 # from server back to client (both VRF1, no translation)
5515 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5516 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5517 TCP(sport=local_port, dport=12348))
5518 self.pg5.add_stream(p)
5519 self.pg_enable_capture(self.pg_interfaces)
5521 capture = self.pg6.get_capture(1)
5526 self.assertEqual(ip.src, self.pg5.remote_ip4)
5527 self.assertEqual(tcp.sport, local_port)
5528 self.assert_packet_checksums_valid(p)
5530 self.logger.error(ppp("Unexpected or invalid packet:", p))
5533 # from client VRF1 to server VRF0 (no translation)
5534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5535 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5536 TCP(sport=local_port, dport=12349))
5537 self.pg0.add_stream(p)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg6.get_capture(1)
5545 self.assertEqual(ip.src, self.pg0.remote_ip4)
5546 self.assertEqual(tcp.sport, local_port)
5547 self.assert_packet_checksums_valid(p)
5549 self.logger.error(ppp("Unexpected or invalid packet:", p))
5552 # from server VRF0 back to client VRF1 (no translation)
5553 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5554 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5555 TCP(sport=local_port, dport=12349))
5556 self.pg0.add_stream(p)
5557 self.pg_enable_capture(self.pg_interfaces)
5559 capture = self.pg6.get_capture(1)
5564 self.assertEqual(ip.src, self.pg0.remote_ip4)
5565 self.assertEqual(tcp.sport, local_port)
5566 self.assert_packet_checksums_valid(p)
5568 self.logger.error(ppp("Unexpected or invalid packet:", p))
5571 # from client VRF0 to server VRF1 (no translation)
5572 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5573 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5574 TCP(sport=12344, dport=local_port))
5575 self.pg0.add_stream(p)
5576 self.pg_enable_capture(self.pg_interfaces)
5578 capture = self.pg5.get_capture(1)
5583 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5584 self.assertEqual(tcp.dport, local_port)
5585 self.assert_packet_checksums_valid(p)
5587 self.logger.error(ppp("Unexpected or invalid packet:", p))
5590 # from server VRF1 back to client VRF0 (no translation)
5591 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5592 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5593 TCP(sport=local_port, dport=12344))
5594 self.pg5.add_stream(p)
5595 self.pg_enable_capture(self.pg_interfaces)
5597 capture = self.pg0.get_capture(1)
5602 self.assertEqual(ip.src, self.pg5.remote_ip4)
5603 self.assertEqual(tcp.sport, local_port)
5604 self.assert_packet_checksums_valid(p)
5606 self.logger.error(ppp("Unexpected or invalid packet:", p))
5609 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5610 def test_session_timeout(self):
5611 """ NAT44 session timeouts """
5612 self.nat44_add_address(self.nat_addr)
5613 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5614 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5616 self.vapi.nat_set_timeouts(icmp=5)
5620 for i in range(0, max_sessions):
5621 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5622 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5623 IP(src=src, dst=self.pg1.remote_ip4) /
5624 ICMP(id=1025, type='echo-request'))
5626 self.pg0.add_stream(pkts)
5627 self.pg_enable_capture(self.pg_interfaces)
5629 self.pg1.get_capture(max_sessions)
5634 for i in range(0, max_sessions):
5635 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5636 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5637 IP(src=src, dst=self.pg1.remote_ip4) /
5638 ICMP(id=1026, type='echo-request'))
5640 self.pg0.add_stream(pkts)
5641 self.pg_enable_capture(self.pg_interfaces)
5643 self.pg1.get_capture(max_sessions)
5646 users = self.vapi.nat44_user_dump()
5648 nsessions = nsessions + user.nsessions
5649 self.assertLess(nsessions, 2 * max_sessions)
5651 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5652 def test_session_limit_per_user(self):
5653 """ Maximum sessions per user limit """
5654 self.nat44_add_address(self.nat_addr)
5655 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5656 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5658 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5659 src_address=self.pg2.local_ip4n,
5661 template_interval=10)
5662 self.vapi.nat_set_timeouts(udp=5)
5664 # get maximum number of translations per user
5665 nat44_config = self.vapi.nat_show_config()
5668 for port in range(0, nat44_config.max_translations_per_user):
5669 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5670 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5671 UDP(sport=1025 + port, dport=1025 + port))
5674 self.pg0.add_stream(pkts)
5675 self.pg_enable_capture(self.pg_interfaces)
5677 capture = self.pg1.get_capture(len(pkts))
5679 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5680 src_port=self.ipfix_src_port)
5682 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5683 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5684 UDP(sport=3001, dport=3002))
5685 self.pg0.add_stream(p)
5686 self.pg_enable_capture(self.pg_interfaces)
5688 capture = self.pg1.assert_nothing_captured()
5690 # verify IPFIX logging
5691 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5693 capture = self.pg2.get_capture(10)
5694 ipfix = IPFIXDecoder()
5695 # first load template
5697 self.assertTrue(p.haslayer(IPFIX))
5698 if p.haslayer(Template):
5699 ipfix.add_template(p.getlayer(Template))
5700 # verify events in data set
5702 if p.haslayer(Data):
5703 data = ipfix.decode_data_set(p.getlayer(Set))
5704 self.verify_ipfix_max_entries_per_user(
5706 nat44_config.max_translations_per_user,
5707 self.pg0.remote_ip4n)
5710 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5711 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5712 UDP(sport=3001, dport=3002))
5713 self.pg0.add_stream(p)
5714 self.pg_enable_capture(self.pg_interfaces)
5716 self.pg1.get_capture(1)
5719 super(TestNAT44EndpointDependent, self).tearDown()
5720 if not self.vpp_dead:
5721 self.logger.info(self.vapi.cli("show nat44 addresses"))
5722 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5723 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5724 self.logger.info(self.vapi.cli("show nat44 interface address"))
5725 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5726 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5727 self.logger.info(self.vapi.cli("show nat timeouts"))
5729 self.vapi.cli("clear logging")
5732 class TestNAT44Out2InDPO(MethodHolder):
5733 """ NAT44 Test Cases using out2in DPO """
5736 def setUpConstants(cls):
5737 super(TestNAT44Out2InDPO, cls).setUpConstants()
5738 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5741 def setUpClass(cls):
5742 super(TestNAT44Out2InDPO, cls).setUpClass()
5743 cls.vapi.cli("set log class nat level debug")
5746 cls.tcp_port_in = 6303
5747 cls.tcp_port_out = 6303
5748 cls.udp_port_in = 6304
5749 cls.udp_port_out = 6304
5750 cls.icmp_id_in = 6305
5751 cls.icmp_id_out = 6305
5752 cls.nat_addr = '10.0.0.3'
5753 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5754 cls.dst_ip4 = '192.168.70.1'
5756 cls.create_pg_interfaces(range(2))
5759 cls.pg0.config_ip4()
5760 cls.pg0.resolve_arp()
5763 cls.pg1.config_ip6()
5764 cls.pg1.resolve_ndp()
5766 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5767 dst_address_length=0,
5768 next_hop_address=cls.pg1.remote_ip6n,
5769 next_hop_sw_if_index=cls.pg1.sw_if_index)
5772 super(TestNAT44Out2InDPO, cls).tearDownClass()
5775 def configure_xlat(self):
5776 self.dst_ip6_pfx = '1:2:3::'
5777 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5779 self.dst_ip6_pfx_len = 96
5780 self.src_ip6_pfx = '4:5:6::'
5781 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5783 self.src_ip6_pfx_len = 96
5784 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5785 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5786 '\x00\x00\x00\x00', 0, is_translation=1,
5789 def test_464xlat_ce(self):
5790 """ Test 464XLAT CE with NAT44 """
5792 nat_config = self.vapi.nat_show_config()
5793 self.assertEqual(1, nat_config.out2in_dpo)
5795 self.configure_xlat()
5797 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5798 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5800 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5801 self.dst_ip6_pfx_len)
5802 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5803 self.src_ip6_pfx_len)
5806 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5807 self.pg0.add_stream(pkts)
5808 self.pg_enable_capture(self.pg_interfaces)
5810 capture = self.pg1.get_capture(len(pkts))
5811 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5814 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5816 self.pg1.add_stream(pkts)
5817 self.pg_enable_capture(self.pg_interfaces)
5819 capture = self.pg0.get_capture(len(pkts))
5820 self.verify_capture_in(capture, self.pg0)
5822 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5824 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5825 self.nat_addr_n, is_add=0)
5827 def test_464xlat_ce_no_nat(self):
5828 """ Test 464XLAT CE without NAT44 """
5830 self.configure_xlat()
5832 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5833 self.dst_ip6_pfx_len)
5834 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5835 self.src_ip6_pfx_len)
5837 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5838 self.pg0.add_stream(pkts)
5839 self.pg_enable_capture(self.pg_interfaces)
5841 capture = self.pg1.get_capture(len(pkts))
5842 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5843 nat_ip=out_dst_ip6, same_port=True)
5845 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5846 self.pg1.add_stream(pkts)
5847 self.pg_enable_capture(self.pg_interfaces)
5849 capture = self.pg0.get_capture(len(pkts))
5850 self.verify_capture_in(capture, self.pg0)
5853 class TestDeterministicNAT(MethodHolder):
5854 """ Deterministic NAT Test Cases """
5857 def setUpConstants(cls):
5858 super(TestDeterministicNAT, cls).setUpConstants()
5859 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5862 def setUpClass(cls):
5863 super(TestDeterministicNAT, cls).setUpClass()
5864 cls.vapi.cli("set log class nat level debug")
5867 cls.tcp_port_in = 6303
5868 cls.tcp_external_port = 6303
5869 cls.udp_port_in = 6304
5870 cls.udp_external_port = 6304
5871 cls.icmp_id_in = 6305
5872 cls.nat_addr = '10.0.0.3'
5874 cls.create_pg_interfaces(range(3))
5875 cls.interfaces = list(cls.pg_interfaces)
5877 for i in cls.interfaces:
5882 cls.pg0.generate_remote_hosts(2)
5883 cls.pg0.configure_ipv4_neighbors()
5886 super(TestDeterministicNAT, cls).tearDownClass()
5889 def create_stream_in(self, in_if, out_if, ttl=64):
5891 Create packet stream for inside network
5893 :param in_if: Inside interface
5894 :param out_if: Outside interface
5895 :param ttl: TTL of generated packets
5899 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5900 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5901 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5905 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5906 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5907 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5911 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5912 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5913 ICMP(id=self.icmp_id_in, type='echo-request'))
5918 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5920 Create packet stream for outside network
5922 :param out_if: Outside interface
5923 :param dst_ip: Destination IP address (Default use global NAT address)
5924 :param ttl: TTL of generated packets
5927 dst_ip = self.nat_addr
5930 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5931 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5932 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
5936 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5937 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5938 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
5942 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5943 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5944 ICMP(id=self.icmp_external_id, type='echo-reply'))
5949 def verify_capture_out(self, capture, nat_ip=None):
5951 Verify captured packets on outside network
5953 :param capture: Captured packets
5954 :param nat_ip: Translated IP address (Default use global NAT address)
5955 :param same_port: Sorce port number is not translated (Default False)
5958 nat_ip = self.nat_addr
5959 for packet in capture:
5961 self.assertEqual(packet[IP].src, nat_ip)
5962 if packet.haslayer(TCP):
5963 self.tcp_port_out = packet[TCP].sport
5964 elif packet.haslayer(UDP):
5965 self.udp_port_out = packet[UDP].sport
5967 self.icmp_external_id = packet[ICMP].id
5969 self.logger.error(ppp("Unexpected or invalid packet "
5970 "(outside network):", packet))
5973 def test_deterministic_mode(self):
5974 """ NAT plugin run deterministic mode """
5975 in_addr = '172.16.255.0'
5976 out_addr = '172.17.255.50'
5977 in_addr_t = '172.16.255.20'
5978 in_addr_n = socket.inet_aton(in_addr)
5979 out_addr_n = socket.inet_aton(out_addr)
5980 in_addr_t_n = socket.inet_aton(in_addr_t)
5984 nat_config = self.vapi.nat_show_config()
5985 self.assertEqual(1, nat_config.deterministic)
5987 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
5989 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
5990 self.assertEqual(rep1.out_addr[:4], out_addr_n)
5991 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
5992 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5994 deterministic_mappings = self.vapi.nat_det_map_dump()
5995 self.assertEqual(len(deterministic_mappings), 1)
5996 dsm = deterministic_mappings[0]
5997 self.assertEqual(in_addr_n, dsm.in_addr[:4])
5998 self.assertEqual(in_plen, dsm.in_plen)
5999 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6000 self.assertEqual(out_plen, dsm.out_plen)
6002 self.clear_nat_det()
6003 deterministic_mappings = self.vapi.nat_det_map_dump()
6004 self.assertEqual(len(deterministic_mappings), 0)
6006 def test_set_timeouts(self):
6007 """ Set deterministic NAT timeouts """
6008 timeouts_before = self.vapi.nat_get_timeouts()
6010 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6011 timeouts_before.tcp_established + 10,
6012 timeouts_before.tcp_transitory + 10,
6013 timeouts_before.icmp + 10)
6015 timeouts_after = self.vapi.nat_get_timeouts()
6017 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6018 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6019 self.assertNotEqual(timeouts_before.tcp_established,
6020 timeouts_after.tcp_established)
6021 self.assertNotEqual(timeouts_before.tcp_transitory,
6022 timeouts_after.tcp_transitory)
6024 def test_det_in(self):
6025 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6027 nat_ip = "10.0.0.10"
6029 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6031 socket.inet_aton(nat_ip),
6033 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6034 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6038 pkts = self.create_stream_in(self.pg0, self.pg1)
6039 self.pg0.add_stream(pkts)
6040 self.pg_enable_capture(self.pg_interfaces)
6042 capture = self.pg1.get_capture(len(pkts))
6043 self.verify_capture_out(capture, nat_ip)
6046 pkts = self.create_stream_out(self.pg1, nat_ip)
6047 self.pg1.add_stream(pkts)
6048 self.pg_enable_capture(self.pg_interfaces)
6050 capture = self.pg0.get_capture(len(pkts))
6051 self.verify_capture_in(capture, self.pg0)
6054 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6055 self.assertEqual(len(sessions), 3)
6059 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6060 self.assertEqual(s.in_port, self.tcp_port_in)
6061 self.assertEqual(s.out_port, self.tcp_port_out)
6062 self.assertEqual(s.ext_port, self.tcp_external_port)
6066 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6067 self.assertEqual(s.in_port, self.udp_port_in)
6068 self.assertEqual(s.out_port, self.udp_port_out)
6069 self.assertEqual(s.ext_port, self.udp_external_port)
6073 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6074 self.assertEqual(s.in_port, self.icmp_id_in)
6075 self.assertEqual(s.out_port, self.icmp_external_id)
6077 def test_multiple_users(self):
6078 """ Deterministic NAT multiple users """
6080 nat_ip = "10.0.0.10"
6082 external_port = 6303
6084 host0 = self.pg0.remote_hosts[0]
6085 host1 = self.pg0.remote_hosts[1]
6087 self.vapi.nat_det_add_del_map(host0.ip4n,
6089 socket.inet_aton(nat_ip),
6091 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6092 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6096 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6097 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6098 TCP(sport=port_in, dport=external_port))
6099 self.pg0.add_stream(p)
6100 self.pg_enable_capture(self.pg_interfaces)
6102 capture = self.pg1.get_capture(1)
6107 self.assertEqual(ip.src, nat_ip)
6108 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6109 self.assertEqual(tcp.dport, external_port)
6110 port_out0 = tcp.sport
6112 self.logger.error(ppp("Unexpected or invalid packet:", p))
6116 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6117 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6118 TCP(sport=port_in, dport=external_port))
6119 self.pg0.add_stream(p)
6120 self.pg_enable_capture(self.pg_interfaces)
6122 capture = self.pg1.get_capture(1)
6127 self.assertEqual(ip.src, nat_ip)
6128 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6129 self.assertEqual(tcp.dport, external_port)
6130 port_out1 = tcp.sport
6132 self.logger.error(ppp("Unexpected or invalid packet:", p))
6135 dms = self.vapi.nat_det_map_dump()
6136 self.assertEqual(1, len(dms))
6137 self.assertEqual(2, dms[0].ses_num)
6140 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6141 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6142 TCP(sport=external_port, dport=port_out0))
6143 self.pg1.add_stream(p)
6144 self.pg_enable_capture(self.pg_interfaces)
6146 capture = self.pg0.get_capture(1)
6151 self.assertEqual(ip.src, self.pg1.remote_ip4)
6152 self.assertEqual(ip.dst, host0.ip4)
6153 self.assertEqual(tcp.dport, port_in)
6154 self.assertEqual(tcp.sport, external_port)
6156 self.logger.error(ppp("Unexpected or invalid packet:", p))
6160 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6161 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6162 TCP(sport=external_port, dport=port_out1))
6163 self.pg1.add_stream(p)
6164 self.pg_enable_capture(self.pg_interfaces)
6166 capture = self.pg0.get_capture(1)
6171 self.assertEqual(ip.src, self.pg1.remote_ip4)
6172 self.assertEqual(ip.dst, host1.ip4)
6173 self.assertEqual(tcp.dport, port_in)
6174 self.assertEqual(tcp.sport, external_port)
6176 self.logger.error(ppp("Unexpected or invalid packet", p))
6179 # session close api test
6180 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6182 self.pg1.remote_ip4n,
6184 dms = self.vapi.nat_det_map_dump()
6185 self.assertEqual(dms[0].ses_num, 1)
6187 self.vapi.nat_det_close_session_in(host0.ip4n,
6189 self.pg1.remote_ip4n,
6191 dms = self.vapi.nat_det_map_dump()
6192 self.assertEqual(dms[0].ses_num, 0)
6194 def test_tcp_session_close_detection_in(self):
6195 """ Deterministic NAT TCP session close from inside network """
6196 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6198 socket.inet_aton(self.nat_addr),
6200 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6201 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6204 self.initiate_tcp_session(self.pg0, self.pg1)
6206 # close the session from inside
6208 # FIN packet in -> out
6209 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6210 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6211 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6213 self.pg0.add_stream(p)
6214 self.pg_enable_capture(self.pg_interfaces)
6216 self.pg1.get_capture(1)
6220 # ACK packet out -> in
6221 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6222 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6223 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6227 # FIN packet out -> in
6228 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6229 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6230 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6234 self.pg1.add_stream(pkts)
6235 self.pg_enable_capture(self.pg_interfaces)
6237 self.pg0.get_capture(2)
6239 # ACK packet in -> out
6240 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6241 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6242 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6244 self.pg0.add_stream(p)
6245 self.pg_enable_capture(self.pg_interfaces)
6247 self.pg1.get_capture(1)
6249 # Check if deterministic NAT44 closed the session
6250 dms = self.vapi.nat_det_map_dump()
6251 self.assertEqual(0, dms[0].ses_num)
6253 self.logger.error("TCP session termination failed")
6256 def test_tcp_session_close_detection_out(self):
6257 """ Deterministic NAT TCP session close from outside network """
6258 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6260 socket.inet_aton(self.nat_addr),
6262 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6263 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6266 self.initiate_tcp_session(self.pg0, self.pg1)
6268 # close the session from outside
6270 # FIN packet out -> in
6271 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6272 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6273 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6275 self.pg1.add_stream(p)
6276 self.pg_enable_capture(self.pg_interfaces)
6278 self.pg0.get_capture(1)
6282 # ACK packet in -> out
6283 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6284 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6285 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6289 # ACK packet in -> out
6290 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6291 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6292 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6296 self.pg0.add_stream(pkts)
6297 self.pg_enable_capture(self.pg_interfaces)
6299 self.pg1.get_capture(2)
6301 # ACK packet out -> in
6302 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6303 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6304 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6306 self.pg1.add_stream(p)
6307 self.pg_enable_capture(self.pg_interfaces)
6309 self.pg0.get_capture(1)
6311 # Check if deterministic NAT44 closed the session
6312 dms = self.vapi.nat_det_map_dump()
6313 self.assertEqual(0, dms[0].ses_num)
6315 self.logger.error("TCP session termination failed")
6318 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6319 def test_session_timeout(self):
6320 """ Deterministic NAT session timeouts """
6321 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6323 socket.inet_aton(self.nat_addr),
6325 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6326 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6329 self.initiate_tcp_session(self.pg0, self.pg1)
6330 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6331 pkts = self.create_stream_in(self.pg0, self.pg1)
6332 self.pg0.add_stream(pkts)
6333 self.pg_enable_capture(self.pg_interfaces)
6335 capture = self.pg1.get_capture(len(pkts))
6338 dms = self.vapi.nat_det_map_dump()
6339 self.assertEqual(0, dms[0].ses_num)
6341 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6342 def test_session_limit_per_user(self):
6343 """ Deterministic NAT maximum sessions per user limit """
6344 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6346 socket.inet_aton(self.nat_addr),
6348 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6349 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6351 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6352 src_address=self.pg2.local_ip4n,
6354 template_interval=10)
6355 self.vapi.nat_ipfix()
6358 for port in range(1025, 2025):
6359 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6360 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6361 UDP(sport=port, dport=port))
6364 self.pg0.add_stream(pkts)
6365 self.pg_enable_capture(self.pg_interfaces)
6367 capture = self.pg1.get_capture(len(pkts))
6369 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6370 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6371 UDP(sport=3001, dport=3002))
6372 self.pg0.add_stream(p)
6373 self.pg_enable_capture(self.pg_interfaces)
6375 capture = self.pg1.assert_nothing_captured()
6377 # verify ICMP error packet
6378 capture = self.pg0.get_capture(1)
6380 self.assertTrue(p.haslayer(ICMP))
6382 self.assertEqual(icmp.type, 3)
6383 self.assertEqual(icmp.code, 1)
6384 self.assertTrue(icmp.haslayer(IPerror))
6385 inner_ip = icmp[IPerror]
6386 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6387 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6389 dms = self.vapi.nat_det_map_dump()
6391 self.assertEqual(1000, dms[0].ses_num)
6393 # verify IPFIX logging
6394 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6396 capture = self.pg2.get_capture(2)
6397 ipfix = IPFIXDecoder()
6398 # first load template
6400 self.assertTrue(p.haslayer(IPFIX))
6401 if p.haslayer(Template):
6402 ipfix.add_template(p.getlayer(Template))
6403 # verify events in data set
6405 if p.haslayer(Data):
6406 data = ipfix.decode_data_set(p.getlayer(Set))
6407 self.verify_ipfix_max_entries_per_user(data,
6409 self.pg0.remote_ip4n)
6411 def clear_nat_det(self):
6413 Clear deterministic NAT configuration.
6415 self.vapi.nat_ipfix(enable=0)
6416 self.vapi.nat_set_timeouts()
6417 deterministic_mappings = self.vapi.nat_det_map_dump()
6418 for dsm in deterministic_mappings:
6419 self.vapi.nat_det_add_del_map(dsm.in_addr,
6425 interfaces = self.vapi.nat44_interface_dump()
6426 for intf in interfaces:
6427 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6432 super(TestDeterministicNAT, self).tearDown()
6433 if not self.vpp_dead:
6434 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6435 self.logger.info(self.vapi.cli("show nat timeouts"))
6437 self.vapi.cli("show nat44 deterministic mappings"))
6439 self.vapi.cli("show nat44 deterministic sessions"))
6440 self.clear_nat_det()
6443 class TestNAT64(MethodHolder):
6444 """ NAT64 Test Cases """
6447 def setUpConstants(cls):
6448 super(TestNAT64, cls).setUpConstants()
6449 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6450 "nat64 st hash buckets 256", "}"])
6453 def setUpClass(cls):
6454 super(TestNAT64, cls).setUpClass()
6457 cls.tcp_port_in = 6303
6458 cls.tcp_port_out = 6303
6459 cls.udp_port_in = 6304
6460 cls.udp_port_out = 6304
6461 cls.icmp_id_in = 6305
6462 cls.icmp_id_out = 6305
6463 cls.nat_addr = '10.0.0.3'
6464 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6466 cls.vrf1_nat_addr = '10.0.10.3'
6467 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6469 cls.ipfix_src_port = 4739
6470 cls.ipfix_domain_id = 1
6472 cls.create_pg_interfaces(range(6))
6473 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6474 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6475 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6477 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6479 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6481 cls.pg0.generate_remote_hosts(2)
6483 for i in cls.ip6_interfaces:
6486 i.configure_ipv6_neighbors()
6488 for i in cls.ip4_interfaces:
6494 cls.pg3.config_ip4()
6495 cls.pg3.resolve_arp()
6496 cls.pg3.config_ip6()
6497 cls.pg3.configure_ipv6_neighbors()
6500 cls.pg5.config_ip6()
6503 super(TestNAT64, cls).tearDownClass()
6506 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6507 """ NAT64 inside interface handles Neighbor Advertisement """
6509 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6512 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6513 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6514 ICMPv6EchoRequest())
6516 self.pg5.add_stream(pkts)
6517 self.pg_enable_capture(self.pg_interfaces)
6520 # Wait for Neighbor Solicitation
6521 capture = self.pg5.get_capture(len(pkts))
6524 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6525 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6526 tgt = packet[ICMPv6ND_NS].tgt
6528 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6531 # Send Neighbor Advertisement
6532 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6533 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6534 ICMPv6ND_NA(tgt=tgt) /
6535 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6537 self.pg5.add_stream(pkts)
6538 self.pg_enable_capture(self.pg_interfaces)
6541 # Try to send ping again
6543 self.pg5.add_stream(pkts)
6544 self.pg_enable_capture(self.pg_interfaces)
6547 # Wait for ping reply
6548 capture = self.pg5.get_capture(len(pkts))
6551 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6552 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6553 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6555 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6558 def test_pool(self):
6559 """ Add/delete address to NAT64 pool """
6560 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6562 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6564 addresses = self.vapi.nat64_pool_addr_dump()
6565 self.assertEqual(len(addresses), 1)
6566 self.assertEqual(addresses[0].address, nat_addr)
6568 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6570 addresses = self.vapi.nat64_pool_addr_dump()
6571 self.assertEqual(len(addresses), 0)
6573 def test_interface(self):
6574 """ Enable/disable NAT64 feature on the interface """
6575 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6576 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6578 interfaces = self.vapi.nat64_interface_dump()
6579 self.assertEqual(len(interfaces), 2)
6582 for intf in interfaces:
6583 if intf.sw_if_index == self.pg0.sw_if_index:
6584 self.assertEqual(intf.is_inside, 1)
6586 elif intf.sw_if_index == self.pg1.sw_if_index:
6587 self.assertEqual(intf.is_inside, 0)
6589 self.assertTrue(pg0_found)
6590 self.assertTrue(pg1_found)
6592 features = self.vapi.cli("show interface features pg0")
6593 self.assertNotEqual(features.find('nat64-in2out'), -1)
6594 features = self.vapi.cli("show interface features pg1")
6595 self.assertNotEqual(features.find('nat64-out2in'), -1)
6597 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6598 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6600 interfaces = self.vapi.nat64_interface_dump()
6601 self.assertEqual(len(interfaces), 0)
6603 def test_static_bib(self):
6604 """ Add/delete static BIB entry """
6605 in_addr = socket.inet_pton(socket.AF_INET6,
6606 '2001:db8:85a3::8a2e:370:7334')
6607 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6610 proto = IP_PROTOS.tcp
6612 self.vapi.nat64_add_del_static_bib(in_addr,
6617 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6622 self.assertEqual(bibe.i_addr, in_addr)
6623 self.assertEqual(bibe.o_addr, out_addr)
6624 self.assertEqual(bibe.i_port, in_port)
6625 self.assertEqual(bibe.o_port, out_port)
6626 self.assertEqual(static_bib_num, 1)
6628 self.vapi.nat64_add_del_static_bib(in_addr,
6634 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6639 self.assertEqual(static_bib_num, 0)
6641 def test_set_timeouts(self):
6642 """ Set NAT64 timeouts """
6643 # verify default values
6644 timeouts = self.vapi.nat_get_timeouts()
6645 self.assertEqual(timeouts.udp, 300)
6646 self.assertEqual(timeouts.icmp, 60)
6647 self.assertEqual(timeouts.tcp_transitory, 240)
6648 self.assertEqual(timeouts.tcp_established, 7440)
6650 # set and verify custom values
6651 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6652 tcp_established=7450)
6653 timeouts = self.vapi.nat_get_timeouts()
6654 self.assertEqual(timeouts.udp, 200)
6655 self.assertEqual(timeouts.icmp, 30)
6656 self.assertEqual(timeouts.tcp_transitory, 250)
6657 self.assertEqual(timeouts.tcp_established, 7450)
6659 def test_dynamic(self):
6660 """ NAT64 dynamic translation test """
6661 self.tcp_port_in = 6303
6662 self.udp_port_in = 6304
6663 self.icmp_id_in = 6305
6665 ses_num_start = self.nat64_get_ses_num()
6667 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6669 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6670 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6673 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6674 self.pg0.add_stream(pkts)
6675 self.pg_enable_capture(self.pg_interfaces)
6677 capture = self.pg1.get_capture(len(pkts))
6678 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6679 dst_ip=self.pg1.remote_ip4)
6682 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6683 self.pg1.add_stream(pkts)
6684 self.pg_enable_capture(self.pg_interfaces)
6686 capture = self.pg0.get_capture(len(pkts))
6687 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6688 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6691 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6692 self.pg0.add_stream(pkts)
6693 self.pg_enable_capture(self.pg_interfaces)
6695 capture = self.pg1.get_capture(len(pkts))
6696 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6697 dst_ip=self.pg1.remote_ip4)
6700 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6701 self.pg1.add_stream(pkts)
6702 self.pg_enable_capture(self.pg_interfaces)
6704 capture = self.pg0.get_capture(len(pkts))
6705 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6707 ses_num_end = self.nat64_get_ses_num()
6709 self.assertEqual(ses_num_end - ses_num_start, 3)
6711 # tenant with specific VRF
6712 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6713 self.vrf1_nat_addr_n,
6714 vrf_id=self.vrf1_id)
6715 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6717 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6718 self.pg2.add_stream(pkts)
6719 self.pg_enable_capture(self.pg_interfaces)
6721 capture = self.pg1.get_capture(len(pkts))
6722 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6723 dst_ip=self.pg1.remote_ip4)
6725 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6726 self.pg1.add_stream(pkts)
6727 self.pg_enable_capture(self.pg_interfaces)
6729 capture = self.pg2.get_capture(len(pkts))
6730 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6732 def test_static(self):
6733 """ NAT64 static translation test """
6734 self.tcp_port_in = 60303
6735 self.udp_port_in = 60304
6736 self.icmp_id_in = 60305
6737 self.tcp_port_out = 60303
6738 self.udp_port_out = 60304
6739 self.icmp_id_out = 60305
6741 ses_num_start = self.nat64_get_ses_num()
6743 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6745 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6746 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6748 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6753 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6758 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6765 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6766 self.pg0.add_stream(pkts)
6767 self.pg_enable_capture(self.pg_interfaces)
6769 capture = self.pg1.get_capture(len(pkts))
6770 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6771 dst_ip=self.pg1.remote_ip4, same_port=True)
6774 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6775 self.pg1.add_stream(pkts)
6776 self.pg_enable_capture(self.pg_interfaces)
6778 capture = self.pg0.get_capture(len(pkts))
6779 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6780 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6782 ses_num_end = self.nat64_get_ses_num()
6784 self.assertEqual(ses_num_end - ses_num_start, 3)
6786 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6787 def test_session_timeout(self):
6788 """ NAT64 session timeout """
6789 self.icmp_id_in = 1234
6790 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6792 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6793 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6794 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6796 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6797 self.pg0.add_stream(pkts)
6798 self.pg_enable_capture(self.pg_interfaces)
6800 capture = self.pg1.get_capture(len(pkts))
6802 ses_num_before_timeout = self.nat64_get_ses_num()
6806 # ICMP and TCP session after timeout
6807 ses_num_after_timeout = self.nat64_get_ses_num()
6808 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6810 def test_icmp_error(self):
6811 """ NAT64 ICMP Error message translation """
6812 self.tcp_port_in = 6303
6813 self.udp_port_in = 6304
6814 self.icmp_id_in = 6305
6816 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6818 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6819 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6821 # send some packets to create sessions
6822 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6823 self.pg0.add_stream(pkts)
6824 self.pg_enable_capture(self.pg_interfaces)
6826 capture_ip4 = self.pg1.get_capture(len(pkts))
6827 self.verify_capture_out(capture_ip4,
6828 nat_ip=self.nat_addr,
6829 dst_ip=self.pg1.remote_ip4)
6831 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6832 self.pg1.add_stream(pkts)
6833 self.pg_enable_capture(self.pg_interfaces)
6835 capture_ip6 = self.pg0.get_capture(len(pkts))
6836 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6837 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6838 self.pg0.remote_ip6)
6841 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6842 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6843 ICMPv6DestUnreach(code=1) /
6844 packet[IPv6] for packet in capture_ip6]
6845 self.pg0.add_stream(pkts)
6846 self.pg_enable_capture(self.pg_interfaces)
6848 capture = self.pg1.get_capture(len(pkts))
6849 for packet in capture:
6851 self.assertEqual(packet[IP].src, self.nat_addr)
6852 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6853 self.assertEqual(packet[ICMP].type, 3)
6854 self.assertEqual(packet[ICMP].code, 13)
6855 inner = packet[IPerror]
6856 self.assertEqual(inner.src, self.pg1.remote_ip4)
6857 self.assertEqual(inner.dst, self.nat_addr)
6858 self.assert_packet_checksums_valid(packet)
6859 if inner.haslayer(TCPerror):
6860 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6861 elif inner.haslayer(UDPerror):
6862 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6864 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6866 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6870 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6871 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6872 ICMP(type=3, code=13) /
6873 packet[IP] for packet in capture_ip4]
6874 self.pg1.add_stream(pkts)
6875 self.pg_enable_capture(self.pg_interfaces)
6877 capture = self.pg0.get_capture(len(pkts))
6878 for packet in capture:
6880 self.assertEqual(packet[IPv6].src, ip.src)
6881 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6882 icmp = packet[ICMPv6DestUnreach]
6883 self.assertEqual(icmp.code, 1)
6884 inner = icmp[IPerror6]
6885 self.assertEqual(inner.src, self.pg0.remote_ip6)
6886 self.assertEqual(inner.dst, ip.src)
6887 self.assert_icmpv6_checksum_valid(packet)
6888 if inner.haslayer(TCPerror):
6889 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6890 elif inner.haslayer(UDPerror):
6891 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6893 self.assertEqual(inner[ICMPv6EchoRequest].id,
6896 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6899 def test_hairpinning(self):
6900 """ NAT64 hairpinning """
6902 client = self.pg0.remote_hosts[0]
6903 server = self.pg0.remote_hosts[1]
6904 server_tcp_in_port = 22
6905 server_tcp_out_port = 4022
6906 server_udp_in_port = 23
6907 server_udp_out_port = 4023
6908 client_tcp_in_port = 1234
6909 client_udp_in_port = 1235
6910 client_tcp_out_port = 0
6911 client_udp_out_port = 0
6912 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6913 nat_addr_ip6 = ip.src
6915 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6917 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6918 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6920 self.vapi.nat64_add_del_static_bib(server.ip6n,
6923 server_tcp_out_port,
6925 self.vapi.nat64_add_del_static_bib(server.ip6n,
6928 server_udp_out_port,
6933 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6934 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6935 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6937 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6938 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6939 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6941 self.pg0.add_stream(pkts)
6942 self.pg_enable_capture(self.pg_interfaces)
6944 capture = self.pg0.get_capture(len(pkts))
6945 for packet in capture:
6947 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6948 self.assertEqual(packet[IPv6].dst, server.ip6)
6949 self.assert_packet_checksums_valid(packet)
6950 if packet.haslayer(TCP):
6951 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6952 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
6953 client_tcp_out_port = packet[TCP].sport
6955 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6956 self.assertEqual(packet[UDP].dport, server_udp_in_port)
6957 client_udp_out_port = packet[UDP].sport
6959 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6964 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6965 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6966 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6968 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6969 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6970 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6972 self.pg0.add_stream(pkts)
6973 self.pg_enable_capture(self.pg_interfaces)
6975 capture = self.pg0.get_capture(len(pkts))
6976 for packet in capture:
6978 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6979 self.assertEqual(packet[IPv6].dst, client.ip6)
6980 self.assert_packet_checksums_valid(packet)
6981 if packet.haslayer(TCP):
6982 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6983 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
6985 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6986 self.assertEqual(packet[UDP].dport, client_udp_in_port)
6988 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6993 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6994 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6995 ICMPv6DestUnreach(code=1) /
6996 packet[IPv6] for packet in capture]
6997 self.pg0.add_stream(pkts)
6998 self.pg_enable_capture(self.pg_interfaces)
7000 capture = self.pg0.get_capture(len(pkts))
7001 for packet in capture:
7003 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7004 self.assertEqual(packet[IPv6].dst, server.ip6)
7005 icmp = packet[ICMPv6DestUnreach]
7006 self.assertEqual(icmp.code, 1)
7007 inner = icmp[IPerror6]
7008 self.assertEqual(inner.src, server.ip6)
7009 self.assertEqual(inner.dst, nat_addr_ip6)
7010 self.assert_packet_checksums_valid(packet)
7011 if inner.haslayer(TCPerror):
7012 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7013 self.assertEqual(inner[TCPerror].dport,
7014 client_tcp_out_port)
7016 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7017 self.assertEqual(inner[UDPerror].dport,
7018 client_udp_out_port)
7020 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7023 def test_prefix(self):
7024 """ NAT64 Network-Specific Prefix """
7026 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7028 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7029 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7030 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7031 self.vrf1_nat_addr_n,
7032 vrf_id=self.vrf1_id)
7033 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7036 global_pref64 = "2001:db8::"
7037 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7038 global_pref64_len = 32
7039 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7041 prefix = self.vapi.nat64_prefix_dump()
7042 self.assertEqual(len(prefix), 1)
7043 self.assertEqual(prefix[0].prefix, global_pref64_n)
7044 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7045 self.assertEqual(prefix[0].vrf_id, 0)
7047 # Add tenant specific prefix
7048 vrf1_pref64 = "2001:db8:122:300::"
7049 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7050 vrf1_pref64_len = 56
7051 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7053 vrf_id=self.vrf1_id)
7054 prefix = self.vapi.nat64_prefix_dump()
7055 self.assertEqual(len(prefix), 2)
7058 pkts = self.create_stream_in_ip6(self.pg0,
7061 plen=global_pref64_len)
7062 self.pg0.add_stream(pkts)
7063 self.pg_enable_capture(self.pg_interfaces)
7065 capture = self.pg1.get_capture(len(pkts))
7066 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7067 dst_ip=self.pg1.remote_ip4)
7069 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7070 self.pg1.add_stream(pkts)
7071 self.pg_enable_capture(self.pg_interfaces)
7073 capture = self.pg0.get_capture(len(pkts))
7074 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7077 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7079 # Tenant specific prefix
7080 pkts = self.create_stream_in_ip6(self.pg2,
7083 plen=vrf1_pref64_len)
7084 self.pg2.add_stream(pkts)
7085 self.pg_enable_capture(self.pg_interfaces)
7087 capture = self.pg1.get_capture(len(pkts))
7088 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7089 dst_ip=self.pg1.remote_ip4)
7091 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7092 self.pg1.add_stream(pkts)
7093 self.pg_enable_capture(self.pg_interfaces)
7095 capture = self.pg2.get_capture(len(pkts))
7096 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7099 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7101 def test_unknown_proto(self):
7102 """ NAT64 translate packet with unknown protocol """
7104 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7106 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7107 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7108 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7111 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7112 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7113 TCP(sport=self.tcp_port_in, dport=20))
7114 self.pg0.add_stream(p)
7115 self.pg_enable_capture(self.pg_interfaces)
7117 p = self.pg1.get_capture(1)
7119 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7120 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7122 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7123 TCP(sport=1234, dport=1234))
7124 self.pg0.add_stream(p)
7125 self.pg_enable_capture(self.pg_interfaces)
7127 p = self.pg1.get_capture(1)
7130 self.assertEqual(packet[IP].src, self.nat_addr)
7131 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7132 self.assertTrue(packet.haslayer(GRE))
7133 self.assert_packet_checksums_valid(packet)
7135 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7139 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7140 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7142 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7143 TCP(sport=1234, dport=1234))
7144 self.pg1.add_stream(p)
7145 self.pg_enable_capture(self.pg_interfaces)
7147 p = self.pg0.get_capture(1)
7150 self.assertEqual(packet[IPv6].src, remote_ip6)
7151 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7152 self.assertEqual(packet[IPv6].nh, 47)
7154 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7157 def test_hairpinning_unknown_proto(self):
7158 """ NAT64 translate packet with unknown protocol - hairpinning """
7160 client = self.pg0.remote_hosts[0]
7161 server = self.pg0.remote_hosts[1]
7162 server_tcp_in_port = 22
7163 server_tcp_out_port = 4022
7164 client_tcp_in_port = 1234
7165 client_tcp_out_port = 1235
7166 server_nat_ip = "10.0.0.100"
7167 client_nat_ip = "10.0.0.110"
7168 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7169 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7170 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7171 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7173 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7175 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7176 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7178 self.vapi.nat64_add_del_static_bib(server.ip6n,
7181 server_tcp_out_port,
7184 self.vapi.nat64_add_del_static_bib(server.ip6n,
7190 self.vapi.nat64_add_del_static_bib(client.ip6n,
7193 client_tcp_out_port,
7197 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7198 IPv6(src=client.ip6, dst=server_nat_ip6) /
7199 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7200 self.pg0.add_stream(p)
7201 self.pg_enable_capture(self.pg_interfaces)
7203 p = self.pg0.get_capture(1)
7205 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7206 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7208 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7209 TCP(sport=1234, dport=1234))
7210 self.pg0.add_stream(p)
7211 self.pg_enable_capture(self.pg_interfaces)
7213 p = self.pg0.get_capture(1)
7216 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7217 self.assertEqual(packet[IPv6].dst, server.ip6)
7218 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7220 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7224 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7225 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7227 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7228 TCP(sport=1234, dport=1234))
7229 self.pg0.add_stream(p)
7230 self.pg_enable_capture(self.pg_interfaces)
7232 p = self.pg0.get_capture(1)
7235 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7236 self.assertEqual(packet[IPv6].dst, client.ip6)
7237 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7239 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7242 def test_one_armed_nat64(self):
7243 """ One armed NAT64 """
7245 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7249 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7251 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7252 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7255 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7256 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7257 TCP(sport=12345, dport=80))
7258 self.pg3.add_stream(p)
7259 self.pg_enable_capture(self.pg_interfaces)
7261 capture = self.pg3.get_capture(1)
7266 self.assertEqual(ip.src, self.nat_addr)
7267 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7268 self.assertNotEqual(tcp.sport, 12345)
7269 external_port = tcp.sport
7270 self.assertEqual(tcp.dport, 80)
7271 self.assert_packet_checksums_valid(p)
7273 self.logger.error(ppp("Unexpected or invalid packet:", p))
7277 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7278 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7279 TCP(sport=80, dport=external_port))
7280 self.pg3.add_stream(p)
7281 self.pg_enable_capture(self.pg_interfaces)
7283 capture = self.pg3.get_capture(1)
7288 self.assertEqual(ip.src, remote_host_ip6)
7289 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7290 self.assertEqual(tcp.sport, 80)
7291 self.assertEqual(tcp.dport, 12345)
7292 self.assert_packet_checksums_valid(p)
7294 self.logger.error(ppp("Unexpected or invalid packet:", p))
7297 def test_frag_in_order(self):
7298 """ NAT64 translate fragments arriving in order """
7299 self.tcp_port_in = random.randint(1025, 65535)
7301 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7303 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7304 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7306 reass = self.vapi.nat_reass_dump()
7307 reass_n_start = len(reass)
7311 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7312 self.tcp_port_in, 20, data)
7313 self.pg0.add_stream(pkts)
7314 self.pg_enable_capture(self.pg_interfaces)
7316 frags = self.pg1.get_capture(len(pkts))
7317 p = self.reass_frags_and_verify(frags,
7319 self.pg1.remote_ip4)
7320 self.assertEqual(p[TCP].dport, 20)
7321 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7322 self.tcp_port_out = p[TCP].sport
7323 self.assertEqual(data, p[Raw].load)
7326 data = "A" * 4 + "b" * 16 + "C" * 3
7327 pkts = self.create_stream_frag(self.pg1,
7332 self.pg1.add_stream(pkts)
7333 self.pg_enable_capture(self.pg_interfaces)
7335 frags = self.pg0.get_capture(len(pkts))
7336 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7337 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7338 self.assertEqual(p[TCP].sport, 20)
7339 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7340 self.assertEqual(data, p[Raw].load)
7342 reass = self.vapi.nat_reass_dump()
7343 reass_n_end = len(reass)
7345 self.assertEqual(reass_n_end - reass_n_start, 2)
7347 def test_reass_hairpinning(self):
7348 """ NAT64 fragments hairpinning """
7350 server = self.pg0.remote_hosts[1]
7351 server_in_port = random.randint(1025, 65535)
7352 server_out_port = random.randint(1025, 65535)
7353 client_in_port = random.randint(1025, 65535)
7354 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7355 nat_addr_ip6 = ip.src
7357 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7359 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7360 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7362 # add static BIB entry for server
7363 self.vapi.nat64_add_del_static_bib(server.ip6n,
7369 # send packet from host to server
7370 pkts = self.create_stream_frag_ip6(self.pg0,
7375 self.pg0.add_stream(pkts)
7376 self.pg_enable_capture(self.pg_interfaces)
7378 frags = self.pg0.get_capture(len(pkts))
7379 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7380 self.assertNotEqual(p[TCP].sport, client_in_port)
7381 self.assertEqual(p[TCP].dport, server_in_port)
7382 self.assertEqual(data, p[Raw].load)
7384 def test_frag_out_of_order(self):
7385 """ NAT64 translate fragments arriving out of order """
7386 self.tcp_port_in = random.randint(1025, 65535)
7388 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7390 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7391 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7395 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7396 self.tcp_port_in, 20, data)
7398 self.pg0.add_stream(pkts)
7399 self.pg_enable_capture(self.pg_interfaces)
7401 frags = self.pg1.get_capture(len(pkts))
7402 p = self.reass_frags_and_verify(frags,
7404 self.pg1.remote_ip4)
7405 self.assertEqual(p[TCP].dport, 20)
7406 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7407 self.tcp_port_out = p[TCP].sport
7408 self.assertEqual(data, p[Raw].load)
7411 data = "A" * 4 + "B" * 16 + "C" * 3
7412 pkts = self.create_stream_frag(self.pg1,
7418 self.pg1.add_stream(pkts)
7419 self.pg_enable_capture(self.pg_interfaces)
7421 frags = self.pg0.get_capture(len(pkts))
7422 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7423 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7424 self.assertEqual(p[TCP].sport, 20)
7425 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7426 self.assertEqual(data, p[Raw].load)
7428 def test_interface_addr(self):
7429 """ Acquire NAT64 pool addresses from interface """
7430 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7432 # no address in NAT64 pool
7433 adresses = self.vapi.nat44_address_dump()
7434 self.assertEqual(0, len(adresses))
7436 # configure interface address and check NAT64 address pool
7437 self.pg4.config_ip4()
7438 addresses = self.vapi.nat64_pool_addr_dump()
7439 self.assertEqual(len(addresses), 1)
7440 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7442 # remove interface address and check NAT64 address pool
7443 self.pg4.unconfig_ip4()
7444 addresses = self.vapi.nat64_pool_addr_dump()
7445 self.assertEqual(0, len(adresses))
7447 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7448 def test_ipfix_max_bibs_sessions(self):
7449 """ IPFIX logging maximum session and BIB entries exceeded """
7452 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7456 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7458 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7459 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7463 for i in range(0, max_bibs):
7464 src = "fd01:aa::%x" % (i)
7465 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7466 IPv6(src=src, dst=remote_host_ip6) /
7467 TCP(sport=12345, dport=80))
7469 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7470 IPv6(src=src, dst=remote_host_ip6) /
7471 TCP(sport=12345, dport=22))
7473 self.pg0.add_stream(pkts)
7474 self.pg_enable_capture(self.pg_interfaces)
7476 self.pg1.get_capture(max_sessions)
7478 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7479 src_address=self.pg3.local_ip4n,
7481 template_interval=10)
7482 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7483 src_port=self.ipfix_src_port)
7485 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7486 IPv6(src=src, dst=remote_host_ip6) /
7487 TCP(sport=12345, dport=25))
7488 self.pg0.add_stream(p)
7489 self.pg_enable_capture(self.pg_interfaces)
7491 self.pg1.assert_nothing_captured()
7493 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7494 capture = self.pg3.get_capture(9)
7495 ipfix = IPFIXDecoder()
7496 # first load template
7498 self.assertTrue(p.haslayer(IPFIX))
7499 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7500 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7501 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7502 self.assertEqual(p[UDP].dport, 4739)
7503 self.assertEqual(p[IPFIX].observationDomainID,
7504 self.ipfix_domain_id)
7505 if p.haslayer(Template):
7506 ipfix.add_template(p.getlayer(Template))
7507 # verify events in data set
7509 if p.haslayer(Data):
7510 data = ipfix.decode_data_set(p.getlayer(Set))
7511 self.verify_ipfix_max_sessions(data, max_sessions)
7513 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7514 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7515 TCP(sport=12345, dport=80))
7516 self.pg0.add_stream(p)
7517 self.pg_enable_capture(self.pg_interfaces)
7519 self.pg1.assert_nothing_captured()
7521 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7522 capture = self.pg3.get_capture(1)
7523 # verify events in data set
7525 self.assertTrue(p.haslayer(IPFIX))
7526 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7527 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7528 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7529 self.assertEqual(p[UDP].dport, 4739)
7530 self.assertEqual(p[IPFIX].observationDomainID,
7531 self.ipfix_domain_id)
7532 if p.haslayer(Data):
7533 data = ipfix.decode_data_set(p.getlayer(Set))
7534 self.verify_ipfix_max_bibs(data, max_bibs)
7536 def test_ipfix_max_frags(self):
7537 """ IPFIX logging maximum fragments pending reassembly exceeded """
7538 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7540 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7541 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7542 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7543 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7544 src_address=self.pg3.local_ip4n,
7546 template_interval=10)
7547 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7548 src_port=self.ipfix_src_port)
7551 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7552 self.tcp_port_in, 20, data)
7554 self.pg0.add_stream(pkts)
7555 self.pg_enable_capture(self.pg_interfaces)
7557 self.pg1.assert_nothing_captured()
7559 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7560 capture = self.pg3.get_capture(9)
7561 ipfix = IPFIXDecoder()
7562 # first load template
7564 self.assertTrue(p.haslayer(IPFIX))
7565 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7566 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7567 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7568 self.assertEqual(p[UDP].dport, 4739)
7569 self.assertEqual(p[IPFIX].observationDomainID,
7570 self.ipfix_domain_id)
7571 if p.haslayer(Template):
7572 ipfix.add_template(p.getlayer(Template))
7573 # verify events in data set
7575 if p.haslayer(Data):
7576 data = ipfix.decode_data_set(p.getlayer(Set))
7577 self.verify_ipfix_max_fragments_ip6(data, 1,
7578 self.pg0.remote_ip6n)
7580 def test_ipfix_bib_ses(self):
7581 """ IPFIX logging NAT64 BIB/session create and delete events """
7582 self.tcp_port_in = random.randint(1025, 65535)
7583 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7587 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7589 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7590 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7591 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7592 src_address=self.pg3.local_ip4n,
7594 template_interval=10)
7595 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7596 src_port=self.ipfix_src_port)
7599 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7600 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7601 TCP(sport=self.tcp_port_in, dport=25))
7602 self.pg0.add_stream(p)
7603 self.pg_enable_capture(self.pg_interfaces)
7605 p = self.pg1.get_capture(1)
7606 self.tcp_port_out = p[0][TCP].sport
7607 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7608 capture = self.pg3.get_capture(10)
7609 ipfix = IPFIXDecoder()
7610 # first load template
7612 self.assertTrue(p.haslayer(IPFIX))
7613 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7614 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7615 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7616 self.assertEqual(p[UDP].dport, 4739)
7617 self.assertEqual(p[IPFIX].observationDomainID,
7618 self.ipfix_domain_id)
7619 if p.haslayer(Template):
7620 ipfix.add_template(p.getlayer(Template))
7621 # verify events in data set
7623 if p.haslayer(Data):
7624 data = ipfix.decode_data_set(p.getlayer(Set))
7625 if ord(data[0][230]) == 10:
7626 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7627 elif ord(data[0][230]) == 6:
7628 self.verify_ipfix_nat64_ses(data,
7630 self.pg0.remote_ip6n,
7631 self.pg1.remote_ip4,
7634 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7637 self.pg_enable_capture(self.pg_interfaces)
7638 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7641 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7642 capture = self.pg3.get_capture(2)
7643 # verify events in data set
7645 self.assertTrue(p.haslayer(IPFIX))
7646 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7647 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7648 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7649 self.assertEqual(p[UDP].dport, 4739)
7650 self.assertEqual(p[IPFIX].observationDomainID,
7651 self.ipfix_domain_id)
7652 if p.haslayer(Data):
7653 data = ipfix.decode_data_set(p.getlayer(Set))
7654 if ord(data[0][230]) == 11:
7655 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7656 elif ord(data[0][230]) == 7:
7657 self.verify_ipfix_nat64_ses(data,
7659 self.pg0.remote_ip6n,
7660 self.pg1.remote_ip4,
7663 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7665 def nat64_get_ses_num(self):
7667 Return number of active NAT64 sessions.
7669 st = self.vapi.nat64_st_dump()
7672 def clear_nat64(self):
7674 Clear NAT64 configuration.
7676 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7677 domain_id=self.ipfix_domain_id)
7678 self.ipfix_src_port = 4739
7679 self.ipfix_domain_id = 1
7681 self.vapi.nat_set_timeouts()
7683 interfaces = self.vapi.nat64_interface_dump()
7684 for intf in interfaces:
7685 if intf.is_inside > 1:
7686 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7689 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7693 bib = self.vapi.nat64_bib_dump(255)
7696 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7704 adresses = self.vapi.nat64_pool_addr_dump()
7705 for addr in adresses:
7706 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7711 prefixes = self.vapi.nat64_prefix_dump()
7712 for prefix in prefixes:
7713 self.vapi.nat64_add_del_prefix(prefix.prefix,
7715 vrf_id=prefix.vrf_id,
7719 super(TestNAT64, self).tearDown()
7720 if not self.vpp_dead:
7721 self.logger.info(self.vapi.cli("show nat64 pool"))
7722 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7723 self.logger.info(self.vapi.cli("show nat64 prefix"))
7724 self.logger.info(self.vapi.cli("show nat64 bib all"))
7725 self.logger.info(self.vapi.cli("show nat64 session table all"))
7726 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7730 class TestDSlite(MethodHolder):
7731 """ DS-Lite Test Cases """
7734 def setUpClass(cls):
7735 super(TestDSlite, cls).setUpClass()
7738 cls.nat_addr = '10.0.0.3'
7739 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7741 cls.create_pg_interfaces(range(2))
7743 cls.pg0.config_ip4()
7744 cls.pg0.resolve_arp()
7746 cls.pg1.config_ip6()
7747 cls.pg1.generate_remote_hosts(2)
7748 cls.pg1.configure_ipv6_neighbors()
7751 super(TestDSlite, cls).tearDownClass()
7754 def test_dslite(self):
7755 """ Test DS-Lite """
7756 nat_config = self.vapi.nat_show_config()
7757 self.assertEqual(0, nat_config.dslite_ce)
7759 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7761 aftr_ip4 = '192.0.0.1'
7762 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7763 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7764 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7765 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7768 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7769 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7770 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7771 UDP(sport=20000, dport=10000))
7772 self.pg1.add_stream(p)
7773 self.pg_enable_capture(self.pg_interfaces)
7775 capture = self.pg0.get_capture(1)
7776 capture = capture[0]
7777 self.assertFalse(capture.haslayer(IPv6))
7778 self.assertEqual(capture[IP].src, self.nat_addr)
7779 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7780 self.assertNotEqual(capture[UDP].sport, 20000)
7781 self.assertEqual(capture[UDP].dport, 10000)
7782 self.assert_packet_checksums_valid(capture)
7783 out_port = capture[UDP].sport
7785 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7786 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7787 UDP(sport=10000, dport=out_port))
7788 self.pg0.add_stream(p)
7789 self.pg_enable_capture(self.pg_interfaces)
7791 capture = self.pg1.get_capture(1)
7792 capture = capture[0]
7793 self.assertEqual(capture[IPv6].src, aftr_ip6)
7794 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7795 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7796 self.assertEqual(capture[IP].dst, '192.168.1.1')
7797 self.assertEqual(capture[UDP].sport, 10000)
7798 self.assertEqual(capture[UDP].dport, 20000)
7799 self.assert_packet_checksums_valid(capture)
7802 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7803 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7804 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7805 TCP(sport=20001, dport=10001))
7806 self.pg1.add_stream(p)
7807 self.pg_enable_capture(self.pg_interfaces)
7809 capture = self.pg0.get_capture(1)
7810 capture = capture[0]
7811 self.assertFalse(capture.haslayer(IPv6))
7812 self.assertEqual(capture[IP].src, self.nat_addr)
7813 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7814 self.assertNotEqual(capture[TCP].sport, 20001)
7815 self.assertEqual(capture[TCP].dport, 10001)
7816 self.assert_packet_checksums_valid(capture)
7817 out_port = capture[TCP].sport
7819 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7820 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7821 TCP(sport=10001, dport=out_port))
7822 self.pg0.add_stream(p)
7823 self.pg_enable_capture(self.pg_interfaces)
7825 capture = self.pg1.get_capture(1)
7826 capture = capture[0]
7827 self.assertEqual(capture[IPv6].src, aftr_ip6)
7828 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7829 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7830 self.assertEqual(capture[IP].dst, '192.168.1.1')
7831 self.assertEqual(capture[TCP].sport, 10001)
7832 self.assertEqual(capture[TCP].dport, 20001)
7833 self.assert_packet_checksums_valid(capture)
7836 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7837 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7838 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7839 ICMP(id=4000, type='echo-request'))
7840 self.pg1.add_stream(p)
7841 self.pg_enable_capture(self.pg_interfaces)
7843 capture = self.pg0.get_capture(1)
7844 capture = capture[0]
7845 self.assertFalse(capture.haslayer(IPv6))
7846 self.assertEqual(capture[IP].src, self.nat_addr)
7847 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7848 self.assertNotEqual(capture[ICMP].id, 4000)
7849 self.assert_packet_checksums_valid(capture)
7850 out_id = capture[ICMP].id
7852 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7853 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7854 ICMP(id=out_id, type='echo-reply'))
7855 self.pg0.add_stream(p)
7856 self.pg_enable_capture(self.pg_interfaces)
7858 capture = self.pg1.get_capture(1)
7859 capture = capture[0]
7860 self.assertEqual(capture[IPv6].src, aftr_ip6)
7861 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7862 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7863 self.assertEqual(capture[IP].dst, '192.168.1.1')
7864 self.assertEqual(capture[ICMP].id, 4000)
7865 self.assert_packet_checksums_valid(capture)
7867 # ping DS-Lite AFTR tunnel endpoint address
7868 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7869 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7870 ICMPv6EchoRequest())
7871 self.pg1.add_stream(p)
7872 self.pg_enable_capture(self.pg_interfaces)
7874 capture = self.pg1.get_capture(1)
7875 capture = capture[0]
7876 self.assertEqual(capture[IPv6].src, aftr_ip6)
7877 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7878 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7881 super(TestDSlite, self).tearDown()
7882 if not self.vpp_dead:
7883 self.logger.info(self.vapi.cli("show dslite pool"))
7885 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7886 self.logger.info(self.vapi.cli("show dslite sessions"))
7889 class TestDSliteCE(MethodHolder):
7890 """ DS-Lite CE Test Cases """
7893 def setUpConstants(cls):
7894 super(TestDSliteCE, cls).setUpConstants()
7895 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7898 def setUpClass(cls):
7899 super(TestDSliteCE, cls).setUpClass()
7902 cls.create_pg_interfaces(range(2))
7904 cls.pg0.config_ip4()
7905 cls.pg0.resolve_arp()
7907 cls.pg1.config_ip6()
7908 cls.pg1.generate_remote_hosts(1)
7909 cls.pg1.configure_ipv6_neighbors()
7912 super(TestDSliteCE, cls).tearDownClass()
7915 def test_dslite_ce(self):
7916 """ Test DS-Lite CE """
7918 nat_config = self.vapi.nat_show_config()
7919 self.assertEqual(1, nat_config.dslite_ce)
7921 b4_ip4 = '192.0.0.2'
7922 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7923 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7924 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7925 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7927 aftr_ip4 = '192.0.0.1'
7928 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7929 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7930 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7931 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7933 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7934 dst_address_length=128,
7935 next_hop_address=self.pg1.remote_ip6n,
7936 next_hop_sw_if_index=self.pg1.sw_if_index,
7940 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7941 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7942 UDP(sport=10000, dport=20000))
7943 self.pg0.add_stream(p)
7944 self.pg_enable_capture(self.pg_interfaces)
7946 capture = self.pg1.get_capture(1)
7947 capture = capture[0]
7948 self.assertEqual(capture[IPv6].src, b4_ip6)
7949 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7950 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7951 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7952 self.assertEqual(capture[UDP].sport, 10000)
7953 self.assertEqual(capture[UDP].dport, 20000)
7954 self.assert_packet_checksums_valid(capture)
7957 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7958 IPv6(dst=b4_ip6, src=aftr_ip6) /
7959 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7960 UDP(sport=20000, dport=10000))
7961 self.pg1.add_stream(p)
7962 self.pg_enable_capture(self.pg_interfaces)
7964 capture = self.pg0.get_capture(1)
7965 capture = capture[0]
7966 self.assertFalse(capture.haslayer(IPv6))
7967 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7968 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7969 self.assertEqual(capture[UDP].sport, 20000)
7970 self.assertEqual(capture[UDP].dport, 10000)
7971 self.assert_packet_checksums_valid(capture)
7973 # ping DS-Lite B4 tunnel endpoint address
7974 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7975 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7976 ICMPv6EchoRequest())
7977 self.pg1.add_stream(p)
7978 self.pg_enable_capture(self.pg_interfaces)
7980 capture = self.pg1.get_capture(1)
7981 capture = capture[0]
7982 self.assertEqual(capture[IPv6].src, b4_ip6)
7983 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7984 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7987 super(TestDSliteCE, self).tearDown()
7988 if not self.vpp_dead:
7990 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7992 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
7995 class TestNAT66(MethodHolder):
7996 """ NAT66 Test Cases """
7999 def setUpClass(cls):
8000 super(TestNAT66, cls).setUpClass()
8003 cls.nat_addr = 'fd01:ff::2'
8004 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8006 cls.create_pg_interfaces(range(2))
8007 cls.interfaces = list(cls.pg_interfaces)
8009 for i in cls.interfaces:
8012 i.configure_ipv6_neighbors()
8015 super(TestNAT66, cls).tearDownClass()
8018 def test_static(self):
8019 """ 1:1 NAT66 test """
8020 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8021 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8022 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8027 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8028 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8031 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8032 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8035 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8036 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8037 ICMPv6EchoRequest())
8039 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8040 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8041 GRE() / IP() / TCP())
8043 self.pg0.add_stream(pkts)
8044 self.pg_enable_capture(self.pg_interfaces)
8046 capture = self.pg1.get_capture(len(pkts))
8047 for packet in capture:
8049 self.assertEqual(packet[IPv6].src, self.nat_addr)
8050 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8051 self.assert_packet_checksums_valid(packet)
8053 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8058 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8059 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8062 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8063 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8066 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8067 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8070 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8071 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8072 GRE() / IP() / TCP())
8074 self.pg1.add_stream(pkts)
8075 self.pg_enable_capture(self.pg_interfaces)
8077 capture = self.pg0.get_capture(len(pkts))
8078 for packet in capture:
8080 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8081 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8082 self.assert_packet_checksums_valid(packet)
8084 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8087 sm = self.vapi.nat66_static_mapping_dump()
8088 self.assertEqual(len(sm), 1)
8089 self.assertEqual(sm[0].total_pkts, 8)
8091 def test_check_no_translate(self):
8092 """ NAT66 translate only when egress interface is outside interface """
8093 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8094 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8095 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8099 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8100 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8102 self.pg0.add_stream([p])
8103 self.pg_enable_capture(self.pg_interfaces)
8105 capture = self.pg1.get_capture(1)
8108 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8109 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8111 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8114 def clear_nat66(self):
8116 Clear NAT66 configuration.
8118 interfaces = self.vapi.nat66_interface_dump()
8119 for intf in interfaces:
8120 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8124 static_mappings = self.vapi.nat66_static_mapping_dump()
8125 for sm in static_mappings:
8126 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8127 sm.external_ip_address,
8132 super(TestNAT66, self).tearDown()
8133 if not self.vpp_dead:
8134 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8135 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8139 if __name__ == '__main__':
8140 unittest.main(testRunner=VppTestRunner)