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)
1941 def test_multiple_inside_interfaces(self):
1942 """ NAT44 multiple non-overlapping address space inside interfaces """
1944 self.nat44_add_address(self.nat_addr)
1945 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1946 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1947 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1950 # between two NAT44 inside interfaces (no translation)
1951 pkts = self.create_stream_in(self.pg0, self.pg1)
1952 self.pg0.add_stream(pkts)
1953 self.pg_enable_capture(self.pg_interfaces)
1955 capture = self.pg1.get_capture(len(pkts))
1956 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1958 # from NAT44 inside to interface without NAT44 feature (no translation)
1959 pkts = self.create_stream_in(self.pg0, self.pg2)
1960 self.pg0.add_stream(pkts)
1961 self.pg_enable_capture(self.pg_interfaces)
1963 capture = self.pg2.get_capture(len(pkts))
1964 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1966 # in2out 1st interface
1967 pkts = self.create_stream_in(self.pg0, self.pg3)
1968 self.pg0.add_stream(pkts)
1969 self.pg_enable_capture(self.pg_interfaces)
1971 capture = self.pg3.get_capture(len(pkts))
1972 self.verify_capture_out(capture)
1974 # out2in 1st interface
1975 pkts = self.create_stream_out(self.pg3)
1976 self.pg3.add_stream(pkts)
1977 self.pg_enable_capture(self.pg_interfaces)
1979 capture = self.pg0.get_capture(len(pkts))
1980 self.verify_capture_in(capture, self.pg0)
1982 # in2out 2nd interface
1983 pkts = self.create_stream_in(self.pg1, self.pg3)
1984 self.pg1.add_stream(pkts)
1985 self.pg_enable_capture(self.pg_interfaces)
1987 capture = self.pg3.get_capture(len(pkts))
1988 self.verify_capture_out(capture)
1990 # out2in 2nd interface
1991 pkts = self.create_stream_out(self.pg3)
1992 self.pg3.add_stream(pkts)
1993 self.pg_enable_capture(self.pg_interfaces)
1995 capture = self.pg1.get_capture(len(pkts))
1996 self.verify_capture_in(capture, self.pg1)
1998 def test_inside_overlapping_interfaces(self):
1999 """ NAT44 multiple inside interfaces with overlapping address space """
2001 static_nat_ip = "10.0.0.10"
2002 self.nat44_add_address(self.nat_addr)
2003 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2005 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2006 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2007 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2008 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2011 # between NAT44 inside interfaces with same VRF (no translation)
2012 pkts = self.create_stream_in(self.pg4, self.pg5)
2013 self.pg4.add_stream(pkts)
2014 self.pg_enable_capture(self.pg_interfaces)
2016 capture = self.pg5.get_capture(len(pkts))
2017 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2019 # between NAT44 inside interfaces with different VRF (hairpinning)
2020 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2021 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2022 TCP(sport=1234, dport=5678))
2023 self.pg4.add_stream(p)
2024 self.pg_enable_capture(self.pg_interfaces)
2026 capture = self.pg6.get_capture(1)
2031 self.assertEqual(ip.src, self.nat_addr)
2032 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2033 self.assertNotEqual(tcp.sport, 1234)
2034 self.assertEqual(tcp.dport, 5678)
2036 self.logger.error(ppp("Unexpected or invalid packet:", p))
2039 # in2out 1st interface
2040 pkts = self.create_stream_in(self.pg4, self.pg3)
2041 self.pg4.add_stream(pkts)
2042 self.pg_enable_capture(self.pg_interfaces)
2044 capture = self.pg3.get_capture(len(pkts))
2045 self.verify_capture_out(capture)
2047 # out2in 1st interface
2048 pkts = self.create_stream_out(self.pg3)
2049 self.pg3.add_stream(pkts)
2050 self.pg_enable_capture(self.pg_interfaces)
2052 capture = self.pg4.get_capture(len(pkts))
2053 self.verify_capture_in(capture, self.pg4)
2055 # in2out 2nd interface
2056 pkts = self.create_stream_in(self.pg5, self.pg3)
2057 self.pg5.add_stream(pkts)
2058 self.pg_enable_capture(self.pg_interfaces)
2060 capture = self.pg3.get_capture(len(pkts))
2061 self.verify_capture_out(capture)
2063 # out2in 2nd interface
2064 pkts = self.create_stream_out(self.pg3)
2065 self.pg3.add_stream(pkts)
2066 self.pg_enable_capture(self.pg_interfaces)
2068 capture = self.pg5.get_capture(len(pkts))
2069 self.verify_capture_in(capture, self.pg5)
2072 addresses = self.vapi.nat44_address_dump()
2073 self.assertEqual(len(addresses), 1)
2074 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2075 self.assertEqual(len(sessions), 3)
2076 for session in sessions:
2077 self.assertFalse(session.is_static)
2078 self.assertEqual(session.inside_ip_address[0:4],
2079 self.pg5.remote_ip4n)
2080 self.assertEqual(session.outside_ip_address,
2081 addresses[0].ip_address)
2082 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2083 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2084 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2085 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2086 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2087 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2088 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2089 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2090 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2092 # in2out 3rd interface
2093 pkts = self.create_stream_in(self.pg6, self.pg3)
2094 self.pg6.add_stream(pkts)
2095 self.pg_enable_capture(self.pg_interfaces)
2097 capture = self.pg3.get_capture(len(pkts))
2098 self.verify_capture_out(capture, static_nat_ip, True)
2100 # out2in 3rd interface
2101 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2102 self.pg3.add_stream(pkts)
2103 self.pg_enable_capture(self.pg_interfaces)
2105 capture = self.pg6.get_capture(len(pkts))
2106 self.verify_capture_in(capture, self.pg6)
2108 # general user and session dump verifications
2109 users = self.vapi.nat44_user_dump()
2110 self.assertTrue(len(users) >= 3)
2111 addresses = self.vapi.nat44_address_dump()
2112 self.assertEqual(len(addresses), 1)
2114 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2116 for session in sessions:
2117 self.assertEqual(user.ip_address, session.inside_ip_address)
2118 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2119 self.assertTrue(session.protocol in
2120 [IP_PROTOS.tcp, IP_PROTOS.udp,
2122 self.assertFalse(session.ext_host_valid)
2125 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2126 self.assertTrue(len(sessions) >= 4)
2127 for session in sessions:
2128 self.assertFalse(session.is_static)
2129 self.assertEqual(session.inside_ip_address[0:4],
2130 self.pg4.remote_ip4n)
2131 self.assertEqual(session.outside_ip_address,
2132 addresses[0].ip_address)
2135 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2136 self.assertTrue(len(sessions) >= 3)
2137 for session in sessions:
2138 self.assertTrue(session.is_static)
2139 self.assertEqual(session.inside_ip_address[0:4],
2140 self.pg6.remote_ip4n)
2141 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2142 map(int, static_nat_ip.split('.')))
2143 self.assertTrue(session.inside_port in
2144 [self.tcp_port_in, self.udp_port_in,
2147 def test_hairpinning(self):
2148 """ NAT44 hairpinning - 1:1 NAPT """
2150 host = self.pg0.remote_hosts[0]
2151 server = self.pg0.remote_hosts[1]
2154 server_in_port = 5678
2155 server_out_port = 8765
2157 self.nat44_add_address(self.nat_addr)
2158 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2159 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2161 # add static mapping for server
2162 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2163 server_in_port, server_out_port,
2164 proto=IP_PROTOS.tcp)
2166 # send packet from host to server
2167 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2168 IP(src=host.ip4, dst=self.nat_addr) /
2169 TCP(sport=host_in_port, dport=server_out_port))
2170 self.pg0.add_stream(p)
2171 self.pg_enable_capture(self.pg_interfaces)
2173 capture = self.pg0.get_capture(1)
2178 self.assertEqual(ip.src, self.nat_addr)
2179 self.assertEqual(ip.dst, server.ip4)
2180 self.assertNotEqual(tcp.sport, host_in_port)
2181 self.assertEqual(tcp.dport, server_in_port)
2182 self.assert_packet_checksums_valid(p)
2183 host_out_port = tcp.sport
2185 self.logger.error(ppp("Unexpected or invalid packet:", p))
2188 # send reply from server to host
2189 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2190 IP(src=server.ip4, dst=self.nat_addr) /
2191 TCP(sport=server_in_port, dport=host_out_port))
2192 self.pg0.add_stream(p)
2193 self.pg_enable_capture(self.pg_interfaces)
2195 capture = self.pg0.get_capture(1)
2200 self.assertEqual(ip.src, self.nat_addr)
2201 self.assertEqual(ip.dst, host.ip4)
2202 self.assertEqual(tcp.sport, server_out_port)
2203 self.assertEqual(tcp.dport, host_in_port)
2204 self.assert_packet_checksums_valid(p)
2206 self.logger.error(ppp("Unexpected or invalid packet:", p))
2209 def test_hairpinning2(self):
2210 """ NAT44 hairpinning - 1:1 NAT"""
2212 server1_nat_ip = "10.0.0.10"
2213 server2_nat_ip = "10.0.0.11"
2214 host = self.pg0.remote_hosts[0]
2215 server1 = self.pg0.remote_hosts[1]
2216 server2 = self.pg0.remote_hosts[2]
2217 server_tcp_port = 22
2218 server_udp_port = 20
2220 self.nat44_add_address(self.nat_addr)
2221 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2222 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2225 # add static mapping for servers
2226 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2227 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2231 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2232 IP(src=host.ip4, dst=server1_nat_ip) /
2233 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2235 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2236 IP(src=host.ip4, dst=server1_nat_ip) /
2237 UDP(sport=self.udp_port_in, dport=server_udp_port))
2239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2240 IP(src=host.ip4, dst=server1_nat_ip) /
2241 ICMP(id=self.icmp_id_in, type='echo-request'))
2243 self.pg0.add_stream(pkts)
2244 self.pg_enable_capture(self.pg_interfaces)
2246 capture = self.pg0.get_capture(len(pkts))
2247 for packet in capture:
2249 self.assertEqual(packet[IP].src, self.nat_addr)
2250 self.assertEqual(packet[IP].dst, server1.ip4)
2251 if packet.haslayer(TCP):
2252 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2253 self.assertEqual(packet[TCP].dport, server_tcp_port)
2254 self.tcp_port_out = packet[TCP].sport
2255 self.assert_packet_checksums_valid(packet)
2256 elif packet.haslayer(UDP):
2257 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2258 self.assertEqual(packet[UDP].dport, server_udp_port)
2259 self.udp_port_out = packet[UDP].sport
2261 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2262 self.icmp_id_out = packet[ICMP].id
2264 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2269 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2270 IP(src=server1.ip4, dst=self.nat_addr) /
2271 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2274 IP(src=server1.ip4, dst=self.nat_addr) /
2275 UDP(sport=server_udp_port, dport=self.udp_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 ICMP(id=self.icmp_id_out, type='echo-reply'))
2281 self.pg0.add_stream(pkts)
2282 self.pg_enable_capture(self.pg_interfaces)
2284 capture = self.pg0.get_capture(len(pkts))
2285 for packet in capture:
2287 self.assertEqual(packet[IP].src, server1_nat_ip)
2288 self.assertEqual(packet[IP].dst, host.ip4)
2289 if packet.haslayer(TCP):
2290 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2291 self.assertEqual(packet[TCP].sport, server_tcp_port)
2292 self.assert_packet_checksums_valid(packet)
2293 elif packet.haslayer(UDP):
2294 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2295 self.assertEqual(packet[UDP].sport, server_udp_port)
2297 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2299 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2302 # server2 to server1
2304 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2305 IP(src=server2.ip4, dst=server1_nat_ip) /
2306 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2309 IP(src=server2.ip4, dst=server1_nat_ip) /
2310 UDP(sport=self.udp_port_in, dport=server_udp_port))
2312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2313 IP(src=server2.ip4, dst=server1_nat_ip) /
2314 ICMP(id=self.icmp_id_in, type='echo-request'))
2316 self.pg0.add_stream(pkts)
2317 self.pg_enable_capture(self.pg_interfaces)
2319 capture = self.pg0.get_capture(len(pkts))
2320 for packet in capture:
2322 self.assertEqual(packet[IP].src, server2_nat_ip)
2323 self.assertEqual(packet[IP].dst, server1.ip4)
2324 if packet.haslayer(TCP):
2325 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2326 self.assertEqual(packet[TCP].dport, server_tcp_port)
2327 self.tcp_port_out = packet[TCP].sport
2328 self.assert_packet_checksums_valid(packet)
2329 elif packet.haslayer(UDP):
2330 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2331 self.assertEqual(packet[UDP].dport, server_udp_port)
2332 self.udp_port_out = packet[UDP].sport
2334 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2335 self.icmp_id_out = packet[ICMP].id
2337 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2340 # server1 to server2
2342 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2343 IP(src=server1.ip4, dst=server2_nat_ip) /
2344 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2346 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2347 IP(src=server1.ip4, dst=server2_nat_ip) /
2348 UDP(sport=server_udp_port, dport=self.udp_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 ICMP(id=self.icmp_id_out, type='echo-reply'))
2354 self.pg0.add_stream(pkts)
2355 self.pg_enable_capture(self.pg_interfaces)
2357 capture = self.pg0.get_capture(len(pkts))
2358 for packet in capture:
2360 self.assertEqual(packet[IP].src, server1_nat_ip)
2361 self.assertEqual(packet[IP].dst, server2.ip4)
2362 if packet.haslayer(TCP):
2363 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2364 self.assertEqual(packet[TCP].sport, server_tcp_port)
2365 self.assert_packet_checksums_valid(packet)
2366 elif packet.haslayer(UDP):
2367 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2368 self.assertEqual(packet[UDP].sport, server_udp_port)
2370 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2372 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2375 def test_max_translations_per_user(self):
2376 """ MAX translations per user - recycle the least recently used """
2378 self.nat44_add_address(self.nat_addr)
2379 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2380 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2383 # get maximum number of translations per user
2384 nat44_config = self.vapi.nat_show_config()
2386 # send more than maximum number of translations per user packets
2387 pkts_num = nat44_config.max_translations_per_user + 5
2389 for port in range(0, pkts_num):
2390 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2391 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2392 TCP(sport=1025 + port))
2394 self.pg0.add_stream(pkts)
2395 self.pg_enable_capture(self.pg_interfaces)
2398 # verify number of translated packet
2399 self.pg1.get_capture(pkts_num)
2401 users = self.vapi.nat44_user_dump()
2403 if user.ip_address == self.pg0.remote_ip4n:
2404 self.assertEqual(user.nsessions,
2405 nat44_config.max_translations_per_user)
2406 self.assertEqual(user.nstaticsessions, 0)
2409 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2411 proto=IP_PROTOS.tcp)
2412 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2413 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2414 TCP(sport=tcp_port))
2415 self.pg0.add_stream(p)
2416 self.pg_enable_capture(self.pg_interfaces)
2418 self.pg1.get_capture(1)
2419 users = self.vapi.nat44_user_dump()
2421 if user.ip_address == self.pg0.remote_ip4n:
2422 self.assertEqual(user.nsessions,
2423 nat44_config.max_translations_per_user - 1)
2424 self.assertEqual(user.nstaticsessions, 1)
2426 def test_interface_addr(self):
2427 """ Acquire NAT44 addresses from interface """
2428 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2430 # no address in NAT pool
2431 adresses = self.vapi.nat44_address_dump()
2432 self.assertEqual(0, len(adresses))
2434 # configure interface address and check NAT address pool
2435 self.pg7.config_ip4()
2436 adresses = self.vapi.nat44_address_dump()
2437 self.assertEqual(1, len(adresses))
2438 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2440 # remove interface address and check NAT address pool
2441 self.pg7.unconfig_ip4()
2442 adresses = self.vapi.nat44_address_dump()
2443 self.assertEqual(0, len(adresses))
2445 def test_interface_addr_static_mapping(self):
2446 """ Static mapping with addresses from interface """
2449 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2450 self.nat44_add_static_mapping(
2452 external_sw_if_index=self.pg7.sw_if_index,
2455 # static mappings with external interface
2456 static_mappings = self.vapi.nat44_static_mapping_dump()
2457 self.assertEqual(1, len(static_mappings))
2458 self.assertEqual(self.pg7.sw_if_index,
2459 static_mappings[0].external_sw_if_index)
2460 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2462 # configure interface address and check static mappings
2463 self.pg7.config_ip4()
2464 static_mappings = self.vapi.nat44_static_mapping_dump()
2465 self.assertEqual(2, len(static_mappings))
2467 for sm in static_mappings:
2468 if sm.external_sw_if_index == 0xFFFFFFFF:
2469 self.assertEqual(sm.external_ip_address[0:4],
2470 self.pg7.local_ip4n)
2471 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2473 self.assertTrue(resolved)
2475 # remove interface address and check static mappings
2476 self.pg7.unconfig_ip4()
2477 static_mappings = self.vapi.nat44_static_mapping_dump()
2478 self.assertEqual(1, len(static_mappings))
2479 self.assertEqual(self.pg7.sw_if_index,
2480 static_mappings[0].external_sw_if_index)
2481 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2483 # configure interface address again and check static mappings
2484 self.pg7.config_ip4()
2485 static_mappings = self.vapi.nat44_static_mapping_dump()
2486 self.assertEqual(2, len(static_mappings))
2488 for sm in static_mappings:
2489 if sm.external_sw_if_index == 0xFFFFFFFF:
2490 self.assertEqual(sm.external_ip_address[0:4],
2491 self.pg7.local_ip4n)
2492 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2494 self.assertTrue(resolved)
2496 # remove static mapping
2497 self.nat44_add_static_mapping(
2499 external_sw_if_index=self.pg7.sw_if_index,
2502 static_mappings = self.vapi.nat44_static_mapping_dump()
2503 self.assertEqual(0, len(static_mappings))
2505 def test_interface_addr_identity_nat(self):
2506 """ Identity NAT with addresses from interface """
2509 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2510 self.vapi.nat44_add_del_identity_mapping(
2511 sw_if_index=self.pg7.sw_if_index,
2513 protocol=IP_PROTOS.tcp,
2516 # identity mappings with external interface
2517 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2518 self.assertEqual(1, len(identity_mappings))
2519 self.assertEqual(self.pg7.sw_if_index,
2520 identity_mappings[0].sw_if_index)
2522 # configure interface address and check identity mappings
2523 self.pg7.config_ip4()
2524 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2526 self.assertEqual(2, len(identity_mappings))
2527 for sm in identity_mappings:
2528 if sm.sw_if_index == 0xFFFFFFFF:
2529 self.assertEqual(identity_mappings[0].ip_address,
2530 self.pg7.local_ip4n)
2531 self.assertEqual(port, identity_mappings[0].port)
2532 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2534 self.assertTrue(resolved)
2536 # remove interface address and check identity mappings
2537 self.pg7.unconfig_ip4()
2538 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2539 self.assertEqual(1, len(identity_mappings))
2540 self.assertEqual(self.pg7.sw_if_index,
2541 identity_mappings[0].sw_if_index)
2543 def test_ipfix_nat44_sess(self):
2544 """ IPFIX logging NAT44 session created/delted """
2545 self.ipfix_domain_id = 10
2546 self.ipfix_src_port = 20202
2547 colector_port = 30303
2548 bind_layers(UDP, IPFIX, dport=30303)
2549 self.nat44_add_address(self.nat_addr)
2550 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2551 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2553 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2554 src_address=self.pg3.local_ip4n,
2556 template_interval=10,
2557 collector_port=colector_port)
2558 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2559 src_port=self.ipfix_src_port)
2561 pkts = self.create_stream_in(self.pg0, self.pg1)
2562 self.pg0.add_stream(pkts)
2563 self.pg_enable_capture(self.pg_interfaces)
2565 capture = self.pg1.get_capture(len(pkts))
2566 self.verify_capture_out(capture)
2567 self.nat44_add_address(self.nat_addr, is_add=0)
2568 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2569 capture = self.pg3.get_capture(9)
2570 ipfix = IPFIXDecoder()
2571 # first load template
2573 self.assertTrue(p.haslayer(IPFIX))
2574 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2575 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2576 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2577 self.assertEqual(p[UDP].dport, colector_port)
2578 self.assertEqual(p[IPFIX].observationDomainID,
2579 self.ipfix_domain_id)
2580 if p.haslayer(Template):
2581 ipfix.add_template(p.getlayer(Template))
2582 # verify events in data set
2584 if p.haslayer(Data):
2585 data = ipfix.decode_data_set(p.getlayer(Set))
2586 self.verify_ipfix_nat44_ses(data)
2588 def test_ipfix_addr_exhausted(self):
2589 """ IPFIX logging NAT addresses exhausted """
2590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2593 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2594 src_address=self.pg3.local_ip4n,
2596 template_interval=10)
2597 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2598 src_port=self.ipfix_src_port)
2600 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2601 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2603 self.pg0.add_stream(p)
2604 self.pg_enable_capture(self.pg_interfaces)
2606 self.pg1.assert_nothing_captured()
2608 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2609 capture = self.pg3.get_capture(9)
2610 ipfix = IPFIXDecoder()
2611 # first load template
2613 self.assertTrue(p.haslayer(IPFIX))
2614 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2615 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2616 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2617 self.assertEqual(p[UDP].dport, 4739)
2618 self.assertEqual(p[IPFIX].observationDomainID,
2619 self.ipfix_domain_id)
2620 if p.haslayer(Template):
2621 ipfix.add_template(p.getlayer(Template))
2622 # verify events in data set
2624 if p.haslayer(Data):
2625 data = ipfix.decode_data_set(p.getlayer(Set))
2626 self.verify_ipfix_addr_exhausted(data)
2628 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2629 def test_ipfix_max_sessions(self):
2630 """ IPFIX logging maximum session entries exceeded """
2631 self.nat44_add_address(self.nat_addr)
2632 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2633 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2636 nat44_config = self.vapi.nat_show_config()
2637 max_sessions = 10 * nat44_config.translation_buckets
2640 for i in range(0, max_sessions):
2641 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2642 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2643 IP(src=src, dst=self.pg1.remote_ip4) /
2646 self.pg0.add_stream(pkts)
2647 self.pg_enable_capture(self.pg_interfaces)
2650 self.pg1.get_capture(max_sessions)
2651 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2652 src_address=self.pg3.local_ip4n,
2654 template_interval=10)
2655 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2656 src_port=self.ipfix_src_port)
2658 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2659 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2661 self.pg0.add_stream(p)
2662 self.pg_enable_capture(self.pg_interfaces)
2664 self.pg1.assert_nothing_captured()
2666 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2667 capture = self.pg3.get_capture(9)
2668 ipfix = IPFIXDecoder()
2669 # first load template
2671 self.assertTrue(p.haslayer(IPFIX))
2672 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2673 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2674 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2675 self.assertEqual(p[UDP].dport, 4739)
2676 self.assertEqual(p[IPFIX].observationDomainID,
2677 self.ipfix_domain_id)
2678 if p.haslayer(Template):
2679 ipfix.add_template(p.getlayer(Template))
2680 # verify events in data set
2682 if p.haslayer(Data):
2683 data = ipfix.decode_data_set(p.getlayer(Set))
2684 self.verify_ipfix_max_sessions(data, max_sessions)
2686 def test_pool_addr_fib(self):
2687 """ NAT44 add pool addresses to FIB """
2688 static_addr = '10.0.0.10'
2689 self.nat44_add_address(self.nat_addr)
2690 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2691 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2693 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2696 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2697 ARP(op=ARP.who_has, pdst=self.nat_addr,
2698 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2699 self.pg1.add_stream(p)
2700 self.pg_enable_capture(self.pg_interfaces)
2702 capture = self.pg1.get_capture(1)
2703 self.assertTrue(capture[0].haslayer(ARP))
2704 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2707 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2708 ARP(op=ARP.who_has, pdst=static_addr,
2709 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2710 self.pg1.add_stream(p)
2711 self.pg_enable_capture(self.pg_interfaces)
2713 capture = self.pg1.get_capture(1)
2714 self.assertTrue(capture[0].haslayer(ARP))
2715 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2717 # send ARP to non-NAT44 interface
2718 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2719 ARP(op=ARP.who_has, pdst=self.nat_addr,
2720 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2721 self.pg2.add_stream(p)
2722 self.pg_enable_capture(self.pg_interfaces)
2724 self.pg1.assert_nothing_captured()
2726 # remove addresses and verify
2727 self.nat44_add_address(self.nat_addr, is_add=0)
2728 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2731 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2732 ARP(op=ARP.who_has, pdst=self.nat_addr,
2733 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2734 self.pg1.add_stream(p)
2735 self.pg_enable_capture(self.pg_interfaces)
2737 self.pg1.assert_nothing_captured()
2739 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2740 ARP(op=ARP.who_has, pdst=static_addr,
2741 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2742 self.pg1.add_stream(p)
2743 self.pg_enable_capture(self.pg_interfaces)
2745 self.pg1.assert_nothing_captured()
2747 def test_vrf_mode(self):
2748 """ NAT44 tenant VRF aware address pool mode """
2752 nat_ip1 = "10.0.0.10"
2753 nat_ip2 = "10.0.0.11"
2755 self.pg0.unconfig_ip4()
2756 self.pg1.unconfig_ip4()
2757 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2758 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2759 self.pg0.set_table_ip4(vrf_id1)
2760 self.pg1.set_table_ip4(vrf_id2)
2761 self.pg0.config_ip4()
2762 self.pg1.config_ip4()
2763 self.pg0.resolve_arp()
2764 self.pg1.resolve_arp()
2766 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2767 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2768 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2769 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2770 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2775 pkts = self.create_stream_in(self.pg0, self.pg2)
2776 self.pg0.add_stream(pkts)
2777 self.pg_enable_capture(self.pg_interfaces)
2779 capture = self.pg2.get_capture(len(pkts))
2780 self.verify_capture_out(capture, nat_ip1)
2783 pkts = self.create_stream_in(self.pg1, self.pg2)
2784 self.pg1.add_stream(pkts)
2785 self.pg_enable_capture(self.pg_interfaces)
2787 capture = self.pg2.get_capture(len(pkts))
2788 self.verify_capture_out(capture, nat_ip2)
2791 self.pg0.unconfig_ip4()
2792 self.pg1.unconfig_ip4()
2793 self.pg0.set_table_ip4(0)
2794 self.pg1.set_table_ip4(0)
2795 self.pg0.config_ip4()
2796 self.pg1.config_ip4()
2797 self.pg0.resolve_arp()
2798 self.pg1.resolve_arp()
2799 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2800 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2802 def test_vrf_feature_independent(self):
2803 """ NAT44 tenant VRF independent address pool mode """
2805 nat_ip1 = "10.0.0.10"
2806 nat_ip2 = "10.0.0.11"
2808 self.nat44_add_address(nat_ip1)
2809 self.nat44_add_address(nat_ip2, vrf_id=99)
2810 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2811 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2812 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2816 pkts = self.create_stream_in(self.pg0, self.pg2)
2817 self.pg0.add_stream(pkts)
2818 self.pg_enable_capture(self.pg_interfaces)
2820 capture = self.pg2.get_capture(len(pkts))
2821 self.verify_capture_out(capture, nat_ip1)
2824 pkts = self.create_stream_in(self.pg1, self.pg2)
2825 self.pg1.add_stream(pkts)
2826 self.pg_enable_capture(self.pg_interfaces)
2828 capture = self.pg2.get_capture(len(pkts))
2829 self.verify_capture_out(capture, nat_ip1)
2831 def test_dynamic_ipless_interfaces(self):
2832 """ NAT44 interfaces without configured IP address """
2834 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2835 mactobinary(self.pg7.remote_mac),
2836 self.pg7.remote_ip4n,
2838 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2839 mactobinary(self.pg8.remote_mac),
2840 self.pg8.remote_ip4n,
2843 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2844 dst_address_length=32,
2845 next_hop_address=self.pg7.remote_ip4n,
2846 next_hop_sw_if_index=self.pg7.sw_if_index)
2847 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2848 dst_address_length=32,
2849 next_hop_address=self.pg8.remote_ip4n,
2850 next_hop_sw_if_index=self.pg8.sw_if_index)
2852 self.nat44_add_address(self.nat_addr)
2853 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2854 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2858 pkts = self.create_stream_in(self.pg7, self.pg8)
2859 self.pg7.add_stream(pkts)
2860 self.pg_enable_capture(self.pg_interfaces)
2862 capture = self.pg8.get_capture(len(pkts))
2863 self.verify_capture_out(capture)
2866 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2867 self.pg8.add_stream(pkts)
2868 self.pg_enable_capture(self.pg_interfaces)
2870 capture = self.pg7.get_capture(len(pkts))
2871 self.verify_capture_in(capture, self.pg7)
2873 def test_static_ipless_interfaces(self):
2874 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2876 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2877 mactobinary(self.pg7.remote_mac),
2878 self.pg7.remote_ip4n,
2880 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2881 mactobinary(self.pg8.remote_mac),
2882 self.pg8.remote_ip4n,
2885 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2886 dst_address_length=32,
2887 next_hop_address=self.pg7.remote_ip4n,
2888 next_hop_sw_if_index=self.pg7.sw_if_index)
2889 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2890 dst_address_length=32,
2891 next_hop_address=self.pg8.remote_ip4n,
2892 next_hop_sw_if_index=self.pg8.sw_if_index)
2894 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2895 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2896 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2900 pkts = self.create_stream_out(self.pg8)
2901 self.pg8.add_stream(pkts)
2902 self.pg_enable_capture(self.pg_interfaces)
2904 capture = self.pg7.get_capture(len(pkts))
2905 self.verify_capture_in(capture, self.pg7)
2908 pkts = self.create_stream_in(self.pg7, self.pg8)
2909 self.pg7.add_stream(pkts)
2910 self.pg_enable_capture(self.pg_interfaces)
2912 capture = self.pg8.get_capture(len(pkts))
2913 self.verify_capture_out(capture, self.nat_addr, True)
2915 def test_static_with_port_ipless_interfaces(self):
2916 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2918 self.tcp_port_out = 30606
2919 self.udp_port_out = 30607
2920 self.icmp_id_out = 30608
2922 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2923 mactobinary(self.pg7.remote_mac),
2924 self.pg7.remote_ip4n,
2926 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2927 mactobinary(self.pg8.remote_mac),
2928 self.pg8.remote_ip4n,
2931 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2932 dst_address_length=32,
2933 next_hop_address=self.pg7.remote_ip4n,
2934 next_hop_sw_if_index=self.pg7.sw_if_index)
2935 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2936 dst_address_length=32,
2937 next_hop_address=self.pg8.remote_ip4n,
2938 next_hop_sw_if_index=self.pg8.sw_if_index)
2940 self.nat44_add_address(self.nat_addr)
2941 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2942 self.tcp_port_in, self.tcp_port_out,
2943 proto=IP_PROTOS.tcp)
2944 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2945 self.udp_port_in, self.udp_port_out,
2946 proto=IP_PROTOS.udp)
2947 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2948 self.icmp_id_in, self.icmp_id_out,
2949 proto=IP_PROTOS.icmp)
2950 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2951 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2955 pkts = self.create_stream_out(self.pg8)
2956 self.pg8.add_stream(pkts)
2957 self.pg_enable_capture(self.pg_interfaces)
2959 capture = self.pg7.get_capture(len(pkts))
2960 self.verify_capture_in(capture, self.pg7)
2963 pkts = self.create_stream_in(self.pg7, self.pg8)
2964 self.pg7.add_stream(pkts)
2965 self.pg_enable_capture(self.pg_interfaces)
2967 capture = self.pg8.get_capture(len(pkts))
2968 self.verify_capture_out(capture)
2970 def test_static_unknown_proto(self):
2971 """ 1:1 NAT translate packet with unknown protocol """
2972 nat_ip = "10.0.0.10"
2973 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2974 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2975 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2979 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2980 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2982 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2983 TCP(sport=1234, dport=1234))
2984 self.pg0.add_stream(p)
2985 self.pg_enable_capture(self.pg_interfaces)
2987 p = self.pg1.get_capture(1)
2990 self.assertEqual(packet[IP].src, nat_ip)
2991 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2992 self.assertTrue(packet.haslayer(GRE))
2993 self.assert_packet_checksums_valid(packet)
2995 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2999 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3000 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3002 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3003 TCP(sport=1234, dport=1234))
3004 self.pg1.add_stream(p)
3005 self.pg_enable_capture(self.pg_interfaces)
3007 p = self.pg0.get_capture(1)
3010 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3011 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3012 self.assertTrue(packet.haslayer(GRE))
3013 self.assert_packet_checksums_valid(packet)
3015 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3018 def test_hairpinning_static_unknown_proto(self):
3019 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3021 host = self.pg0.remote_hosts[0]
3022 server = self.pg0.remote_hosts[1]
3024 host_nat_ip = "10.0.0.10"
3025 server_nat_ip = "10.0.0.11"
3027 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3028 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3029 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3030 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3034 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3035 IP(src=host.ip4, dst=server_nat_ip) /
3037 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3038 TCP(sport=1234, dport=1234))
3039 self.pg0.add_stream(p)
3040 self.pg_enable_capture(self.pg_interfaces)
3042 p = self.pg0.get_capture(1)
3045 self.assertEqual(packet[IP].src, host_nat_ip)
3046 self.assertEqual(packet[IP].dst, server.ip4)
3047 self.assertTrue(packet.haslayer(GRE))
3048 self.assert_packet_checksums_valid(packet)
3050 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3054 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3055 IP(src=server.ip4, dst=host_nat_ip) /
3057 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3058 TCP(sport=1234, dport=1234))
3059 self.pg0.add_stream(p)
3060 self.pg_enable_capture(self.pg_interfaces)
3062 p = self.pg0.get_capture(1)
3065 self.assertEqual(packet[IP].src, server_nat_ip)
3066 self.assertEqual(packet[IP].dst, host.ip4)
3067 self.assertTrue(packet.haslayer(GRE))
3068 self.assert_packet_checksums_valid(packet)
3070 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3073 def test_output_feature(self):
3074 """ NAT44 interface output feature (in2out postrouting) """
3075 self.nat44_add_address(self.nat_addr)
3076 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3077 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3078 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3082 pkts = self.create_stream_in(self.pg0, self.pg3)
3083 self.pg0.add_stream(pkts)
3084 self.pg_enable_capture(self.pg_interfaces)
3086 capture = self.pg3.get_capture(len(pkts))
3087 self.verify_capture_out(capture)
3090 pkts = self.create_stream_out(self.pg3)
3091 self.pg3.add_stream(pkts)
3092 self.pg_enable_capture(self.pg_interfaces)
3094 capture = self.pg0.get_capture(len(pkts))
3095 self.verify_capture_in(capture, self.pg0)
3097 # from non-NAT interface to NAT inside interface
3098 pkts = self.create_stream_in(self.pg2, self.pg0)
3099 self.pg2.add_stream(pkts)
3100 self.pg_enable_capture(self.pg_interfaces)
3102 capture = self.pg0.get_capture(len(pkts))
3103 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3105 def test_output_feature_vrf_aware(self):
3106 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3107 nat_ip_vrf10 = "10.0.0.10"
3108 nat_ip_vrf20 = "10.0.0.20"
3110 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3111 dst_address_length=32,
3112 next_hop_address=self.pg3.remote_ip4n,
3113 next_hop_sw_if_index=self.pg3.sw_if_index,
3115 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3116 dst_address_length=32,
3117 next_hop_address=self.pg3.remote_ip4n,
3118 next_hop_sw_if_index=self.pg3.sw_if_index,
3121 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3122 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3123 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3124 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3125 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3129 pkts = self.create_stream_in(self.pg4, self.pg3)
3130 self.pg4.add_stream(pkts)
3131 self.pg_enable_capture(self.pg_interfaces)
3133 capture = self.pg3.get_capture(len(pkts))
3134 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3137 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3138 self.pg3.add_stream(pkts)
3139 self.pg_enable_capture(self.pg_interfaces)
3141 capture = self.pg4.get_capture(len(pkts))
3142 self.verify_capture_in(capture, self.pg4)
3145 pkts = self.create_stream_in(self.pg6, self.pg3)
3146 self.pg6.add_stream(pkts)
3147 self.pg_enable_capture(self.pg_interfaces)
3149 capture = self.pg3.get_capture(len(pkts))
3150 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3153 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3154 self.pg3.add_stream(pkts)
3155 self.pg_enable_capture(self.pg_interfaces)
3157 capture = self.pg6.get_capture(len(pkts))
3158 self.verify_capture_in(capture, self.pg6)
3160 def test_output_feature_hairpinning(self):
3161 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3162 host = self.pg0.remote_hosts[0]
3163 server = self.pg0.remote_hosts[1]
3166 server_in_port = 5678
3167 server_out_port = 8765
3169 self.nat44_add_address(self.nat_addr)
3170 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3171 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3174 # add static mapping for server
3175 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3176 server_in_port, server_out_port,
3177 proto=IP_PROTOS.tcp)
3179 # send packet from host to server
3180 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3181 IP(src=host.ip4, dst=self.nat_addr) /
3182 TCP(sport=host_in_port, dport=server_out_port))
3183 self.pg0.add_stream(p)
3184 self.pg_enable_capture(self.pg_interfaces)
3186 capture = self.pg0.get_capture(1)
3191 self.assertEqual(ip.src, self.nat_addr)
3192 self.assertEqual(ip.dst, server.ip4)
3193 self.assertNotEqual(tcp.sport, host_in_port)
3194 self.assertEqual(tcp.dport, server_in_port)
3195 self.assert_packet_checksums_valid(p)
3196 host_out_port = tcp.sport
3198 self.logger.error(ppp("Unexpected or invalid packet:", p))
3201 # send reply from server to host
3202 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3203 IP(src=server.ip4, dst=self.nat_addr) /
3204 TCP(sport=server_in_port, dport=host_out_port))
3205 self.pg0.add_stream(p)
3206 self.pg_enable_capture(self.pg_interfaces)
3208 capture = self.pg0.get_capture(1)
3213 self.assertEqual(ip.src, self.nat_addr)
3214 self.assertEqual(ip.dst, host.ip4)
3215 self.assertEqual(tcp.sport, server_out_port)
3216 self.assertEqual(tcp.dport, host_in_port)
3217 self.assert_packet_checksums_valid(p)
3219 self.logger.error(ppp("Unexpected or invalid packet:", p))
3222 def test_one_armed_nat44(self):
3223 """ One armed NAT44 """
3224 remote_host = self.pg9.remote_hosts[0]
3225 local_host = self.pg9.remote_hosts[1]
3228 self.nat44_add_address(self.nat_addr)
3229 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3230 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3234 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3235 IP(src=local_host.ip4, dst=remote_host.ip4) /
3236 TCP(sport=12345, dport=80))
3237 self.pg9.add_stream(p)
3238 self.pg_enable_capture(self.pg_interfaces)
3240 capture = self.pg9.get_capture(1)
3245 self.assertEqual(ip.src, self.nat_addr)
3246 self.assertEqual(ip.dst, remote_host.ip4)
3247 self.assertNotEqual(tcp.sport, 12345)
3248 external_port = tcp.sport
3249 self.assertEqual(tcp.dport, 80)
3250 self.assert_packet_checksums_valid(p)
3252 self.logger.error(ppp("Unexpected or invalid packet:", p))
3256 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3257 IP(src=remote_host.ip4, dst=self.nat_addr) /
3258 TCP(sport=80, dport=external_port))
3259 self.pg9.add_stream(p)
3260 self.pg_enable_capture(self.pg_interfaces)
3262 capture = self.pg9.get_capture(1)
3267 self.assertEqual(ip.src, remote_host.ip4)
3268 self.assertEqual(ip.dst, local_host.ip4)
3269 self.assertEqual(tcp.sport, 80)
3270 self.assertEqual(tcp.dport, 12345)
3271 self.assert_packet_checksums_valid(p)
3273 self.logger.error(ppp("Unexpected or invalid packet:", p))
3276 def test_del_session(self):
3277 """ Delete NAT44 session """
3278 self.nat44_add_address(self.nat_addr)
3279 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3280 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3283 pkts = self.create_stream_in(self.pg0, self.pg1)
3284 self.pg0.add_stream(pkts)
3285 self.pg_enable_capture(self.pg_interfaces)
3287 self.pg1.get_capture(len(pkts))
3289 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3290 nsessions = len(sessions)
3292 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3293 sessions[0].inside_port,
3294 sessions[0].protocol)
3295 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3296 sessions[1].outside_port,
3297 sessions[1].protocol,
3300 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3301 self.assertEqual(nsessions - len(sessions), 2)
3303 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3304 sessions[0].inside_port,
3305 sessions[0].protocol)
3307 self.verify_no_nat44_user()
3309 def test_set_get_reass(self):
3310 """ NAT44 set/get virtual fragmentation reassembly """
3311 reas_cfg1 = self.vapi.nat_get_reass()
3313 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3314 max_reass=reas_cfg1.ip4_max_reass * 2,
3315 max_frag=reas_cfg1.ip4_max_frag * 2)
3317 reas_cfg2 = self.vapi.nat_get_reass()
3319 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3320 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3321 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3323 self.vapi.nat_set_reass(drop_frag=1)
3324 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3326 def test_frag_in_order(self):
3327 """ NAT44 translate fragments arriving in order """
3329 self.nat44_add_address(self.nat_addr)
3330 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3331 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3334 data = "A" * 4 + "B" * 16 + "C" * 3
3335 self.tcp_port_in = random.randint(1025, 65535)
3337 reass = self.vapi.nat_reass_dump()
3338 reass_n_start = len(reass)
3341 pkts = self.create_stream_frag(self.pg0,
3342 self.pg1.remote_ip4,
3346 self.pg0.add_stream(pkts)
3347 self.pg_enable_capture(self.pg_interfaces)
3349 frags = self.pg1.get_capture(len(pkts))
3350 p = self.reass_frags_and_verify(frags,
3352 self.pg1.remote_ip4)
3353 self.assertEqual(p[TCP].dport, 20)
3354 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3355 self.tcp_port_out = p[TCP].sport
3356 self.assertEqual(data, p[Raw].load)
3359 pkts = self.create_stream_frag(self.pg1,
3364 self.pg1.add_stream(pkts)
3365 self.pg_enable_capture(self.pg_interfaces)
3367 frags = self.pg0.get_capture(len(pkts))
3368 p = self.reass_frags_and_verify(frags,
3369 self.pg1.remote_ip4,
3370 self.pg0.remote_ip4)
3371 self.assertEqual(p[TCP].sport, 20)
3372 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3373 self.assertEqual(data, p[Raw].load)
3375 reass = self.vapi.nat_reass_dump()
3376 reass_n_end = len(reass)
3378 self.assertEqual(reass_n_end - reass_n_start, 2)
3380 def test_reass_hairpinning(self):
3381 """ NAT44 fragments hairpinning """
3383 server = self.pg0.remote_hosts[1]
3384 host_in_port = random.randint(1025, 65535)
3385 server_in_port = random.randint(1025, 65535)
3386 server_out_port = random.randint(1025, 65535)
3387 data = "A" * 4 + "B" * 16 + "C" * 3
3389 self.nat44_add_address(self.nat_addr)
3390 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3391 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3393 # add static mapping for server
3394 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3395 server_in_port, server_out_port,
3396 proto=IP_PROTOS.tcp)
3398 # send packet from host to server
3399 pkts = self.create_stream_frag(self.pg0,
3404 self.pg0.add_stream(pkts)
3405 self.pg_enable_capture(self.pg_interfaces)
3407 frags = self.pg0.get_capture(len(pkts))
3408 p = self.reass_frags_and_verify(frags,
3411 self.assertNotEqual(p[TCP].sport, host_in_port)
3412 self.assertEqual(p[TCP].dport, server_in_port)
3413 self.assertEqual(data, p[Raw].load)
3415 def test_frag_out_of_order(self):
3416 """ NAT44 translate fragments arriving out of order """
3418 self.nat44_add_address(self.nat_addr)
3419 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3420 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3423 data = "A" * 4 + "B" * 16 + "C" * 3
3424 random.randint(1025, 65535)
3427 pkts = self.create_stream_frag(self.pg0,
3428 self.pg1.remote_ip4,
3433 self.pg0.add_stream(pkts)
3434 self.pg_enable_capture(self.pg_interfaces)
3436 frags = self.pg1.get_capture(len(pkts))
3437 p = self.reass_frags_and_verify(frags,
3439 self.pg1.remote_ip4)
3440 self.assertEqual(p[TCP].dport, 20)
3441 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3442 self.tcp_port_out = p[TCP].sport
3443 self.assertEqual(data, p[Raw].load)
3446 pkts = self.create_stream_frag(self.pg1,
3452 self.pg1.add_stream(pkts)
3453 self.pg_enable_capture(self.pg_interfaces)
3455 frags = self.pg0.get_capture(len(pkts))
3456 p = self.reass_frags_and_verify(frags,
3457 self.pg1.remote_ip4,
3458 self.pg0.remote_ip4)
3459 self.assertEqual(p[TCP].sport, 20)
3460 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3461 self.assertEqual(data, p[Raw].load)
3463 def test_port_restricted(self):
3464 """ Port restricted NAT44 (MAP-E CE) """
3465 self.nat44_add_address(self.nat_addr)
3466 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3467 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3469 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3474 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3475 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3476 TCP(sport=4567, dport=22))
3477 self.pg0.add_stream(p)
3478 self.pg_enable_capture(self.pg_interfaces)
3480 capture = self.pg1.get_capture(1)
3485 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3486 self.assertEqual(ip.src, self.nat_addr)
3487 self.assertEqual(tcp.dport, 22)
3488 self.assertNotEqual(tcp.sport, 4567)
3489 self.assertEqual((tcp.sport >> 6) & 63, 10)
3490 self.assert_packet_checksums_valid(p)
3492 self.logger.error(ppp("Unexpected or invalid packet:", p))
3495 def test_port_range(self):
3496 """ External address port range """
3497 self.nat44_add_address(self.nat_addr)
3498 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3499 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3501 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3506 for port in range(0, 5):
3507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3508 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3509 TCP(sport=1125 + port))
3511 self.pg0.add_stream(pkts)
3512 self.pg_enable_capture(self.pg_interfaces)
3514 capture = self.pg1.get_capture(3)
3517 self.assertGreaterEqual(tcp.sport, 1025)
3518 self.assertLessEqual(tcp.sport, 1027)
3520 def test_ipfix_max_frags(self):
3521 """ IPFIX logging maximum fragments pending reassembly exceeded """
3522 self.nat44_add_address(self.nat_addr)
3523 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3524 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3526 self.vapi.nat_set_reass(max_frag=1)
3527 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3528 src_address=self.pg3.local_ip4n,
3530 template_interval=10)
3531 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3532 src_port=self.ipfix_src_port)
3534 data = "A" * 4 + "B" * 16 + "C" * 3
3535 self.tcp_port_in = random.randint(1025, 65535)
3536 pkts = self.create_stream_frag(self.pg0,
3537 self.pg1.remote_ip4,
3542 self.pg0.add_stream(pkts)
3543 self.pg_enable_capture(self.pg_interfaces)
3545 self.pg1.assert_nothing_captured()
3547 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3548 capture = self.pg3.get_capture(9)
3549 ipfix = IPFIXDecoder()
3550 # first load template
3552 self.assertTrue(p.haslayer(IPFIX))
3553 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3554 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3555 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3556 self.assertEqual(p[UDP].dport, 4739)
3557 self.assertEqual(p[IPFIX].observationDomainID,
3558 self.ipfix_domain_id)
3559 if p.haslayer(Template):
3560 ipfix.add_template(p.getlayer(Template))
3561 # verify events in data set
3563 if p.haslayer(Data):
3564 data = ipfix.decode_data_set(p.getlayer(Set))
3565 self.verify_ipfix_max_fragments_ip4(data, 1,
3566 self.pg0.remote_ip4n)
3568 def test_multiple_outside_vrf(self):
3569 """ Multiple outside VRF """
3573 self.pg1.unconfig_ip4()
3574 self.pg2.unconfig_ip4()
3575 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3576 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3577 self.pg1.set_table_ip4(vrf_id1)
3578 self.pg2.set_table_ip4(vrf_id2)
3579 self.pg1.config_ip4()
3580 self.pg2.config_ip4()
3581 self.pg1.resolve_arp()
3582 self.pg2.resolve_arp()
3584 self.nat44_add_address(self.nat_addr)
3585 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3586 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3588 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3593 pkts = self.create_stream_in(self.pg0, self.pg1)
3594 self.pg0.add_stream(pkts)
3595 self.pg_enable_capture(self.pg_interfaces)
3597 capture = self.pg1.get_capture(len(pkts))
3598 self.verify_capture_out(capture, self.nat_addr)
3600 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3601 self.pg1.add_stream(pkts)
3602 self.pg_enable_capture(self.pg_interfaces)
3604 capture = self.pg0.get_capture(len(pkts))
3605 self.verify_capture_in(capture, self.pg0)
3607 self.tcp_port_in = 60303
3608 self.udp_port_in = 60304
3609 self.icmp_id_in = 60305
3612 pkts = self.create_stream_in(self.pg0, self.pg2)
3613 self.pg0.add_stream(pkts)
3614 self.pg_enable_capture(self.pg_interfaces)
3616 capture = self.pg2.get_capture(len(pkts))
3617 self.verify_capture_out(capture, self.nat_addr)
3619 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3620 self.pg2.add_stream(pkts)
3621 self.pg_enable_capture(self.pg_interfaces)
3623 capture = self.pg0.get_capture(len(pkts))
3624 self.verify_capture_in(capture, self.pg0)
3627 self.pg1.unconfig_ip4()
3628 self.pg2.unconfig_ip4()
3629 self.pg1.set_table_ip4(0)
3630 self.pg2.set_table_ip4(0)
3631 self.pg1.config_ip4()
3632 self.pg2.config_ip4()
3633 self.pg1.resolve_arp()
3634 self.pg2.resolve_arp()
3636 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3637 def test_session_timeout(self):
3638 """ NAT44 session timeouts """
3639 self.nat44_add_address(self.nat_addr)
3640 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3641 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3643 self.vapi.nat_set_timeouts(udp=5)
3647 for i in range(0, max_sessions):
3648 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3649 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3650 IP(src=src, dst=self.pg1.remote_ip4) /
3651 UDP(sport=1025, dport=53))
3653 self.pg0.add_stream(pkts)
3654 self.pg_enable_capture(self.pg_interfaces)
3656 self.pg1.get_capture(max_sessions)
3661 for i in range(0, max_sessions):
3662 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3663 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3664 IP(src=src, dst=self.pg1.remote_ip4) /
3665 UDP(sport=1026, dport=53))
3667 self.pg0.add_stream(pkts)
3668 self.pg_enable_capture(self.pg_interfaces)
3670 self.pg1.get_capture(max_sessions)
3673 users = self.vapi.nat44_user_dump()
3675 nsessions = nsessions + user.nsessions
3676 self.assertLess(nsessions, 2 * max_sessions)
3678 def test_mss_clamping(self):
3679 """ TCP MSS clamping """
3680 self.nat44_add_address(self.nat_addr)
3681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3685 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3686 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3687 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3688 flags="S", options=[('MSS', 1400)]))
3690 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3691 self.pg0.add_stream(p)
3692 self.pg_enable_capture(self.pg_interfaces)
3694 capture = self.pg1.get_capture(1)
3695 # Negotiated MSS value greater than configured - changed
3696 self.verify_mss_value(capture[0], 1000)
3698 self.vapi.nat_set_mss_clamping(enable=0)
3699 self.pg0.add_stream(p)
3700 self.pg_enable_capture(self.pg_interfaces)
3702 capture = self.pg1.get_capture(1)
3703 # MSS clamping disabled - negotiated MSS unchanged
3704 self.verify_mss_value(capture[0], 1400)
3706 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3707 self.pg0.add_stream(p)
3708 self.pg_enable_capture(self.pg_interfaces)
3710 capture = self.pg1.get_capture(1)
3711 # Negotiated MSS value smaller than configured - unchanged
3712 self.verify_mss_value(capture[0], 1400)
3715 super(TestNAT44, self).tearDown()
3716 if not self.vpp_dead:
3717 self.logger.info(self.vapi.cli("show nat44 addresses"))
3718 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3719 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3720 self.logger.info(self.vapi.cli("show nat44 interface address"))
3721 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3722 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3723 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3724 self.logger.info(self.vapi.cli("show nat timeouts"))
3726 self.vapi.cli("show nat addr-port-assignment-alg"))
3728 self.vapi.cli("clear logging")
3731 class TestNAT44EndpointDependent(MethodHolder):
3732 """ Endpoint-Dependent mapping and filtering test cases """
3735 def setUpConstants(cls):
3736 super(TestNAT44EndpointDependent, cls).setUpConstants()
3737 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3740 def setUpClass(cls):
3741 super(TestNAT44EndpointDependent, cls).setUpClass()
3742 cls.vapi.cli("set log class nat level debug")
3744 cls.tcp_port_in = 6303
3745 cls.tcp_port_out = 6303
3746 cls.udp_port_in = 6304
3747 cls.udp_port_out = 6304
3748 cls.icmp_id_in = 6305
3749 cls.icmp_id_out = 6305
3750 cls.nat_addr = '10.0.0.3'
3751 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3752 cls.ipfix_src_port = 4739
3753 cls.ipfix_domain_id = 1
3754 cls.tcp_external_port = 80
3756 cls.create_pg_interfaces(range(7))
3757 cls.interfaces = list(cls.pg_interfaces[0:3])
3759 for i in cls.interfaces:
3764 cls.pg0.generate_remote_hosts(3)
3765 cls.pg0.configure_ipv4_neighbors()
3769 cls.pg4.generate_remote_hosts(2)
3770 cls.pg4.config_ip4()
3771 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3772 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3776 cls.pg4.resolve_arp()
3777 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3778 cls.pg4.resolve_arp()
3780 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3781 cls.vapi.ip_table_add_del(1, is_add=1)
3783 cls.pg5._local_ip4 = "10.1.1.1"
3784 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3786 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3787 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3788 socket.AF_INET, cls.pg5.remote_ip4)
3789 cls.pg5.set_table_ip4(1)
3790 cls.pg5.config_ip4()
3792 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3793 dst_address_length=32,
3795 next_hop_sw_if_index=cls.pg5.sw_if_index,
3796 next_hop_address=zero_ip4n)
3798 cls.pg6._local_ip4 = "10.1.2.1"
3799 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3801 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3802 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3803 socket.AF_INET, cls.pg6.remote_ip4)
3804 cls.pg6.set_table_ip4(1)
3805 cls.pg6.config_ip4()
3807 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3808 dst_address_length=32,
3810 next_hop_sw_if_index=cls.pg6.sw_if_index,
3811 next_hop_address=zero_ip4n)
3813 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3814 dst_address_length=16,
3815 next_hop_address=zero_ip4n,
3817 next_hop_table_id=1)
3818 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3819 dst_address_length=0,
3820 next_hop_address=zero_ip4n,
3822 next_hop_table_id=0)
3823 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3824 dst_address_length=0,
3826 next_hop_sw_if_index=cls.pg1.sw_if_index,
3827 next_hop_address=cls.pg1.local_ip4n)
3829 cls.pg5.resolve_arp()
3830 cls.pg6.resolve_arp()
3833 super(TestNAT44EndpointDependent, cls).tearDownClass()
3836 def test_frag_in_order(self):
3837 """ NAT44 translate fragments arriving in order """
3838 self.nat44_add_address(self.nat_addr)
3839 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3840 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3842 self.frag_in_order(proto=IP_PROTOS.tcp)
3843 self.frag_in_order(proto=IP_PROTOS.udp)
3844 self.frag_in_order(proto=IP_PROTOS.icmp)
3846 def test_frag_in_order_dont_translate(self):
3847 """ NAT44 don't translate fragments arriving in order """
3848 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3849 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3851 self.vapi.nat44_forwarding_enable_disable(enable=True)
3852 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3854 def test_frag_out_of_order(self):
3855 """ NAT44 translate fragments arriving out of order """
3856 self.nat44_add_address(self.nat_addr)
3857 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3858 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3860 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3861 self.frag_out_of_order(proto=IP_PROTOS.udp)
3862 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3864 def test_frag_out_of_order_dont_translate(self):
3865 """ NAT44 don't translate fragments arriving out of order """
3866 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3867 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3869 self.vapi.nat44_forwarding_enable_disable(enable=True)
3870 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3872 def test_frag_in_order_in_plus_out(self):
3873 """ in+out interface fragments in order """
3874 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3875 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3877 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3878 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3881 self.server = self.pg1.remote_hosts[0]
3883 self.server_in_addr = self.server.ip4
3884 self.server_out_addr = '11.11.11.11'
3885 self.server_in_port = random.randint(1025, 65535)
3886 self.server_out_port = random.randint(1025, 65535)
3888 self.nat44_add_address(self.server_out_addr)
3890 # add static mappings for server
3891 self.nat44_add_static_mapping(self.server_in_addr,
3892 self.server_out_addr,
3893 self.server_in_port,
3894 self.server_out_port,
3895 proto=IP_PROTOS.tcp)
3896 self.nat44_add_static_mapping(self.server_in_addr,
3897 self.server_out_addr,
3898 self.server_in_port,
3899 self.server_out_port,
3900 proto=IP_PROTOS.udp)
3901 self.nat44_add_static_mapping(self.server_in_addr,
3902 self.server_out_addr,
3903 proto=IP_PROTOS.icmp)
3905 self.vapi.nat_set_reass(timeout=10)
3907 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3908 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3909 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3911 def test_frag_out_of_order_in_plus_out(self):
3912 """ in+out interface fragments out of order """
3913 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3916 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3917 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3920 self.server = self.pg1.remote_hosts[0]
3922 self.server_in_addr = self.server.ip4
3923 self.server_out_addr = '11.11.11.11'
3924 self.server_in_port = random.randint(1025, 65535)
3925 self.server_out_port = random.randint(1025, 65535)
3927 self.nat44_add_address(self.server_out_addr)
3929 # add static mappings for server
3930 self.nat44_add_static_mapping(self.server_in_addr,
3931 self.server_out_addr,
3932 self.server_in_port,
3933 self.server_out_port,
3934 proto=IP_PROTOS.tcp)
3935 self.nat44_add_static_mapping(self.server_in_addr,
3936 self.server_out_addr,
3937 self.server_in_port,
3938 self.server_out_port,
3939 proto=IP_PROTOS.udp)
3940 self.nat44_add_static_mapping(self.server_in_addr,
3941 self.server_out_addr,
3942 proto=IP_PROTOS.icmp)
3944 self.vapi.nat_set_reass(timeout=10)
3946 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3947 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3948 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3950 def test_reass_hairpinning(self):
3951 """ NAT44 fragments hairpinning """
3952 self.server = self.pg0.remote_hosts[1]
3953 self.host_in_port = random.randint(1025, 65535)
3954 self.server_in_port = random.randint(1025, 65535)
3955 self.server_out_port = random.randint(1025, 65535)
3957 self.nat44_add_address(self.nat_addr)
3958 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3959 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3961 # add static mapping for server
3962 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3963 self.server_in_port,
3964 self.server_out_port,
3965 proto=IP_PROTOS.tcp)
3966 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3967 self.server_in_port,
3968 self.server_out_port,
3969 proto=IP_PROTOS.udp)
3970 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3971 proto=IP_PROTOS.icmp)
3973 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3974 self.reass_hairpinning(proto=IP_PROTOS.udp)
3975 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3977 def test_dynamic(self):
3978 """ NAT44 dynamic translation test """
3980 self.nat44_add_address(self.nat_addr)
3981 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3982 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3985 nat_config = self.vapi.nat_show_config()
3986 self.assertEqual(1, nat_config.endpoint_dependent)
3989 pkts = self.create_stream_in(self.pg0, self.pg1)
3990 self.pg0.add_stream(pkts)
3991 self.pg_enable_capture(self.pg_interfaces)
3993 capture = self.pg1.get_capture(len(pkts))
3994 self.verify_capture_out(capture)
3997 pkts = self.create_stream_out(self.pg1)
3998 self.pg1.add_stream(pkts)
3999 self.pg_enable_capture(self.pg_interfaces)
4001 capture = self.pg0.get_capture(len(pkts))
4002 self.verify_capture_in(capture, self.pg0)
4004 def test_forwarding(self):
4005 """ NAT44 forwarding test """
4007 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4008 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4010 self.vapi.nat44_forwarding_enable_disable(1)
4012 real_ip = self.pg0.remote_ip4n
4013 alias_ip = self.nat_addr_n
4014 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4015 external_ip=alias_ip)
4018 # in2out - static mapping match
4020 pkts = self.create_stream_out(self.pg1)
4021 self.pg1.add_stream(pkts)
4022 self.pg_enable_capture(self.pg_interfaces)
4024 capture = self.pg0.get_capture(len(pkts))
4025 self.verify_capture_in(capture, self.pg0)
4027 pkts = self.create_stream_in(self.pg0, self.pg1)
4028 self.pg0.add_stream(pkts)
4029 self.pg_enable_capture(self.pg_interfaces)
4031 capture = self.pg1.get_capture(len(pkts))
4032 self.verify_capture_out(capture, same_port=True)
4034 # in2out - no static mapping match
4036 host0 = self.pg0.remote_hosts[0]
4037 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4039 pkts = self.create_stream_out(self.pg1,
4040 dst_ip=self.pg0.remote_ip4,
4041 use_inside_ports=True)
4042 self.pg1.add_stream(pkts)
4043 self.pg_enable_capture(self.pg_interfaces)
4045 capture = self.pg0.get_capture(len(pkts))
4046 self.verify_capture_in(capture, self.pg0)
4048 pkts = self.create_stream_in(self.pg0, self.pg1)
4049 self.pg0.add_stream(pkts)
4050 self.pg_enable_capture(self.pg_interfaces)
4052 capture = self.pg1.get_capture(len(pkts))
4053 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4056 self.pg0.remote_hosts[0] = host0
4058 user = self.pg0.remote_hosts[1]
4059 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4060 self.assertEqual(len(sessions), 3)
4061 self.assertTrue(sessions[0].ext_host_valid)
4062 self.vapi.nat44_del_session(
4063 sessions[0].inside_ip_address,
4064 sessions[0].inside_port,
4065 sessions[0].protocol,
4066 ext_host_address=sessions[0].ext_host_address,
4067 ext_host_port=sessions[0].ext_host_port)
4068 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4069 self.assertEqual(len(sessions), 2)
4072 self.vapi.nat44_forwarding_enable_disable(0)
4073 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4074 external_ip=alias_ip,
4077 def test_static_lb(self):
4078 """ NAT44 local service load balancing """
4079 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4082 server1 = self.pg0.remote_hosts[0]
4083 server2 = self.pg0.remote_hosts[1]
4085 locals = [{'addr': server1.ip4n,
4089 {'addr': server2.ip4n,
4094 self.nat44_add_address(self.nat_addr)
4095 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4098 local_num=len(locals),
4100 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4101 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4104 # from client to service
4105 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4106 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4107 TCP(sport=12345, dport=external_port))
4108 self.pg1.add_stream(p)
4109 self.pg_enable_capture(self.pg_interfaces)
4111 capture = self.pg0.get_capture(1)
4117 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4118 if ip.dst == server1.ip4:
4122 self.assertEqual(tcp.dport, local_port)
4123 self.assert_packet_checksums_valid(p)
4125 self.logger.error(ppp("Unexpected or invalid packet:", p))
4128 # from service back to client
4129 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4130 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4131 TCP(sport=local_port, dport=12345))
4132 self.pg0.add_stream(p)
4133 self.pg_enable_capture(self.pg_interfaces)
4135 capture = self.pg1.get_capture(1)
4140 self.assertEqual(ip.src, self.nat_addr)
4141 self.assertEqual(tcp.sport, external_port)
4142 self.assert_packet_checksums_valid(p)
4144 self.logger.error(ppp("Unexpected or invalid packet:", p))
4147 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4148 self.assertEqual(len(sessions), 1)
4149 self.assertTrue(sessions[0].ext_host_valid)
4150 self.vapi.nat44_del_session(
4151 sessions[0].inside_ip_address,
4152 sessions[0].inside_port,
4153 sessions[0].protocol,
4154 ext_host_address=sessions[0].ext_host_address,
4155 ext_host_port=sessions[0].ext_host_port)
4156 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4157 self.assertEqual(len(sessions), 0)
4159 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4160 def test_static_lb_multi_clients(self):
4161 """ NAT44 local service load balancing - multiple clients"""
4163 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4166 server1 = self.pg0.remote_hosts[0]
4167 server2 = self.pg0.remote_hosts[1]
4169 locals = [{'addr': server1.ip4n,
4173 {'addr': server2.ip4n,
4178 self.nat44_add_address(self.nat_addr)
4179 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4182 local_num=len(locals),
4184 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4185 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4190 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4192 for client in clients:
4193 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4194 IP(src=client, dst=self.nat_addr) /
4195 TCP(sport=12345, dport=external_port))
4197 self.pg1.add_stream(pkts)
4198 self.pg_enable_capture(self.pg_interfaces)
4200 capture = self.pg0.get_capture(len(pkts))
4202 if p[IP].dst == server1.ip4:
4206 self.assertTrue(server1_n > server2_n)
4208 def test_static_lb_2(self):
4209 """ NAT44 local service load balancing (asymmetrical rule) """
4210 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4213 server1 = self.pg0.remote_hosts[0]
4214 server2 = self.pg0.remote_hosts[1]
4216 locals = [{'addr': server1.ip4n,
4220 {'addr': server2.ip4n,
4225 self.vapi.nat44_forwarding_enable_disable(1)
4226 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4230 local_num=len(locals),
4232 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4233 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4236 # from client to service
4237 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4238 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4239 TCP(sport=12345, dport=external_port))
4240 self.pg1.add_stream(p)
4241 self.pg_enable_capture(self.pg_interfaces)
4243 capture = self.pg0.get_capture(1)
4249 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4250 if ip.dst == server1.ip4:
4254 self.assertEqual(tcp.dport, local_port)
4255 self.assert_packet_checksums_valid(p)
4257 self.logger.error(ppp("Unexpected or invalid packet:", p))
4260 # from service back to client
4261 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4262 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4263 TCP(sport=local_port, dport=12345))
4264 self.pg0.add_stream(p)
4265 self.pg_enable_capture(self.pg_interfaces)
4267 capture = self.pg1.get_capture(1)
4272 self.assertEqual(ip.src, self.nat_addr)
4273 self.assertEqual(tcp.sport, external_port)
4274 self.assert_packet_checksums_valid(p)
4276 self.logger.error(ppp("Unexpected or invalid packet:", p))
4279 # from client to server (no translation)
4280 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4281 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4282 TCP(sport=12346, dport=local_port))
4283 self.pg1.add_stream(p)
4284 self.pg_enable_capture(self.pg_interfaces)
4286 capture = self.pg0.get_capture(1)
4292 self.assertEqual(ip.dst, server1.ip4)
4293 self.assertEqual(tcp.dport, local_port)
4294 self.assert_packet_checksums_valid(p)
4296 self.logger.error(ppp("Unexpected or invalid packet:", p))
4299 # from service back to client (no translation)
4300 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4301 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4302 TCP(sport=local_port, dport=12346))
4303 self.pg0.add_stream(p)
4304 self.pg_enable_capture(self.pg_interfaces)
4306 capture = self.pg1.get_capture(1)
4311 self.assertEqual(ip.src, server1.ip4)
4312 self.assertEqual(tcp.sport, local_port)
4313 self.assert_packet_checksums_valid(p)
4315 self.logger.error(ppp("Unexpected or invalid packet:", p))
4318 def test_lb_affinity(self):
4319 """ NAT44 local service load balancing affinity """
4320 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4323 server1 = self.pg0.remote_hosts[0]
4324 server2 = self.pg0.remote_hosts[1]
4326 locals = [{'addr': server1.ip4n,
4330 {'addr': server2.ip4n,
4335 self.nat44_add_address(self.nat_addr)
4336 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4340 local_num=len(locals),
4342 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4343 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4346 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4347 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4348 TCP(sport=1025, dport=external_port))
4349 self.pg1.add_stream(p)
4350 self.pg_enable_capture(self.pg_interfaces)
4352 capture = self.pg0.get_capture(1)
4353 backend = capture[0][IP].dst
4355 sessions = self.vapi.nat44_user_session_dump(
4356 socket.inet_pton(socket.AF_INET, backend), 0)
4357 self.assertEqual(len(sessions), 1)
4358 self.assertTrue(sessions[0].ext_host_valid)
4359 self.vapi.nat44_del_session(
4360 sessions[0].inside_ip_address,
4361 sessions[0].inside_port,
4362 sessions[0].protocol,
4363 ext_host_address=sessions[0].ext_host_address,
4364 ext_host_port=sessions[0].ext_host_port)
4367 for port in range(1030, 1100):
4368 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4369 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4370 TCP(sport=port, dport=external_port))
4372 self.pg1.add_stream(pkts)
4373 self.pg_enable_capture(self.pg_interfaces)
4375 capture = self.pg0.get_capture(len(pkts))
4377 self.assertEqual(p[IP].dst, backend)
4379 def test_unknown_proto(self):
4380 """ NAT44 translate packet with unknown protocol """
4381 self.nat44_add_address(self.nat_addr)
4382 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4383 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4387 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4388 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4389 TCP(sport=self.tcp_port_in, dport=20))
4390 self.pg0.add_stream(p)
4391 self.pg_enable_capture(self.pg_interfaces)
4393 p = self.pg1.get_capture(1)
4395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4396 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4398 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4399 TCP(sport=1234, dport=1234))
4400 self.pg0.add_stream(p)
4401 self.pg_enable_capture(self.pg_interfaces)
4403 p = self.pg1.get_capture(1)
4406 self.assertEqual(packet[IP].src, self.nat_addr)
4407 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4408 self.assertTrue(packet.haslayer(GRE))
4409 self.assert_packet_checksums_valid(packet)
4411 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4415 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4416 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4418 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4419 TCP(sport=1234, dport=1234))
4420 self.pg1.add_stream(p)
4421 self.pg_enable_capture(self.pg_interfaces)
4423 p = self.pg0.get_capture(1)
4426 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4427 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4428 self.assertTrue(packet.haslayer(GRE))
4429 self.assert_packet_checksums_valid(packet)
4431 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4434 def test_hairpinning_unknown_proto(self):
4435 """ NAT44 translate packet with unknown protocol - hairpinning """
4436 host = self.pg0.remote_hosts[0]
4437 server = self.pg0.remote_hosts[1]
4439 server_out_port = 8765
4440 server_nat_ip = "10.0.0.11"
4442 self.nat44_add_address(self.nat_addr)
4443 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4444 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4447 # add static mapping for server
4448 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4451 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4452 IP(src=host.ip4, dst=server_nat_ip) /
4453 TCP(sport=host_in_port, dport=server_out_port))
4454 self.pg0.add_stream(p)
4455 self.pg_enable_capture(self.pg_interfaces)
4457 self.pg0.get_capture(1)
4459 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4460 IP(src=host.ip4, dst=server_nat_ip) /
4462 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4463 TCP(sport=1234, dport=1234))
4464 self.pg0.add_stream(p)
4465 self.pg_enable_capture(self.pg_interfaces)
4467 p = self.pg0.get_capture(1)
4470 self.assertEqual(packet[IP].src, self.nat_addr)
4471 self.assertEqual(packet[IP].dst, server.ip4)
4472 self.assertTrue(packet.haslayer(GRE))
4473 self.assert_packet_checksums_valid(packet)
4475 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4479 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4480 IP(src=server.ip4, dst=self.nat_addr) /
4482 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4483 TCP(sport=1234, dport=1234))
4484 self.pg0.add_stream(p)
4485 self.pg_enable_capture(self.pg_interfaces)
4487 p = self.pg0.get_capture(1)
4490 self.assertEqual(packet[IP].src, server_nat_ip)
4491 self.assertEqual(packet[IP].dst, host.ip4)
4492 self.assertTrue(packet.haslayer(GRE))
4493 self.assert_packet_checksums_valid(packet)
4495 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4498 def test_output_feature_and_service(self):
4499 """ NAT44 interface output feature and services """
4500 external_addr = '1.2.3.4'
4504 self.vapi.nat44_forwarding_enable_disable(1)
4505 self.nat44_add_address(self.nat_addr)
4506 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4507 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4508 local_port, external_port,
4509 proto=IP_PROTOS.tcp, out2in_only=1)
4510 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4511 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4513 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4516 # from client to service
4517 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4518 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4519 TCP(sport=12345, dport=external_port))
4520 self.pg1.add_stream(p)
4521 self.pg_enable_capture(self.pg_interfaces)
4523 capture = self.pg0.get_capture(1)
4528 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4529 self.assertEqual(tcp.dport, local_port)
4530 self.assert_packet_checksums_valid(p)
4532 self.logger.error(ppp("Unexpected or invalid packet:", p))
4535 # from service back to client
4536 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4537 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4538 TCP(sport=local_port, dport=12345))
4539 self.pg0.add_stream(p)
4540 self.pg_enable_capture(self.pg_interfaces)
4542 capture = self.pg1.get_capture(1)
4547 self.assertEqual(ip.src, external_addr)
4548 self.assertEqual(tcp.sport, external_port)
4549 self.assert_packet_checksums_valid(p)
4551 self.logger.error(ppp("Unexpected or invalid packet:", p))
4554 # from local network host to external network
4555 pkts = self.create_stream_in(self.pg0, self.pg1)
4556 self.pg0.add_stream(pkts)
4557 self.pg_enable_capture(self.pg_interfaces)
4559 capture = self.pg1.get_capture(len(pkts))
4560 self.verify_capture_out(capture)
4561 pkts = self.create_stream_in(self.pg0, self.pg1)
4562 self.pg0.add_stream(pkts)
4563 self.pg_enable_capture(self.pg_interfaces)
4565 capture = self.pg1.get_capture(len(pkts))
4566 self.verify_capture_out(capture)
4568 # from external network back to local network host
4569 pkts = self.create_stream_out(self.pg1)
4570 self.pg1.add_stream(pkts)
4571 self.pg_enable_capture(self.pg_interfaces)
4573 capture = self.pg0.get_capture(len(pkts))
4574 self.verify_capture_in(capture, self.pg0)
4576 def test_output_feature_and_service2(self):
4577 """ NAT44 interface output feature and service host direct access """
4578 self.vapi.nat44_forwarding_enable_disable(1)
4579 self.nat44_add_address(self.nat_addr)
4580 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4583 # session initiaded from service host - translate
4584 pkts = self.create_stream_in(self.pg0, self.pg1)
4585 self.pg0.add_stream(pkts)
4586 self.pg_enable_capture(self.pg_interfaces)
4588 capture = self.pg1.get_capture(len(pkts))
4589 self.verify_capture_out(capture)
4591 pkts = self.create_stream_out(self.pg1)
4592 self.pg1.add_stream(pkts)
4593 self.pg_enable_capture(self.pg_interfaces)
4595 capture = self.pg0.get_capture(len(pkts))
4596 self.verify_capture_in(capture, self.pg0)
4598 # session initiaded from remote host - do not translate
4599 self.tcp_port_in = 60303
4600 self.udp_port_in = 60304
4601 self.icmp_id_in = 60305
4602 pkts = self.create_stream_out(self.pg1,
4603 self.pg0.remote_ip4,
4604 use_inside_ports=True)
4605 self.pg1.add_stream(pkts)
4606 self.pg_enable_capture(self.pg_interfaces)
4608 capture = self.pg0.get_capture(len(pkts))
4609 self.verify_capture_in(capture, self.pg0)
4611 pkts = self.create_stream_in(self.pg0, self.pg1)
4612 self.pg0.add_stream(pkts)
4613 self.pg_enable_capture(self.pg_interfaces)
4615 capture = self.pg1.get_capture(len(pkts))
4616 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4619 def test_output_feature_and_service3(self):
4620 """ NAT44 interface output feature and DST NAT """
4621 external_addr = '1.2.3.4'
4625 self.vapi.nat44_forwarding_enable_disable(1)
4626 self.nat44_add_address(self.nat_addr)
4627 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4628 local_port, external_port,
4629 proto=IP_PROTOS.tcp, out2in_only=1)
4630 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4631 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4633 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4636 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4637 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4638 TCP(sport=12345, dport=external_port))
4639 self.pg0.add_stream(p)
4640 self.pg_enable_capture(self.pg_interfaces)
4642 capture = self.pg1.get_capture(1)
4647 self.assertEqual(ip.src, self.pg0.remote_ip4)
4648 self.assertEqual(tcp.sport, 12345)
4649 self.assertEqual(ip.dst, self.pg1.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.pg1.remote_mac, dst=self.pg1.local_mac) /
4657 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4658 TCP(sport=local_port, dport=12345))
4659 self.pg1.add_stream(p)
4660 self.pg_enable_capture(self.pg_interfaces)
4662 capture = self.pg0.get_capture(1)
4667 self.assertEqual(ip.src, external_addr)
4668 self.assertEqual(tcp.sport, external_port)
4669 self.assertEqual(ip.dst, self.pg0.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 test_next_src_nat(self):
4677 """ On way back forward packet to nat44-in2out node. """
4678 twice_nat_addr = '10.0.1.3'
4681 post_twice_nat_port = 0
4683 self.vapi.nat44_forwarding_enable_disable(1)
4684 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4685 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4686 local_port, external_port,
4687 proto=IP_PROTOS.tcp, out2in_only=1,
4688 self_twice_nat=1, vrf_id=1)
4689 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4692 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4693 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4694 TCP(sport=12345, dport=external_port))
4695 self.pg6.add_stream(p)
4696 self.pg_enable_capture(self.pg_interfaces)
4698 capture = self.pg6.get_capture(1)
4703 self.assertEqual(ip.src, twice_nat_addr)
4704 self.assertNotEqual(tcp.sport, 12345)
4705 post_twice_nat_port = tcp.sport
4706 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4707 self.assertEqual(tcp.dport, local_port)
4708 self.assert_packet_checksums_valid(p)
4710 self.logger.error(ppp("Unexpected or invalid packet:", p))
4713 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4714 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4715 TCP(sport=local_port, dport=post_twice_nat_port))
4716 self.pg6.add_stream(p)
4717 self.pg_enable_capture(self.pg_interfaces)
4719 capture = self.pg6.get_capture(1)
4724 self.assertEqual(ip.src, self.pg1.remote_ip4)
4725 self.assertEqual(tcp.sport, external_port)
4726 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4727 self.assertEqual(tcp.dport, 12345)
4728 self.assert_packet_checksums_valid(p)
4730 self.logger.error(ppp("Unexpected or invalid packet:", p))
4733 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4735 twice_nat_addr = '10.0.1.3'
4743 port_in1 = port_in+1
4744 port_in2 = port_in+2
4749 server1 = self.pg0.remote_hosts[0]
4750 server2 = self.pg0.remote_hosts[1]
4762 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4765 self.nat44_add_address(self.nat_addr)
4766 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4768 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4770 proto=IP_PROTOS.tcp,
4771 twice_nat=int(not self_twice_nat),
4772 self_twice_nat=int(self_twice_nat))
4774 locals = [{'addr': server1.ip4n,
4778 {'addr': server2.ip4n,
4782 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4783 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4787 not self_twice_nat),
4790 local_num=len(locals),
4792 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4793 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4800 assert client_id is not None
4802 client = self.pg0.remote_hosts[0]
4803 elif client_id == 2:
4804 client = self.pg0.remote_hosts[1]
4806 client = pg1.remote_hosts[0]
4807 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4808 IP(src=client.ip4, dst=self.nat_addr) /
4809 TCP(sport=eh_port_out, dport=port_out))
4811 self.pg_enable_capture(self.pg_interfaces)
4813 capture = pg0.get_capture(1)
4819 if ip.dst == server1.ip4:
4825 self.assertEqual(ip.dst, server.ip4)
4827 self.assertIn(tcp.dport, [port_in1, port_in2])
4829 self.assertEqual(tcp.dport, port_in)
4831 self.assertEqual(ip.src, twice_nat_addr)
4832 self.assertNotEqual(tcp.sport, eh_port_out)
4834 self.assertEqual(ip.src, client.ip4)
4835 self.assertEqual(tcp.sport, eh_port_out)
4837 eh_port_in = tcp.sport
4838 saved_port_in = tcp.dport
4839 self.assert_packet_checksums_valid(p)
4841 self.logger.error(ppp("Unexpected or invalid packet:", p))
4844 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4845 IP(src=server.ip4, dst=eh_addr_in) /
4846 TCP(sport=saved_port_in, dport=eh_port_in))
4848 self.pg_enable_capture(self.pg_interfaces)
4850 capture = pg1.get_capture(1)
4855 self.assertEqual(ip.dst, client.ip4)
4856 self.assertEqual(ip.src, self.nat_addr)
4857 self.assertEqual(tcp.dport, eh_port_out)
4858 self.assertEqual(tcp.sport, port_out)
4859 self.assert_packet_checksums_valid(p)
4861 self.logger.error(ppp("Unexpected or invalid packet:", p))
4865 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4866 self.assertEqual(len(sessions), 1)
4867 self.assertTrue(sessions[0].ext_host_valid)
4868 self.assertTrue(sessions[0].is_twicenat)
4869 self.vapi.nat44_del_session(
4870 sessions[0].inside_ip_address,
4871 sessions[0].inside_port,
4872 sessions[0].protocol,
4873 ext_host_address=sessions[0].ext_host_nat_address,
4874 ext_host_port=sessions[0].ext_host_nat_port)
4875 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4876 self.assertEqual(len(sessions), 0)
4878 def test_twice_nat(self):
4880 self.twice_nat_common()
4882 def test_self_twice_nat_positive(self):
4883 """ Self Twice NAT44 (positive test) """
4884 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4886 def test_self_twice_nat_negative(self):
4887 """ Self Twice NAT44 (negative test) """
4888 self.twice_nat_common(self_twice_nat=True)
4890 def test_twice_nat_lb(self):
4891 """ Twice NAT44 local service load balancing """
4892 self.twice_nat_common(lb=True)
4894 def test_self_twice_nat_lb_positive(self):
4895 """ Self Twice NAT44 local service load balancing (positive test) """
4896 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4899 def test_self_twice_nat_lb_negative(self):
4900 """ Self Twice NAT44 local service load balancing (negative test) """
4901 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4904 def test_twice_nat_interface_addr(self):
4905 """ Acquire twice NAT44 addresses from interface """
4906 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4908 # no address in NAT pool
4909 adresses = self.vapi.nat44_address_dump()
4910 self.assertEqual(0, len(adresses))
4912 # configure interface address and check NAT address pool
4913 self.pg3.config_ip4()
4914 adresses = self.vapi.nat44_address_dump()
4915 self.assertEqual(1, len(adresses))
4916 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4917 self.assertEqual(adresses[0].twice_nat, 1)
4919 # remove interface address and check NAT address pool
4920 self.pg3.unconfig_ip4()
4921 adresses = self.vapi.nat44_address_dump()
4922 self.assertEqual(0, len(adresses))
4924 def test_tcp_session_close_in(self):
4925 """ Close TCP session from inside network """
4926 self.tcp_port_out = 10505
4927 self.nat44_add_address(self.nat_addr)
4928 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4932 proto=IP_PROTOS.tcp,
4934 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4935 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4938 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4939 start_sessnum = len(sessions)
4941 self.initiate_tcp_session(self.pg0, self.pg1)
4943 # FIN packet in -> out
4944 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4945 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4946 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4947 flags="FA", seq=100, ack=300))
4948 self.pg0.add_stream(p)
4949 self.pg_enable_capture(self.pg_interfaces)
4951 self.pg1.get_capture(1)
4955 # ACK packet out -> in
4956 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4957 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4958 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4959 flags="A", seq=300, ack=101))
4962 # FIN packet out -> in
4963 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4964 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4965 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4966 flags="FA", seq=300, ack=101))
4969 self.pg1.add_stream(pkts)
4970 self.pg_enable_capture(self.pg_interfaces)
4972 self.pg0.get_capture(2)
4974 # ACK packet in -> out
4975 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4976 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4977 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4978 flags="A", seq=101, ack=301))
4979 self.pg0.add_stream(p)
4980 self.pg_enable_capture(self.pg_interfaces)
4982 self.pg1.get_capture(1)
4984 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4986 self.assertEqual(len(sessions) - start_sessnum, 0)
4988 def test_tcp_session_close_out(self):
4989 """ Close TCP session from outside network """
4990 self.tcp_port_out = 10505
4991 self.nat44_add_address(self.nat_addr)
4992 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4996 proto=IP_PROTOS.tcp,
4998 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4999 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5002 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5003 start_sessnum = len(sessions)
5005 self.initiate_tcp_session(self.pg0, self.pg1)
5007 # FIN packet out -> in
5008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5009 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5010 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5011 flags="FA", seq=100, ack=300))
5012 self.pg1.add_stream(p)
5013 self.pg_enable_capture(self.pg_interfaces)
5015 self.pg0.get_capture(1)
5017 # FIN+ACK packet in -> out
5018 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5019 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5020 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5021 flags="FA", seq=300, ack=101))
5023 self.pg0.add_stream(p)
5024 self.pg_enable_capture(self.pg_interfaces)
5026 self.pg1.get_capture(1)
5028 # ACK packet out -> in
5029 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5030 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5031 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5032 flags="A", seq=101, ack=301))
5033 self.pg1.add_stream(p)
5034 self.pg_enable_capture(self.pg_interfaces)
5036 self.pg0.get_capture(1)
5038 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5040 self.assertEqual(len(sessions) - start_sessnum, 0)
5042 def test_tcp_session_close_simultaneous(self):
5043 """ Close TCP session from inside network """
5044 self.tcp_port_out = 10505
5045 self.nat44_add_address(self.nat_addr)
5046 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5050 proto=IP_PROTOS.tcp,
5052 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5053 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5056 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5057 start_sessnum = len(sessions)
5059 self.initiate_tcp_session(self.pg0, self.pg1)
5061 # FIN packet in -> out
5062 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5063 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5064 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5065 flags="FA", seq=100, ack=300))
5066 self.pg0.add_stream(p)
5067 self.pg_enable_capture(self.pg_interfaces)
5069 self.pg1.get_capture(1)
5071 # FIN packet out -> in
5072 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5073 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5074 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5075 flags="FA", seq=300, ack=100))
5076 self.pg1.add_stream(p)
5077 self.pg_enable_capture(self.pg_interfaces)
5079 self.pg0.get_capture(1)
5081 # ACK packet in -> out
5082 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5083 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5084 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5085 flags="A", seq=101, ack=301))
5086 self.pg0.add_stream(p)
5087 self.pg_enable_capture(self.pg_interfaces)
5089 self.pg1.get_capture(1)
5091 # ACK packet out -> in
5092 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5093 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5094 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5095 flags="A", seq=301, ack=101))
5096 self.pg1.add_stream(p)
5097 self.pg_enable_capture(self.pg_interfaces)
5099 self.pg0.get_capture(1)
5101 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5103 self.assertEqual(len(sessions) - start_sessnum, 0)
5105 def test_one_armed_nat44_static(self):
5106 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5107 remote_host = self.pg4.remote_hosts[0]
5108 local_host = self.pg4.remote_hosts[1]
5113 self.vapi.nat44_forwarding_enable_disable(1)
5114 self.nat44_add_address(self.nat_addr, twice_nat=1)
5115 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5116 local_port, external_port,
5117 proto=IP_PROTOS.tcp, out2in_only=1,
5119 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5120 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5123 # from client to service
5124 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5125 IP(src=remote_host.ip4, dst=self.nat_addr) /
5126 TCP(sport=12345, dport=external_port))
5127 self.pg4.add_stream(p)
5128 self.pg_enable_capture(self.pg_interfaces)
5130 capture = self.pg4.get_capture(1)
5135 self.assertEqual(ip.dst, local_host.ip4)
5136 self.assertEqual(ip.src, self.nat_addr)
5137 self.assertEqual(tcp.dport, local_port)
5138 self.assertNotEqual(tcp.sport, 12345)
5139 eh_port_in = tcp.sport
5140 self.assert_packet_checksums_valid(p)
5142 self.logger.error(ppp("Unexpected or invalid packet:", p))
5145 # from service back to client
5146 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5147 IP(src=local_host.ip4, dst=self.nat_addr) /
5148 TCP(sport=local_port, dport=eh_port_in))
5149 self.pg4.add_stream(p)
5150 self.pg_enable_capture(self.pg_interfaces)
5152 capture = self.pg4.get_capture(1)
5157 self.assertEqual(ip.src, self.nat_addr)
5158 self.assertEqual(ip.dst, remote_host.ip4)
5159 self.assertEqual(tcp.sport, external_port)
5160 self.assertEqual(tcp.dport, 12345)
5161 self.assert_packet_checksums_valid(p)
5163 self.logger.error(ppp("Unexpected or invalid packet:", p))
5166 def test_static_with_port_out2(self):
5167 """ 1:1 NAPT asymmetrical rule """
5172 self.vapi.nat44_forwarding_enable_disable(1)
5173 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5174 local_port, external_port,
5175 proto=IP_PROTOS.tcp, out2in_only=1)
5176 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5177 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5180 # from client to service
5181 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5182 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5183 TCP(sport=12345, dport=external_port))
5184 self.pg1.add_stream(p)
5185 self.pg_enable_capture(self.pg_interfaces)
5187 capture = self.pg0.get_capture(1)
5192 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5193 self.assertEqual(tcp.dport, local_port)
5194 self.assert_packet_checksums_valid(p)
5196 self.logger.error(ppp("Unexpected or invalid packet:", p))
5200 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5201 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5202 ICMP(type=11) / capture[0][IP])
5203 self.pg0.add_stream(p)
5204 self.pg_enable_capture(self.pg_interfaces)
5206 capture = self.pg1.get_capture(1)
5209 self.assertEqual(p[IP].src, self.nat_addr)
5211 self.assertEqual(inner.dst, self.nat_addr)
5212 self.assertEqual(inner[TCPerror].dport, external_port)
5214 self.logger.error(ppp("Unexpected or invalid packet:", p))
5217 # from service back to client
5218 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5219 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5220 TCP(sport=local_port, dport=12345))
5221 self.pg0.add_stream(p)
5222 self.pg_enable_capture(self.pg_interfaces)
5224 capture = self.pg1.get_capture(1)
5229 self.assertEqual(ip.src, self.nat_addr)
5230 self.assertEqual(tcp.sport, external_port)
5231 self.assert_packet_checksums_valid(p)
5233 self.logger.error(ppp("Unexpected or invalid packet:", p))
5237 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5238 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5239 ICMP(type=11) / capture[0][IP])
5240 self.pg1.add_stream(p)
5241 self.pg_enable_capture(self.pg_interfaces)
5243 capture = self.pg0.get_capture(1)
5246 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5248 self.assertEqual(inner.src, self.pg0.remote_ip4)
5249 self.assertEqual(inner[TCPerror].sport, local_port)
5251 self.logger.error(ppp("Unexpected or invalid packet:", p))
5254 # from client to server (no translation)
5255 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5256 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5257 TCP(sport=12346, dport=local_port))
5258 self.pg1.add_stream(p)
5259 self.pg_enable_capture(self.pg_interfaces)
5261 capture = self.pg0.get_capture(1)
5266 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5267 self.assertEqual(tcp.dport, local_port)
5268 self.assert_packet_checksums_valid(p)
5270 self.logger.error(ppp("Unexpected or invalid packet:", p))
5273 # from service back to client (no translation)
5274 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5275 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5276 TCP(sport=local_port, dport=12346))
5277 self.pg0.add_stream(p)
5278 self.pg_enable_capture(self.pg_interfaces)
5280 capture = self.pg1.get_capture(1)
5285 self.assertEqual(ip.src, self.pg0.remote_ip4)
5286 self.assertEqual(tcp.sport, local_port)
5287 self.assert_packet_checksums_valid(p)
5289 self.logger.error(ppp("Unexpected or invalid packet:", p))
5292 def test_output_feature(self):
5293 """ NAT44 interface output feature (in2out postrouting) """
5294 self.vapi.nat44_forwarding_enable_disable(1)
5295 self.nat44_add_address(self.nat_addr)
5296 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5298 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5302 pkts = self.create_stream_in(self.pg0, self.pg1)
5303 self.pg0.add_stream(pkts)
5304 self.pg_enable_capture(self.pg_interfaces)
5306 capture = self.pg1.get_capture(len(pkts))
5307 self.verify_capture_out(capture)
5310 pkts = self.create_stream_out(self.pg1)
5311 self.pg1.add_stream(pkts)
5312 self.pg_enable_capture(self.pg_interfaces)
5314 capture = self.pg0.get_capture(len(pkts))
5315 self.verify_capture_in(capture, self.pg0)
5317 def test_multiple_vrf(self):
5318 """ Multiple VRF setup """
5319 external_addr = '1.2.3.4'
5324 self.vapi.nat44_forwarding_enable_disable(1)
5325 self.nat44_add_address(self.nat_addr)
5326 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5327 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5329 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5331 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5332 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5334 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5336 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5337 local_port, external_port, vrf_id=1,
5338 proto=IP_PROTOS.tcp, out2in_only=1)
5339 self.nat44_add_static_mapping(
5340 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5341 local_port=local_port, vrf_id=0, external_port=external_port,
5342 proto=IP_PROTOS.tcp, out2in_only=1)
5344 # from client to service (both VRF1)
5345 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5346 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5347 TCP(sport=12345, dport=external_port))
5348 self.pg6.add_stream(p)
5349 self.pg_enable_capture(self.pg_interfaces)
5351 capture = self.pg5.get_capture(1)
5356 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5357 self.assertEqual(tcp.dport, local_port)
5358 self.assert_packet_checksums_valid(p)
5360 self.logger.error(ppp("Unexpected or invalid packet:", p))
5363 # from service back to client (both VRF1)
5364 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5365 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5366 TCP(sport=local_port, dport=12345))
5367 self.pg5.add_stream(p)
5368 self.pg_enable_capture(self.pg_interfaces)
5370 capture = self.pg6.get_capture(1)
5375 self.assertEqual(ip.src, external_addr)
5376 self.assertEqual(tcp.sport, external_port)
5377 self.assert_packet_checksums_valid(p)
5379 self.logger.error(ppp("Unexpected or invalid packet:", p))
5382 # dynamic NAT from VRF1 to VRF0 (output-feature)
5383 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5384 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5385 TCP(sport=2345, dport=22))
5386 self.pg5.add_stream(p)
5387 self.pg_enable_capture(self.pg_interfaces)
5389 capture = self.pg1.get_capture(1)
5394 self.assertEqual(ip.src, self.nat_addr)
5395 self.assertNotEqual(tcp.sport, 2345)
5396 self.assert_packet_checksums_valid(p)
5399 self.logger.error(ppp("Unexpected or invalid packet:", p))
5402 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5403 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5404 TCP(sport=22, dport=port))
5405 self.pg1.add_stream(p)
5406 self.pg_enable_capture(self.pg_interfaces)
5408 capture = self.pg5.get_capture(1)
5413 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5414 self.assertEqual(tcp.dport, 2345)
5415 self.assert_packet_checksums_valid(p)
5417 self.logger.error(ppp("Unexpected or invalid packet:", p))
5420 # from client VRF1 to service VRF0
5421 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5422 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5423 TCP(sport=12346, dport=external_port))
5424 self.pg6.add_stream(p)
5425 self.pg_enable_capture(self.pg_interfaces)
5427 capture = self.pg0.get_capture(1)
5432 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5433 self.assertEqual(tcp.dport, local_port)
5434 self.assert_packet_checksums_valid(p)
5436 self.logger.error(ppp("Unexpected or invalid packet:", p))
5439 # from service VRF0 back to client VRF1
5440 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5441 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5442 TCP(sport=local_port, dport=12346))
5443 self.pg0.add_stream(p)
5444 self.pg_enable_capture(self.pg_interfaces)
5446 capture = self.pg6.get_capture(1)
5451 self.assertEqual(ip.src, self.pg0.local_ip4)
5452 self.assertEqual(tcp.sport, external_port)
5453 self.assert_packet_checksums_valid(p)
5455 self.logger.error(ppp("Unexpected or invalid packet:", p))
5458 # from client VRF0 to service VRF1
5459 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5460 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5461 TCP(sport=12347, dport=external_port))
5462 self.pg0.add_stream(p)
5463 self.pg_enable_capture(self.pg_interfaces)
5465 capture = self.pg5.get_capture(1)
5470 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5471 self.assertEqual(tcp.dport, local_port)
5472 self.assert_packet_checksums_valid(p)
5474 self.logger.error(ppp("Unexpected or invalid packet:", p))
5477 # from service VRF1 back to client VRF0
5478 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5479 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5480 TCP(sport=local_port, dport=12347))
5481 self.pg5.add_stream(p)
5482 self.pg_enable_capture(self.pg_interfaces)
5484 capture = self.pg0.get_capture(1)
5489 self.assertEqual(ip.src, external_addr)
5490 self.assertEqual(tcp.sport, external_port)
5491 self.assert_packet_checksums_valid(p)
5493 self.logger.error(ppp("Unexpected or invalid packet:", p))
5496 # from client to server (both VRF1, no translation)
5497 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5498 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5499 TCP(sport=12348, dport=local_port))
5500 self.pg6.add_stream(p)
5501 self.pg_enable_capture(self.pg_interfaces)
5503 capture = self.pg5.get_capture(1)
5508 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5509 self.assertEqual(tcp.dport, local_port)
5510 self.assert_packet_checksums_valid(p)
5512 self.logger.error(ppp("Unexpected or invalid packet:", p))
5515 # from server back to client (both VRF1, no translation)
5516 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5517 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5518 TCP(sport=local_port, dport=12348))
5519 self.pg5.add_stream(p)
5520 self.pg_enable_capture(self.pg_interfaces)
5522 capture = self.pg6.get_capture(1)
5527 self.assertEqual(ip.src, self.pg5.remote_ip4)
5528 self.assertEqual(tcp.sport, local_port)
5529 self.assert_packet_checksums_valid(p)
5531 self.logger.error(ppp("Unexpected or invalid packet:", p))
5534 # from client VRF1 to server VRF0 (no translation)
5535 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5536 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5537 TCP(sport=local_port, dport=12349))
5538 self.pg0.add_stream(p)
5539 self.pg_enable_capture(self.pg_interfaces)
5541 capture = self.pg6.get_capture(1)
5546 self.assertEqual(ip.src, self.pg0.remote_ip4)
5547 self.assertEqual(tcp.sport, local_port)
5548 self.assert_packet_checksums_valid(p)
5550 self.logger.error(ppp("Unexpected or invalid packet:", p))
5553 # from server VRF0 back to client VRF1 (no translation)
5554 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5555 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5556 TCP(sport=local_port, dport=12349))
5557 self.pg0.add_stream(p)
5558 self.pg_enable_capture(self.pg_interfaces)
5560 capture = self.pg6.get_capture(1)
5565 self.assertEqual(ip.src, self.pg0.remote_ip4)
5566 self.assertEqual(tcp.sport, local_port)
5567 self.assert_packet_checksums_valid(p)
5569 self.logger.error(ppp("Unexpected or invalid packet:", p))
5572 # from client VRF0 to server VRF1 (no translation)
5573 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5574 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5575 TCP(sport=12344, dport=local_port))
5576 self.pg0.add_stream(p)
5577 self.pg_enable_capture(self.pg_interfaces)
5579 capture = self.pg5.get_capture(1)
5584 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5585 self.assertEqual(tcp.dport, local_port)
5586 self.assert_packet_checksums_valid(p)
5588 self.logger.error(ppp("Unexpected or invalid packet:", p))
5591 # from server VRF1 back to client VRF0 (no translation)
5592 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5593 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5594 TCP(sport=local_port, dport=12344))
5595 self.pg5.add_stream(p)
5596 self.pg_enable_capture(self.pg_interfaces)
5598 capture = self.pg0.get_capture(1)
5603 self.assertEqual(ip.src, self.pg5.remote_ip4)
5604 self.assertEqual(tcp.sport, local_port)
5605 self.assert_packet_checksums_valid(p)
5607 self.logger.error(ppp("Unexpected or invalid packet:", p))
5610 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5611 def test_session_timeout(self):
5612 """ NAT44 session timeouts """
5613 self.nat44_add_address(self.nat_addr)
5614 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5615 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5617 self.vapi.nat_set_timeouts(icmp=5)
5621 for i in range(0, max_sessions):
5622 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5623 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5624 IP(src=src, dst=self.pg1.remote_ip4) /
5625 ICMP(id=1025, type='echo-request'))
5627 self.pg0.add_stream(pkts)
5628 self.pg_enable_capture(self.pg_interfaces)
5630 self.pg1.get_capture(max_sessions)
5635 for i in range(0, max_sessions):
5636 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5637 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5638 IP(src=src, dst=self.pg1.remote_ip4) /
5639 ICMP(id=1026, type='echo-request'))
5641 self.pg0.add_stream(pkts)
5642 self.pg_enable_capture(self.pg_interfaces)
5644 self.pg1.get_capture(max_sessions)
5647 users = self.vapi.nat44_user_dump()
5649 nsessions = nsessions + user.nsessions
5650 self.assertLess(nsessions, 2 * max_sessions)
5652 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5653 def test_session_limit_per_user(self):
5654 """ Maximum sessions per user limit """
5655 self.nat44_add_address(self.nat_addr)
5656 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5657 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5659 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5660 src_address=self.pg2.local_ip4n,
5662 template_interval=10)
5663 self.vapi.nat_set_timeouts(udp=5)
5665 # get maximum number of translations per user
5666 nat44_config = self.vapi.nat_show_config()
5669 for port in range(0, nat44_config.max_translations_per_user):
5670 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5671 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5672 UDP(sport=1025 + port, dport=1025 + port))
5675 self.pg0.add_stream(pkts)
5676 self.pg_enable_capture(self.pg_interfaces)
5678 capture = self.pg1.get_capture(len(pkts))
5680 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5681 src_port=self.ipfix_src_port)
5683 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5684 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5685 UDP(sport=3001, dport=3002))
5686 self.pg0.add_stream(p)
5687 self.pg_enable_capture(self.pg_interfaces)
5689 capture = self.pg1.assert_nothing_captured()
5691 # verify IPFIX logging
5692 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5694 capture = self.pg2.get_capture(10)
5695 ipfix = IPFIXDecoder()
5696 # first load template
5698 self.assertTrue(p.haslayer(IPFIX))
5699 if p.haslayer(Template):
5700 ipfix.add_template(p.getlayer(Template))
5701 # verify events in data set
5703 if p.haslayer(Data):
5704 data = ipfix.decode_data_set(p.getlayer(Set))
5705 self.verify_ipfix_max_entries_per_user(
5707 nat44_config.max_translations_per_user,
5708 self.pg0.remote_ip4n)
5711 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5712 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5713 UDP(sport=3001, dport=3002))
5714 self.pg0.add_stream(p)
5715 self.pg_enable_capture(self.pg_interfaces)
5717 self.pg1.get_capture(1)
5720 super(TestNAT44EndpointDependent, self).tearDown()
5721 if not self.vpp_dead:
5722 self.logger.info(self.vapi.cli("show nat44 addresses"))
5723 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5724 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5725 self.logger.info(self.vapi.cli("show nat44 interface address"))
5726 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5727 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5728 self.logger.info(self.vapi.cli("show nat timeouts"))
5730 self.vapi.cli("clear logging")
5733 class TestNAT44Out2InDPO(MethodHolder):
5734 """ NAT44 Test Cases using out2in DPO """
5737 def setUpConstants(cls):
5738 super(TestNAT44Out2InDPO, cls).setUpConstants()
5739 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5742 def setUpClass(cls):
5743 super(TestNAT44Out2InDPO, cls).setUpClass()
5744 cls.vapi.cli("set log class nat level debug")
5747 cls.tcp_port_in = 6303
5748 cls.tcp_port_out = 6303
5749 cls.udp_port_in = 6304
5750 cls.udp_port_out = 6304
5751 cls.icmp_id_in = 6305
5752 cls.icmp_id_out = 6305
5753 cls.nat_addr = '10.0.0.3'
5754 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5755 cls.dst_ip4 = '192.168.70.1'
5757 cls.create_pg_interfaces(range(2))
5760 cls.pg0.config_ip4()
5761 cls.pg0.resolve_arp()
5764 cls.pg1.config_ip6()
5765 cls.pg1.resolve_ndp()
5767 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5768 dst_address_length=0,
5769 next_hop_address=cls.pg1.remote_ip6n,
5770 next_hop_sw_if_index=cls.pg1.sw_if_index)
5773 super(TestNAT44Out2InDPO, cls).tearDownClass()
5776 def configure_xlat(self):
5777 self.dst_ip6_pfx = '1:2:3::'
5778 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5780 self.dst_ip6_pfx_len = 96
5781 self.src_ip6_pfx = '4:5:6::'
5782 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5784 self.src_ip6_pfx_len = 96
5785 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5786 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5787 '\x00\x00\x00\x00', 0, is_translation=1,
5790 def test_464xlat_ce(self):
5791 """ Test 464XLAT CE with NAT44 """
5793 nat_config = self.vapi.nat_show_config()
5794 self.assertEqual(1, nat_config.out2in_dpo)
5796 self.configure_xlat()
5798 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5799 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5801 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5802 self.dst_ip6_pfx_len)
5803 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5804 self.src_ip6_pfx_len)
5807 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5808 self.pg0.add_stream(pkts)
5809 self.pg_enable_capture(self.pg_interfaces)
5811 capture = self.pg1.get_capture(len(pkts))
5812 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5815 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5817 self.pg1.add_stream(pkts)
5818 self.pg_enable_capture(self.pg_interfaces)
5820 capture = self.pg0.get_capture(len(pkts))
5821 self.verify_capture_in(capture, self.pg0)
5823 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5825 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5826 self.nat_addr_n, is_add=0)
5828 def test_464xlat_ce_no_nat(self):
5829 """ Test 464XLAT CE without NAT44 """
5831 self.configure_xlat()
5833 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5834 self.dst_ip6_pfx_len)
5835 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5836 self.src_ip6_pfx_len)
5838 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5839 self.pg0.add_stream(pkts)
5840 self.pg_enable_capture(self.pg_interfaces)
5842 capture = self.pg1.get_capture(len(pkts))
5843 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5844 nat_ip=out_dst_ip6, same_port=True)
5846 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5847 self.pg1.add_stream(pkts)
5848 self.pg_enable_capture(self.pg_interfaces)
5850 capture = self.pg0.get_capture(len(pkts))
5851 self.verify_capture_in(capture, self.pg0)
5854 class TestDeterministicNAT(MethodHolder):
5855 """ Deterministic NAT Test Cases """
5858 def setUpConstants(cls):
5859 super(TestDeterministicNAT, cls).setUpConstants()
5860 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5863 def setUpClass(cls):
5864 super(TestDeterministicNAT, cls).setUpClass()
5865 cls.vapi.cli("set log class nat level debug")
5868 cls.tcp_port_in = 6303
5869 cls.tcp_external_port = 6303
5870 cls.udp_port_in = 6304
5871 cls.udp_external_port = 6304
5872 cls.icmp_id_in = 6305
5873 cls.nat_addr = '10.0.0.3'
5875 cls.create_pg_interfaces(range(3))
5876 cls.interfaces = list(cls.pg_interfaces)
5878 for i in cls.interfaces:
5883 cls.pg0.generate_remote_hosts(2)
5884 cls.pg0.configure_ipv4_neighbors()
5887 super(TestDeterministicNAT, cls).tearDownClass()
5890 def create_stream_in(self, in_if, out_if, ttl=64):
5892 Create packet stream for inside network
5894 :param in_if: Inside interface
5895 :param out_if: Outside interface
5896 :param ttl: TTL of generated packets
5900 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5901 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5902 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5906 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5907 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5908 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5912 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5913 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5914 ICMP(id=self.icmp_id_in, type='echo-request'))
5919 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5921 Create packet stream for outside network
5923 :param out_if: Outside interface
5924 :param dst_ip: Destination IP address (Default use global NAT address)
5925 :param ttl: TTL of generated packets
5928 dst_ip = self.nat_addr
5931 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5932 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5933 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
5937 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5938 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5939 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
5943 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5944 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5945 ICMP(id=self.icmp_external_id, type='echo-reply'))
5950 def verify_capture_out(self, capture, nat_ip=None):
5952 Verify captured packets on outside network
5954 :param capture: Captured packets
5955 :param nat_ip: Translated IP address (Default use global NAT address)
5956 :param same_port: Sorce port number is not translated (Default False)
5959 nat_ip = self.nat_addr
5960 for packet in capture:
5962 self.assertEqual(packet[IP].src, nat_ip)
5963 if packet.haslayer(TCP):
5964 self.tcp_port_out = packet[TCP].sport
5965 elif packet.haslayer(UDP):
5966 self.udp_port_out = packet[UDP].sport
5968 self.icmp_external_id = packet[ICMP].id
5970 self.logger.error(ppp("Unexpected or invalid packet "
5971 "(outside network):", packet))
5974 def test_deterministic_mode(self):
5975 """ NAT plugin run deterministic mode """
5976 in_addr = '172.16.255.0'
5977 out_addr = '172.17.255.50'
5978 in_addr_t = '172.16.255.20'
5979 in_addr_n = socket.inet_aton(in_addr)
5980 out_addr_n = socket.inet_aton(out_addr)
5981 in_addr_t_n = socket.inet_aton(in_addr_t)
5985 nat_config = self.vapi.nat_show_config()
5986 self.assertEqual(1, nat_config.deterministic)
5988 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
5990 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
5991 self.assertEqual(rep1.out_addr[:4], out_addr_n)
5992 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
5993 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5995 deterministic_mappings = self.vapi.nat_det_map_dump()
5996 self.assertEqual(len(deterministic_mappings), 1)
5997 dsm = deterministic_mappings[0]
5998 self.assertEqual(in_addr_n, dsm.in_addr[:4])
5999 self.assertEqual(in_plen, dsm.in_plen)
6000 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6001 self.assertEqual(out_plen, dsm.out_plen)
6003 self.clear_nat_det()
6004 deterministic_mappings = self.vapi.nat_det_map_dump()
6005 self.assertEqual(len(deterministic_mappings), 0)
6007 def test_set_timeouts(self):
6008 """ Set deterministic NAT timeouts """
6009 timeouts_before = self.vapi.nat_get_timeouts()
6011 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6012 timeouts_before.tcp_established + 10,
6013 timeouts_before.tcp_transitory + 10,
6014 timeouts_before.icmp + 10)
6016 timeouts_after = self.vapi.nat_get_timeouts()
6018 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6019 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6020 self.assertNotEqual(timeouts_before.tcp_established,
6021 timeouts_after.tcp_established)
6022 self.assertNotEqual(timeouts_before.tcp_transitory,
6023 timeouts_after.tcp_transitory)
6025 def test_det_in(self):
6026 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6028 nat_ip = "10.0.0.10"
6030 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6032 socket.inet_aton(nat_ip),
6034 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6035 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6039 pkts = self.create_stream_in(self.pg0, self.pg1)
6040 self.pg0.add_stream(pkts)
6041 self.pg_enable_capture(self.pg_interfaces)
6043 capture = self.pg1.get_capture(len(pkts))
6044 self.verify_capture_out(capture, nat_ip)
6047 pkts = self.create_stream_out(self.pg1, nat_ip)
6048 self.pg1.add_stream(pkts)
6049 self.pg_enable_capture(self.pg_interfaces)
6051 capture = self.pg0.get_capture(len(pkts))
6052 self.verify_capture_in(capture, self.pg0)
6055 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6056 self.assertEqual(len(sessions), 3)
6060 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6061 self.assertEqual(s.in_port, self.tcp_port_in)
6062 self.assertEqual(s.out_port, self.tcp_port_out)
6063 self.assertEqual(s.ext_port, self.tcp_external_port)
6067 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6068 self.assertEqual(s.in_port, self.udp_port_in)
6069 self.assertEqual(s.out_port, self.udp_port_out)
6070 self.assertEqual(s.ext_port, self.udp_external_port)
6074 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6075 self.assertEqual(s.in_port, self.icmp_id_in)
6076 self.assertEqual(s.out_port, self.icmp_external_id)
6078 def test_multiple_users(self):
6079 """ Deterministic NAT multiple users """
6081 nat_ip = "10.0.0.10"
6083 external_port = 6303
6085 host0 = self.pg0.remote_hosts[0]
6086 host1 = self.pg0.remote_hosts[1]
6088 self.vapi.nat_det_add_del_map(host0.ip4n,
6090 socket.inet_aton(nat_ip),
6092 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6093 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6097 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6098 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6099 TCP(sport=port_in, dport=external_port))
6100 self.pg0.add_stream(p)
6101 self.pg_enable_capture(self.pg_interfaces)
6103 capture = self.pg1.get_capture(1)
6108 self.assertEqual(ip.src, nat_ip)
6109 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6110 self.assertEqual(tcp.dport, external_port)
6111 port_out0 = tcp.sport
6113 self.logger.error(ppp("Unexpected or invalid packet:", p))
6117 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6118 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6119 TCP(sport=port_in, dport=external_port))
6120 self.pg0.add_stream(p)
6121 self.pg_enable_capture(self.pg_interfaces)
6123 capture = self.pg1.get_capture(1)
6128 self.assertEqual(ip.src, nat_ip)
6129 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6130 self.assertEqual(tcp.dport, external_port)
6131 port_out1 = tcp.sport
6133 self.logger.error(ppp("Unexpected or invalid packet:", p))
6136 dms = self.vapi.nat_det_map_dump()
6137 self.assertEqual(1, len(dms))
6138 self.assertEqual(2, dms[0].ses_num)
6141 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6142 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6143 TCP(sport=external_port, dport=port_out0))
6144 self.pg1.add_stream(p)
6145 self.pg_enable_capture(self.pg_interfaces)
6147 capture = self.pg0.get_capture(1)
6152 self.assertEqual(ip.src, self.pg1.remote_ip4)
6153 self.assertEqual(ip.dst, host0.ip4)
6154 self.assertEqual(tcp.dport, port_in)
6155 self.assertEqual(tcp.sport, external_port)
6157 self.logger.error(ppp("Unexpected or invalid packet:", p))
6161 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6162 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6163 TCP(sport=external_port, dport=port_out1))
6164 self.pg1.add_stream(p)
6165 self.pg_enable_capture(self.pg_interfaces)
6167 capture = self.pg0.get_capture(1)
6172 self.assertEqual(ip.src, self.pg1.remote_ip4)
6173 self.assertEqual(ip.dst, host1.ip4)
6174 self.assertEqual(tcp.dport, port_in)
6175 self.assertEqual(tcp.sport, external_port)
6177 self.logger.error(ppp("Unexpected or invalid packet", p))
6180 # session close api test
6181 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6183 self.pg1.remote_ip4n,
6185 dms = self.vapi.nat_det_map_dump()
6186 self.assertEqual(dms[0].ses_num, 1)
6188 self.vapi.nat_det_close_session_in(host0.ip4n,
6190 self.pg1.remote_ip4n,
6192 dms = self.vapi.nat_det_map_dump()
6193 self.assertEqual(dms[0].ses_num, 0)
6195 def test_tcp_session_close_detection_in(self):
6196 """ Deterministic NAT TCP session close from inside network """
6197 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6199 socket.inet_aton(self.nat_addr),
6201 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6202 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6205 self.initiate_tcp_session(self.pg0, self.pg1)
6207 # close the session from inside
6209 # FIN packet in -> out
6210 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6211 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6212 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6214 self.pg0.add_stream(p)
6215 self.pg_enable_capture(self.pg_interfaces)
6217 self.pg1.get_capture(1)
6221 # ACK packet out -> in
6222 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6223 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6224 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6228 # FIN packet out -> in
6229 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6230 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6231 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6235 self.pg1.add_stream(pkts)
6236 self.pg_enable_capture(self.pg_interfaces)
6238 self.pg0.get_capture(2)
6240 # ACK packet in -> out
6241 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6242 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6243 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6245 self.pg0.add_stream(p)
6246 self.pg_enable_capture(self.pg_interfaces)
6248 self.pg1.get_capture(1)
6250 # Check if deterministic NAT44 closed the session
6251 dms = self.vapi.nat_det_map_dump()
6252 self.assertEqual(0, dms[0].ses_num)
6254 self.logger.error("TCP session termination failed")
6257 def test_tcp_session_close_detection_out(self):
6258 """ Deterministic NAT TCP session close from outside network """
6259 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6261 socket.inet_aton(self.nat_addr),
6263 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6264 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6267 self.initiate_tcp_session(self.pg0, self.pg1)
6269 # close the session from outside
6271 # FIN packet out -> in
6272 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6273 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6274 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6276 self.pg1.add_stream(p)
6277 self.pg_enable_capture(self.pg_interfaces)
6279 self.pg0.get_capture(1)
6283 # ACK packet in -> out
6284 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6285 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6286 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6290 # ACK packet in -> out
6291 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6292 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6293 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6297 self.pg0.add_stream(pkts)
6298 self.pg_enable_capture(self.pg_interfaces)
6300 self.pg1.get_capture(2)
6302 # ACK packet out -> in
6303 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6304 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6305 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6307 self.pg1.add_stream(p)
6308 self.pg_enable_capture(self.pg_interfaces)
6310 self.pg0.get_capture(1)
6312 # Check if deterministic NAT44 closed the session
6313 dms = self.vapi.nat_det_map_dump()
6314 self.assertEqual(0, dms[0].ses_num)
6316 self.logger.error("TCP session termination failed")
6319 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6320 def test_session_timeout(self):
6321 """ Deterministic NAT session timeouts """
6322 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6324 socket.inet_aton(self.nat_addr),
6326 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6327 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6330 self.initiate_tcp_session(self.pg0, self.pg1)
6331 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6332 pkts = self.create_stream_in(self.pg0, self.pg1)
6333 self.pg0.add_stream(pkts)
6334 self.pg_enable_capture(self.pg_interfaces)
6336 capture = self.pg1.get_capture(len(pkts))
6339 dms = self.vapi.nat_det_map_dump()
6340 self.assertEqual(0, dms[0].ses_num)
6342 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6343 def test_session_limit_per_user(self):
6344 """ Deterministic NAT maximum sessions per user limit """
6345 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6347 socket.inet_aton(self.nat_addr),
6349 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6350 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6352 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6353 src_address=self.pg2.local_ip4n,
6355 template_interval=10)
6356 self.vapi.nat_ipfix()
6359 for port in range(1025, 2025):
6360 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6361 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6362 UDP(sport=port, dport=port))
6365 self.pg0.add_stream(pkts)
6366 self.pg_enable_capture(self.pg_interfaces)
6368 capture = self.pg1.get_capture(len(pkts))
6370 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6371 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6372 UDP(sport=3001, dport=3002))
6373 self.pg0.add_stream(p)
6374 self.pg_enable_capture(self.pg_interfaces)
6376 capture = self.pg1.assert_nothing_captured()
6378 # verify ICMP error packet
6379 capture = self.pg0.get_capture(1)
6381 self.assertTrue(p.haslayer(ICMP))
6383 self.assertEqual(icmp.type, 3)
6384 self.assertEqual(icmp.code, 1)
6385 self.assertTrue(icmp.haslayer(IPerror))
6386 inner_ip = icmp[IPerror]
6387 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6388 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6390 dms = self.vapi.nat_det_map_dump()
6392 self.assertEqual(1000, dms[0].ses_num)
6394 # verify IPFIX logging
6395 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6397 capture = self.pg2.get_capture(2)
6398 ipfix = IPFIXDecoder()
6399 # first load template
6401 self.assertTrue(p.haslayer(IPFIX))
6402 if p.haslayer(Template):
6403 ipfix.add_template(p.getlayer(Template))
6404 # verify events in data set
6406 if p.haslayer(Data):
6407 data = ipfix.decode_data_set(p.getlayer(Set))
6408 self.verify_ipfix_max_entries_per_user(data,
6410 self.pg0.remote_ip4n)
6412 def clear_nat_det(self):
6414 Clear deterministic NAT configuration.
6416 self.vapi.nat_ipfix(enable=0)
6417 self.vapi.nat_set_timeouts()
6418 deterministic_mappings = self.vapi.nat_det_map_dump()
6419 for dsm in deterministic_mappings:
6420 self.vapi.nat_det_add_del_map(dsm.in_addr,
6426 interfaces = self.vapi.nat44_interface_dump()
6427 for intf in interfaces:
6428 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6433 super(TestDeterministicNAT, self).tearDown()
6434 if not self.vpp_dead:
6435 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6436 self.logger.info(self.vapi.cli("show nat timeouts"))
6438 self.vapi.cli("show nat44 deterministic mappings"))
6440 self.vapi.cli("show nat44 deterministic sessions"))
6441 self.clear_nat_det()
6444 class TestNAT64(MethodHolder):
6445 """ NAT64 Test Cases """
6448 def setUpConstants(cls):
6449 super(TestNAT64, cls).setUpConstants()
6450 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6451 "nat64 st hash buckets 256", "}"])
6454 def setUpClass(cls):
6455 super(TestNAT64, cls).setUpClass()
6458 cls.tcp_port_in = 6303
6459 cls.tcp_port_out = 6303
6460 cls.udp_port_in = 6304
6461 cls.udp_port_out = 6304
6462 cls.icmp_id_in = 6305
6463 cls.icmp_id_out = 6305
6464 cls.nat_addr = '10.0.0.3'
6465 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6467 cls.vrf1_nat_addr = '10.0.10.3'
6468 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6470 cls.ipfix_src_port = 4739
6471 cls.ipfix_domain_id = 1
6473 cls.create_pg_interfaces(range(6))
6474 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6475 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6476 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6478 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6480 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6482 cls.pg0.generate_remote_hosts(2)
6484 for i in cls.ip6_interfaces:
6487 i.configure_ipv6_neighbors()
6489 for i in cls.ip4_interfaces:
6495 cls.pg3.config_ip4()
6496 cls.pg3.resolve_arp()
6497 cls.pg3.config_ip6()
6498 cls.pg3.configure_ipv6_neighbors()
6501 cls.pg5.config_ip6()
6504 super(TestNAT64, cls).tearDownClass()
6507 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6508 """ NAT64 inside interface handles Neighbor Advertisement """
6510 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6513 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6514 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6515 ICMPv6EchoRequest())
6517 self.pg5.add_stream(pkts)
6518 self.pg_enable_capture(self.pg_interfaces)
6521 # Wait for Neighbor Solicitation
6522 capture = self.pg5.get_capture(len(pkts))
6525 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6526 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6527 tgt = packet[ICMPv6ND_NS].tgt
6529 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6532 # Send Neighbor Advertisement
6533 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6534 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6535 ICMPv6ND_NA(tgt=tgt) /
6536 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6538 self.pg5.add_stream(pkts)
6539 self.pg_enable_capture(self.pg_interfaces)
6542 # Try to send ping again
6544 self.pg5.add_stream(pkts)
6545 self.pg_enable_capture(self.pg_interfaces)
6548 # Wait for ping reply
6549 capture = self.pg5.get_capture(len(pkts))
6552 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6553 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6554 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6556 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6559 def test_pool(self):
6560 """ Add/delete address to NAT64 pool """
6561 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6563 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6565 addresses = self.vapi.nat64_pool_addr_dump()
6566 self.assertEqual(len(addresses), 1)
6567 self.assertEqual(addresses[0].address, nat_addr)
6569 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6571 addresses = self.vapi.nat64_pool_addr_dump()
6572 self.assertEqual(len(addresses), 0)
6574 def test_interface(self):
6575 """ Enable/disable NAT64 feature on the interface """
6576 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6577 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6579 interfaces = self.vapi.nat64_interface_dump()
6580 self.assertEqual(len(interfaces), 2)
6583 for intf in interfaces:
6584 if intf.sw_if_index == self.pg0.sw_if_index:
6585 self.assertEqual(intf.is_inside, 1)
6587 elif intf.sw_if_index == self.pg1.sw_if_index:
6588 self.assertEqual(intf.is_inside, 0)
6590 self.assertTrue(pg0_found)
6591 self.assertTrue(pg1_found)
6593 features = self.vapi.cli("show interface features pg0")
6594 self.assertNotEqual(features.find('nat64-in2out'), -1)
6595 features = self.vapi.cli("show interface features pg1")
6596 self.assertNotEqual(features.find('nat64-out2in'), -1)
6598 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6599 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6601 interfaces = self.vapi.nat64_interface_dump()
6602 self.assertEqual(len(interfaces), 0)
6604 def test_static_bib(self):
6605 """ Add/delete static BIB entry """
6606 in_addr = socket.inet_pton(socket.AF_INET6,
6607 '2001:db8:85a3::8a2e:370:7334')
6608 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6611 proto = IP_PROTOS.tcp
6613 self.vapi.nat64_add_del_static_bib(in_addr,
6618 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6623 self.assertEqual(bibe.i_addr, in_addr)
6624 self.assertEqual(bibe.o_addr, out_addr)
6625 self.assertEqual(bibe.i_port, in_port)
6626 self.assertEqual(bibe.o_port, out_port)
6627 self.assertEqual(static_bib_num, 1)
6629 self.vapi.nat64_add_del_static_bib(in_addr,
6635 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6640 self.assertEqual(static_bib_num, 0)
6642 def test_set_timeouts(self):
6643 """ Set NAT64 timeouts """
6644 # verify default values
6645 timeouts = self.vapi.nat_get_timeouts()
6646 self.assertEqual(timeouts.udp, 300)
6647 self.assertEqual(timeouts.icmp, 60)
6648 self.assertEqual(timeouts.tcp_transitory, 240)
6649 self.assertEqual(timeouts.tcp_established, 7440)
6651 # set and verify custom values
6652 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6653 tcp_established=7450)
6654 timeouts = self.vapi.nat_get_timeouts()
6655 self.assertEqual(timeouts.udp, 200)
6656 self.assertEqual(timeouts.icmp, 30)
6657 self.assertEqual(timeouts.tcp_transitory, 250)
6658 self.assertEqual(timeouts.tcp_established, 7450)
6660 def test_dynamic(self):
6661 """ NAT64 dynamic translation test """
6662 self.tcp_port_in = 6303
6663 self.udp_port_in = 6304
6664 self.icmp_id_in = 6305
6666 ses_num_start = self.nat64_get_ses_num()
6668 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6670 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6671 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6674 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6675 self.pg0.add_stream(pkts)
6676 self.pg_enable_capture(self.pg_interfaces)
6678 capture = self.pg1.get_capture(len(pkts))
6679 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6680 dst_ip=self.pg1.remote_ip4)
6683 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6684 self.pg1.add_stream(pkts)
6685 self.pg_enable_capture(self.pg_interfaces)
6687 capture = self.pg0.get_capture(len(pkts))
6688 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6689 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6692 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6693 self.pg0.add_stream(pkts)
6694 self.pg_enable_capture(self.pg_interfaces)
6696 capture = self.pg1.get_capture(len(pkts))
6697 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6698 dst_ip=self.pg1.remote_ip4)
6701 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6702 self.pg1.add_stream(pkts)
6703 self.pg_enable_capture(self.pg_interfaces)
6705 capture = self.pg0.get_capture(len(pkts))
6706 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6708 ses_num_end = self.nat64_get_ses_num()
6710 self.assertEqual(ses_num_end - ses_num_start, 3)
6712 # tenant with specific VRF
6713 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6714 self.vrf1_nat_addr_n,
6715 vrf_id=self.vrf1_id)
6716 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6718 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6719 self.pg2.add_stream(pkts)
6720 self.pg_enable_capture(self.pg_interfaces)
6722 capture = self.pg1.get_capture(len(pkts))
6723 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6724 dst_ip=self.pg1.remote_ip4)
6726 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6727 self.pg1.add_stream(pkts)
6728 self.pg_enable_capture(self.pg_interfaces)
6730 capture = self.pg2.get_capture(len(pkts))
6731 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6733 def test_static(self):
6734 """ NAT64 static translation test """
6735 self.tcp_port_in = 60303
6736 self.udp_port_in = 60304
6737 self.icmp_id_in = 60305
6738 self.tcp_port_out = 60303
6739 self.udp_port_out = 60304
6740 self.icmp_id_out = 60305
6742 ses_num_start = self.nat64_get_ses_num()
6744 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6746 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6747 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6749 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6754 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6759 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6766 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6767 self.pg0.add_stream(pkts)
6768 self.pg_enable_capture(self.pg_interfaces)
6770 capture = self.pg1.get_capture(len(pkts))
6771 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6772 dst_ip=self.pg1.remote_ip4, same_port=True)
6775 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6776 self.pg1.add_stream(pkts)
6777 self.pg_enable_capture(self.pg_interfaces)
6779 capture = self.pg0.get_capture(len(pkts))
6780 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6781 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6783 ses_num_end = self.nat64_get_ses_num()
6785 self.assertEqual(ses_num_end - ses_num_start, 3)
6787 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6788 def test_session_timeout(self):
6789 """ NAT64 session timeout """
6790 self.icmp_id_in = 1234
6791 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6793 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6794 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6795 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6797 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6798 self.pg0.add_stream(pkts)
6799 self.pg_enable_capture(self.pg_interfaces)
6801 capture = self.pg1.get_capture(len(pkts))
6803 ses_num_before_timeout = self.nat64_get_ses_num()
6807 # ICMP and TCP session after timeout
6808 ses_num_after_timeout = self.nat64_get_ses_num()
6809 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6811 def test_icmp_error(self):
6812 """ NAT64 ICMP Error message translation """
6813 self.tcp_port_in = 6303
6814 self.udp_port_in = 6304
6815 self.icmp_id_in = 6305
6817 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6819 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6820 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6822 # send some packets to create sessions
6823 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6824 self.pg0.add_stream(pkts)
6825 self.pg_enable_capture(self.pg_interfaces)
6827 capture_ip4 = self.pg1.get_capture(len(pkts))
6828 self.verify_capture_out(capture_ip4,
6829 nat_ip=self.nat_addr,
6830 dst_ip=self.pg1.remote_ip4)
6832 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6833 self.pg1.add_stream(pkts)
6834 self.pg_enable_capture(self.pg_interfaces)
6836 capture_ip6 = self.pg0.get_capture(len(pkts))
6837 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6838 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6839 self.pg0.remote_ip6)
6842 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6843 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6844 ICMPv6DestUnreach(code=1) /
6845 packet[IPv6] for packet in capture_ip6]
6846 self.pg0.add_stream(pkts)
6847 self.pg_enable_capture(self.pg_interfaces)
6849 capture = self.pg1.get_capture(len(pkts))
6850 for packet in capture:
6852 self.assertEqual(packet[IP].src, self.nat_addr)
6853 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6854 self.assertEqual(packet[ICMP].type, 3)
6855 self.assertEqual(packet[ICMP].code, 13)
6856 inner = packet[IPerror]
6857 self.assertEqual(inner.src, self.pg1.remote_ip4)
6858 self.assertEqual(inner.dst, self.nat_addr)
6859 self.assert_packet_checksums_valid(packet)
6860 if inner.haslayer(TCPerror):
6861 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6862 elif inner.haslayer(UDPerror):
6863 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6865 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6867 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6871 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6872 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6873 ICMP(type=3, code=13) /
6874 packet[IP] for packet in capture_ip4]
6875 self.pg1.add_stream(pkts)
6876 self.pg_enable_capture(self.pg_interfaces)
6878 capture = self.pg0.get_capture(len(pkts))
6879 for packet in capture:
6881 self.assertEqual(packet[IPv6].src, ip.src)
6882 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6883 icmp = packet[ICMPv6DestUnreach]
6884 self.assertEqual(icmp.code, 1)
6885 inner = icmp[IPerror6]
6886 self.assertEqual(inner.src, self.pg0.remote_ip6)
6887 self.assertEqual(inner.dst, ip.src)
6888 self.assert_icmpv6_checksum_valid(packet)
6889 if inner.haslayer(TCPerror):
6890 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6891 elif inner.haslayer(UDPerror):
6892 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6894 self.assertEqual(inner[ICMPv6EchoRequest].id,
6897 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6900 def test_hairpinning(self):
6901 """ NAT64 hairpinning """
6903 client = self.pg0.remote_hosts[0]
6904 server = self.pg0.remote_hosts[1]
6905 server_tcp_in_port = 22
6906 server_tcp_out_port = 4022
6907 server_udp_in_port = 23
6908 server_udp_out_port = 4023
6909 client_tcp_in_port = 1234
6910 client_udp_in_port = 1235
6911 client_tcp_out_port = 0
6912 client_udp_out_port = 0
6913 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6914 nat_addr_ip6 = ip.src
6916 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6918 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6919 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6921 self.vapi.nat64_add_del_static_bib(server.ip6n,
6924 server_tcp_out_port,
6926 self.vapi.nat64_add_del_static_bib(server.ip6n,
6929 server_udp_out_port,
6934 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6935 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6936 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6938 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6939 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6940 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6942 self.pg0.add_stream(pkts)
6943 self.pg_enable_capture(self.pg_interfaces)
6945 capture = self.pg0.get_capture(len(pkts))
6946 for packet in capture:
6948 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6949 self.assertEqual(packet[IPv6].dst, server.ip6)
6950 self.assert_packet_checksums_valid(packet)
6951 if packet.haslayer(TCP):
6952 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6953 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
6954 client_tcp_out_port = packet[TCP].sport
6956 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6957 self.assertEqual(packet[UDP].dport, server_udp_in_port)
6958 client_udp_out_port = packet[UDP].sport
6960 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6965 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6966 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6967 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6969 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6970 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6971 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6973 self.pg0.add_stream(pkts)
6974 self.pg_enable_capture(self.pg_interfaces)
6976 capture = self.pg0.get_capture(len(pkts))
6977 for packet in capture:
6979 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6980 self.assertEqual(packet[IPv6].dst, client.ip6)
6981 self.assert_packet_checksums_valid(packet)
6982 if packet.haslayer(TCP):
6983 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6984 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
6986 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6987 self.assertEqual(packet[UDP].dport, client_udp_in_port)
6989 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6994 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6995 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6996 ICMPv6DestUnreach(code=1) /
6997 packet[IPv6] for packet in capture]
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, server.ip6)
7006 icmp = packet[ICMPv6DestUnreach]
7007 self.assertEqual(icmp.code, 1)
7008 inner = icmp[IPerror6]
7009 self.assertEqual(inner.src, server.ip6)
7010 self.assertEqual(inner.dst, nat_addr_ip6)
7011 self.assert_packet_checksums_valid(packet)
7012 if inner.haslayer(TCPerror):
7013 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7014 self.assertEqual(inner[TCPerror].dport,
7015 client_tcp_out_port)
7017 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7018 self.assertEqual(inner[UDPerror].dport,
7019 client_udp_out_port)
7021 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7024 def test_prefix(self):
7025 """ NAT64 Network-Specific Prefix """
7027 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7029 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7030 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7031 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7032 self.vrf1_nat_addr_n,
7033 vrf_id=self.vrf1_id)
7034 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7037 global_pref64 = "2001:db8::"
7038 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7039 global_pref64_len = 32
7040 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7042 prefix = self.vapi.nat64_prefix_dump()
7043 self.assertEqual(len(prefix), 1)
7044 self.assertEqual(prefix[0].prefix, global_pref64_n)
7045 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7046 self.assertEqual(prefix[0].vrf_id, 0)
7048 # Add tenant specific prefix
7049 vrf1_pref64 = "2001:db8:122:300::"
7050 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7051 vrf1_pref64_len = 56
7052 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7054 vrf_id=self.vrf1_id)
7055 prefix = self.vapi.nat64_prefix_dump()
7056 self.assertEqual(len(prefix), 2)
7059 pkts = self.create_stream_in_ip6(self.pg0,
7062 plen=global_pref64_len)
7063 self.pg0.add_stream(pkts)
7064 self.pg_enable_capture(self.pg_interfaces)
7066 capture = self.pg1.get_capture(len(pkts))
7067 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7068 dst_ip=self.pg1.remote_ip4)
7070 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7071 self.pg1.add_stream(pkts)
7072 self.pg_enable_capture(self.pg_interfaces)
7074 capture = self.pg0.get_capture(len(pkts))
7075 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7078 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7080 # Tenant specific prefix
7081 pkts = self.create_stream_in_ip6(self.pg2,
7084 plen=vrf1_pref64_len)
7085 self.pg2.add_stream(pkts)
7086 self.pg_enable_capture(self.pg_interfaces)
7088 capture = self.pg1.get_capture(len(pkts))
7089 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7090 dst_ip=self.pg1.remote_ip4)
7092 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7093 self.pg1.add_stream(pkts)
7094 self.pg_enable_capture(self.pg_interfaces)
7096 capture = self.pg2.get_capture(len(pkts))
7097 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7100 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7102 def test_unknown_proto(self):
7103 """ NAT64 translate packet with unknown protocol """
7105 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7107 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7108 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7109 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7112 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7113 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7114 TCP(sport=self.tcp_port_in, dport=20))
7115 self.pg0.add_stream(p)
7116 self.pg_enable_capture(self.pg_interfaces)
7118 p = self.pg1.get_capture(1)
7120 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7121 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7123 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7124 TCP(sport=1234, dport=1234))
7125 self.pg0.add_stream(p)
7126 self.pg_enable_capture(self.pg_interfaces)
7128 p = self.pg1.get_capture(1)
7131 self.assertEqual(packet[IP].src, self.nat_addr)
7132 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7133 self.assertTrue(packet.haslayer(GRE))
7134 self.assert_packet_checksums_valid(packet)
7136 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7140 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7141 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7143 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7144 TCP(sport=1234, dport=1234))
7145 self.pg1.add_stream(p)
7146 self.pg_enable_capture(self.pg_interfaces)
7148 p = self.pg0.get_capture(1)
7151 self.assertEqual(packet[IPv6].src, remote_ip6)
7152 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7153 self.assertEqual(packet[IPv6].nh, 47)
7155 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7158 def test_hairpinning_unknown_proto(self):
7159 """ NAT64 translate packet with unknown protocol - hairpinning """
7161 client = self.pg0.remote_hosts[0]
7162 server = self.pg0.remote_hosts[1]
7163 server_tcp_in_port = 22
7164 server_tcp_out_port = 4022
7165 client_tcp_in_port = 1234
7166 client_tcp_out_port = 1235
7167 server_nat_ip = "10.0.0.100"
7168 client_nat_ip = "10.0.0.110"
7169 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7170 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7171 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7172 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7174 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7176 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7177 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7179 self.vapi.nat64_add_del_static_bib(server.ip6n,
7182 server_tcp_out_port,
7185 self.vapi.nat64_add_del_static_bib(server.ip6n,
7191 self.vapi.nat64_add_del_static_bib(client.ip6n,
7194 client_tcp_out_port,
7198 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7199 IPv6(src=client.ip6, dst=server_nat_ip6) /
7200 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7201 self.pg0.add_stream(p)
7202 self.pg_enable_capture(self.pg_interfaces)
7204 p = self.pg0.get_capture(1)
7206 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7207 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7209 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7210 TCP(sport=1234, dport=1234))
7211 self.pg0.add_stream(p)
7212 self.pg_enable_capture(self.pg_interfaces)
7214 p = self.pg0.get_capture(1)
7217 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7218 self.assertEqual(packet[IPv6].dst, server.ip6)
7219 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7221 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7225 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7226 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7228 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7229 TCP(sport=1234, dport=1234))
7230 self.pg0.add_stream(p)
7231 self.pg_enable_capture(self.pg_interfaces)
7233 p = self.pg0.get_capture(1)
7236 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7237 self.assertEqual(packet[IPv6].dst, client.ip6)
7238 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7240 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7243 def test_one_armed_nat64(self):
7244 """ One armed NAT64 """
7246 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7250 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7252 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7253 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7256 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7257 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7258 TCP(sport=12345, dport=80))
7259 self.pg3.add_stream(p)
7260 self.pg_enable_capture(self.pg_interfaces)
7262 capture = self.pg3.get_capture(1)
7267 self.assertEqual(ip.src, self.nat_addr)
7268 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7269 self.assertNotEqual(tcp.sport, 12345)
7270 external_port = tcp.sport
7271 self.assertEqual(tcp.dport, 80)
7272 self.assert_packet_checksums_valid(p)
7274 self.logger.error(ppp("Unexpected or invalid packet:", p))
7278 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7279 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7280 TCP(sport=80, dport=external_port))
7281 self.pg3.add_stream(p)
7282 self.pg_enable_capture(self.pg_interfaces)
7284 capture = self.pg3.get_capture(1)
7289 self.assertEqual(ip.src, remote_host_ip6)
7290 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7291 self.assertEqual(tcp.sport, 80)
7292 self.assertEqual(tcp.dport, 12345)
7293 self.assert_packet_checksums_valid(p)
7295 self.logger.error(ppp("Unexpected or invalid packet:", p))
7298 def test_frag_in_order(self):
7299 """ NAT64 translate fragments arriving in order """
7300 self.tcp_port_in = random.randint(1025, 65535)
7302 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7304 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7305 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7307 reass = self.vapi.nat_reass_dump()
7308 reass_n_start = len(reass)
7312 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7313 self.tcp_port_in, 20, data)
7314 self.pg0.add_stream(pkts)
7315 self.pg_enable_capture(self.pg_interfaces)
7317 frags = self.pg1.get_capture(len(pkts))
7318 p = self.reass_frags_and_verify(frags,
7320 self.pg1.remote_ip4)
7321 self.assertEqual(p[TCP].dport, 20)
7322 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7323 self.tcp_port_out = p[TCP].sport
7324 self.assertEqual(data, p[Raw].load)
7327 data = "A" * 4 + "b" * 16 + "C" * 3
7328 pkts = self.create_stream_frag(self.pg1,
7333 self.pg1.add_stream(pkts)
7334 self.pg_enable_capture(self.pg_interfaces)
7336 frags = self.pg0.get_capture(len(pkts))
7337 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7338 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7339 self.assertEqual(p[TCP].sport, 20)
7340 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7341 self.assertEqual(data, p[Raw].load)
7343 reass = self.vapi.nat_reass_dump()
7344 reass_n_end = len(reass)
7346 self.assertEqual(reass_n_end - reass_n_start, 2)
7348 def test_reass_hairpinning(self):
7349 """ NAT64 fragments hairpinning """
7351 server = self.pg0.remote_hosts[1]
7352 server_in_port = random.randint(1025, 65535)
7353 server_out_port = random.randint(1025, 65535)
7354 client_in_port = random.randint(1025, 65535)
7355 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7356 nat_addr_ip6 = ip.src
7358 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7360 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7361 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7363 # add static BIB entry for server
7364 self.vapi.nat64_add_del_static_bib(server.ip6n,
7370 # send packet from host to server
7371 pkts = self.create_stream_frag_ip6(self.pg0,
7376 self.pg0.add_stream(pkts)
7377 self.pg_enable_capture(self.pg_interfaces)
7379 frags = self.pg0.get_capture(len(pkts))
7380 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7381 self.assertNotEqual(p[TCP].sport, client_in_port)
7382 self.assertEqual(p[TCP].dport, server_in_port)
7383 self.assertEqual(data, p[Raw].load)
7385 def test_frag_out_of_order(self):
7386 """ NAT64 translate fragments arriving out of order """
7387 self.tcp_port_in = random.randint(1025, 65535)
7389 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7391 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7392 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7396 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7397 self.tcp_port_in, 20, data)
7399 self.pg0.add_stream(pkts)
7400 self.pg_enable_capture(self.pg_interfaces)
7402 frags = self.pg1.get_capture(len(pkts))
7403 p = self.reass_frags_and_verify(frags,
7405 self.pg1.remote_ip4)
7406 self.assertEqual(p[TCP].dport, 20)
7407 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7408 self.tcp_port_out = p[TCP].sport
7409 self.assertEqual(data, p[Raw].load)
7412 data = "A" * 4 + "B" * 16 + "C" * 3
7413 pkts = self.create_stream_frag(self.pg1,
7419 self.pg1.add_stream(pkts)
7420 self.pg_enable_capture(self.pg_interfaces)
7422 frags = self.pg0.get_capture(len(pkts))
7423 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7424 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7425 self.assertEqual(p[TCP].sport, 20)
7426 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7427 self.assertEqual(data, p[Raw].load)
7429 def test_interface_addr(self):
7430 """ Acquire NAT64 pool addresses from interface """
7431 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7433 # no address in NAT64 pool
7434 adresses = self.vapi.nat44_address_dump()
7435 self.assertEqual(0, len(adresses))
7437 # configure interface address and check NAT64 address pool
7438 self.pg4.config_ip4()
7439 addresses = self.vapi.nat64_pool_addr_dump()
7440 self.assertEqual(len(addresses), 1)
7441 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7443 # remove interface address and check NAT64 address pool
7444 self.pg4.unconfig_ip4()
7445 addresses = self.vapi.nat64_pool_addr_dump()
7446 self.assertEqual(0, len(adresses))
7448 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7449 def test_ipfix_max_bibs_sessions(self):
7450 """ IPFIX logging maximum session and BIB entries exceeded """
7453 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7457 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7459 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7460 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7464 for i in range(0, max_bibs):
7465 src = "fd01:aa::%x" % (i)
7466 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7467 IPv6(src=src, dst=remote_host_ip6) /
7468 TCP(sport=12345, dport=80))
7470 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7471 IPv6(src=src, dst=remote_host_ip6) /
7472 TCP(sport=12345, dport=22))
7474 self.pg0.add_stream(pkts)
7475 self.pg_enable_capture(self.pg_interfaces)
7477 self.pg1.get_capture(max_sessions)
7479 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7480 src_address=self.pg3.local_ip4n,
7482 template_interval=10)
7483 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7484 src_port=self.ipfix_src_port)
7486 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7487 IPv6(src=src, dst=remote_host_ip6) /
7488 TCP(sport=12345, dport=25))
7489 self.pg0.add_stream(p)
7490 self.pg_enable_capture(self.pg_interfaces)
7492 self.pg1.assert_nothing_captured()
7494 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7495 capture = self.pg3.get_capture(9)
7496 ipfix = IPFIXDecoder()
7497 # first load template
7499 self.assertTrue(p.haslayer(IPFIX))
7500 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7501 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7502 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7503 self.assertEqual(p[UDP].dport, 4739)
7504 self.assertEqual(p[IPFIX].observationDomainID,
7505 self.ipfix_domain_id)
7506 if p.haslayer(Template):
7507 ipfix.add_template(p.getlayer(Template))
7508 # verify events in data set
7510 if p.haslayer(Data):
7511 data = ipfix.decode_data_set(p.getlayer(Set))
7512 self.verify_ipfix_max_sessions(data, max_sessions)
7514 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7515 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7516 TCP(sport=12345, dport=80))
7517 self.pg0.add_stream(p)
7518 self.pg_enable_capture(self.pg_interfaces)
7520 self.pg1.assert_nothing_captured()
7522 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7523 capture = self.pg3.get_capture(1)
7524 # verify events in data set
7526 self.assertTrue(p.haslayer(IPFIX))
7527 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7528 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7529 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7530 self.assertEqual(p[UDP].dport, 4739)
7531 self.assertEqual(p[IPFIX].observationDomainID,
7532 self.ipfix_domain_id)
7533 if p.haslayer(Data):
7534 data = ipfix.decode_data_set(p.getlayer(Set))
7535 self.verify_ipfix_max_bibs(data, max_bibs)
7537 def test_ipfix_max_frags(self):
7538 """ IPFIX logging maximum fragments pending reassembly exceeded """
7539 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7541 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7542 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7543 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7544 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7545 src_address=self.pg3.local_ip4n,
7547 template_interval=10)
7548 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7549 src_port=self.ipfix_src_port)
7552 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7553 self.tcp_port_in, 20, data)
7555 self.pg0.add_stream(pkts)
7556 self.pg_enable_capture(self.pg_interfaces)
7558 self.pg1.assert_nothing_captured()
7560 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7561 capture = self.pg3.get_capture(9)
7562 ipfix = IPFIXDecoder()
7563 # first load template
7565 self.assertTrue(p.haslayer(IPFIX))
7566 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7567 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7568 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7569 self.assertEqual(p[UDP].dport, 4739)
7570 self.assertEqual(p[IPFIX].observationDomainID,
7571 self.ipfix_domain_id)
7572 if p.haslayer(Template):
7573 ipfix.add_template(p.getlayer(Template))
7574 # verify events in data set
7576 if p.haslayer(Data):
7577 data = ipfix.decode_data_set(p.getlayer(Set))
7578 self.verify_ipfix_max_fragments_ip6(data, 1,
7579 self.pg0.remote_ip6n)
7581 def test_ipfix_bib_ses(self):
7582 """ IPFIX logging NAT64 BIB/session create and delete events """
7583 self.tcp_port_in = random.randint(1025, 65535)
7584 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7588 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7590 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7591 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7592 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7593 src_address=self.pg3.local_ip4n,
7595 template_interval=10)
7596 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7597 src_port=self.ipfix_src_port)
7600 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7601 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7602 TCP(sport=self.tcp_port_in, dport=25))
7603 self.pg0.add_stream(p)
7604 self.pg_enable_capture(self.pg_interfaces)
7606 p = self.pg1.get_capture(1)
7607 self.tcp_port_out = p[0][TCP].sport
7608 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7609 capture = self.pg3.get_capture(10)
7610 ipfix = IPFIXDecoder()
7611 # first load template
7613 self.assertTrue(p.haslayer(IPFIX))
7614 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7615 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7616 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7617 self.assertEqual(p[UDP].dport, 4739)
7618 self.assertEqual(p[IPFIX].observationDomainID,
7619 self.ipfix_domain_id)
7620 if p.haslayer(Template):
7621 ipfix.add_template(p.getlayer(Template))
7622 # verify events in data set
7624 if p.haslayer(Data):
7625 data = ipfix.decode_data_set(p.getlayer(Set))
7626 if ord(data[0][230]) == 10:
7627 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7628 elif ord(data[0][230]) == 6:
7629 self.verify_ipfix_nat64_ses(data,
7631 self.pg0.remote_ip6n,
7632 self.pg1.remote_ip4,
7635 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7638 self.pg_enable_capture(self.pg_interfaces)
7639 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7642 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7643 capture = self.pg3.get_capture(2)
7644 # verify events in data set
7646 self.assertTrue(p.haslayer(IPFIX))
7647 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7648 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7649 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7650 self.assertEqual(p[UDP].dport, 4739)
7651 self.assertEqual(p[IPFIX].observationDomainID,
7652 self.ipfix_domain_id)
7653 if p.haslayer(Data):
7654 data = ipfix.decode_data_set(p.getlayer(Set))
7655 if ord(data[0][230]) == 11:
7656 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7657 elif ord(data[0][230]) == 7:
7658 self.verify_ipfix_nat64_ses(data,
7660 self.pg0.remote_ip6n,
7661 self.pg1.remote_ip4,
7664 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7666 def nat64_get_ses_num(self):
7668 Return number of active NAT64 sessions.
7670 st = self.vapi.nat64_st_dump()
7673 def clear_nat64(self):
7675 Clear NAT64 configuration.
7677 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7678 domain_id=self.ipfix_domain_id)
7679 self.ipfix_src_port = 4739
7680 self.ipfix_domain_id = 1
7682 self.vapi.nat_set_timeouts()
7684 interfaces = self.vapi.nat64_interface_dump()
7685 for intf in interfaces:
7686 if intf.is_inside > 1:
7687 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7690 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7694 bib = self.vapi.nat64_bib_dump(255)
7697 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7705 adresses = self.vapi.nat64_pool_addr_dump()
7706 for addr in adresses:
7707 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7712 prefixes = self.vapi.nat64_prefix_dump()
7713 for prefix in prefixes:
7714 self.vapi.nat64_add_del_prefix(prefix.prefix,
7716 vrf_id=prefix.vrf_id,
7720 super(TestNAT64, self).tearDown()
7721 if not self.vpp_dead:
7722 self.logger.info(self.vapi.cli("show nat64 pool"))
7723 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7724 self.logger.info(self.vapi.cli("show nat64 prefix"))
7725 self.logger.info(self.vapi.cli("show nat64 bib all"))
7726 self.logger.info(self.vapi.cli("show nat64 session table all"))
7727 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7731 class TestDSlite(MethodHolder):
7732 """ DS-Lite Test Cases """
7735 def setUpClass(cls):
7736 super(TestDSlite, cls).setUpClass()
7739 cls.nat_addr = '10.0.0.3'
7740 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7742 cls.create_pg_interfaces(range(2))
7744 cls.pg0.config_ip4()
7745 cls.pg0.resolve_arp()
7747 cls.pg1.config_ip6()
7748 cls.pg1.generate_remote_hosts(2)
7749 cls.pg1.configure_ipv6_neighbors()
7752 super(TestDSlite, cls).tearDownClass()
7755 def test_dslite(self):
7756 """ Test DS-Lite """
7757 nat_config = self.vapi.nat_show_config()
7758 self.assertEqual(0, nat_config.dslite_ce)
7760 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7762 aftr_ip4 = '192.0.0.1'
7763 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7764 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7765 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7766 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7769 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7770 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7771 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7772 UDP(sport=20000, dport=10000))
7773 self.pg1.add_stream(p)
7774 self.pg_enable_capture(self.pg_interfaces)
7776 capture = self.pg0.get_capture(1)
7777 capture = capture[0]
7778 self.assertFalse(capture.haslayer(IPv6))
7779 self.assertEqual(capture[IP].src, self.nat_addr)
7780 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7781 self.assertNotEqual(capture[UDP].sport, 20000)
7782 self.assertEqual(capture[UDP].dport, 10000)
7783 self.assert_packet_checksums_valid(capture)
7784 out_port = capture[UDP].sport
7786 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7787 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7788 UDP(sport=10000, dport=out_port))
7789 self.pg0.add_stream(p)
7790 self.pg_enable_capture(self.pg_interfaces)
7792 capture = self.pg1.get_capture(1)
7793 capture = capture[0]
7794 self.assertEqual(capture[IPv6].src, aftr_ip6)
7795 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7796 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7797 self.assertEqual(capture[IP].dst, '192.168.1.1')
7798 self.assertEqual(capture[UDP].sport, 10000)
7799 self.assertEqual(capture[UDP].dport, 20000)
7800 self.assert_packet_checksums_valid(capture)
7803 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7804 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7805 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7806 TCP(sport=20001, dport=10001))
7807 self.pg1.add_stream(p)
7808 self.pg_enable_capture(self.pg_interfaces)
7810 capture = self.pg0.get_capture(1)
7811 capture = capture[0]
7812 self.assertFalse(capture.haslayer(IPv6))
7813 self.assertEqual(capture[IP].src, self.nat_addr)
7814 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7815 self.assertNotEqual(capture[TCP].sport, 20001)
7816 self.assertEqual(capture[TCP].dport, 10001)
7817 self.assert_packet_checksums_valid(capture)
7818 out_port = capture[TCP].sport
7820 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7821 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7822 TCP(sport=10001, dport=out_port))
7823 self.pg0.add_stream(p)
7824 self.pg_enable_capture(self.pg_interfaces)
7826 capture = self.pg1.get_capture(1)
7827 capture = capture[0]
7828 self.assertEqual(capture[IPv6].src, aftr_ip6)
7829 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7830 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7831 self.assertEqual(capture[IP].dst, '192.168.1.1')
7832 self.assertEqual(capture[TCP].sport, 10001)
7833 self.assertEqual(capture[TCP].dport, 20001)
7834 self.assert_packet_checksums_valid(capture)
7837 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7838 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7839 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7840 ICMP(id=4000, type='echo-request'))
7841 self.pg1.add_stream(p)
7842 self.pg_enable_capture(self.pg_interfaces)
7844 capture = self.pg0.get_capture(1)
7845 capture = capture[0]
7846 self.assertFalse(capture.haslayer(IPv6))
7847 self.assertEqual(capture[IP].src, self.nat_addr)
7848 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7849 self.assertNotEqual(capture[ICMP].id, 4000)
7850 self.assert_packet_checksums_valid(capture)
7851 out_id = capture[ICMP].id
7853 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7854 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7855 ICMP(id=out_id, type='echo-reply'))
7856 self.pg0.add_stream(p)
7857 self.pg_enable_capture(self.pg_interfaces)
7859 capture = self.pg1.get_capture(1)
7860 capture = capture[0]
7861 self.assertEqual(capture[IPv6].src, aftr_ip6)
7862 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7863 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7864 self.assertEqual(capture[IP].dst, '192.168.1.1')
7865 self.assertEqual(capture[ICMP].id, 4000)
7866 self.assert_packet_checksums_valid(capture)
7868 # ping DS-Lite AFTR tunnel endpoint address
7869 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7870 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7871 ICMPv6EchoRequest())
7872 self.pg1.add_stream(p)
7873 self.pg_enable_capture(self.pg_interfaces)
7875 capture = self.pg1.get_capture(1)
7876 capture = capture[0]
7877 self.assertEqual(capture[IPv6].src, aftr_ip6)
7878 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7879 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7882 super(TestDSlite, self).tearDown()
7883 if not self.vpp_dead:
7884 self.logger.info(self.vapi.cli("show dslite pool"))
7886 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7887 self.logger.info(self.vapi.cli("show dslite sessions"))
7890 class TestDSliteCE(MethodHolder):
7891 """ DS-Lite CE Test Cases """
7894 def setUpConstants(cls):
7895 super(TestDSliteCE, cls).setUpConstants()
7896 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7899 def setUpClass(cls):
7900 super(TestDSliteCE, cls).setUpClass()
7903 cls.create_pg_interfaces(range(2))
7905 cls.pg0.config_ip4()
7906 cls.pg0.resolve_arp()
7908 cls.pg1.config_ip6()
7909 cls.pg1.generate_remote_hosts(1)
7910 cls.pg1.configure_ipv6_neighbors()
7913 super(TestDSliteCE, cls).tearDownClass()
7916 def test_dslite_ce(self):
7917 """ Test DS-Lite CE """
7919 nat_config = self.vapi.nat_show_config()
7920 self.assertEqual(1, nat_config.dslite_ce)
7922 b4_ip4 = '192.0.0.2'
7923 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7924 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7925 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7926 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7928 aftr_ip4 = '192.0.0.1'
7929 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7930 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7931 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7932 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7934 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7935 dst_address_length=128,
7936 next_hop_address=self.pg1.remote_ip6n,
7937 next_hop_sw_if_index=self.pg1.sw_if_index,
7941 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7942 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7943 UDP(sport=10000, dport=20000))
7944 self.pg0.add_stream(p)
7945 self.pg_enable_capture(self.pg_interfaces)
7947 capture = self.pg1.get_capture(1)
7948 capture = capture[0]
7949 self.assertEqual(capture[IPv6].src, b4_ip6)
7950 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7951 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7952 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7953 self.assertEqual(capture[UDP].sport, 10000)
7954 self.assertEqual(capture[UDP].dport, 20000)
7955 self.assert_packet_checksums_valid(capture)
7958 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7959 IPv6(dst=b4_ip6, src=aftr_ip6) /
7960 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7961 UDP(sport=20000, dport=10000))
7962 self.pg1.add_stream(p)
7963 self.pg_enable_capture(self.pg_interfaces)
7965 capture = self.pg0.get_capture(1)
7966 capture = capture[0]
7967 self.assertFalse(capture.haslayer(IPv6))
7968 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7969 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7970 self.assertEqual(capture[UDP].sport, 20000)
7971 self.assertEqual(capture[UDP].dport, 10000)
7972 self.assert_packet_checksums_valid(capture)
7974 # ping DS-Lite B4 tunnel endpoint address
7975 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7976 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7977 ICMPv6EchoRequest())
7978 self.pg1.add_stream(p)
7979 self.pg_enable_capture(self.pg_interfaces)
7981 capture = self.pg1.get_capture(1)
7982 capture = capture[0]
7983 self.assertEqual(capture[IPv6].src, b4_ip6)
7984 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7985 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7988 super(TestDSliteCE, self).tearDown()
7989 if not self.vpp_dead:
7991 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7993 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
7996 class TestNAT66(MethodHolder):
7997 """ NAT66 Test Cases """
8000 def setUpClass(cls):
8001 super(TestNAT66, cls).setUpClass()
8004 cls.nat_addr = 'fd01:ff::2'
8005 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8007 cls.create_pg_interfaces(range(2))
8008 cls.interfaces = list(cls.pg_interfaces)
8010 for i in cls.interfaces:
8013 i.configure_ipv6_neighbors()
8016 super(TestNAT66, cls).tearDownClass()
8019 def test_static(self):
8020 """ 1:1 NAT66 test """
8021 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8022 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8023 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8028 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8029 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8032 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8033 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8036 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8037 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8038 ICMPv6EchoRequest())
8040 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8041 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8042 GRE() / IP() / TCP())
8044 self.pg0.add_stream(pkts)
8045 self.pg_enable_capture(self.pg_interfaces)
8047 capture = self.pg1.get_capture(len(pkts))
8048 for packet in capture:
8050 self.assertEqual(packet[IPv6].src, self.nat_addr)
8051 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8052 self.assert_packet_checksums_valid(packet)
8054 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8059 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8060 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8063 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8064 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8067 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8068 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8071 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8072 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8073 GRE() / IP() / TCP())
8075 self.pg1.add_stream(pkts)
8076 self.pg_enable_capture(self.pg_interfaces)
8078 capture = self.pg0.get_capture(len(pkts))
8079 for packet in capture:
8081 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8082 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8083 self.assert_packet_checksums_valid(packet)
8085 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8088 sm = self.vapi.nat66_static_mapping_dump()
8089 self.assertEqual(len(sm), 1)
8090 self.assertEqual(sm[0].total_pkts, 8)
8092 def test_check_no_translate(self):
8093 """ NAT66 translate only when egress interface is outside interface """
8094 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8095 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8096 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8100 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8101 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8103 self.pg0.add_stream([p])
8104 self.pg_enable_capture(self.pg_interfaces)
8106 capture = self.pg1.get_capture(1)
8109 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8110 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8112 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8115 def clear_nat66(self):
8117 Clear NAT66 configuration.
8119 interfaces = self.vapi.nat66_interface_dump()
8120 for intf in interfaces:
8121 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8125 static_mappings = self.vapi.nat66_static_mapping_dump()
8126 for sm in static_mappings:
8127 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8128 sm.external_ip_address,
8133 super(TestNAT66, self).tearDown()
8134 if not self.vpp_dead:
8135 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8136 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8140 if __name__ == '__main__':
8141 unittest.main(testRunner=VppTestRunner)