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_frag_forwarding(self):
3343 """ NAT44 forwarding fragment test """
3344 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3345 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3346 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3348 self.vapi.nat44_forwarding_enable_disable(1)
3350 data = "A" * 16 + "B" * 16 + "C" * 3
3351 pkts = self.create_stream_frag(self.pg1,
3352 self.pg0.remote_ip4,
3356 proto=IP_PROTOS.udp)
3357 self.pg1.add_stream(pkts)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 frags = self.pg0.get_capture(len(pkts))
3361 p = self.reass_frags_and_verify(frags,
3362 self.pg1.remote_ip4,
3363 self.pg0.remote_ip4)
3364 self.assertEqual(p[UDP].sport, 4789)
3365 self.assertEqual(p[UDP].dport, 4789)
3366 self.assertEqual(data, p[Raw].load)
3368 def test_reass_hairpinning(self):
3369 """ NAT44 fragments hairpinning """
3371 self.server = self.pg0.remote_hosts[1]
3372 self.host_in_port = random.randint(1025, 65535)
3373 self.server_in_port = random.randint(1025, 65535)
3374 self.server_out_port = random.randint(1025, 65535)
3376 self.nat44_add_address(self.nat_addr)
3377 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3378 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3380 # add static mapping for server
3381 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3382 self.server_in_port,
3383 self.server_out_port,
3384 proto=IP_PROTOS.tcp)
3385 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3386 self.server_in_port,
3387 self.server_out_port,
3388 proto=IP_PROTOS.udp)
3389 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3391 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3392 self.reass_hairpinning(proto=IP_PROTOS.udp)
3393 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3395 def test_frag_out_of_order(self):
3396 """ NAT44 translate fragments arriving out of order """
3398 self.nat44_add_address(self.nat_addr)
3399 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3400 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3403 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3404 self.frag_out_of_order(proto=IP_PROTOS.udp)
3405 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3407 def test_port_restricted(self):
3408 """ Port restricted NAT44 (MAP-E CE) """
3409 self.nat44_add_address(self.nat_addr)
3410 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3411 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3413 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3418 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3419 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3420 TCP(sport=4567, dport=22))
3421 self.pg0.add_stream(p)
3422 self.pg_enable_capture(self.pg_interfaces)
3424 capture = self.pg1.get_capture(1)
3429 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3430 self.assertEqual(ip.src, self.nat_addr)
3431 self.assertEqual(tcp.dport, 22)
3432 self.assertNotEqual(tcp.sport, 4567)
3433 self.assertEqual((tcp.sport >> 6) & 63, 10)
3434 self.assert_packet_checksums_valid(p)
3436 self.logger.error(ppp("Unexpected or invalid packet:", p))
3439 def test_port_range(self):
3440 """ External address port range """
3441 self.nat44_add_address(self.nat_addr)
3442 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3443 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3445 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3450 for port in range(0, 5):
3451 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3452 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3453 TCP(sport=1125 + port))
3455 self.pg0.add_stream(pkts)
3456 self.pg_enable_capture(self.pg_interfaces)
3458 capture = self.pg1.get_capture(3)
3461 self.assertGreaterEqual(tcp.sport, 1025)
3462 self.assertLessEqual(tcp.sport, 1027)
3464 def test_ipfix_max_frags(self):
3465 """ IPFIX logging maximum fragments pending reassembly exceeded """
3466 self.nat44_add_address(self.nat_addr)
3467 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3468 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3470 self.vapi.nat_set_reass(max_frag=1)
3471 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3472 src_address=self.pg3.local_ip4n,
3474 template_interval=10)
3475 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3476 src_port=self.ipfix_src_port)
3478 data = "A" * 4 + "B" * 16 + "C" * 3
3479 self.tcp_port_in = random.randint(1025, 65535)
3480 pkts = self.create_stream_frag(self.pg0,
3481 self.pg1.remote_ip4,
3486 self.pg0.add_stream(pkts)
3487 self.pg_enable_capture(self.pg_interfaces)
3489 self.pg1.assert_nothing_captured()
3491 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3492 capture = self.pg3.get_capture(9)
3493 ipfix = IPFIXDecoder()
3494 # first load template
3496 self.assertTrue(p.haslayer(IPFIX))
3497 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3498 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3499 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3500 self.assertEqual(p[UDP].dport, 4739)
3501 self.assertEqual(p[IPFIX].observationDomainID,
3502 self.ipfix_domain_id)
3503 if p.haslayer(Template):
3504 ipfix.add_template(p.getlayer(Template))
3505 # verify events in data set
3507 if p.haslayer(Data):
3508 data = ipfix.decode_data_set(p.getlayer(Set))
3509 self.verify_ipfix_max_fragments_ip4(data, 1,
3510 self.pg0.remote_ip4n)
3512 def test_multiple_outside_vrf(self):
3513 """ Multiple outside VRF """
3517 self.pg1.unconfig_ip4()
3518 self.pg2.unconfig_ip4()
3519 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3520 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3521 self.pg1.set_table_ip4(vrf_id1)
3522 self.pg2.set_table_ip4(vrf_id2)
3523 self.pg1.config_ip4()
3524 self.pg2.config_ip4()
3525 self.pg1.resolve_arp()
3526 self.pg2.resolve_arp()
3528 self.nat44_add_address(self.nat_addr)
3529 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3530 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3532 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3537 pkts = self.create_stream_in(self.pg0, self.pg1)
3538 self.pg0.add_stream(pkts)
3539 self.pg_enable_capture(self.pg_interfaces)
3541 capture = self.pg1.get_capture(len(pkts))
3542 self.verify_capture_out(capture, self.nat_addr)
3544 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3545 self.pg1.add_stream(pkts)
3546 self.pg_enable_capture(self.pg_interfaces)
3548 capture = self.pg0.get_capture(len(pkts))
3549 self.verify_capture_in(capture, self.pg0)
3551 self.tcp_port_in = 60303
3552 self.udp_port_in = 60304
3553 self.icmp_id_in = 60305
3556 pkts = self.create_stream_in(self.pg0, self.pg2)
3557 self.pg0.add_stream(pkts)
3558 self.pg_enable_capture(self.pg_interfaces)
3560 capture = self.pg2.get_capture(len(pkts))
3561 self.verify_capture_out(capture, self.nat_addr)
3563 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3564 self.pg2.add_stream(pkts)
3565 self.pg_enable_capture(self.pg_interfaces)
3567 capture = self.pg0.get_capture(len(pkts))
3568 self.verify_capture_in(capture, self.pg0)
3571 self.pg1.unconfig_ip4()
3572 self.pg2.unconfig_ip4()
3573 self.pg1.set_table_ip4(0)
3574 self.pg2.set_table_ip4(0)
3575 self.pg1.config_ip4()
3576 self.pg2.config_ip4()
3577 self.pg1.resolve_arp()
3578 self.pg2.resolve_arp()
3580 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3581 def test_session_timeout(self):
3582 """ NAT44 session timeouts """
3583 self.nat44_add_address(self.nat_addr)
3584 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3585 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3587 self.vapi.nat_set_timeouts(udp=5)
3591 for i in range(0, max_sessions):
3592 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3593 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3594 IP(src=src, dst=self.pg1.remote_ip4) /
3595 UDP(sport=1025, dport=53))
3597 self.pg0.add_stream(pkts)
3598 self.pg_enable_capture(self.pg_interfaces)
3600 self.pg1.get_capture(max_sessions)
3605 for i in range(0, max_sessions):
3606 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3607 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3608 IP(src=src, dst=self.pg1.remote_ip4) /
3609 UDP(sport=1026, dport=53))
3611 self.pg0.add_stream(pkts)
3612 self.pg_enable_capture(self.pg_interfaces)
3614 self.pg1.get_capture(max_sessions)
3617 users = self.vapi.nat44_user_dump()
3619 nsessions = nsessions + user.nsessions
3620 self.assertLess(nsessions, 2 * max_sessions)
3622 def test_mss_clamping(self):
3623 """ TCP MSS clamping """
3624 self.nat44_add_address(self.nat_addr)
3625 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3626 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3629 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3630 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3631 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3632 flags="S", options=[('MSS', 1400)]))
3634 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3635 self.pg0.add_stream(p)
3636 self.pg_enable_capture(self.pg_interfaces)
3638 capture = self.pg1.get_capture(1)
3639 # Negotiated MSS value greater than configured - changed
3640 self.verify_mss_value(capture[0], 1000)
3642 self.vapi.nat_set_mss_clamping(enable=0)
3643 self.pg0.add_stream(p)
3644 self.pg_enable_capture(self.pg_interfaces)
3646 capture = self.pg1.get_capture(1)
3647 # MSS clamping disabled - negotiated MSS unchanged
3648 self.verify_mss_value(capture[0], 1400)
3650 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3651 self.pg0.add_stream(p)
3652 self.pg_enable_capture(self.pg_interfaces)
3654 capture = self.pg1.get_capture(1)
3655 # Negotiated MSS value smaller than configured - unchanged
3656 self.verify_mss_value(capture[0], 1400)
3659 super(TestNAT44, self).tearDown()
3660 if not self.vpp_dead:
3661 self.logger.info(self.vapi.cli("show nat44 addresses"))
3662 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3663 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3664 self.logger.info(self.vapi.cli("show nat44 interface address"))
3665 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3666 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3667 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3668 self.logger.info(self.vapi.cli("show nat timeouts"))
3670 self.vapi.cli("show nat addr-port-assignment-alg"))
3672 self.vapi.cli("clear logging")
3675 class TestNAT44EndpointDependent(MethodHolder):
3676 """ Endpoint-Dependent mapping and filtering test cases """
3679 def setUpConstants(cls):
3680 super(TestNAT44EndpointDependent, cls).setUpConstants()
3681 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3684 def setUpClass(cls):
3685 super(TestNAT44EndpointDependent, cls).setUpClass()
3686 cls.vapi.cli("set log class nat level debug")
3688 cls.tcp_port_in = 6303
3689 cls.tcp_port_out = 6303
3690 cls.udp_port_in = 6304
3691 cls.udp_port_out = 6304
3692 cls.icmp_id_in = 6305
3693 cls.icmp_id_out = 6305
3694 cls.nat_addr = '10.0.0.3'
3695 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3696 cls.ipfix_src_port = 4739
3697 cls.ipfix_domain_id = 1
3698 cls.tcp_external_port = 80
3700 cls.create_pg_interfaces(range(7))
3701 cls.interfaces = list(cls.pg_interfaces[0:3])
3703 for i in cls.interfaces:
3708 cls.pg0.generate_remote_hosts(3)
3709 cls.pg0.configure_ipv4_neighbors()
3713 cls.pg4.generate_remote_hosts(2)
3714 cls.pg4.config_ip4()
3715 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3716 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3720 cls.pg4.resolve_arp()
3721 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3722 cls.pg4.resolve_arp()
3724 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3725 cls.vapi.ip_table_add_del(1, is_add=1)
3727 cls.pg5._local_ip4 = "10.1.1.1"
3728 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3730 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3731 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3732 socket.AF_INET, cls.pg5.remote_ip4)
3733 cls.pg5.set_table_ip4(1)
3734 cls.pg5.config_ip4()
3736 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3737 dst_address_length=32,
3739 next_hop_sw_if_index=cls.pg5.sw_if_index,
3740 next_hop_address=zero_ip4n)
3742 cls.pg6._local_ip4 = "10.1.2.1"
3743 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3745 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3746 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3747 socket.AF_INET, cls.pg6.remote_ip4)
3748 cls.pg6.set_table_ip4(1)
3749 cls.pg6.config_ip4()
3751 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3752 dst_address_length=32,
3754 next_hop_sw_if_index=cls.pg6.sw_if_index,
3755 next_hop_address=zero_ip4n)
3757 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3758 dst_address_length=16,
3759 next_hop_address=zero_ip4n,
3761 next_hop_table_id=1)
3762 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3763 dst_address_length=0,
3764 next_hop_address=zero_ip4n,
3766 next_hop_table_id=0)
3767 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3768 dst_address_length=0,
3770 next_hop_sw_if_index=cls.pg1.sw_if_index,
3771 next_hop_address=cls.pg1.local_ip4n)
3773 cls.pg5.resolve_arp()
3774 cls.pg6.resolve_arp()
3777 super(TestNAT44EndpointDependent, cls).tearDownClass()
3780 def test_frag_in_order(self):
3781 """ NAT44 translate fragments arriving in order """
3782 self.nat44_add_address(self.nat_addr)
3783 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3784 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3786 self.frag_in_order(proto=IP_PROTOS.tcp)
3787 self.frag_in_order(proto=IP_PROTOS.udp)
3788 self.frag_in_order(proto=IP_PROTOS.icmp)
3790 def test_frag_in_order_dont_translate(self):
3791 """ NAT44 don't translate fragments arriving in order """
3792 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3793 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3795 self.vapi.nat44_forwarding_enable_disable(enable=True)
3796 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3798 def test_frag_out_of_order(self):
3799 """ NAT44 translate fragments arriving out of order """
3800 self.nat44_add_address(self.nat_addr)
3801 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3802 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3804 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3805 self.frag_out_of_order(proto=IP_PROTOS.udp)
3806 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3808 def test_frag_out_of_order_dont_translate(self):
3809 """ NAT44 don't translate fragments arriving out of order """
3810 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3811 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3813 self.vapi.nat44_forwarding_enable_disable(enable=True)
3814 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3816 def test_frag_in_order_in_plus_out(self):
3817 """ in+out interface fragments in order """
3818 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3819 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3821 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3822 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3825 self.server = self.pg1.remote_hosts[0]
3827 self.server_in_addr = self.server.ip4
3828 self.server_out_addr = '11.11.11.11'
3829 self.server_in_port = random.randint(1025, 65535)
3830 self.server_out_port = random.randint(1025, 65535)
3832 self.nat44_add_address(self.server_out_addr)
3834 # add static mappings for server
3835 self.nat44_add_static_mapping(self.server_in_addr,
3836 self.server_out_addr,
3837 self.server_in_port,
3838 self.server_out_port,
3839 proto=IP_PROTOS.tcp)
3840 self.nat44_add_static_mapping(self.server_in_addr,
3841 self.server_out_addr,
3842 self.server_in_port,
3843 self.server_out_port,
3844 proto=IP_PROTOS.udp)
3845 self.nat44_add_static_mapping(self.server_in_addr,
3846 self.server_out_addr,
3847 proto=IP_PROTOS.icmp)
3849 self.vapi.nat_set_reass(timeout=10)
3851 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3852 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3853 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3855 def test_frag_out_of_order_in_plus_out(self):
3856 """ in+out interface fragments out of order """
3857 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3858 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3860 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3861 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3864 self.server = self.pg1.remote_hosts[0]
3866 self.server_in_addr = self.server.ip4
3867 self.server_out_addr = '11.11.11.11'
3868 self.server_in_port = random.randint(1025, 65535)
3869 self.server_out_port = random.randint(1025, 65535)
3871 self.nat44_add_address(self.server_out_addr)
3873 # add static mappings for server
3874 self.nat44_add_static_mapping(self.server_in_addr,
3875 self.server_out_addr,
3876 self.server_in_port,
3877 self.server_out_port,
3878 proto=IP_PROTOS.tcp)
3879 self.nat44_add_static_mapping(self.server_in_addr,
3880 self.server_out_addr,
3881 self.server_in_port,
3882 self.server_out_port,
3883 proto=IP_PROTOS.udp)
3884 self.nat44_add_static_mapping(self.server_in_addr,
3885 self.server_out_addr,
3886 proto=IP_PROTOS.icmp)
3888 self.vapi.nat_set_reass(timeout=10)
3890 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3891 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3892 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3894 def test_reass_hairpinning(self):
3895 """ NAT44 fragments hairpinning """
3896 self.server = self.pg0.remote_hosts[1]
3897 self.host_in_port = random.randint(1025, 65535)
3898 self.server_in_port = random.randint(1025, 65535)
3899 self.server_out_port = random.randint(1025, 65535)
3901 self.nat44_add_address(self.nat_addr)
3902 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3903 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3905 # add static mapping for server
3906 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3907 self.server_in_port,
3908 self.server_out_port,
3909 proto=IP_PROTOS.tcp)
3910 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3911 self.server_in_port,
3912 self.server_out_port,
3913 proto=IP_PROTOS.udp)
3914 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3916 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3917 self.reass_hairpinning(proto=IP_PROTOS.udp)
3918 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3920 def test_dynamic(self):
3921 """ NAT44 dynamic translation test """
3923 self.nat44_add_address(self.nat_addr)
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,
3928 nat_config = self.vapi.nat_show_config()
3929 self.assertEqual(1, nat_config.endpoint_dependent)
3932 pkts = self.create_stream_in(self.pg0, self.pg1)
3933 self.pg0.add_stream(pkts)
3934 self.pg_enable_capture(self.pg_interfaces)
3936 capture = self.pg1.get_capture(len(pkts))
3937 self.verify_capture_out(capture)
3940 pkts = self.create_stream_out(self.pg1)
3941 self.pg1.add_stream(pkts)
3942 self.pg_enable_capture(self.pg_interfaces)
3944 capture = self.pg0.get_capture(len(pkts))
3945 self.verify_capture_in(capture, self.pg0)
3947 def test_forwarding(self):
3948 """ NAT44 forwarding test """
3950 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3951 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3953 self.vapi.nat44_forwarding_enable_disable(1)
3955 real_ip = self.pg0.remote_ip4n
3956 alias_ip = self.nat_addr_n
3957 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3958 external_ip=alias_ip)
3961 # in2out - static mapping match
3963 pkts = self.create_stream_out(self.pg1)
3964 self.pg1.add_stream(pkts)
3965 self.pg_enable_capture(self.pg_interfaces)
3967 capture = self.pg0.get_capture(len(pkts))
3968 self.verify_capture_in(capture, self.pg0)
3970 pkts = self.create_stream_in(self.pg0, self.pg1)
3971 self.pg0.add_stream(pkts)
3972 self.pg_enable_capture(self.pg_interfaces)
3974 capture = self.pg1.get_capture(len(pkts))
3975 self.verify_capture_out(capture, same_port=True)
3977 # in2out - no static mapping match
3979 host0 = self.pg0.remote_hosts[0]
3980 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3982 pkts = self.create_stream_out(self.pg1,
3983 dst_ip=self.pg0.remote_ip4,
3984 use_inside_ports=True)
3985 self.pg1.add_stream(pkts)
3986 self.pg_enable_capture(self.pg_interfaces)
3988 capture = self.pg0.get_capture(len(pkts))
3989 self.verify_capture_in(capture, self.pg0)
3991 pkts = self.create_stream_in(self.pg0, self.pg1)
3992 self.pg0.add_stream(pkts)
3993 self.pg_enable_capture(self.pg_interfaces)
3995 capture = self.pg1.get_capture(len(pkts))
3996 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3999 self.pg0.remote_hosts[0] = host0
4001 user = self.pg0.remote_hosts[1]
4002 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4003 self.assertEqual(len(sessions), 3)
4004 self.assertTrue(sessions[0].ext_host_valid)
4005 self.vapi.nat44_del_session(
4006 sessions[0].inside_ip_address,
4007 sessions[0].inside_port,
4008 sessions[0].protocol,
4009 ext_host_address=sessions[0].ext_host_address,
4010 ext_host_port=sessions[0].ext_host_port)
4011 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4012 self.assertEqual(len(sessions), 2)
4015 self.vapi.nat44_forwarding_enable_disable(0)
4016 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4017 external_ip=alias_ip,
4020 def test_static_lb(self):
4021 """ NAT44 local service load balancing """
4022 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4025 server1 = self.pg0.remote_hosts[0]
4026 server2 = self.pg0.remote_hosts[1]
4028 locals = [{'addr': server1.ip4n,
4032 {'addr': server2.ip4n,
4037 self.nat44_add_address(self.nat_addr)
4038 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4041 local_num=len(locals),
4043 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4044 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4047 # from client to service
4048 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4049 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4050 TCP(sport=12345, dport=external_port))
4051 self.pg1.add_stream(p)
4052 self.pg_enable_capture(self.pg_interfaces)
4054 capture = self.pg0.get_capture(1)
4060 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4061 if ip.dst == server1.ip4:
4065 self.assertEqual(tcp.dport, local_port)
4066 self.assert_packet_checksums_valid(p)
4068 self.logger.error(ppp("Unexpected or invalid packet:", p))
4071 # from service back to client
4072 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4073 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4074 TCP(sport=local_port, dport=12345))
4075 self.pg0.add_stream(p)
4076 self.pg_enable_capture(self.pg_interfaces)
4078 capture = self.pg1.get_capture(1)
4083 self.assertEqual(ip.src, self.nat_addr)
4084 self.assertEqual(tcp.sport, external_port)
4085 self.assert_packet_checksums_valid(p)
4087 self.logger.error(ppp("Unexpected or invalid packet:", p))
4090 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4091 self.assertEqual(len(sessions), 1)
4092 self.assertTrue(sessions[0].ext_host_valid)
4093 self.vapi.nat44_del_session(
4094 sessions[0].inside_ip_address,
4095 sessions[0].inside_port,
4096 sessions[0].protocol,
4097 ext_host_address=sessions[0].ext_host_address,
4098 ext_host_port=sessions[0].ext_host_port)
4099 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4100 self.assertEqual(len(sessions), 0)
4102 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4103 def test_static_lb_multi_clients(self):
4104 """ NAT44 local service load balancing - multiple clients"""
4106 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4109 server1 = self.pg0.remote_hosts[0]
4110 server2 = self.pg0.remote_hosts[1]
4112 locals = [{'addr': server1.ip4n,
4116 {'addr': server2.ip4n,
4121 self.nat44_add_address(self.nat_addr)
4122 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4125 local_num=len(locals),
4127 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4128 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4133 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4135 for client in clients:
4136 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4137 IP(src=client, dst=self.nat_addr) /
4138 TCP(sport=12345, dport=external_port))
4140 self.pg1.add_stream(pkts)
4141 self.pg_enable_capture(self.pg_interfaces)
4143 capture = self.pg0.get_capture(len(pkts))
4145 if p[IP].dst == server1.ip4:
4149 self.assertTrue(server1_n > server2_n)
4151 def test_static_lb_2(self):
4152 """ NAT44 local service load balancing (asymmetrical rule) """
4153 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4156 server1 = self.pg0.remote_hosts[0]
4157 server2 = self.pg0.remote_hosts[1]
4159 locals = [{'addr': server1.ip4n,
4163 {'addr': server2.ip4n,
4168 self.vapi.nat44_forwarding_enable_disable(1)
4169 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4173 local_num=len(locals),
4175 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4176 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4179 # from client to service
4180 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4181 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4182 TCP(sport=12345, dport=external_port))
4183 self.pg1.add_stream(p)
4184 self.pg_enable_capture(self.pg_interfaces)
4186 capture = self.pg0.get_capture(1)
4192 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4193 if ip.dst == server1.ip4:
4197 self.assertEqual(tcp.dport, local_port)
4198 self.assert_packet_checksums_valid(p)
4200 self.logger.error(ppp("Unexpected or invalid packet:", p))
4203 # from service back to client
4204 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4205 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4206 TCP(sport=local_port, dport=12345))
4207 self.pg0.add_stream(p)
4208 self.pg_enable_capture(self.pg_interfaces)
4210 capture = self.pg1.get_capture(1)
4215 self.assertEqual(ip.src, self.nat_addr)
4216 self.assertEqual(tcp.sport, external_port)
4217 self.assert_packet_checksums_valid(p)
4219 self.logger.error(ppp("Unexpected or invalid packet:", p))
4222 # from client to server (no translation)
4223 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4224 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4225 TCP(sport=12346, dport=local_port))
4226 self.pg1.add_stream(p)
4227 self.pg_enable_capture(self.pg_interfaces)
4229 capture = self.pg0.get_capture(1)
4235 self.assertEqual(ip.dst, server1.ip4)
4236 self.assertEqual(tcp.dport, local_port)
4237 self.assert_packet_checksums_valid(p)
4239 self.logger.error(ppp("Unexpected or invalid packet:", p))
4242 # from service back to client (no translation)
4243 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4244 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4245 TCP(sport=local_port, dport=12346))
4246 self.pg0.add_stream(p)
4247 self.pg_enable_capture(self.pg_interfaces)
4249 capture = self.pg1.get_capture(1)
4254 self.assertEqual(ip.src, server1.ip4)
4255 self.assertEqual(tcp.sport, local_port)
4256 self.assert_packet_checksums_valid(p)
4258 self.logger.error(ppp("Unexpected or invalid packet:", p))
4261 def test_lb_affinity(self):
4262 """ NAT44 local service load balancing affinity """
4263 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4266 server1 = self.pg0.remote_hosts[0]
4267 server2 = self.pg0.remote_hosts[1]
4269 locals = [{'addr': server1.ip4n,
4273 {'addr': server2.ip4n,
4278 self.nat44_add_address(self.nat_addr)
4279 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4283 local_num=len(locals),
4285 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4286 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4289 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4290 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4291 TCP(sport=1025, dport=external_port))
4292 self.pg1.add_stream(p)
4293 self.pg_enable_capture(self.pg_interfaces)
4295 capture = self.pg0.get_capture(1)
4296 backend = capture[0][IP].dst
4298 sessions = self.vapi.nat44_user_session_dump(
4299 socket.inet_pton(socket.AF_INET, backend), 0)
4300 self.assertEqual(len(sessions), 1)
4301 self.assertTrue(sessions[0].ext_host_valid)
4302 self.vapi.nat44_del_session(
4303 sessions[0].inside_ip_address,
4304 sessions[0].inside_port,
4305 sessions[0].protocol,
4306 ext_host_address=sessions[0].ext_host_address,
4307 ext_host_port=sessions[0].ext_host_port)
4310 for port in range(1030, 1100):
4311 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4312 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4313 TCP(sport=port, dport=external_port))
4315 self.pg1.add_stream(pkts)
4316 self.pg_enable_capture(self.pg_interfaces)
4318 capture = self.pg0.get_capture(len(pkts))
4320 self.assertEqual(p[IP].dst, backend)
4322 def test_unknown_proto(self):
4323 """ NAT44 translate packet with unknown protocol """
4324 self.nat44_add_address(self.nat_addr)
4325 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4326 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4331 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4332 TCP(sport=self.tcp_port_in, dport=20))
4333 self.pg0.add_stream(p)
4334 self.pg_enable_capture(self.pg_interfaces)
4336 p = self.pg1.get_capture(1)
4338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4339 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4341 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4342 TCP(sport=1234, dport=1234))
4343 self.pg0.add_stream(p)
4344 self.pg_enable_capture(self.pg_interfaces)
4346 p = self.pg1.get_capture(1)
4349 self.assertEqual(packet[IP].src, self.nat_addr)
4350 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4351 self.assertTrue(packet.haslayer(GRE))
4352 self.assert_packet_checksums_valid(packet)
4354 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4358 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4359 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4361 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4362 TCP(sport=1234, dport=1234))
4363 self.pg1.add_stream(p)
4364 self.pg_enable_capture(self.pg_interfaces)
4366 p = self.pg0.get_capture(1)
4369 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4370 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4371 self.assertTrue(packet.haslayer(GRE))
4372 self.assert_packet_checksums_valid(packet)
4374 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4377 def test_hairpinning_unknown_proto(self):
4378 """ NAT44 translate packet with unknown protocol - hairpinning """
4379 host = self.pg0.remote_hosts[0]
4380 server = self.pg0.remote_hosts[1]
4382 server_out_port = 8765
4383 server_nat_ip = "10.0.0.11"
4385 self.nat44_add_address(self.nat_addr)
4386 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4387 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4390 # add static mapping for server
4391 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4394 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4395 IP(src=host.ip4, dst=server_nat_ip) /
4396 TCP(sport=host_in_port, dport=server_out_port))
4397 self.pg0.add_stream(p)
4398 self.pg_enable_capture(self.pg_interfaces)
4400 self.pg0.get_capture(1)
4402 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4403 IP(src=host.ip4, dst=server_nat_ip) /
4405 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4406 TCP(sport=1234, dport=1234))
4407 self.pg0.add_stream(p)
4408 self.pg_enable_capture(self.pg_interfaces)
4410 p = self.pg0.get_capture(1)
4413 self.assertEqual(packet[IP].src, self.nat_addr)
4414 self.assertEqual(packet[IP].dst, server.ip4)
4415 self.assertTrue(packet.haslayer(GRE))
4416 self.assert_packet_checksums_valid(packet)
4418 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4422 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4423 IP(src=server.ip4, dst=self.nat_addr) /
4425 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4426 TCP(sport=1234, dport=1234))
4427 self.pg0.add_stream(p)
4428 self.pg_enable_capture(self.pg_interfaces)
4430 p = self.pg0.get_capture(1)
4433 self.assertEqual(packet[IP].src, server_nat_ip)
4434 self.assertEqual(packet[IP].dst, host.ip4)
4435 self.assertTrue(packet.haslayer(GRE))
4436 self.assert_packet_checksums_valid(packet)
4438 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4441 def test_output_feature_and_service(self):
4442 """ NAT44 interface output feature and services """
4443 external_addr = '1.2.3.4'
4447 self.vapi.nat44_forwarding_enable_disable(1)
4448 self.nat44_add_address(self.nat_addr)
4449 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4450 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4451 local_port, external_port,
4452 proto=IP_PROTOS.tcp, out2in_only=1)
4453 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4454 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4456 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4459 # from client to service
4460 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4461 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4462 TCP(sport=12345, dport=external_port))
4463 self.pg1.add_stream(p)
4464 self.pg_enable_capture(self.pg_interfaces)
4466 capture = self.pg0.get_capture(1)
4471 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4472 self.assertEqual(tcp.dport, local_port)
4473 self.assert_packet_checksums_valid(p)
4475 self.logger.error(ppp("Unexpected or invalid packet:", p))
4478 # from service back to client
4479 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4480 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4481 TCP(sport=local_port, dport=12345))
4482 self.pg0.add_stream(p)
4483 self.pg_enable_capture(self.pg_interfaces)
4485 capture = self.pg1.get_capture(1)
4490 self.assertEqual(ip.src, external_addr)
4491 self.assertEqual(tcp.sport, external_port)
4492 self.assert_packet_checksums_valid(p)
4494 self.logger.error(ppp("Unexpected or invalid packet:", p))
4497 # from local network host to external network
4498 pkts = self.create_stream_in(self.pg0, self.pg1)
4499 self.pg0.add_stream(pkts)
4500 self.pg_enable_capture(self.pg_interfaces)
4502 capture = self.pg1.get_capture(len(pkts))
4503 self.verify_capture_out(capture)
4504 pkts = self.create_stream_in(self.pg0, self.pg1)
4505 self.pg0.add_stream(pkts)
4506 self.pg_enable_capture(self.pg_interfaces)
4508 capture = self.pg1.get_capture(len(pkts))
4509 self.verify_capture_out(capture)
4511 # from external network back to local network host
4512 pkts = self.create_stream_out(self.pg1)
4513 self.pg1.add_stream(pkts)
4514 self.pg_enable_capture(self.pg_interfaces)
4516 capture = self.pg0.get_capture(len(pkts))
4517 self.verify_capture_in(capture, self.pg0)
4519 def test_output_feature_and_service2(self):
4520 """ NAT44 interface output feature and service host direct access """
4521 self.vapi.nat44_forwarding_enable_disable(1)
4522 self.nat44_add_address(self.nat_addr)
4523 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4526 # session initiaded from service host - translate
4527 pkts = self.create_stream_in(self.pg0, self.pg1)
4528 self.pg0.add_stream(pkts)
4529 self.pg_enable_capture(self.pg_interfaces)
4531 capture = self.pg1.get_capture(len(pkts))
4532 self.verify_capture_out(capture)
4534 pkts = self.create_stream_out(self.pg1)
4535 self.pg1.add_stream(pkts)
4536 self.pg_enable_capture(self.pg_interfaces)
4538 capture = self.pg0.get_capture(len(pkts))
4539 self.verify_capture_in(capture, self.pg0)
4541 # session initiaded from remote host - do not translate
4542 self.tcp_port_in = 60303
4543 self.udp_port_in = 60304
4544 self.icmp_id_in = 60305
4545 pkts = self.create_stream_out(self.pg1,
4546 self.pg0.remote_ip4,
4547 use_inside_ports=True)
4548 self.pg1.add_stream(pkts)
4549 self.pg_enable_capture(self.pg_interfaces)
4551 capture = self.pg0.get_capture(len(pkts))
4552 self.verify_capture_in(capture, self.pg0)
4554 pkts = self.create_stream_in(self.pg0, self.pg1)
4555 self.pg0.add_stream(pkts)
4556 self.pg_enable_capture(self.pg_interfaces)
4558 capture = self.pg1.get_capture(len(pkts))
4559 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4562 def test_output_feature_and_service3(self):
4563 """ NAT44 interface output feature and DST NAT """
4564 external_addr = '1.2.3.4'
4568 self.vapi.nat44_forwarding_enable_disable(1)
4569 self.nat44_add_address(self.nat_addr)
4570 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4571 local_port, external_port,
4572 proto=IP_PROTOS.tcp, out2in_only=1)
4573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4574 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4576 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4579 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4580 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4581 TCP(sport=12345, dport=external_port))
4582 self.pg0.add_stream(p)
4583 self.pg_enable_capture(self.pg_interfaces)
4585 capture = self.pg1.get_capture(1)
4590 self.assertEqual(ip.src, self.pg0.remote_ip4)
4591 self.assertEqual(tcp.sport, 12345)
4592 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4593 self.assertEqual(tcp.dport, local_port)
4594 self.assert_packet_checksums_valid(p)
4596 self.logger.error(ppp("Unexpected or invalid packet:", p))
4599 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4600 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4601 TCP(sport=local_port, dport=12345))
4602 self.pg1.add_stream(p)
4603 self.pg_enable_capture(self.pg_interfaces)
4605 capture = self.pg0.get_capture(1)
4610 self.assertEqual(ip.src, external_addr)
4611 self.assertEqual(tcp.sport, external_port)
4612 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4613 self.assertEqual(tcp.dport, 12345)
4614 self.assert_packet_checksums_valid(p)
4616 self.logger.error(ppp("Unexpected or invalid packet:", p))
4619 def test_next_src_nat(self):
4620 """ On way back forward packet to nat44-in2out node. """
4621 twice_nat_addr = '10.0.1.3'
4624 post_twice_nat_port = 0
4626 self.vapi.nat44_forwarding_enable_disable(1)
4627 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4628 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4629 local_port, external_port,
4630 proto=IP_PROTOS.tcp, out2in_only=1,
4631 self_twice_nat=1, vrf_id=1)
4632 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4635 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4636 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4637 TCP(sport=12345, dport=external_port))
4638 self.pg6.add_stream(p)
4639 self.pg_enable_capture(self.pg_interfaces)
4641 capture = self.pg6.get_capture(1)
4646 self.assertEqual(ip.src, twice_nat_addr)
4647 self.assertNotEqual(tcp.sport, 12345)
4648 post_twice_nat_port = tcp.sport
4649 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4650 self.assertEqual(tcp.dport, local_port)
4651 self.assert_packet_checksums_valid(p)
4653 self.logger.error(ppp("Unexpected or invalid packet:", p))
4656 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4657 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4658 TCP(sport=local_port, dport=post_twice_nat_port))
4659 self.pg6.add_stream(p)
4660 self.pg_enable_capture(self.pg_interfaces)
4662 capture = self.pg6.get_capture(1)
4667 self.assertEqual(ip.src, self.pg1.remote_ip4)
4668 self.assertEqual(tcp.sport, external_port)
4669 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4670 self.assertEqual(tcp.dport, 12345)
4671 self.assert_packet_checksums_valid(p)
4673 self.logger.error(ppp("Unexpected or invalid packet:", p))
4676 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4678 twice_nat_addr = '10.0.1.3'
4686 port_in1 = port_in+1
4687 port_in2 = port_in+2
4692 server1 = self.pg0.remote_hosts[0]
4693 server2 = self.pg0.remote_hosts[1]
4705 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4708 self.nat44_add_address(self.nat_addr)
4709 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4711 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4713 proto=IP_PROTOS.tcp,
4714 twice_nat=int(not self_twice_nat),
4715 self_twice_nat=int(self_twice_nat))
4717 locals = [{'addr': server1.ip4n,
4721 {'addr': server2.ip4n,
4725 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4726 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4730 not self_twice_nat),
4733 local_num=len(locals),
4735 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4736 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4743 assert client_id is not None
4745 client = self.pg0.remote_hosts[0]
4746 elif client_id == 2:
4747 client = self.pg0.remote_hosts[1]
4749 client = pg1.remote_hosts[0]
4750 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4751 IP(src=client.ip4, dst=self.nat_addr) /
4752 TCP(sport=eh_port_out, dport=port_out))
4754 self.pg_enable_capture(self.pg_interfaces)
4756 capture = pg0.get_capture(1)
4762 if ip.dst == server1.ip4:
4768 self.assertEqual(ip.dst, server.ip4)
4770 self.assertIn(tcp.dport, [port_in1, port_in2])
4772 self.assertEqual(tcp.dport, port_in)
4774 self.assertEqual(ip.src, twice_nat_addr)
4775 self.assertNotEqual(tcp.sport, eh_port_out)
4777 self.assertEqual(ip.src, client.ip4)
4778 self.assertEqual(tcp.sport, eh_port_out)
4780 eh_port_in = tcp.sport
4781 saved_port_in = tcp.dport
4782 self.assert_packet_checksums_valid(p)
4784 self.logger.error(ppp("Unexpected or invalid packet:", p))
4787 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4788 IP(src=server.ip4, dst=eh_addr_in) /
4789 TCP(sport=saved_port_in, dport=eh_port_in))
4791 self.pg_enable_capture(self.pg_interfaces)
4793 capture = pg1.get_capture(1)
4798 self.assertEqual(ip.dst, client.ip4)
4799 self.assertEqual(ip.src, self.nat_addr)
4800 self.assertEqual(tcp.dport, eh_port_out)
4801 self.assertEqual(tcp.sport, port_out)
4802 self.assert_packet_checksums_valid(p)
4804 self.logger.error(ppp("Unexpected or invalid packet:", p))
4808 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4809 self.assertEqual(len(sessions), 1)
4810 self.assertTrue(sessions[0].ext_host_valid)
4811 self.assertTrue(sessions[0].is_twicenat)
4812 self.vapi.nat44_del_session(
4813 sessions[0].inside_ip_address,
4814 sessions[0].inside_port,
4815 sessions[0].protocol,
4816 ext_host_address=sessions[0].ext_host_nat_address,
4817 ext_host_port=sessions[0].ext_host_nat_port)
4818 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4819 self.assertEqual(len(sessions), 0)
4821 def test_twice_nat(self):
4823 self.twice_nat_common()
4825 def test_self_twice_nat_positive(self):
4826 """ Self Twice NAT44 (positive test) """
4827 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4829 def test_self_twice_nat_negative(self):
4830 """ Self Twice NAT44 (negative test) """
4831 self.twice_nat_common(self_twice_nat=True)
4833 def test_twice_nat_lb(self):
4834 """ Twice NAT44 local service load balancing """
4835 self.twice_nat_common(lb=True)
4837 def test_self_twice_nat_lb_positive(self):
4838 """ Self Twice NAT44 local service load balancing (positive test) """
4839 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4842 def test_self_twice_nat_lb_negative(self):
4843 """ Self Twice NAT44 local service load balancing (negative test) """
4844 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4847 def test_twice_nat_interface_addr(self):
4848 """ Acquire twice NAT44 addresses from interface """
4849 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4851 # no address in NAT pool
4852 adresses = self.vapi.nat44_address_dump()
4853 self.assertEqual(0, len(adresses))
4855 # configure interface address and check NAT address pool
4856 self.pg3.config_ip4()
4857 adresses = self.vapi.nat44_address_dump()
4858 self.assertEqual(1, len(adresses))
4859 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4860 self.assertEqual(adresses[0].twice_nat, 1)
4862 # remove interface address and check NAT address pool
4863 self.pg3.unconfig_ip4()
4864 adresses = self.vapi.nat44_address_dump()
4865 self.assertEqual(0, len(adresses))
4867 def test_tcp_close(self):
4868 """ Close TCP session from inside network - output feature """
4869 self.vapi.nat44_forwarding_enable_disable(1)
4870 self.nat44_add_address(self.pg1.local_ip4)
4871 twice_nat_addr = '10.0.1.3'
4872 service_ip = '192.168.16.150'
4873 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4874 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4875 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4877 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4879 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4883 proto=IP_PROTOS.tcp,
4886 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4887 start_sessnum = len(sessions)
4889 # SYN packet out->in
4890 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4891 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4892 TCP(sport=33898, dport=80, flags="S"))
4893 self.pg1.add_stream(p)
4894 self.pg_enable_capture(self.pg_interfaces)
4896 capture = self.pg0.get_capture(1)
4898 tcp_port = p[TCP].sport
4900 # SYN + ACK packet in->out
4901 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4902 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4903 TCP(sport=80, dport=tcp_port, flags="SA"))
4904 self.pg0.add_stream(p)
4905 self.pg_enable_capture(self.pg_interfaces)
4907 self.pg1.get_capture(1)
4909 # ACK packet out->in
4910 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4911 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4912 TCP(sport=33898, dport=80, flags="A"))
4913 self.pg1.add_stream(p)
4914 self.pg_enable_capture(self.pg_interfaces)
4916 self.pg0.get_capture(1)
4918 # FIN packet in -> out
4919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4920 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4921 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
4922 self.pg0.add_stream(p)
4923 self.pg_enable_capture(self.pg_interfaces)
4925 self.pg1.get_capture(1)
4927 # FIN+ACK packet out -> in
4928 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4929 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4930 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
4931 self.pg1.add_stream(p)
4932 self.pg_enable_capture(self.pg_interfaces)
4934 self.pg0.get_capture(1)
4936 # ACK packet in -> out
4937 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4938 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4939 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
4940 self.pg0.add_stream(p)
4941 self.pg_enable_capture(self.pg_interfaces)
4943 self.pg1.get_capture(1)
4945 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4947 self.assertEqual(len(sessions) - start_sessnum, 0)
4949 def test_tcp_session_close_in(self):
4950 """ Close TCP session from inside network """
4951 self.tcp_port_out = 10505
4952 self.nat44_add_address(self.nat_addr)
4953 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4957 proto=IP_PROTOS.tcp,
4959 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4960 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4963 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4964 start_sessnum = len(sessions)
4966 self.initiate_tcp_session(self.pg0, self.pg1)
4968 # FIN packet in -> out
4969 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4970 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4971 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4972 flags="FA", seq=100, ack=300))
4973 self.pg0.add_stream(p)
4974 self.pg_enable_capture(self.pg_interfaces)
4976 self.pg1.get_capture(1)
4980 # ACK packet out -> in
4981 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4982 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4983 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4984 flags="A", seq=300, ack=101))
4987 # FIN packet out -> in
4988 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4989 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4990 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4991 flags="FA", seq=300, ack=101))
4994 self.pg1.add_stream(pkts)
4995 self.pg_enable_capture(self.pg_interfaces)
4997 self.pg0.get_capture(2)
4999 # ACK packet in -> out
5000 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5001 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5002 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5003 flags="A", seq=101, ack=301))
5004 self.pg0.add_stream(p)
5005 self.pg_enable_capture(self.pg_interfaces)
5007 self.pg1.get_capture(1)
5009 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5011 self.assertEqual(len(sessions) - start_sessnum, 0)
5013 def test_tcp_session_close_out(self):
5014 """ Close TCP session from outside network """
5015 self.tcp_port_out = 10505
5016 self.nat44_add_address(self.nat_addr)
5017 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5021 proto=IP_PROTOS.tcp,
5023 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5024 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5027 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5028 start_sessnum = len(sessions)
5030 self.initiate_tcp_session(self.pg0, self.pg1)
5032 # FIN packet out -> in
5033 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5034 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5035 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5036 flags="FA", seq=100, ack=300))
5037 self.pg1.add_stream(p)
5038 self.pg_enable_capture(self.pg_interfaces)
5040 self.pg0.get_capture(1)
5042 # FIN+ACK packet in -> out
5043 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5044 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5045 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5046 flags="FA", seq=300, ack=101))
5048 self.pg0.add_stream(p)
5049 self.pg_enable_capture(self.pg_interfaces)
5051 self.pg1.get_capture(1)
5053 # ACK packet out -> in
5054 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5055 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5056 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5057 flags="A", seq=101, ack=301))
5058 self.pg1.add_stream(p)
5059 self.pg_enable_capture(self.pg_interfaces)
5061 self.pg0.get_capture(1)
5063 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5065 self.assertEqual(len(sessions) - start_sessnum, 0)
5067 def test_tcp_session_close_simultaneous(self):
5068 """ Close TCP session from inside network """
5069 self.tcp_port_out = 10505
5070 self.nat44_add_address(self.nat_addr)
5071 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5075 proto=IP_PROTOS.tcp,
5077 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5078 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5081 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5082 start_sessnum = len(sessions)
5084 self.initiate_tcp_session(self.pg0, self.pg1)
5086 # FIN packet in -> out
5087 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5088 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5089 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5090 flags="FA", seq=100, ack=300))
5091 self.pg0.add_stream(p)
5092 self.pg_enable_capture(self.pg_interfaces)
5094 self.pg1.get_capture(1)
5096 # FIN packet out -> in
5097 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5098 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5099 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5100 flags="FA", seq=300, ack=100))
5101 self.pg1.add_stream(p)
5102 self.pg_enable_capture(self.pg_interfaces)
5104 self.pg0.get_capture(1)
5106 # ACK packet in -> out
5107 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5108 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5109 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5110 flags="A", seq=101, ack=301))
5111 self.pg0.add_stream(p)
5112 self.pg_enable_capture(self.pg_interfaces)
5114 self.pg1.get_capture(1)
5116 # ACK packet out -> in
5117 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5118 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5119 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5120 flags="A", seq=301, ack=101))
5121 self.pg1.add_stream(p)
5122 self.pg_enable_capture(self.pg_interfaces)
5124 self.pg0.get_capture(1)
5126 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5128 self.assertEqual(len(sessions) - start_sessnum, 0)
5130 def test_one_armed_nat44_static(self):
5131 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5132 remote_host = self.pg4.remote_hosts[0]
5133 local_host = self.pg4.remote_hosts[1]
5138 self.vapi.nat44_forwarding_enable_disable(1)
5139 self.nat44_add_address(self.nat_addr, twice_nat=1)
5140 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5141 local_port, external_port,
5142 proto=IP_PROTOS.tcp, out2in_only=1,
5144 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5145 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5148 # from client to service
5149 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5150 IP(src=remote_host.ip4, dst=self.nat_addr) /
5151 TCP(sport=12345, dport=external_port))
5152 self.pg4.add_stream(p)
5153 self.pg_enable_capture(self.pg_interfaces)
5155 capture = self.pg4.get_capture(1)
5160 self.assertEqual(ip.dst, local_host.ip4)
5161 self.assertEqual(ip.src, self.nat_addr)
5162 self.assertEqual(tcp.dport, local_port)
5163 self.assertNotEqual(tcp.sport, 12345)
5164 eh_port_in = tcp.sport
5165 self.assert_packet_checksums_valid(p)
5167 self.logger.error(ppp("Unexpected or invalid packet:", p))
5170 # from service back to client
5171 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5172 IP(src=local_host.ip4, dst=self.nat_addr) /
5173 TCP(sport=local_port, dport=eh_port_in))
5174 self.pg4.add_stream(p)
5175 self.pg_enable_capture(self.pg_interfaces)
5177 capture = self.pg4.get_capture(1)
5182 self.assertEqual(ip.src, self.nat_addr)
5183 self.assertEqual(ip.dst, remote_host.ip4)
5184 self.assertEqual(tcp.sport, external_port)
5185 self.assertEqual(tcp.dport, 12345)
5186 self.assert_packet_checksums_valid(p)
5188 self.logger.error(ppp("Unexpected or invalid packet:", p))
5191 def test_static_with_port_out2(self):
5192 """ 1:1 NAPT asymmetrical rule """
5197 self.vapi.nat44_forwarding_enable_disable(1)
5198 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5199 local_port, external_port,
5200 proto=IP_PROTOS.tcp, out2in_only=1)
5201 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5202 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5205 # from client to service
5206 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5207 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5208 TCP(sport=12345, dport=external_port))
5209 self.pg1.add_stream(p)
5210 self.pg_enable_capture(self.pg_interfaces)
5212 capture = self.pg0.get_capture(1)
5217 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5218 self.assertEqual(tcp.dport, local_port)
5219 self.assert_packet_checksums_valid(p)
5221 self.logger.error(ppp("Unexpected or invalid packet:", p))
5225 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5226 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5227 ICMP(type=11) / capture[0][IP])
5228 self.pg0.add_stream(p)
5229 self.pg_enable_capture(self.pg_interfaces)
5231 capture = self.pg1.get_capture(1)
5234 self.assertEqual(p[IP].src, self.nat_addr)
5236 self.assertEqual(inner.dst, self.nat_addr)
5237 self.assertEqual(inner[TCPerror].dport, external_port)
5239 self.logger.error(ppp("Unexpected or invalid packet:", p))
5242 # from service back to client
5243 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5244 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5245 TCP(sport=local_port, dport=12345))
5246 self.pg0.add_stream(p)
5247 self.pg_enable_capture(self.pg_interfaces)
5249 capture = self.pg1.get_capture(1)
5254 self.assertEqual(ip.src, self.nat_addr)
5255 self.assertEqual(tcp.sport, external_port)
5256 self.assert_packet_checksums_valid(p)
5258 self.logger.error(ppp("Unexpected or invalid packet:", p))
5262 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5263 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5264 ICMP(type=11) / capture[0][IP])
5265 self.pg1.add_stream(p)
5266 self.pg_enable_capture(self.pg_interfaces)
5268 capture = self.pg0.get_capture(1)
5271 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5273 self.assertEqual(inner.src, self.pg0.remote_ip4)
5274 self.assertEqual(inner[TCPerror].sport, local_port)
5276 self.logger.error(ppp("Unexpected or invalid packet:", p))
5279 # from client to server (no translation)
5280 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5281 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5282 TCP(sport=12346, dport=local_port))
5283 self.pg1.add_stream(p)
5284 self.pg_enable_capture(self.pg_interfaces)
5286 capture = self.pg0.get_capture(1)
5291 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5292 self.assertEqual(tcp.dport, local_port)
5293 self.assert_packet_checksums_valid(p)
5295 self.logger.error(ppp("Unexpected or invalid packet:", p))
5298 # from service back to client (no translation)
5299 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5300 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5301 TCP(sport=local_port, dport=12346))
5302 self.pg0.add_stream(p)
5303 self.pg_enable_capture(self.pg_interfaces)
5305 capture = self.pg1.get_capture(1)
5310 self.assertEqual(ip.src, self.pg0.remote_ip4)
5311 self.assertEqual(tcp.sport, local_port)
5312 self.assert_packet_checksums_valid(p)
5314 self.logger.error(ppp("Unexpected or invalid packet:", p))
5317 def test_output_feature(self):
5318 """ NAT44 interface output feature (in2out postrouting) """
5319 self.vapi.nat44_forwarding_enable_disable(1)
5320 self.nat44_add_address(self.nat_addr)
5321 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5323 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5327 pkts = self.create_stream_in(self.pg0, self.pg1)
5328 self.pg0.add_stream(pkts)
5329 self.pg_enable_capture(self.pg_interfaces)
5331 capture = self.pg1.get_capture(len(pkts))
5332 self.verify_capture_out(capture)
5335 pkts = self.create_stream_out(self.pg1)
5336 self.pg1.add_stream(pkts)
5337 self.pg_enable_capture(self.pg_interfaces)
5339 capture = self.pg0.get_capture(len(pkts))
5340 self.verify_capture_in(capture, self.pg0)
5342 def test_multiple_vrf(self):
5343 """ Multiple VRF setup """
5344 external_addr = '1.2.3.4'
5349 self.vapi.nat44_forwarding_enable_disable(1)
5350 self.nat44_add_address(self.nat_addr)
5351 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5352 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5354 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5356 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5357 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5359 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5361 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5362 local_port, external_port, vrf_id=1,
5363 proto=IP_PROTOS.tcp, out2in_only=1)
5364 self.nat44_add_static_mapping(
5365 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5366 local_port=local_port, vrf_id=0, external_port=external_port,
5367 proto=IP_PROTOS.tcp, out2in_only=1)
5369 # from client to service (both VRF1)
5370 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5371 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5372 TCP(sport=12345, dport=external_port))
5373 self.pg6.add_stream(p)
5374 self.pg_enable_capture(self.pg_interfaces)
5376 capture = self.pg5.get_capture(1)
5381 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5382 self.assertEqual(tcp.dport, local_port)
5383 self.assert_packet_checksums_valid(p)
5385 self.logger.error(ppp("Unexpected or invalid packet:", p))
5388 # from service back to client (both VRF1)
5389 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5390 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5391 TCP(sport=local_port, dport=12345))
5392 self.pg5.add_stream(p)
5393 self.pg_enable_capture(self.pg_interfaces)
5395 capture = self.pg6.get_capture(1)
5400 self.assertEqual(ip.src, external_addr)
5401 self.assertEqual(tcp.sport, external_port)
5402 self.assert_packet_checksums_valid(p)
5404 self.logger.error(ppp("Unexpected or invalid packet:", p))
5407 # dynamic NAT from VRF1 to VRF0 (output-feature)
5408 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5409 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5410 TCP(sport=2345, dport=22))
5411 self.pg5.add_stream(p)
5412 self.pg_enable_capture(self.pg_interfaces)
5414 capture = self.pg1.get_capture(1)
5419 self.assertEqual(ip.src, self.nat_addr)
5420 self.assertNotEqual(tcp.sport, 2345)
5421 self.assert_packet_checksums_valid(p)
5424 self.logger.error(ppp("Unexpected or invalid packet:", p))
5427 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5429 TCP(sport=22, dport=port))
5430 self.pg1.add_stream(p)
5431 self.pg_enable_capture(self.pg_interfaces)
5433 capture = self.pg5.get_capture(1)
5438 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5439 self.assertEqual(tcp.dport, 2345)
5440 self.assert_packet_checksums_valid(p)
5442 self.logger.error(ppp("Unexpected or invalid packet:", p))
5445 # from client VRF1 to service VRF0
5446 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5447 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5448 TCP(sport=12346, dport=external_port))
5449 self.pg6.add_stream(p)
5450 self.pg_enable_capture(self.pg_interfaces)
5452 capture = self.pg0.get_capture(1)
5457 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5458 self.assertEqual(tcp.dport, local_port)
5459 self.assert_packet_checksums_valid(p)
5461 self.logger.error(ppp("Unexpected or invalid packet:", p))
5464 # from service VRF0 back to client VRF1
5465 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5466 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5467 TCP(sport=local_port, dport=12346))
5468 self.pg0.add_stream(p)
5469 self.pg_enable_capture(self.pg_interfaces)
5471 capture = self.pg6.get_capture(1)
5476 self.assertEqual(ip.src, self.pg0.local_ip4)
5477 self.assertEqual(tcp.sport, external_port)
5478 self.assert_packet_checksums_valid(p)
5480 self.logger.error(ppp("Unexpected or invalid packet:", p))
5483 # from client VRF0 to service VRF1
5484 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5485 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5486 TCP(sport=12347, dport=external_port))
5487 self.pg0.add_stream(p)
5488 self.pg_enable_capture(self.pg_interfaces)
5490 capture = self.pg5.get_capture(1)
5495 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5496 self.assertEqual(tcp.dport, local_port)
5497 self.assert_packet_checksums_valid(p)
5499 self.logger.error(ppp("Unexpected or invalid packet:", p))
5502 # from service VRF1 back to client VRF0
5503 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5504 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5505 TCP(sport=local_port, dport=12347))
5506 self.pg5.add_stream(p)
5507 self.pg_enable_capture(self.pg_interfaces)
5509 capture = self.pg0.get_capture(1)
5514 self.assertEqual(ip.src, external_addr)
5515 self.assertEqual(tcp.sport, external_port)
5516 self.assert_packet_checksums_valid(p)
5518 self.logger.error(ppp("Unexpected or invalid packet:", p))
5521 # from client to server (both VRF1, no translation)
5522 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5523 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5524 TCP(sport=12348, dport=local_port))
5525 self.pg6.add_stream(p)
5526 self.pg_enable_capture(self.pg_interfaces)
5528 capture = self.pg5.get_capture(1)
5533 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5534 self.assertEqual(tcp.dport, local_port)
5535 self.assert_packet_checksums_valid(p)
5537 self.logger.error(ppp("Unexpected or invalid packet:", p))
5540 # from server back to client (both VRF1, no translation)
5541 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5542 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5543 TCP(sport=local_port, dport=12348))
5544 self.pg5.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 capture = self.pg6.get_capture(1)
5552 self.assertEqual(ip.src, self.pg5.remote_ip4)
5553 self.assertEqual(tcp.sport, local_port)
5554 self.assert_packet_checksums_valid(p)
5556 self.logger.error(ppp("Unexpected or invalid packet:", p))
5559 # from client VRF1 to server VRF0 (no translation)
5560 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5561 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5562 TCP(sport=local_port, dport=12349))
5563 self.pg0.add_stream(p)
5564 self.pg_enable_capture(self.pg_interfaces)
5566 capture = self.pg6.get_capture(1)
5571 self.assertEqual(ip.src, self.pg0.remote_ip4)
5572 self.assertEqual(tcp.sport, local_port)
5573 self.assert_packet_checksums_valid(p)
5575 self.logger.error(ppp("Unexpected or invalid packet:", p))
5578 # from server VRF0 back to client VRF1 (no translation)
5579 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5580 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5581 TCP(sport=local_port, dport=12349))
5582 self.pg0.add_stream(p)
5583 self.pg_enable_capture(self.pg_interfaces)
5585 capture = self.pg6.get_capture(1)
5590 self.assertEqual(ip.src, self.pg0.remote_ip4)
5591 self.assertEqual(tcp.sport, local_port)
5592 self.assert_packet_checksums_valid(p)
5594 self.logger.error(ppp("Unexpected or invalid packet:", p))
5597 # from client VRF0 to server VRF1 (no translation)
5598 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5599 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5600 TCP(sport=12344, dport=local_port))
5601 self.pg0.add_stream(p)
5602 self.pg_enable_capture(self.pg_interfaces)
5604 capture = self.pg5.get_capture(1)
5609 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5610 self.assertEqual(tcp.dport, local_port)
5611 self.assert_packet_checksums_valid(p)
5613 self.logger.error(ppp("Unexpected or invalid packet:", p))
5616 # from server VRF1 back to client VRF0 (no translation)
5617 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5618 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5619 TCP(sport=local_port, dport=12344))
5620 self.pg5.add_stream(p)
5621 self.pg_enable_capture(self.pg_interfaces)
5623 capture = self.pg0.get_capture(1)
5628 self.assertEqual(ip.src, self.pg5.remote_ip4)
5629 self.assertEqual(tcp.sport, local_port)
5630 self.assert_packet_checksums_valid(p)
5632 self.logger.error(ppp("Unexpected or invalid packet:", p))
5635 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5636 def test_session_timeout(self):
5637 """ NAT44 session timeouts """
5638 self.nat44_add_address(self.nat_addr)
5639 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5640 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5642 self.vapi.nat_set_timeouts(icmp=5)
5646 for i in range(0, max_sessions):
5647 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5648 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5649 IP(src=src, dst=self.pg1.remote_ip4) /
5650 ICMP(id=1025, type='echo-request'))
5652 self.pg0.add_stream(pkts)
5653 self.pg_enable_capture(self.pg_interfaces)
5655 self.pg1.get_capture(max_sessions)
5660 for i in range(0, max_sessions):
5661 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5663 IP(src=src, dst=self.pg1.remote_ip4) /
5664 ICMP(id=1026, type='echo-request'))
5666 self.pg0.add_stream(pkts)
5667 self.pg_enable_capture(self.pg_interfaces)
5669 self.pg1.get_capture(max_sessions)
5672 users = self.vapi.nat44_user_dump()
5674 nsessions = nsessions + user.nsessions
5675 self.assertLess(nsessions, 2 * max_sessions)
5677 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5678 def test_session_limit_per_user(self):
5679 """ Maximum sessions per user limit """
5680 self.nat44_add_address(self.nat_addr)
5681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5684 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5685 src_address=self.pg2.local_ip4n,
5687 template_interval=10)
5688 self.vapi.nat_set_timeouts(udp=5)
5690 # get maximum number of translations per user
5691 nat44_config = self.vapi.nat_show_config()
5694 for port in range(0, nat44_config.max_translations_per_user):
5695 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5696 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5697 UDP(sport=1025 + port, dport=1025 + port))
5700 self.pg0.add_stream(pkts)
5701 self.pg_enable_capture(self.pg_interfaces)
5703 capture = self.pg1.get_capture(len(pkts))
5705 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5706 src_port=self.ipfix_src_port)
5708 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5709 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5710 UDP(sport=3001, dport=3002))
5711 self.pg0.add_stream(p)
5712 self.pg_enable_capture(self.pg_interfaces)
5714 capture = self.pg1.assert_nothing_captured()
5716 # verify IPFIX logging
5717 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5719 capture = self.pg2.get_capture(10)
5720 ipfix = IPFIXDecoder()
5721 # first load template
5723 self.assertTrue(p.haslayer(IPFIX))
5724 if p.haslayer(Template):
5725 ipfix.add_template(p.getlayer(Template))
5726 # verify events in data set
5728 if p.haslayer(Data):
5729 data = ipfix.decode_data_set(p.getlayer(Set))
5730 self.verify_ipfix_max_entries_per_user(
5732 nat44_config.max_translations_per_user,
5733 self.pg0.remote_ip4n)
5736 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5737 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5738 UDP(sport=3001, dport=3002))
5739 self.pg0.add_stream(p)
5740 self.pg_enable_capture(self.pg_interfaces)
5742 self.pg1.get_capture(1)
5745 super(TestNAT44EndpointDependent, self).tearDown()
5746 if not self.vpp_dead:
5747 self.logger.info(self.vapi.cli("show nat44 addresses"))
5748 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5749 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5750 self.logger.info(self.vapi.cli("show nat44 interface address"))
5751 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5752 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5753 self.logger.info(self.vapi.cli("show nat timeouts"))
5755 self.vapi.cli("clear logging")
5758 class TestNAT44Out2InDPO(MethodHolder):
5759 """ NAT44 Test Cases using out2in DPO """
5762 def setUpConstants(cls):
5763 super(TestNAT44Out2InDPO, cls).setUpConstants()
5764 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5767 def setUpClass(cls):
5768 super(TestNAT44Out2InDPO, cls).setUpClass()
5769 cls.vapi.cli("set log class nat level debug")
5772 cls.tcp_port_in = 6303
5773 cls.tcp_port_out = 6303
5774 cls.udp_port_in = 6304
5775 cls.udp_port_out = 6304
5776 cls.icmp_id_in = 6305
5777 cls.icmp_id_out = 6305
5778 cls.nat_addr = '10.0.0.3'
5779 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5780 cls.dst_ip4 = '192.168.70.1'
5782 cls.create_pg_interfaces(range(2))
5785 cls.pg0.config_ip4()
5786 cls.pg0.resolve_arp()
5789 cls.pg1.config_ip6()
5790 cls.pg1.resolve_ndp()
5792 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5793 dst_address_length=0,
5794 next_hop_address=cls.pg1.remote_ip6n,
5795 next_hop_sw_if_index=cls.pg1.sw_if_index)
5798 super(TestNAT44Out2InDPO, cls).tearDownClass()
5801 def configure_xlat(self):
5802 self.dst_ip6_pfx = '1:2:3::'
5803 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5805 self.dst_ip6_pfx_len = 96
5806 self.src_ip6_pfx = '4:5:6::'
5807 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5809 self.src_ip6_pfx_len = 96
5810 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5811 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5812 '\x00\x00\x00\x00', 0, is_translation=1,
5815 def test_464xlat_ce(self):
5816 """ Test 464XLAT CE with NAT44 """
5818 nat_config = self.vapi.nat_show_config()
5819 self.assertEqual(1, nat_config.out2in_dpo)
5821 self.configure_xlat()
5823 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5824 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5826 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5827 self.dst_ip6_pfx_len)
5828 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5829 self.src_ip6_pfx_len)
5832 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5833 self.pg0.add_stream(pkts)
5834 self.pg_enable_capture(self.pg_interfaces)
5836 capture = self.pg1.get_capture(len(pkts))
5837 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5840 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5842 self.pg1.add_stream(pkts)
5843 self.pg_enable_capture(self.pg_interfaces)
5845 capture = self.pg0.get_capture(len(pkts))
5846 self.verify_capture_in(capture, self.pg0)
5848 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5850 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5851 self.nat_addr_n, is_add=0)
5853 def test_464xlat_ce_no_nat(self):
5854 """ Test 464XLAT CE without NAT44 """
5856 self.configure_xlat()
5858 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5859 self.dst_ip6_pfx_len)
5860 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5861 self.src_ip6_pfx_len)
5863 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5864 self.pg0.add_stream(pkts)
5865 self.pg_enable_capture(self.pg_interfaces)
5867 capture = self.pg1.get_capture(len(pkts))
5868 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5869 nat_ip=out_dst_ip6, same_port=True)
5871 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5872 self.pg1.add_stream(pkts)
5873 self.pg_enable_capture(self.pg_interfaces)
5875 capture = self.pg0.get_capture(len(pkts))
5876 self.verify_capture_in(capture, self.pg0)
5879 class TestDeterministicNAT(MethodHolder):
5880 """ Deterministic NAT Test Cases """
5883 def setUpConstants(cls):
5884 super(TestDeterministicNAT, cls).setUpConstants()
5885 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5888 def setUpClass(cls):
5889 super(TestDeterministicNAT, cls).setUpClass()
5890 cls.vapi.cli("set log class nat level debug")
5893 cls.tcp_port_in = 6303
5894 cls.tcp_external_port = 6303
5895 cls.udp_port_in = 6304
5896 cls.udp_external_port = 6304
5897 cls.icmp_id_in = 6305
5898 cls.nat_addr = '10.0.0.3'
5900 cls.create_pg_interfaces(range(3))
5901 cls.interfaces = list(cls.pg_interfaces)
5903 for i in cls.interfaces:
5908 cls.pg0.generate_remote_hosts(2)
5909 cls.pg0.configure_ipv4_neighbors()
5912 super(TestDeterministicNAT, cls).tearDownClass()
5915 def create_stream_in(self, in_if, out_if, ttl=64):
5917 Create packet stream for inside network
5919 :param in_if: Inside interface
5920 :param out_if: Outside interface
5921 :param ttl: TTL of generated packets
5925 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5926 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5927 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5931 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5932 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5933 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5937 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5938 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5939 ICMP(id=self.icmp_id_in, type='echo-request'))
5944 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5946 Create packet stream for outside network
5948 :param out_if: Outside interface
5949 :param dst_ip: Destination IP address (Default use global NAT address)
5950 :param ttl: TTL of generated packets
5953 dst_ip = self.nat_addr
5956 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5957 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5958 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
5962 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5963 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5964 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
5968 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5969 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5970 ICMP(id=self.icmp_external_id, type='echo-reply'))
5975 def verify_capture_out(self, capture, nat_ip=None):
5977 Verify captured packets on outside network
5979 :param capture: Captured packets
5980 :param nat_ip: Translated IP address (Default use global NAT address)
5981 :param same_port: Sorce port number is not translated (Default False)
5984 nat_ip = self.nat_addr
5985 for packet in capture:
5987 self.assertEqual(packet[IP].src, nat_ip)
5988 if packet.haslayer(TCP):
5989 self.tcp_port_out = packet[TCP].sport
5990 elif packet.haslayer(UDP):
5991 self.udp_port_out = packet[UDP].sport
5993 self.icmp_external_id = packet[ICMP].id
5995 self.logger.error(ppp("Unexpected or invalid packet "
5996 "(outside network):", packet))
5999 def test_deterministic_mode(self):
6000 """ NAT plugin run deterministic mode """
6001 in_addr = '172.16.255.0'
6002 out_addr = '172.17.255.50'
6003 in_addr_t = '172.16.255.20'
6004 in_addr_n = socket.inet_aton(in_addr)
6005 out_addr_n = socket.inet_aton(out_addr)
6006 in_addr_t_n = socket.inet_aton(in_addr_t)
6010 nat_config = self.vapi.nat_show_config()
6011 self.assertEqual(1, nat_config.deterministic)
6013 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6015 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6016 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6017 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6018 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6020 deterministic_mappings = self.vapi.nat_det_map_dump()
6021 self.assertEqual(len(deterministic_mappings), 1)
6022 dsm = deterministic_mappings[0]
6023 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6024 self.assertEqual(in_plen, dsm.in_plen)
6025 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6026 self.assertEqual(out_plen, dsm.out_plen)
6028 self.clear_nat_det()
6029 deterministic_mappings = self.vapi.nat_det_map_dump()
6030 self.assertEqual(len(deterministic_mappings), 0)
6032 def test_set_timeouts(self):
6033 """ Set deterministic NAT timeouts """
6034 timeouts_before = self.vapi.nat_get_timeouts()
6036 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6037 timeouts_before.tcp_established + 10,
6038 timeouts_before.tcp_transitory + 10,
6039 timeouts_before.icmp + 10)
6041 timeouts_after = self.vapi.nat_get_timeouts()
6043 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6044 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6045 self.assertNotEqual(timeouts_before.tcp_established,
6046 timeouts_after.tcp_established)
6047 self.assertNotEqual(timeouts_before.tcp_transitory,
6048 timeouts_after.tcp_transitory)
6050 def test_det_in(self):
6051 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6053 nat_ip = "10.0.0.10"
6055 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6057 socket.inet_aton(nat_ip),
6059 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6060 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6064 pkts = self.create_stream_in(self.pg0, self.pg1)
6065 self.pg0.add_stream(pkts)
6066 self.pg_enable_capture(self.pg_interfaces)
6068 capture = self.pg1.get_capture(len(pkts))
6069 self.verify_capture_out(capture, nat_ip)
6072 pkts = self.create_stream_out(self.pg1, nat_ip)
6073 self.pg1.add_stream(pkts)
6074 self.pg_enable_capture(self.pg_interfaces)
6076 capture = self.pg0.get_capture(len(pkts))
6077 self.verify_capture_in(capture, self.pg0)
6080 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6081 self.assertEqual(len(sessions), 3)
6085 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6086 self.assertEqual(s.in_port, self.tcp_port_in)
6087 self.assertEqual(s.out_port, self.tcp_port_out)
6088 self.assertEqual(s.ext_port, self.tcp_external_port)
6092 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6093 self.assertEqual(s.in_port, self.udp_port_in)
6094 self.assertEqual(s.out_port, self.udp_port_out)
6095 self.assertEqual(s.ext_port, self.udp_external_port)
6099 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6100 self.assertEqual(s.in_port, self.icmp_id_in)
6101 self.assertEqual(s.out_port, self.icmp_external_id)
6103 def test_multiple_users(self):
6104 """ Deterministic NAT multiple users """
6106 nat_ip = "10.0.0.10"
6108 external_port = 6303
6110 host0 = self.pg0.remote_hosts[0]
6111 host1 = self.pg0.remote_hosts[1]
6113 self.vapi.nat_det_add_del_map(host0.ip4n,
6115 socket.inet_aton(nat_ip),
6117 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6118 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6122 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6123 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6124 TCP(sport=port_in, dport=external_port))
6125 self.pg0.add_stream(p)
6126 self.pg_enable_capture(self.pg_interfaces)
6128 capture = self.pg1.get_capture(1)
6133 self.assertEqual(ip.src, nat_ip)
6134 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6135 self.assertEqual(tcp.dport, external_port)
6136 port_out0 = tcp.sport
6138 self.logger.error(ppp("Unexpected or invalid packet:", p))
6142 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6143 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6144 TCP(sport=port_in, dport=external_port))
6145 self.pg0.add_stream(p)
6146 self.pg_enable_capture(self.pg_interfaces)
6148 capture = self.pg1.get_capture(1)
6153 self.assertEqual(ip.src, nat_ip)
6154 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6155 self.assertEqual(tcp.dport, external_port)
6156 port_out1 = tcp.sport
6158 self.logger.error(ppp("Unexpected or invalid packet:", p))
6161 dms = self.vapi.nat_det_map_dump()
6162 self.assertEqual(1, len(dms))
6163 self.assertEqual(2, dms[0].ses_num)
6166 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6167 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6168 TCP(sport=external_port, dport=port_out0))
6169 self.pg1.add_stream(p)
6170 self.pg_enable_capture(self.pg_interfaces)
6172 capture = self.pg0.get_capture(1)
6177 self.assertEqual(ip.src, self.pg1.remote_ip4)
6178 self.assertEqual(ip.dst, host0.ip4)
6179 self.assertEqual(tcp.dport, port_in)
6180 self.assertEqual(tcp.sport, external_port)
6182 self.logger.error(ppp("Unexpected or invalid packet:", p))
6186 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6187 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6188 TCP(sport=external_port, dport=port_out1))
6189 self.pg1.add_stream(p)
6190 self.pg_enable_capture(self.pg_interfaces)
6192 capture = self.pg0.get_capture(1)
6197 self.assertEqual(ip.src, self.pg1.remote_ip4)
6198 self.assertEqual(ip.dst, host1.ip4)
6199 self.assertEqual(tcp.dport, port_in)
6200 self.assertEqual(tcp.sport, external_port)
6202 self.logger.error(ppp("Unexpected or invalid packet", p))
6205 # session close api test
6206 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6208 self.pg1.remote_ip4n,
6210 dms = self.vapi.nat_det_map_dump()
6211 self.assertEqual(dms[0].ses_num, 1)
6213 self.vapi.nat_det_close_session_in(host0.ip4n,
6215 self.pg1.remote_ip4n,
6217 dms = self.vapi.nat_det_map_dump()
6218 self.assertEqual(dms[0].ses_num, 0)
6220 def test_tcp_session_close_detection_in(self):
6221 """ Deterministic NAT TCP session close from inside network """
6222 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6224 socket.inet_aton(self.nat_addr),
6226 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6227 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6230 self.initiate_tcp_session(self.pg0, self.pg1)
6232 # close the session from inside
6234 # FIN packet in -> out
6235 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6236 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6237 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6239 self.pg0.add_stream(p)
6240 self.pg_enable_capture(self.pg_interfaces)
6242 self.pg1.get_capture(1)
6246 # ACK packet out -> in
6247 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6248 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6249 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6253 # FIN packet out -> in
6254 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6255 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6256 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6260 self.pg1.add_stream(pkts)
6261 self.pg_enable_capture(self.pg_interfaces)
6263 self.pg0.get_capture(2)
6265 # ACK packet in -> out
6266 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6267 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6268 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6270 self.pg0.add_stream(p)
6271 self.pg_enable_capture(self.pg_interfaces)
6273 self.pg1.get_capture(1)
6275 # Check if deterministic NAT44 closed the session
6276 dms = self.vapi.nat_det_map_dump()
6277 self.assertEqual(0, dms[0].ses_num)
6279 self.logger.error("TCP session termination failed")
6282 def test_tcp_session_close_detection_out(self):
6283 """ Deterministic NAT TCP session close from outside network """
6284 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6286 socket.inet_aton(self.nat_addr),
6288 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6289 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6292 self.initiate_tcp_session(self.pg0, self.pg1)
6294 # close the session from outside
6296 # FIN packet out -> in
6297 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6298 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6299 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6301 self.pg1.add_stream(p)
6302 self.pg_enable_capture(self.pg_interfaces)
6304 self.pg0.get_capture(1)
6308 # ACK packet in -> out
6309 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6310 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6311 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6315 # ACK packet in -> out
6316 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6317 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6318 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6322 self.pg0.add_stream(pkts)
6323 self.pg_enable_capture(self.pg_interfaces)
6325 self.pg1.get_capture(2)
6327 # ACK packet out -> in
6328 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6329 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6330 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6332 self.pg1.add_stream(p)
6333 self.pg_enable_capture(self.pg_interfaces)
6335 self.pg0.get_capture(1)
6337 # Check if deterministic NAT44 closed the session
6338 dms = self.vapi.nat_det_map_dump()
6339 self.assertEqual(0, dms[0].ses_num)
6341 self.logger.error("TCP session termination failed")
6344 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6345 def test_session_timeout(self):
6346 """ Deterministic NAT session timeouts """
6347 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6349 socket.inet_aton(self.nat_addr),
6351 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6352 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6355 self.initiate_tcp_session(self.pg0, self.pg1)
6356 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6357 pkts = self.create_stream_in(self.pg0, self.pg1)
6358 self.pg0.add_stream(pkts)
6359 self.pg_enable_capture(self.pg_interfaces)
6361 capture = self.pg1.get_capture(len(pkts))
6364 dms = self.vapi.nat_det_map_dump()
6365 self.assertEqual(0, dms[0].ses_num)
6367 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6368 def test_session_limit_per_user(self):
6369 """ Deterministic NAT maximum sessions per user limit """
6370 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6372 socket.inet_aton(self.nat_addr),
6374 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6375 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6377 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6378 src_address=self.pg2.local_ip4n,
6380 template_interval=10)
6381 self.vapi.nat_ipfix()
6384 for port in range(1025, 2025):
6385 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6386 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6387 UDP(sport=port, dport=port))
6390 self.pg0.add_stream(pkts)
6391 self.pg_enable_capture(self.pg_interfaces)
6393 capture = self.pg1.get_capture(len(pkts))
6395 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6396 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6397 UDP(sport=3001, dport=3002))
6398 self.pg0.add_stream(p)
6399 self.pg_enable_capture(self.pg_interfaces)
6401 capture = self.pg1.assert_nothing_captured()
6403 # verify ICMP error packet
6404 capture = self.pg0.get_capture(1)
6406 self.assertTrue(p.haslayer(ICMP))
6408 self.assertEqual(icmp.type, 3)
6409 self.assertEqual(icmp.code, 1)
6410 self.assertTrue(icmp.haslayer(IPerror))
6411 inner_ip = icmp[IPerror]
6412 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6413 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6415 dms = self.vapi.nat_det_map_dump()
6417 self.assertEqual(1000, dms[0].ses_num)
6419 # verify IPFIX logging
6420 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6422 capture = self.pg2.get_capture(2)
6423 ipfix = IPFIXDecoder()
6424 # first load template
6426 self.assertTrue(p.haslayer(IPFIX))
6427 if p.haslayer(Template):
6428 ipfix.add_template(p.getlayer(Template))
6429 # verify events in data set
6431 if p.haslayer(Data):
6432 data = ipfix.decode_data_set(p.getlayer(Set))
6433 self.verify_ipfix_max_entries_per_user(data,
6435 self.pg0.remote_ip4n)
6437 def clear_nat_det(self):
6439 Clear deterministic NAT configuration.
6441 self.vapi.nat_ipfix(enable=0)
6442 self.vapi.nat_set_timeouts()
6443 deterministic_mappings = self.vapi.nat_det_map_dump()
6444 for dsm in deterministic_mappings:
6445 self.vapi.nat_det_add_del_map(dsm.in_addr,
6451 interfaces = self.vapi.nat44_interface_dump()
6452 for intf in interfaces:
6453 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6458 super(TestDeterministicNAT, self).tearDown()
6459 if not self.vpp_dead:
6460 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6461 self.logger.info(self.vapi.cli("show nat timeouts"))
6463 self.vapi.cli("show nat44 deterministic mappings"))
6465 self.vapi.cli("show nat44 deterministic sessions"))
6466 self.clear_nat_det()
6469 class TestNAT64(MethodHolder):
6470 """ NAT64 Test Cases """
6473 def setUpConstants(cls):
6474 super(TestNAT64, cls).setUpConstants()
6475 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6476 "nat64 st hash buckets 256", "}"])
6479 def setUpClass(cls):
6480 super(TestNAT64, cls).setUpClass()
6483 cls.tcp_port_in = 6303
6484 cls.tcp_port_out = 6303
6485 cls.udp_port_in = 6304
6486 cls.udp_port_out = 6304
6487 cls.icmp_id_in = 6305
6488 cls.icmp_id_out = 6305
6489 cls.nat_addr = '10.0.0.3'
6490 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6492 cls.vrf1_nat_addr = '10.0.10.3'
6493 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6495 cls.ipfix_src_port = 4739
6496 cls.ipfix_domain_id = 1
6498 cls.create_pg_interfaces(range(6))
6499 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6500 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6501 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6503 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6505 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6507 cls.pg0.generate_remote_hosts(2)
6509 for i in cls.ip6_interfaces:
6512 i.configure_ipv6_neighbors()
6514 for i in cls.ip4_interfaces:
6520 cls.pg3.config_ip4()
6521 cls.pg3.resolve_arp()
6522 cls.pg3.config_ip6()
6523 cls.pg3.configure_ipv6_neighbors()
6526 cls.pg5.config_ip6()
6529 super(TestNAT64, cls).tearDownClass()
6532 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6533 """ NAT64 inside interface handles Neighbor Advertisement """
6535 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6538 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6539 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6540 ICMPv6EchoRequest())
6542 self.pg5.add_stream(pkts)
6543 self.pg_enable_capture(self.pg_interfaces)
6546 # Wait for Neighbor Solicitation
6547 capture = self.pg5.get_capture(len(pkts))
6550 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6551 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6552 tgt = packet[ICMPv6ND_NS].tgt
6554 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6557 # Send Neighbor Advertisement
6558 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6559 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6560 ICMPv6ND_NA(tgt=tgt) /
6561 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6563 self.pg5.add_stream(pkts)
6564 self.pg_enable_capture(self.pg_interfaces)
6567 # Try to send ping again
6569 self.pg5.add_stream(pkts)
6570 self.pg_enable_capture(self.pg_interfaces)
6573 # Wait for ping reply
6574 capture = self.pg5.get_capture(len(pkts))
6577 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6578 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6579 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6581 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6584 def test_pool(self):
6585 """ Add/delete address to NAT64 pool """
6586 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6588 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6590 addresses = self.vapi.nat64_pool_addr_dump()
6591 self.assertEqual(len(addresses), 1)
6592 self.assertEqual(addresses[0].address, nat_addr)
6594 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6596 addresses = self.vapi.nat64_pool_addr_dump()
6597 self.assertEqual(len(addresses), 0)
6599 def test_interface(self):
6600 """ Enable/disable NAT64 feature on the interface """
6601 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6602 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6604 interfaces = self.vapi.nat64_interface_dump()
6605 self.assertEqual(len(interfaces), 2)
6608 for intf in interfaces:
6609 if intf.sw_if_index == self.pg0.sw_if_index:
6610 self.assertEqual(intf.is_inside, 1)
6612 elif intf.sw_if_index == self.pg1.sw_if_index:
6613 self.assertEqual(intf.is_inside, 0)
6615 self.assertTrue(pg0_found)
6616 self.assertTrue(pg1_found)
6618 features = self.vapi.cli("show interface features pg0")
6619 self.assertNotEqual(features.find('nat64-in2out'), -1)
6620 features = self.vapi.cli("show interface features pg1")
6621 self.assertNotEqual(features.find('nat64-out2in'), -1)
6623 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6624 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6626 interfaces = self.vapi.nat64_interface_dump()
6627 self.assertEqual(len(interfaces), 0)
6629 def test_static_bib(self):
6630 """ Add/delete static BIB entry """
6631 in_addr = socket.inet_pton(socket.AF_INET6,
6632 '2001:db8:85a3::8a2e:370:7334')
6633 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6636 proto = IP_PROTOS.tcp
6638 self.vapi.nat64_add_del_static_bib(in_addr,
6643 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6648 self.assertEqual(bibe.i_addr, in_addr)
6649 self.assertEqual(bibe.o_addr, out_addr)
6650 self.assertEqual(bibe.i_port, in_port)
6651 self.assertEqual(bibe.o_port, out_port)
6652 self.assertEqual(static_bib_num, 1)
6654 self.vapi.nat64_add_del_static_bib(in_addr,
6660 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6665 self.assertEqual(static_bib_num, 0)
6667 def test_set_timeouts(self):
6668 """ Set NAT64 timeouts """
6669 # verify default values
6670 timeouts = self.vapi.nat_get_timeouts()
6671 self.assertEqual(timeouts.udp, 300)
6672 self.assertEqual(timeouts.icmp, 60)
6673 self.assertEqual(timeouts.tcp_transitory, 240)
6674 self.assertEqual(timeouts.tcp_established, 7440)
6676 # set and verify custom values
6677 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6678 tcp_established=7450)
6679 timeouts = self.vapi.nat_get_timeouts()
6680 self.assertEqual(timeouts.udp, 200)
6681 self.assertEqual(timeouts.icmp, 30)
6682 self.assertEqual(timeouts.tcp_transitory, 250)
6683 self.assertEqual(timeouts.tcp_established, 7450)
6685 def test_dynamic(self):
6686 """ NAT64 dynamic translation test """
6687 self.tcp_port_in = 6303
6688 self.udp_port_in = 6304
6689 self.icmp_id_in = 6305
6691 ses_num_start = self.nat64_get_ses_num()
6693 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6695 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6696 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6699 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6700 self.pg0.add_stream(pkts)
6701 self.pg_enable_capture(self.pg_interfaces)
6703 capture = self.pg1.get_capture(len(pkts))
6704 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6705 dst_ip=self.pg1.remote_ip4)
6708 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6709 self.pg1.add_stream(pkts)
6710 self.pg_enable_capture(self.pg_interfaces)
6712 capture = self.pg0.get_capture(len(pkts))
6713 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6714 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6717 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6718 self.pg0.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.nat_addr,
6723 dst_ip=self.pg1.remote_ip4)
6726 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6727 self.pg1.add_stream(pkts)
6728 self.pg_enable_capture(self.pg_interfaces)
6730 capture = self.pg0.get_capture(len(pkts))
6731 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6733 ses_num_end = self.nat64_get_ses_num()
6735 self.assertEqual(ses_num_end - ses_num_start, 3)
6737 # tenant with specific VRF
6738 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6739 self.vrf1_nat_addr_n,
6740 vrf_id=self.vrf1_id)
6741 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6743 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6744 self.pg2.add_stream(pkts)
6745 self.pg_enable_capture(self.pg_interfaces)
6747 capture = self.pg1.get_capture(len(pkts))
6748 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6749 dst_ip=self.pg1.remote_ip4)
6751 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6752 self.pg1.add_stream(pkts)
6753 self.pg_enable_capture(self.pg_interfaces)
6755 capture = self.pg2.get_capture(len(pkts))
6756 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6758 def test_static(self):
6759 """ NAT64 static translation test """
6760 self.tcp_port_in = 60303
6761 self.udp_port_in = 60304
6762 self.icmp_id_in = 60305
6763 self.tcp_port_out = 60303
6764 self.udp_port_out = 60304
6765 self.icmp_id_out = 60305
6767 ses_num_start = self.nat64_get_ses_num()
6769 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6771 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6772 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6774 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6779 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6784 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6791 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6792 self.pg0.add_stream(pkts)
6793 self.pg_enable_capture(self.pg_interfaces)
6795 capture = self.pg1.get_capture(len(pkts))
6796 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6797 dst_ip=self.pg1.remote_ip4, same_port=True)
6800 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6801 self.pg1.add_stream(pkts)
6802 self.pg_enable_capture(self.pg_interfaces)
6804 capture = self.pg0.get_capture(len(pkts))
6805 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6806 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6808 ses_num_end = self.nat64_get_ses_num()
6810 self.assertEqual(ses_num_end - ses_num_start, 3)
6812 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6813 def test_session_timeout(self):
6814 """ NAT64 session timeout """
6815 self.icmp_id_in = 1234
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)
6820 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
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 = self.pg1.get_capture(len(pkts))
6828 ses_num_before_timeout = self.nat64_get_ses_num()
6832 # ICMP and TCP session after timeout
6833 ses_num_after_timeout = self.nat64_get_ses_num()
6834 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6836 def test_icmp_error(self):
6837 """ NAT64 ICMP Error message translation """
6838 self.tcp_port_in = 6303
6839 self.udp_port_in = 6304
6840 self.icmp_id_in = 6305
6842 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6844 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6845 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6847 # send some packets to create sessions
6848 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6849 self.pg0.add_stream(pkts)
6850 self.pg_enable_capture(self.pg_interfaces)
6852 capture_ip4 = self.pg1.get_capture(len(pkts))
6853 self.verify_capture_out(capture_ip4,
6854 nat_ip=self.nat_addr,
6855 dst_ip=self.pg1.remote_ip4)
6857 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6858 self.pg1.add_stream(pkts)
6859 self.pg_enable_capture(self.pg_interfaces)
6861 capture_ip6 = self.pg0.get_capture(len(pkts))
6862 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6863 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6864 self.pg0.remote_ip6)
6867 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6868 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6869 ICMPv6DestUnreach(code=1) /
6870 packet[IPv6] for packet in capture_ip6]
6871 self.pg0.add_stream(pkts)
6872 self.pg_enable_capture(self.pg_interfaces)
6874 capture = self.pg1.get_capture(len(pkts))
6875 for packet in capture:
6877 self.assertEqual(packet[IP].src, self.nat_addr)
6878 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6879 self.assertEqual(packet[ICMP].type, 3)
6880 self.assertEqual(packet[ICMP].code, 13)
6881 inner = packet[IPerror]
6882 self.assertEqual(inner.src, self.pg1.remote_ip4)
6883 self.assertEqual(inner.dst, self.nat_addr)
6884 self.assert_packet_checksums_valid(packet)
6885 if inner.haslayer(TCPerror):
6886 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6887 elif inner.haslayer(UDPerror):
6888 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6890 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6892 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6896 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6897 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6898 ICMP(type=3, code=13) /
6899 packet[IP] for packet in capture_ip4]
6900 self.pg1.add_stream(pkts)
6901 self.pg_enable_capture(self.pg_interfaces)
6903 capture = self.pg0.get_capture(len(pkts))
6904 for packet in capture:
6906 self.assertEqual(packet[IPv6].src, ip.src)
6907 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6908 icmp = packet[ICMPv6DestUnreach]
6909 self.assertEqual(icmp.code, 1)
6910 inner = icmp[IPerror6]
6911 self.assertEqual(inner.src, self.pg0.remote_ip6)
6912 self.assertEqual(inner.dst, ip.src)
6913 self.assert_icmpv6_checksum_valid(packet)
6914 if inner.haslayer(TCPerror):
6915 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6916 elif inner.haslayer(UDPerror):
6917 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6919 self.assertEqual(inner[ICMPv6EchoRequest].id,
6922 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6925 def test_hairpinning(self):
6926 """ NAT64 hairpinning """
6928 client = self.pg0.remote_hosts[0]
6929 server = self.pg0.remote_hosts[1]
6930 server_tcp_in_port = 22
6931 server_tcp_out_port = 4022
6932 server_udp_in_port = 23
6933 server_udp_out_port = 4023
6934 client_tcp_in_port = 1234
6935 client_udp_in_port = 1235
6936 client_tcp_out_port = 0
6937 client_udp_out_port = 0
6938 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6939 nat_addr_ip6 = ip.src
6941 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6943 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6944 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6946 self.vapi.nat64_add_del_static_bib(server.ip6n,
6949 server_tcp_out_port,
6951 self.vapi.nat64_add_del_static_bib(server.ip6n,
6954 server_udp_out_port,
6959 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6960 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6961 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6963 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6964 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6965 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6967 self.pg0.add_stream(pkts)
6968 self.pg_enable_capture(self.pg_interfaces)
6970 capture = self.pg0.get_capture(len(pkts))
6971 for packet in capture:
6973 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6974 self.assertEqual(packet[IPv6].dst, server.ip6)
6975 self.assert_packet_checksums_valid(packet)
6976 if packet.haslayer(TCP):
6977 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6978 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
6979 client_tcp_out_port = packet[TCP].sport
6981 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6982 self.assertEqual(packet[UDP].dport, server_udp_in_port)
6983 client_udp_out_port = packet[UDP].sport
6985 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6990 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6991 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6992 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6994 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6995 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6996 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6998 self.pg0.add_stream(pkts)
6999 self.pg_enable_capture(self.pg_interfaces)
7001 capture = self.pg0.get_capture(len(pkts))
7002 for packet in capture:
7004 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7005 self.assertEqual(packet[IPv6].dst, client.ip6)
7006 self.assert_packet_checksums_valid(packet)
7007 if packet.haslayer(TCP):
7008 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7009 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7011 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7012 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7014 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7019 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7020 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7021 ICMPv6DestUnreach(code=1) /
7022 packet[IPv6] for packet in capture]
7023 self.pg0.add_stream(pkts)
7024 self.pg_enable_capture(self.pg_interfaces)
7026 capture = self.pg0.get_capture(len(pkts))
7027 for packet in capture:
7029 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7030 self.assertEqual(packet[IPv6].dst, server.ip6)
7031 icmp = packet[ICMPv6DestUnreach]
7032 self.assertEqual(icmp.code, 1)
7033 inner = icmp[IPerror6]
7034 self.assertEqual(inner.src, server.ip6)
7035 self.assertEqual(inner.dst, nat_addr_ip6)
7036 self.assert_packet_checksums_valid(packet)
7037 if inner.haslayer(TCPerror):
7038 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7039 self.assertEqual(inner[TCPerror].dport,
7040 client_tcp_out_port)
7042 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7043 self.assertEqual(inner[UDPerror].dport,
7044 client_udp_out_port)
7046 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7049 def test_prefix(self):
7050 """ NAT64 Network-Specific Prefix """
7052 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7054 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7055 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7056 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7057 self.vrf1_nat_addr_n,
7058 vrf_id=self.vrf1_id)
7059 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7062 global_pref64 = "2001:db8::"
7063 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7064 global_pref64_len = 32
7065 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7067 prefix = self.vapi.nat64_prefix_dump()
7068 self.assertEqual(len(prefix), 1)
7069 self.assertEqual(prefix[0].prefix, global_pref64_n)
7070 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7071 self.assertEqual(prefix[0].vrf_id, 0)
7073 # Add tenant specific prefix
7074 vrf1_pref64 = "2001:db8:122:300::"
7075 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7076 vrf1_pref64_len = 56
7077 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7079 vrf_id=self.vrf1_id)
7080 prefix = self.vapi.nat64_prefix_dump()
7081 self.assertEqual(len(prefix), 2)
7084 pkts = self.create_stream_in_ip6(self.pg0,
7087 plen=global_pref64_len)
7088 self.pg0.add_stream(pkts)
7089 self.pg_enable_capture(self.pg_interfaces)
7091 capture = self.pg1.get_capture(len(pkts))
7092 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7093 dst_ip=self.pg1.remote_ip4)
7095 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7096 self.pg1.add_stream(pkts)
7097 self.pg_enable_capture(self.pg_interfaces)
7099 capture = self.pg0.get_capture(len(pkts))
7100 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7103 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7105 # Tenant specific prefix
7106 pkts = self.create_stream_in_ip6(self.pg2,
7109 plen=vrf1_pref64_len)
7110 self.pg2.add_stream(pkts)
7111 self.pg_enable_capture(self.pg_interfaces)
7113 capture = self.pg1.get_capture(len(pkts))
7114 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7115 dst_ip=self.pg1.remote_ip4)
7117 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7118 self.pg1.add_stream(pkts)
7119 self.pg_enable_capture(self.pg_interfaces)
7121 capture = self.pg2.get_capture(len(pkts))
7122 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7125 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7127 def test_unknown_proto(self):
7128 """ NAT64 translate packet with unknown protocol """
7130 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7132 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7133 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7134 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7137 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7138 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7139 TCP(sport=self.tcp_port_in, dport=20))
7140 self.pg0.add_stream(p)
7141 self.pg_enable_capture(self.pg_interfaces)
7143 p = self.pg1.get_capture(1)
7145 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7146 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7148 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7149 TCP(sport=1234, dport=1234))
7150 self.pg0.add_stream(p)
7151 self.pg_enable_capture(self.pg_interfaces)
7153 p = self.pg1.get_capture(1)
7156 self.assertEqual(packet[IP].src, self.nat_addr)
7157 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7158 self.assertTrue(packet.haslayer(GRE))
7159 self.assert_packet_checksums_valid(packet)
7161 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7165 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7166 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7168 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7169 TCP(sport=1234, dport=1234))
7170 self.pg1.add_stream(p)
7171 self.pg_enable_capture(self.pg_interfaces)
7173 p = self.pg0.get_capture(1)
7176 self.assertEqual(packet[IPv6].src, remote_ip6)
7177 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7178 self.assertEqual(packet[IPv6].nh, 47)
7180 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7183 def test_hairpinning_unknown_proto(self):
7184 """ NAT64 translate packet with unknown protocol - hairpinning """
7186 client = self.pg0.remote_hosts[0]
7187 server = self.pg0.remote_hosts[1]
7188 server_tcp_in_port = 22
7189 server_tcp_out_port = 4022
7190 client_tcp_in_port = 1234
7191 client_tcp_out_port = 1235
7192 server_nat_ip = "10.0.0.100"
7193 client_nat_ip = "10.0.0.110"
7194 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7195 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7196 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7197 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7199 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7201 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7202 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7204 self.vapi.nat64_add_del_static_bib(server.ip6n,
7207 server_tcp_out_port,
7210 self.vapi.nat64_add_del_static_bib(server.ip6n,
7216 self.vapi.nat64_add_del_static_bib(client.ip6n,
7219 client_tcp_out_port,
7223 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7224 IPv6(src=client.ip6, dst=server_nat_ip6) /
7225 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7226 self.pg0.add_stream(p)
7227 self.pg_enable_capture(self.pg_interfaces)
7229 p = self.pg0.get_capture(1)
7231 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7232 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7234 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7235 TCP(sport=1234, dport=1234))
7236 self.pg0.add_stream(p)
7237 self.pg_enable_capture(self.pg_interfaces)
7239 p = self.pg0.get_capture(1)
7242 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7243 self.assertEqual(packet[IPv6].dst, server.ip6)
7244 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7246 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7250 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7251 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7253 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7254 TCP(sport=1234, dport=1234))
7255 self.pg0.add_stream(p)
7256 self.pg_enable_capture(self.pg_interfaces)
7258 p = self.pg0.get_capture(1)
7261 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7262 self.assertEqual(packet[IPv6].dst, client.ip6)
7263 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7265 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7268 def test_one_armed_nat64(self):
7269 """ One armed NAT64 """
7271 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7275 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7277 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7278 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7281 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7282 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7283 TCP(sport=12345, dport=80))
7284 self.pg3.add_stream(p)
7285 self.pg_enable_capture(self.pg_interfaces)
7287 capture = self.pg3.get_capture(1)
7292 self.assertEqual(ip.src, self.nat_addr)
7293 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7294 self.assertNotEqual(tcp.sport, 12345)
7295 external_port = tcp.sport
7296 self.assertEqual(tcp.dport, 80)
7297 self.assert_packet_checksums_valid(p)
7299 self.logger.error(ppp("Unexpected or invalid packet:", p))
7303 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7304 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7305 TCP(sport=80, dport=external_port))
7306 self.pg3.add_stream(p)
7307 self.pg_enable_capture(self.pg_interfaces)
7309 capture = self.pg3.get_capture(1)
7314 self.assertEqual(ip.src, remote_host_ip6)
7315 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7316 self.assertEqual(tcp.sport, 80)
7317 self.assertEqual(tcp.dport, 12345)
7318 self.assert_packet_checksums_valid(p)
7320 self.logger.error(ppp("Unexpected or invalid packet:", p))
7323 def test_frag_in_order(self):
7324 """ NAT64 translate fragments arriving in order """
7325 self.tcp_port_in = random.randint(1025, 65535)
7327 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7329 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7330 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7332 reass = self.vapi.nat_reass_dump()
7333 reass_n_start = len(reass)
7337 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7338 self.tcp_port_in, 20, data)
7339 self.pg0.add_stream(pkts)
7340 self.pg_enable_capture(self.pg_interfaces)
7342 frags = self.pg1.get_capture(len(pkts))
7343 p = self.reass_frags_and_verify(frags,
7345 self.pg1.remote_ip4)
7346 self.assertEqual(p[TCP].dport, 20)
7347 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7348 self.tcp_port_out = p[TCP].sport
7349 self.assertEqual(data, p[Raw].load)
7352 data = "A" * 4 + "b" * 16 + "C" * 3
7353 pkts = self.create_stream_frag(self.pg1,
7358 self.pg1.add_stream(pkts)
7359 self.pg_enable_capture(self.pg_interfaces)
7361 frags = self.pg0.get_capture(len(pkts))
7362 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7363 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7364 self.assertEqual(p[TCP].sport, 20)
7365 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7366 self.assertEqual(data, p[Raw].load)
7368 reass = self.vapi.nat_reass_dump()
7369 reass_n_end = len(reass)
7371 self.assertEqual(reass_n_end - reass_n_start, 2)
7373 def test_reass_hairpinning(self):
7374 """ NAT64 fragments hairpinning """
7376 server = self.pg0.remote_hosts[1]
7377 server_in_port = random.randint(1025, 65535)
7378 server_out_port = random.randint(1025, 65535)
7379 client_in_port = random.randint(1025, 65535)
7380 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7381 nat_addr_ip6 = ip.src
7383 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7385 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7386 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7388 # add static BIB entry for server
7389 self.vapi.nat64_add_del_static_bib(server.ip6n,
7395 # send packet from host to server
7396 pkts = self.create_stream_frag_ip6(self.pg0,
7401 self.pg0.add_stream(pkts)
7402 self.pg_enable_capture(self.pg_interfaces)
7404 frags = self.pg0.get_capture(len(pkts))
7405 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7406 self.assertNotEqual(p[TCP].sport, client_in_port)
7407 self.assertEqual(p[TCP].dport, server_in_port)
7408 self.assertEqual(data, p[Raw].load)
7410 def test_frag_out_of_order(self):
7411 """ NAT64 translate fragments arriving out of order """
7412 self.tcp_port_in = random.randint(1025, 65535)
7414 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7416 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7417 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7421 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7422 self.tcp_port_in, 20, data)
7424 self.pg0.add_stream(pkts)
7425 self.pg_enable_capture(self.pg_interfaces)
7427 frags = self.pg1.get_capture(len(pkts))
7428 p = self.reass_frags_and_verify(frags,
7430 self.pg1.remote_ip4)
7431 self.assertEqual(p[TCP].dport, 20)
7432 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7433 self.tcp_port_out = p[TCP].sport
7434 self.assertEqual(data, p[Raw].load)
7437 data = "A" * 4 + "B" * 16 + "C" * 3
7438 pkts = self.create_stream_frag(self.pg1,
7444 self.pg1.add_stream(pkts)
7445 self.pg_enable_capture(self.pg_interfaces)
7447 frags = self.pg0.get_capture(len(pkts))
7448 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7449 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7450 self.assertEqual(p[TCP].sport, 20)
7451 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7452 self.assertEqual(data, p[Raw].load)
7454 def test_interface_addr(self):
7455 """ Acquire NAT64 pool addresses from interface """
7456 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7458 # no address in NAT64 pool
7459 adresses = self.vapi.nat44_address_dump()
7460 self.assertEqual(0, len(adresses))
7462 # configure interface address and check NAT64 address pool
7463 self.pg4.config_ip4()
7464 addresses = self.vapi.nat64_pool_addr_dump()
7465 self.assertEqual(len(addresses), 1)
7466 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7468 # remove interface address and check NAT64 address pool
7469 self.pg4.unconfig_ip4()
7470 addresses = self.vapi.nat64_pool_addr_dump()
7471 self.assertEqual(0, len(adresses))
7473 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7474 def test_ipfix_max_bibs_sessions(self):
7475 """ IPFIX logging maximum session and BIB entries exceeded """
7478 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7482 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7484 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7485 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7489 for i in range(0, max_bibs):
7490 src = "fd01:aa::%x" % (i)
7491 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7492 IPv6(src=src, dst=remote_host_ip6) /
7493 TCP(sport=12345, dport=80))
7495 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7496 IPv6(src=src, dst=remote_host_ip6) /
7497 TCP(sport=12345, dport=22))
7499 self.pg0.add_stream(pkts)
7500 self.pg_enable_capture(self.pg_interfaces)
7502 self.pg1.get_capture(max_sessions)
7504 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7505 src_address=self.pg3.local_ip4n,
7507 template_interval=10)
7508 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7509 src_port=self.ipfix_src_port)
7511 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7512 IPv6(src=src, dst=remote_host_ip6) /
7513 TCP(sport=12345, dport=25))
7514 self.pg0.add_stream(p)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 self.pg1.assert_nothing_captured()
7519 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7520 capture = self.pg3.get_capture(9)
7521 ipfix = IPFIXDecoder()
7522 # first load template
7524 self.assertTrue(p.haslayer(IPFIX))
7525 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7526 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7527 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7528 self.assertEqual(p[UDP].dport, 4739)
7529 self.assertEqual(p[IPFIX].observationDomainID,
7530 self.ipfix_domain_id)
7531 if p.haslayer(Template):
7532 ipfix.add_template(p.getlayer(Template))
7533 # verify events in data set
7535 if p.haslayer(Data):
7536 data = ipfix.decode_data_set(p.getlayer(Set))
7537 self.verify_ipfix_max_sessions(data, max_sessions)
7539 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7540 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7541 TCP(sport=12345, dport=80))
7542 self.pg0.add_stream(p)
7543 self.pg_enable_capture(self.pg_interfaces)
7545 self.pg1.assert_nothing_captured()
7547 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7548 capture = self.pg3.get_capture(1)
7549 # verify events in data set
7551 self.assertTrue(p.haslayer(IPFIX))
7552 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7553 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7554 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7555 self.assertEqual(p[UDP].dport, 4739)
7556 self.assertEqual(p[IPFIX].observationDomainID,
7557 self.ipfix_domain_id)
7558 if p.haslayer(Data):
7559 data = ipfix.decode_data_set(p.getlayer(Set))
7560 self.verify_ipfix_max_bibs(data, max_bibs)
7562 def test_ipfix_max_frags(self):
7563 """ IPFIX logging maximum fragments pending reassembly exceeded """
7564 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7566 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7567 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7568 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7569 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7570 src_address=self.pg3.local_ip4n,
7572 template_interval=10)
7573 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7574 src_port=self.ipfix_src_port)
7577 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7578 self.tcp_port_in, 20, data)
7580 self.pg0.add_stream(pkts)
7581 self.pg_enable_capture(self.pg_interfaces)
7583 self.pg1.assert_nothing_captured()
7585 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7586 capture = self.pg3.get_capture(9)
7587 ipfix = IPFIXDecoder()
7588 # first load template
7590 self.assertTrue(p.haslayer(IPFIX))
7591 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7592 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7593 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7594 self.assertEqual(p[UDP].dport, 4739)
7595 self.assertEqual(p[IPFIX].observationDomainID,
7596 self.ipfix_domain_id)
7597 if p.haslayer(Template):
7598 ipfix.add_template(p.getlayer(Template))
7599 # verify events in data set
7601 if p.haslayer(Data):
7602 data = ipfix.decode_data_set(p.getlayer(Set))
7603 self.verify_ipfix_max_fragments_ip6(data, 1,
7604 self.pg0.remote_ip6n)
7606 def test_ipfix_bib_ses(self):
7607 """ IPFIX logging NAT64 BIB/session create and delete events """
7608 self.tcp_port_in = random.randint(1025, 65535)
7609 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7613 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7615 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7616 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7617 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7618 src_address=self.pg3.local_ip4n,
7620 template_interval=10)
7621 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7622 src_port=self.ipfix_src_port)
7625 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7626 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7627 TCP(sport=self.tcp_port_in, dport=25))
7628 self.pg0.add_stream(p)
7629 self.pg_enable_capture(self.pg_interfaces)
7631 p = self.pg1.get_capture(1)
7632 self.tcp_port_out = p[0][TCP].sport
7633 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7634 capture = self.pg3.get_capture(10)
7635 ipfix = IPFIXDecoder()
7636 # first load template
7638 self.assertTrue(p.haslayer(IPFIX))
7639 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7640 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7641 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7642 self.assertEqual(p[UDP].dport, 4739)
7643 self.assertEqual(p[IPFIX].observationDomainID,
7644 self.ipfix_domain_id)
7645 if p.haslayer(Template):
7646 ipfix.add_template(p.getlayer(Template))
7647 # verify events in data set
7649 if p.haslayer(Data):
7650 data = ipfix.decode_data_set(p.getlayer(Set))
7651 if ord(data[0][230]) == 10:
7652 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7653 elif ord(data[0][230]) == 6:
7654 self.verify_ipfix_nat64_ses(data,
7656 self.pg0.remote_ip6n,
7657 self.pg1.remote_ip4,
7660 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7663 self.pg_enable_capture(self.pg_interfaces)
7664 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7667 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7668 capture = self.pg3.get_capture(2)
7669 # verify events in data set
7671 self.assertTrue(p.haslayer(IPFIX))
7672 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7673 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7674 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7675 self.assertEqual(p[UDP].dport, 4739)
7676 self.assertEqual(p[IPFIX].observationDomainID,
7677 self.ipfix_domain_id)
7678 if p.haslayer(Data):
7679 data = ipfix.decode_data_set(p.getlayer(Set))
7680 if ord(data[0][230]) == 11:
7681 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7682 elif ord(data[0][230]) == 7:
7683 self.verify_ipfix_nat64_ses(data,
7685 self.pg0.remote_ip6n,
7686 self.pg1.remote_ip4,
7689 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7691 def nat64_get_ses_num(self):
7693 Return number of active NAT64 sessions.
7695 st = self.vapi.nat64_st_dump()
7698 def clear_nat64(self):
7700 Clear NAT64 configuration.
7702 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7703 domain_id=self.ipfix_domain_id)
7704 self.ipfix_src_port = 4739
7705 self.ipfix_domain_id = 1
7707 self.vapi.nat_set_timeouts()
7709 interfaces = self.vapi.nat64_interface_dump()
7710 for intf in interfaces:
7711 if intf.is_inside > 1:
7712 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7715 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7719 bib = self.vapi.nat64_bib_dump(255)
7722 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7730 adresses = self.vapi.nat64_pool_addr_dump()
7731 for addr in adresses:
7732 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7737 prefixes = self.vapi.nat64_prefix_dump()
7738 for prefix in prefixes:
7739 self.vapi.nat64_add_del_prefix(prefix.prefix,
7741 vrf_id=prefix.vrf_id,
7745 super(TestNAT64, self).tearDown()
7746 if not self.vpp_dead:
7747 self.logger.info(self.vapi.cli("show nat64 pool"))
7748 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7749 self.logger.info(self.vapi.cli("show nat64 prefix"))
7750 self.logger.info(self.vapi.cli("show nat64 bib all"))
7751 self.logger.info(self.vapi.cli("show nat64 session table all"))
7752 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7756 class TestDSlite(MethodHolder):
7757 """ DS-Lite Test Cases """
7760 def setUpClass(cls):
7761 super(TestDSlite, cls).setUpClass()
7764 cls.nat_addr = '10.0.0.3'
7765 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7767 cls.create_pg_interfaces(range(2))
7769 cls.pg0.config_ip4()
7770 cls.pg0.resolve_arp()
7772 cls.pg1.config_ip6()
7773 cls.pg1.generate_remote_hosts(2)
7774 cls.pg1.configure_ipv6_neighbors()
7777 super(TestDSlite, cls).tearDownClass()
7780 def test_dslite(self):
7781 """ Test DS-Lite """
7782 nat_config = self.vapi.nat_show_config()
7783 self.assertEqual(0, nat_config.dslite_ce)
7785 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7787 aftr_ip4 = '192.0.0.1'
7788 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7789 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7790 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7791 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7794 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7795 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7796 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7797 UDP(sport=20000, dport=10000))
7798 self.pg1.add_stream(p)
7799 self.pg_enable_capture(self.pg_interfaces)
7801 capture = self.pg0.get_capture(1)
7802 capture = capture[0]
7803 self.assertFalse(capture.haslayer(IPv6))
7804 self.assertEqual(capture[IP].src, self.nat_addr)
7805 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7806 self.assertNotEqual(capture[UDP].sport, 20000)
7807 self.assertEqual(capture[UDP].dport, 10000)
7808 self.assert_packet_checksums_valid(capture)
7809 out_port = capture[UDP].sport
7811 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7812 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7813 UDP(sport=10000, dport=out_port))
7814 self.pg0.add_stream(p)
7815 self.pg_enable_capture(self.pg_interfaces)
7817 capture = self.pg1.get_capture(1)
7818 capture = capture[0]
7819 self.assertEqual(capture[IPv6].src, aftr_ip6)
7820 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7821 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7822 self.assertEqual(capture[IP].dst, '192.168.1.1')
7823 self.assertEqual(capture[UDP].sport, 10000)
7824 self.assertEqual(capture[UDP].dport, 20000)
7825 self.assert_packet_checksums_valid(capture)
7828 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7829 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7830 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7831 TCP(sport=20001, dport=10001))
7832 self.pg1.add_stream(p)
7833 self.pg_enable_capture(self.pg_interfaces)
7835 capture = self.pg0.get_capture(1)
7836 capture = capture[0]
7837 self.assertFalse(capture.haslayer(IPv6))
7838 self.assertEqual(capture[IP].src, self.nat_addr)
7839 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7840 self.assertNotEqual(capture[TCP].sport, 20001)
7841 self.assertEqual(capture[TCP].dport, 10001)
7842 self.assert_packet_checksums_valid(capture)
7843 out_port = capture[TCP].sport
7845 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7846 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7847 TCP(sport=10001, dport=out_port))
7848 self.pg0.add_stream(p)
7849 self.pg_enable_capture(self.pg_interfaces)
7851 capture = self.pg1.get_capture(1)
7852 capture = capture[0]
7853 self.assertEqual(capture[IPv6].src, aftr_ip6)
7854 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7855 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7856 self.assertEqual(capture[IP].dst, '192.168.1.1')
7857 self.assertEqual(capture[TCP].sport, 10001)
7858 self.assertEqual(capture[TCP].dport, 20001)
7859 self.assert_packet_checksums_valid(capture)
7862 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7863 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7864 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7865 ICMP(id=4000, type='echo-request'))
7866 self.pg1.add_stream(p)
7867 self.pg_enable_capture(self.pg_interfaces)
7869 capture = self.pg0.get_capture(1)
7870 capture = capture[0]
7871 self.assertFalse(capture.haslayer(IPv6))
7872 self.assertEqual(capture[IP].src, self.nat_addr)
7873 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7874 self.assertNotEqual(capture[ICMP].id, 4000)
7875 self.assert_packet_checksums_valid(capture)
7876 out_id = capture[ICMP].id
7878 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7879 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7880 ICMP(id=out_id, type='echo-reply'))
7881 self.pg0.add_stream(p)
7882 self.pg_enable_capture(self.pg_interfaces)
7884 capture = self.pg1.get_capture(1)
7885 capture = capture[0]
7886 self.assertEqual(capture[IPv6].src, aftr_ip6)
7887 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7888 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7889 self.assertEqual(capture[IP].dst, '192.168.1.1')
7890 self.assertEqual(capture[ICMP].id, 4000)
7891 self.assert_packet_checksums_valid(capture)
7893 # ping DS-Lite AFTR tunnel endpoint address
7894 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7895 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7896 ICMPv6EchoRequest())
7897 self.pg1.add_stream(p)
7898 self.pg_enable_capture(self.pg_interfaces)
7900 capture = self.pg1.get_capture(1)
7901 capture = capture[0]
7902 self.assertEqual(capture[IPv6].src, aftr_ip6)
7903 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7904 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7907 super(TestDSlite, self).tearDown()
7908 if not self.vpp_dead:
7909 self.logger.info(self.vapi.cli("show dslite pool"))
7911 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7912 self.logger.info(self.vapi.cli("show dslite sessions"))
7915 class TestDSliteCE(MethodHolder):
7916 """ DS-Lite CE Test Cases """
7919 def setUpConstants(cls):
7920 super(TestDSliteCE, cls).setUpConstants()
7921 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7924 def setUpClass(cls):
7925 super(TestDSliteCE, cls).setUpClass()
7928 cls.create_pg_interfaces(range(2))
7930 cls.pg0.config_ip4()
7931 cls.pg0.resolve_arp()
7933 cls.pg1.config_ip6()
7934 cls.pg1.generate_remote_hosts(1)
7935 cls.pg1.configure_ipv6_neighbors()
7938 super(TestDSliteCE, cls).tearDownClass()
7941 def test_dslite_ce(self):
7942 """ Test DS-Lite CE """
7944 nat_config = self.vapi.nat_show_config()
7945 self.assertEqual(1, nat_config.dslite_ce)
7947 b4_ip4 = '192.0.0.2'
7948 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7949 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7950 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7951 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7953 aftr_ip4 = '192.0.0.1'
7954 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7955 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7956 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7957 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7959 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7960 dst_address_length=128,
7961 next_hop_address=self.pg1.remote_ip6n,
7962 next_hop_sw_if_index=self.pg1.sw_if_index,
7966 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7967 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7968 UDP(sport=10000, dport=20000))
7969 self.pg0.add_stream(p)
7970 self.pg_enable_capture(self.pg_interfaces)
7972 capture = self.pg1.get_capture(1)
7973 capture = capture[0]
7974 self.assertEqual(capture[IPv6].src, b4_ip6)
7975 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7976 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7977 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7978 self.assertEqual(capture[UDP].sport, 10000)
7979 self.assertEqual(capture[UDP].dport, 20000)
7980 self.assert_packet_checksums_valid(capture)
7983 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7984 IPv6(dst=b4_ip6, src=aftr_ip6) /
7985 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7986 UDP(sport=20000, dport=10000))
7987 self.pg1.add_stream(p)
7988 self.pg_enable_capture(self.pg_interfaces)
7990 capture = self.pg0.get_capture(1)
7991 capture = capture[0]
7992 self.assertFalse(capture.haslayer(IPv6))
7993 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7994 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7995 self.assertEqual(capture[UDP].sport, 20000)
7996 self.assertEqual(capture[UDP].dport, 10000)
7997 self.assert_packet_checksums_valid(capture)
7999 # ping DS-Lite B4 tunnel endpoint address
8000 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8001 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8002 ICMPv6EchoRequest())
8003 self.pg1.add_stream(p)
8004 self.pg_enable_capture(self.pg_interfaces)
8006 capture = self.pg1.get_capture(1)
8007 capture = capture[0]
8008 self.assertEqual(capture[IPv6].src, b4_ip6)
8009 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8010 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8013 super(TestDSliteCE, self).tearDown()
8014 if not self.vpp_dead:
8016 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8018 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8021 class TestNAT66(MethodHolder):
8022 """ NAT66 Test Cases """
8025 def setUpClass(cls):
8026 super(TestNAT66, cls).setUpClass()
8029 cls.nat_addr = 'fd01:ff::2'
8030 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8032 cls.create_pg_interfaces(range(2))
8033 cls.interfaces = list(cls.pg_interfaces)
8035 for i in cls.interfaces:
8038 i.configure_ipv6_neighbors()
8041 super(TestNAT66, cls).tearDownClass()
8044 def test_static(self):
8045 """ 1:1 NAT66 test """
8046 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8047 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8048 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8053 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8054 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8057 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8058 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8061 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8062 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8063 ICMPv6EchoRequest())
8065 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8066 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8067 GRE() / IP() / TCP())
8069 self.pg0.add_stream(pkts)
8070 self.pg_enable_capture(self.pg_interfaces)
8072 capture = self.pg1.get_capture(len(pkts))
8073 for packet in capture:
8075 self.assertEqual(packet[IPv6].src, self.nat_addr)
8076 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8077 self.assert_packet_checksums_valid(packet)
8079 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8084 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8085 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8088 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8089 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8092 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8093 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8096 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8097 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8098 GRE() / IP() / TCP())
8100 self.pg1.add_stream(pkts)
8101 self.pg_enable_capture(self.pg_interfaces)
8103 capture = self.pg0.get_capture(len(pkts))
8104 for packet in capture:
8106 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8107 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8108 self.assert_packet_checksums_valid(packet)
8110 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8113 sm = self.vapi.nat66_static_mapping_dump()
8114 self.assertEqual(len(sm), 1)
8115 self.assertEqual(sm[0].total_pkts, 8)
8117 def test_check_no_translate(self):
8118 """ NAT66 translate only when egress interface is outside interface """
8119 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8120 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8121 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8125 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8126 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8128 self.pg0.add_stream([p])
8129 self.pg_enable_capture(self.pg_interfaces)
8131 capture = self.pg1.get_capture(1)
8134 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8135 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8137 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8140 def clear_nat66(self):
8142 Clear NAT66 configuration.
8144 interfaces = self.vapi.nat66_interface_dump()
8145 for intf in interfaces:
8146 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8150 static_mappings = self.vapi.nat66_static_mapping_dump()
8151 for sm in static_mappings:
8152 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8153 sm.external_ip_address,
8158 super(TestNAT66, self).tearDown()
8159 if not self.vpp_dead:
8160 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8161 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8165 if __name__ == '__main__':
8166 unittest.main(testRunner=VppTestRunner)