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 def test_multiple_inside_interfaces(self):
1939 """ NAT44 multiple non-overlapping address space inside interfaces """
1941 self.nat44_add_address(self.nat_addr)
1942 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1943 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1944 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1947 # between two NAT44 inside interfaces (no translation)
1948 pkts = self.create_stream_in(self.pg0, self.pg1)
1949 self.pg0.add_stream(pkts)
1950 self.pg_enable_capture(self.pg_interfaces)
1952 capture = self.pg1.get_capture(len(pkts))
1953 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1955 # from NAT44 inside to interface without NAT44 feature (no translation)
1956 pkts = self.create_stream_in(self.pg0, self.pg2)
1957 self.pg0.add_stream(pkts)
1958 self.pg_enable_capture(self.pg_interfaces)
1960 capture = self.pg2.get_capture(len(pkts))
1961 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1963 # in2out 1st interface
1964 pkts = self.create_stream_in(self.pg0, self.pg3)
1965 self.pg0.add_stream(pkts)
1966 self.pg_enable_capture(self.pg_interfaces)
1968 capture = self.pg3.get_capture(len(pkts))
1969 self.verify_capture_out(capture)
1971 # out2in 1st interface
1972 pkts = self.create_stream_out(self.pg3)
1973 self.pg3.add_stream(pkts)
1974 self.pg_enable_capture(self.pg_interfaces)
1976 capture = self.pg0.get_capture(len(pkts))
1977 self.verify_capture_in(capture, self.pg0)
1979 # in2out 2nd interface
1980 pkts = self.create_stream_in(self.pg1, self.pg3)
1981 self.pg1.add_stream(pkts)
1982 self.pg_enable_capture(self.pg_interfaces)
1984 capture = self.pg3.get_capture(len(pkts))
1985 self.verify_capture_out(capture)
1987 # out2in 2nd interface
1988 pkts = self.create_stream_out(self.pg3)
1989 self.pg3.add_stream(pkts)
1990 self.pg_enable_capture(self.pg_interfaces)
1992 capture = self.pg1.get_capture(len(pkts))
1993 self.verify_capture_in(capture, self.pg1)
1995 def test_inside_overlapping_interfaces(self):
1996 """ NAT44 multiple inside interfaces with overlapping address space """
1998 static_nat_ip = "10.0.0.10"
1999 self.nat44_add_address(self.nat_addr)
2000 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2002 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2003 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2004 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2005 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2008 # between NAT44 inside interfaces with same VRF (no translation)
2009 pkts = self.create_stream_in(self.pg4, self.pg5)
2010 self.pg4.add_stream(pkts)
2011 self.pg_enable_capture(self.pg_interfaces)
2013 capture = self.pg5.get_capture(len(pkts))
2014 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2016 # between NAT44 inside interfaces with different VRF (hairpinning)
2017 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2018 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2019 TCP(sport=1234, dport=5678))
2020 self.pg4.add_stream(p)
2021 self.pg_enable_capture(self.pg_interfaces)
2023 capture = self.pg6.get_capture(1)
2028 self.assertEqual(ip.src, self.nat_addr)
2029 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2030 self.assertNotEqual(tcp.sport, 1234)
2031 self.assertEqual(tcp.dport, 5678)
2033 self.logger.error(ppp("Unexpected or invalid packet:", p))
2036 # in2out 1st interface
2037 pkts = self.create_stream_in(self.pg4, self.pg3)
2038 self.pg4.add_stream(pkts)
2039 self.pg_enable_capture(self.pg_interfaces)
2041 capture = self.pg3.get_capture(len(pkts))
2042 self.verify_capture_out(capture)
2044 # out2in 1st interface
2045 pkts = self.create_stream_out(self.pg3)
2046 self.pg3.add_stream(pkts)
2047 self.pg_enable_capture(self.pg_interfaces)
2049 capture = self.pg4.get_capture(len(pkts))
2050 self.verify_capture_in(capture, self.pg4)
2052 # in2out 2nd interface
2053 pkts = self.create_stream_in(self.pg5, self.pg3)
2054 self.pg5.add_stream(pkts)
2055 self.pg_enable_capture(self.pg_interfaces)
2057 capture = self.pg3.get_capture(len(pkts))
2058 self.verify_capture_out(capture)
2060 # out2in 2nd interface
2061 pkts = self.create_stream_out(self.pg3)
2062 self.pg3.add_stream(pkts)
2063 self.pg_enable_capture(self.pg_interfaces)
2065 capture = self.pg5.get_capture(len(pkts))
2066 self.verify_capture_in(capture, self.pg5)
2069 addresses = self.vapi.nat44_address_dump()
2070 self.assertEqual(len(addresses), 1)
2071 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2072 self.assertEqual(len(sessions), 3)
2073 for session in sessions:
2074 self.assertFalse(session.is_static)
2075 self.assertEqual(session.inside_ip_address[0:4],
2076 self.pg5.remote_ip4n)
2077 self.assertEqual(session.outside_ip_address,
2078 addresses[0].ip_address)
2079 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2080 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2081 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2082 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2083 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2084 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2085 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2086 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2087 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2089 # in2out 3rd interface
2090 pkts = self.create_stream_in(self.pg6, self.pg3)
2091 self.pg6.add_stream(pkts)
2092 self.pg_enable_capture(self.pg_interfaces)
2094 capture = self.pg3.get_capture(len(pkts))
2095 self.verify_capture_out(capture, static_nat_ip, True)
2097 # out2in 3rd interface
2098 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2099 self.pg3.add_stream(pkts)
2100 self.pg_enable_capture(self.pg_interfaces)
2102 capture = self.pg6.get_capture(len(pkts))
2103 self.verify_capture_in(capture, self.pg6)
2105 # general user and session dump verifications
2106 users = self.vapi.nat44_user_dump()
2107 self.assertTrue(len(users) >= 3)
2108 addresses = self.vapi.nat44_address_dump()
2109 self.assertEqual(len(addresses), 1)
2111 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2113 for session in sessions:
2114 self.assertEqual(user.ip_address, session.inside_ip_address)
2115 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2116 self.assertTrue(session.protocol in
2117 [IP_PROTOS.tcp, IP_PROTOS.udp,
2119 self.assertFalse(session.ext_host_valid)
2122 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2123 self.assertTrue(len(sessions) >= 4)
2124 for session in sessions:
2125 self.assertFalse(session.is_static)
2126 self.assertEqual(session.inside_ip_address[0:4],
2127 self.pg4.remote_ip4n)
2128 self.assertEqual(session.outside_ip_address,
2129 addresses[0].ip_address)
2132 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2133 self.assertTrue(len(sessions) >= 3)
2134 for session in sessions:
2135 self.assertTrue(session.is_static)
2136 self.assertEqual(session.inside_ip_address[0:4],
2137 self.pg6.remote_ip4n)
2138 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2139 map(int, static_nat_ip.split('.')))
2140 self.assertTrue(session.inside_port in
2141 [self.tcp_port_in, self.udp_port_in,
2144 def test_hairpinning(self):
2145 """ NAT44 hairpinning - 1:1 NAPT """
2147 host = self.pg0.remote_hosts[0]
2148 server = self.pg0.remote_hosts[1]
2151 server_in_port = 5678
2152 server_out_port = 8765
2154 self.nat44_add_address(self.nat_addr)
2155 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2156 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2158 # add static mapping for server
2159 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2160 server_in_port, server_out_port,
2161 proto=IP_PROTOS.tcp)
2163 # send packet from host to server
2164 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2165 IP(src=host.ip4, dst=self.nat_addr) /
2166 TCP(sport=host_in_port, dport=server_out_port))
2167 self.pg0.add_stream(p)
2168 self.pg_enable_capture(self.pg_interfaces)
2170 capture = self.pg0.get_capture(1)
2175 self.assertEqual(ip.src, self.nat_addr)
2176 self.assertEqual(ip.dst, server.ip4)
2177 self.assertNotEqual(tcp.sport, host_in_port)
2178 self.assertEqual(tcp.dport, server_in_port)
2179 self.assert_packet_checksums_valid(p)
2180 host_out_port = tcp.sport
2182 self.logger.error(ppp("Unexpected or invalid packet:", p))
2185 # send reply from server to host
2186 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2187 IP(src=server.ip4, dst=self.nat_addr) /
2188 TCP(sport=server_in_port, dport=host_out_port))
2189 self.pg0.add_stream(p)
2190 self.pg_enable_capture(self.pg_interfaces)
2192 capture = self.pg0.get_capture(1)
2197 self.assertEqual(ip.src, self.nat_addr)
2198 self.assertEqual(ip.dst, host.ip4)
2199 self.assertEqual(tcp.sport, server_out_port)
2200 self.assertEqual(tcp.dport, host_in_port)
2201 self.assert_packet_checksums_valid(p)
2203 self.logger.error(ppp("Unexpected or invalid packet:", p))
2206 def test_hairpinning2(self):
2207 """ NAT44 hairpinning - 1:1 NAT"""
2209 server1_nat_ip = "10.0.0.10"
2210 server2_nat_ip = "10.0.0.11"
2211 host = self.pg0.remote_hosts[0]
2212 server1 = self.pg0.remote_hosts[1]
2213 server2 = self.pg0.remote_hosts[2]
2214 server_tcp_port = 22
2215 server_udp_port = 20
2217 self.nat44_add_address(self.nat_addr)
2218 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2219 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2222 # add static mapping for servers
2223 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2224 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2228 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2229 IP(src=host.ip4, dst=server1_nat_ip) /
2230 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2232 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2233 IP(src=host.ip4, dst=server1_nat_ip) /
2234 UDP(sport=self.udp_port_in, dport=server_udp_port))
2236 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2237 IP(src=host.ip4, dst=server1_nat_ip) /
2238 ICMP(id=self.icmp_id_in, type='echo-request'))
2240 self.pg0.add_stream(pkts)
2241 self.pg_enable_capture(self.pg_interfaces)
2243 capture = self.pg0.get_capture(len(pkts))
2244 for packet in capture:
2246 self.assertEqual(packet[IP].src, self.nat_addr)
2247 self.assertEqual(packet[IP].dst, server1.ip4)
2248 if packet.haslayer(TCP):
2249 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2250 self.assertEqual(packet[TCP].dport, server_tcp_port)
2251 self.tcp_port_out = packet[TCP].sport
2252 self.assert_packet_checksums_valid(packet)
2253 elif packet.haslayer(UDP):
2254 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2255 self.assertEqual(packet[UDP].dport, server_udp_port)
2256 self.udp_port_out = packet[UDP].sport
2258 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2259 self.icmp_id_out = packet[ICMP].id
2261 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2266 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2267 IP(src=server1.ip4, dst=self.nat_addr) /
2268 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2270 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2271 IP(src=server1.ip4, dst=self.nat_addr) /
2272 UDP(sport=server_udp_port, dport=self.udp_port_out))
2274 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2275 IP(src=server1.ip4, dst=self.nat_addr) /
2276 ICMP(id=self.icmp_id_out, type='echo-reply'))
2278 self.pg0.add_stream(pkts)
2279 self.pg_enable_capture(self.pg_interfaces)
2281 capture = self.pg0.get_capture(len(pkts))
2282 for packet in capture:
2284 self.assertEqual(packet[IP].src, server1_nat_ip)
2285 self.assertEqual(packet[IP].dst, host.ip4)
2286 if packet.haslayer(TCP):
2287 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2288 self.assertEqual(packet[TCP].sport, server_tcp_port)
2289 self.assert_packet_checksums_valid(packet)
2290 elif packet.haslayer(UDP):
2291 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2292 self.assertEqual(packet[UDP].sport, server_udp_port)
2294 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2296 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2299 # server2 to server1
2301 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2302 IP(src=server2.ip4, dst=server1_nat_ip) /
2303 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2305 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2306 IP(src=server2.ip4, dst=server1_nat_ip) /
2307 UDP(sport=self.udp_port_in, dport=server_udp_port))
2309 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2310 IP(src=server2.ip4, dst=server1_nat_ip) /
2311 ICMP(id=self.icmp_id_in, type='echo-request'))
2313 self.pg0.add_stream(pkts)
2314 self.pg_enable_capture(self.pg_interfaces)
2316 capture = self.pg0.get_capture(len(pkts))
2317 for packet in capture:
2319 self.assertEqual(packet[IP].src, server2_nat_ip)
2320 self.assertEqual(packet[IP].dst, server1.ip4)
2321 if packet.haslayer(TCP):
2322 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2323 self.assertEqual(packet[TCP].dport, server_tcp_port)
2324 self.tcp_port_out = packet[TCP].sport
2325 self.assert_packet_checksums_valid(packet)
2326 elif packet.haslayer(UDP):
2327 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2328 self.assertEqual(packet[UDP].dport, server_udp_port)
2329 self.udp_port_out = packet[UDP].sport
2331 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2332 self.icmp_id_out = packet[ICMP].id
2334 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2337 # server1 to server2
2339 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2340 IP(src=server1.ip4, dst=server2_nat_ip) /
2341 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2343 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2344 IP(src=server1.ip4, dst=server2_nat_ip) /
2345 UDP(sport=server_udp_port, dport=self.udp_port_out))
2347 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2348 IP(src=server1.ip4, dst=server2_nat_ip) /
2349 ICMP(id=self.icmp_id_out, type='echo-reply'))
2351 self.pg0.add_stream(pkts)
2352 self.pg_enable_capture(self.pg_interfaces)
2354 capture = self.pg0.get_capture(len(pkts))
2355 for packet in capture:
2357 self.assertEqual(packet[IP].src, server1_nat_ip)
2358 self.assertEqual(packet[IP].dst, server2.ip4)
2359 if packet.haslayer(TCP):
2360 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2361 self.assertEqual(packet[TCP].sport, server_tcp_port)
2362 self.assert_packet_checksums_valid(packet)
2363 elif packet.haslayer(UDP):
2364 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2365 self.assertEqual(packet[UDP].sport, server_udp_port)
2367 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2369 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2372 def test_max_translations_per_user(self):
2373 """ MAX translations per user - recycle the least recently used """
2375 self.nat44_add_address(self.nat_addr)
2376 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2377 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2380 # get maximum number of translations per user
2381 nat44_config = self.vapi.nat_show_config()
2383 # send more than maximum number of translations per user packets
2384 pkts_num = nat44_config.max_translations_per_user + 5
2386 for port in range(0, pkts_num):
2387 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2388 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2389 TCP(sport=1025 + port))
2391 self.pg0.add_stream(pkts)
2392 self.pg_enable_capture(self.pg_interfaces)
2395 # verify number of translated packet
2396 self.pg1.get_capture(pkts_num)
2398 users = self.vapi.nat44_user_dump()
2400 if user.ip_address == self.pg0.remote_ip4n:
2401 self.assertEqual(user.nsessions,
2402 nat44_config.max_translations_per_user)
2403 self.assertEqual(user.nstaticsessions, 0)
2406 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2408 proto=IP_PROTOS.tcp)
2409 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2410 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2411 TCP(sport=tcp_port))
2412 self.pg0.add_stream(p)
2413 self.pg_enable_capture(self.pg_interfaces)
2415 self.pg1.get_capture(1)
2416 users = self.vapi.nat44_user_dump()
2418 if user.ip_address == self.pg0.remote_ip4n:
2419 self.assertEqual(user.nsessions,
2420 nat44_config.max_translations_per_user - 1)
2421 self.assertEqual(user.nstaticsessions, 1)
2423 def test_interface_addr(self):
2424 """ Acquire NAT44 addresses from interface """
2425 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2427 # no address in NAT pool
2428 adresses = self.vapi.nat44_address_dump()
2429 self.assertEqual(0, len(adresses))
2431 # configure interface address and check NAT address pool
2432 self.pg7.config_ip4()
2433 adresses = self.vapi.nat44_address_dump()
2434 self.assertEqual(1, len(adresses))
2435 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2437 # remove interface address and check NAT address pool
2438 self.pg7.unconfig_ip4()
2439 adresses = self.vapi.nat44_address_dump()
2440 self.assertEqual(0, len(adresses))
2442 def test_interface_addr_static_mapping(self):
2443 """ Static mapping with addresses from interface """
2446 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2447 self.nat44_add_static_mapping(
2449 external_sw_if_index=self.pg7.sw_if_index,
2452 # static mappings with external interface
2453 static_mappings = self.vapi.nat44_static_mapping_dump()
2454 self.assertEqual(1, len(static_mappings))
2455 self.assertEqual(self.pg7.sw_if_index,
2456 static_mappings[0].external_sw_if_index)
2457 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2459 # configure interface address and check static mappings
2460 self.pg7.config_ip4()
2461 static_mappings = self.vapi.nat44_static_mapping_dump()
2462 self.assertEqual(2, len(static_mappings))
2464 for sm in static_mappings:
2465 if sm.external_sw_if_index == 0xFFFFFFFF:
2466 self.assertEqual(sm.external_ip_address[0:4],
2467 self.pg7.local_ip4n)
2468 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2470 self.assertTrue(resolved)
2472 # remove interface address and check static mappings
2473 self.pg7.unconfig_ip4()
2474 static_mappings = self.vapi.nat44_static_mapping_dump()
2475 self.assertEqual(1, len(static_mappings))
2476 self.assertEqual(self.pg7.sw_if_index,
2477 static_mappings[0].external_sw_if_index)
2478 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2480 # configure interface address again and check static mappings
2481 self.pg7.config_ip4()
2482 static_mappings = self.vapi.nat44_static_mapping_dump()
2483 self.assertEqual(2, len(static_mappings))
2485 for sm in static_mappings:
2486 if sm.external_sw_if_index == 0xFFFFFFFF:
2487 self.assertEqual(sm.external_ip_address[0:4],
2488 self.pg7.local_ip4n)
2489 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2491 self.assertTrue(resolved)
2493 # remove static mapping
2494 self.nat44_add_static_mapping(
2496 external_sw_if_index=self.pg7.sw_if_index,
2499 static_mappings = self.vapi.nat44_static_mapping_dump()
2500 self.assertEqual(0, len(static_mappings))
2502 def test_interface_addr_identity_nat(self):
2503 """ Identity NAT with addresses from interface """
2506 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2507 self.vapi.nat44_add_del_identity_mapping(
2508 sw_if_index=self.pg7.sw_if_index,
2510 protocol=IP_PROTOS.tcp,
2513 # identity mappings with external interface
2514 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2515 self.assertEqual(1, len(identity_mappings))
2516 self.assertEqual(self.pg7.sw_if_index,
2517 identity_mappings[0].sw_if_index)
2519 # configure interface address and check identity mappings
2520 self.pg7.config_ip4()
2521 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2523 self.assertEqual(2, len(identity_mappings))
2524 for sm in identity_mappings:
2525 if sm.sw_if_index == 0xFFFFFFFF:
2526 self.assertEqual(identity_mappings[0].ip_address,
2527 self.pg7.local_ip4n)
2528 self.assertEqual(port, identity_mappings[0].port)
2529 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2531 self.assertTrue(resolved)
2533 # remove interface address and check identity mappings
2534 self.pg7.unconfig_ip4()
2535 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2536 self.assertEqual(1, len(identity_mappings))
2537 self.assertEqual(self.pg7.sw_if_index,
2538 identity_mappings[0].sw_if_index)
2540 def test_ipfix_nat44_sess(self):
2541 """ IPFIX logging NAT44 session created/delted """
2542 self.ipfix_domain_id = 10
2543 self.ipfix_src_port = 20202
2544 colector_port = 30303
2545 bind_layers(UDP, IPFIX, dport=30303)
2546 self.nat44_add_address(self.nat_addr)
2547 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2548 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2550 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2551 src_address=self.pg3.local_ip4n,
2553 template_interval=10,
2554 collector_port=colector_port)
2555 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2556 src_port=self.ipfix_src_port)
2558 pkts = self.create_stream_in(self.pg0, self.pg1)
2559 self.pg0.add_stream(pkts)
2560 self.pg_enable_capture(self.pg_interfaces)
2562 capture = self.pg1.get_capture(len(pkts))
2563 self.verify_capture_out(capture)
2564 self.nat44_add_address(self.nat_addr, is_add=0)
2565 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2566 capture = self.pg3.get_capture(9)
2567 ipfix = IPFIXDecoder()
2568 # first load template
2570 self.assertTrue(p.haslayer(IPFIX))
2571 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2572 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2573 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2574 self.assertEqual(p[UDP].dport, colector_port)
2575 self.assertEqual(p[IPFIX].observationDomainID,
2576 self.ipfix_domain_id)
2577 if p.haslayer(Template):
2578 ipfix.add_template(p.getlayer(Template))
2579 # verify events in data set
2581 if p.haslayer(Data):
2582 data = ipfix.decode_data_set(p.getlayer(Set))
2583 self.verify_ipfix_nat44_ses(data)
2585 def test_ipfix_addr_exhausted(self):
2586 """ IPFIX logging NAT addresses exhausted """
2587 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2588 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2590 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2591 src_address=self.pg3.local_ip4n,
2593 template_interval=10)
2594 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2595 src_port=self.ipfix_src_port)
2597 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2598 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2600 self.pg0.add_stream(p)
2601 self.pg_enable_capture(self.pg_interfaces)
2603 self.pg1.assert_nothing_captured()
2605 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2606 capture = self.pg3.get_capture(9)
2607 ipfix = IPFIXDecoder()
2608 # first load template
2610 self.assertTrue(p.haslayer(IPFIX))
2611 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2612 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2613 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2614 self.assertEqual(p[UDP].dport, 4739)
2615 self.assertEqual(p[IPFIX].observationDomainID,
2616 self.ipfix_domain_id)
2617 if p.haslayer(Template):
2618 ipfix.add_template(p.getlayer(Template))
2619 # verify events in data set
2621 if p.haslayer(Data):
2622 data = ipfix.decode_data_set(p.getlayer(Set))
2623 self.verify_ipfix_addr_exhausted(data)
2625 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2626 def test_ipfix_max_sessions(self):
2627 """ IPFIX logging maximum session entries exceeded """
2628 self.nat44_add_address(self.nat_addr)
2629 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2630 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2633 nat44_config = self.vapi.nat_show_config()
2634 max_sessions = 10 * nat44_config.translation_buckets
2637 for i in range(0, max_sessions):
2638 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2639 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2640 IP(src=src, dst=self.pg1.remote_ip4) /
2643 self.pg0.add_stream(pkts)
2644 self.pg_enable_capture(self.pg_interfaces)
2647 self.pg1.get_capture(max_sessions)
2648 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2649 src_address=self.pg3.local_ip4n,
2651 template_interval=10)
2652 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2653 src_port=self.ipfix_src_port)
2655 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2656 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2658 self.pg0.add_stream(p)
2659 self.pg_enable_capture(self.pg_interfaces)
2661 self.pg1.assert_nothing_captured()
2663 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2664 capture = self.pg3.get_capture(9)
2665 ipfix = IPFIXDecoder()
2666 # first load template
2668 self.assertTrue(p.haslayer(IPFIX))
2669 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2670 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2671 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2672 self.assertEqual(p[UDP].dport, 4739)
2673 self.assertEqual(p[IPFIX].observationDomainID,
2674 self.ipfix_domain_id)
2675 if p.haslayer(Template):
2676 ipfix.add_template(p.getlayer(Template))
2677 # verify events in data set
2679 if p.haslayer(Data):
2680 data = ipfix.decode_data_set(p.getlayer(Set))
2681 self.verify_ipfix_max_sessions(data, max_sessions)
2683 def test_pool_addr_fib(self):
2684 """ NAT44 add pool addresses to FIB """
2685 static_addr = '10.0.0.10'
2686 self.nat44_add_address(self.nat_addr)
2687 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2688 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2690 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2693 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2694 ARP(op=ARP.who_has, pdst=self.nat_addr,
2695 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2696 self.pg1.add_stream(p)
2697 self.pg_enable_capture(self.pg_interfaces)
2699 capture = self.pg1.get_capture(1)
2700 self.assertTrue(capture[0].haslayer(ARP))
2701 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2704 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2705 ARP(op=ARP.who_has, pdst=static_addr,
2706 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2707 self.pg1.add_stream(p)
2708 self.pg_enable_capture(self.pg_interfaces)
2710 capture = self.pg1.get_capture(1)
2711 self.assertTrue(capture[0].haslayer(ARP))
2712 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2714 # send ARP to non-NAT44 interface
2715 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2716 ARP(op=ARP.who_has, pdst=self.nat_addr,
2717 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2718 self.pg2.add_stream(p)
2719 self.pg_enable_capture(self.pg_interfaces)
2721 self.pg1.assert_nothing_captured()
2723 # remove addresses and verify
2724 self.nat44_add_address(self.nat_addr, is_add=0)
2725 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2728 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2729 ARP(op=ARP.who_has, pdst=self.nat_addr,
2730 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2731 self.pg1.add_stream(p)
2732 self.pg_enable_capture(self.pg_interfaces)
2734 self.pg1.assert_nothing_captured()
2736 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2737 ARP(op=ARP.who_has, pdst=static_addr,
2738 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2739 self.pg1.add_stream(p)
2740 self.pg_enable_capture(self.pg_interfaces)
2742 self.pg1.assert_nothing_captured()
2744 def test_vrf_mode(self):
2745 """ NAT44 tenant VRF aware address pool mode """
2749 nat_ip1 = "10.0.0.10"
2750 nat_ip2 = "10.0.0.11"
2752 self.pg0.unconfig_ip4()
2753 self.pg1.unconfig_ip4()
2754 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2755 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2756 self.pg0.set_table_ip4(vrf_id1)
2757 self.pg1.set_table_ip4(vrf_id2)
2758 self.pg0.config_ip4()
2759 self.pg1.config_ip4()
2760 self.pg0.resolve_arp()
2761 self.pg1.resolve_arp()
2763 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2764 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2765 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2766 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2767 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2772 pkts = self.create_stream_in(self.pg0, self.pg2)
2773 self.pg0.add_stream(pkts)
2774 self.pg_enable_capture(self.pg_interfaces)
2776 capture = self.pg2.get_capture(len(pkts))
2777 self.verify_capture_out(capture, nat_ip1)
2780 pkts = self.create_stream_in(self.pg1, self.pg2)
2781 self.pg1.add_stream(pkts)
2782 self.pg_enable_capture(self.pg_interfaces)
2784 capture = self.pg2.get_capture(len(pkts))
2785 self.verify_capture_out(capture, nat_ip2)
2788 self.pg0.unconfig_ip4()
2789 self.pg1.unconfig_ip4()
2790 self.pg0.set_table_ip4(0)
2791 self.pg1.set_table_ip4(0)
2792 self.pg0.config_ip4()
2793 self.pg1.config_ip4()
2794 self.pg0.resolve_arp()
2795 self.pg1.resolve_arp()
2796 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2797 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2799 def test_vrf_feature_independent(self):
2800 """ NAT44 tenant VRF independent address pool mode """
2802 nat_ip1 = "10.0.0.10"
2803 nat_ip2 = "10.0.0.11"
2805 self.nat44_add_address(nat_ip1)
2806 self.nat44_add_address(nat_ip2, vrf_id=99)
2807 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2808 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2809 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2813 pkts = self.create_stream_in(self.pg0, self.pg2)
2814 self.pg0.add_stream(pkts)
2815 self.pg_enable_capture(self.pg_interfaces)
2817 capture = self.pg2.get_capture(len(pkts))
2818 self.verify_capture_out(capture, nat_ip1)
2821 pkts = self.create_stream_in(self.pg1, self.pg2)
2822 self.pg1.add_stream(pkts)
2823 self.pg_enable_capture(self.pg_interfaces)
2825 capture = self.pg2.get_capture(len(pkts))
2826 self.verify_capture_out(capture, nat_ip1)
2828 def test_dynamic_ipless_interfaces(self):
2829 """ NAT44 interfaces without configured IP address """
2831 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2832 mactobinary(self.pg7.remote_mac),
2833 self.pg7.remote_ip4n,
2835 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2836 mactobinary(self.pg8.remote_mac),
2837 self.pg8.remote_ip4n,
2840 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2841 dst_address_length=32,
2842 next_hop_address=self.pg7.remote_ip4n,
2843 next_hop_sw_if_index=self.pg7.sw_if_index)
2844 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2845 dst_address_length=32,
2846 next_hop_address=self.pg8.remote_ip4n,
2847 next_hop_sw_if_index=self.pg8.sw_if_index)
2849 self.nat44_add_address(self.nat_addr)
2850 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2851 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2855 pkts = self.create_stream_in(self.pg7, self.pg8)
2856 self.pg7.add_stream(pkts)
2857 self.pg_enable_capture(self.pg_interfaces)
2859 capture = self.pg8.get_capture(len(pkts))
2860 self.verify_capture_out(capture)
2863 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2864 self.pg8.add_stream(pkts)
2865 self.pg_enable_capture(self.pg_interfaces)
2867 capture = self.pg7.get_capture(len(pkts))
2868 self.verify_capture_in(capture, self.pg7)
2870 def test_static_ipless_interfaces(self):
2871 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2873 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2874 mactobinary(self.pg7.remote_mac),
2875 self.pg7.remote_ip4n,
2877 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2878 mactobinary(self.pg8.remote_mac),
2879 self.pg8.remote_ip4n,
2882 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2883 dst_address_length=32,
2884 next_hop_address=self.pg7.remote_ip4n,
2885 next_hop_sw_if_index=self.pg7.sw_if_index)
2886 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2887 dst_address_length=32,
2888 next_hop_address=self.pg8.remote_ip4n,
2889 next_hop_sw_if_index=self.pg8.sw_if_index)
2891 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2892 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2893 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2897 pkts = self.create_stream_out(self.pg8)
2898 self.pg8.add_stream(pkts)
2899 self.pg_enable_capture(self.pg_interfaces)
2901 capture = self.pg7.get_capture(len(pkts))
2902 self.verify_capture_in(capture, self.pg7)
2905 pkts = self.create_stream_in(self.pg7, self.pg8)
2906 self.pg7.add_stream(pkts)
2907 self.pg_enable_capture(self.pg_interfaces)
2909 capture = self.pg8.get_capture(len(pkts))
2910 self.verify_capture_out(capture, self.nat_addr, True)
2912 def test_static_with_port_ipless_interfaces(self):
2913 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2915 self.tcp_port_out = 30606
2916 self.udp_port_out = 30607
2917 self.icmp_id_out = 30608
2919 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2920 mactobinary(self.pg7.remote_mac),
2921 self.pg7.remote_ip4n,
2923 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2924 mactobinary(self.pg8.remote_mac),
2925 self.pg8.remote_ip4n,
2928 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2929 dst_address_length=32,
2930 next_hop_address=self.pg7.remote_ip4n,
2931 next_hop_sw_if_index=self.pg7.sw_if_index)
2932 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2933 dst_address_length=32,
2934 next_hop_address=self.pg8.remote_ip4n,
2935 next_hop_sw_if_index=self.pg8.sw_if_index)
2937 self.nat44_add_address(self.nat_addr)
2938 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2939 self.tcp_port_in, self.tcp_port_out,
2940 proto=IP_PROTOS.tcp)
2941 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2942 self.udp_port_in, self.udp_port_out,
2943 proto=IP_PROTOS.udp)
2944 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2945 self.icmp_id_in, self.icmp_id_out,
2946 proto=IP_PROTOS.icmp)
2947 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2948 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2952 pkts = self.create_stream_out(self.pg8)
2953 self.pg8.add_stream(pkts)
2954 self.pg_enable_capture(self.pg_interfaces)
2956 capture = self.pg7.get_capture(len(pkts))
2957 self.verify_capture_in(capture, self.pg7)
2960 pkts = self.create_stream_in(self.pg7, self.pg8)
2961 self.pg7.add_stream(pkts)
2962 self.pg_enable_capture(self.pg_interfaces)
2964 capture = self.pg8.get_capture(len(pkts))
2965 self.verify_capture_out(capture)
2967 def test_static_unknown_proto(self):
2968 """ 1:1 NAT translate packet with unknown protocol """
2969 nat_ip = "10.0.0.10"
2970 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2971 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2972 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2976 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2977 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2979 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2980 TCP(sport=1234, dport=1234))
2981 self.pg0.add_stream(p)
2982 self.pg_enable_capture(self.pg_interfaces)
2984 p = self.pg1.get_capture(1)
2987 self.assertEqual(packet[IP].src, nat_ip)
2988 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2989 self.assertTrue(packet.haslayer(GRE))
2990 self.assert_packet_checksums_valid(packet)
2992 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2996 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
2997 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
2999 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3000 TCP(sport=1234, dport=1234))
3001 self.pg1.add_stream(p)
3002 self.pg_enable_capture(self.pg_interfaces)
3004 p = self.pg0.get_capture(1)
3007 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3008 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3009 self.assertTrue(packet.haslayer(GRE))
3010 self.assert_packet_checksums_valid(packet)
3012 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3015 def test_hairpinning_static_unknown_proto(self):
3016 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3018 host = self.pg0.remote_hosts[0]
3019 server = self.pg0.remote_hosts[1]
3021 host_nat_ip = "10.0.0.10"
3022 server_nat_ip = "10.0.0.11"
3024 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3025 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3026 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3027 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3031 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3032 IP(src=host.ip4, dst=server_nat_ip) /
3034 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3035 TCP(sport=1234, dport=1234))
3036 self.pg0.add_stream(p)
3037 self.pg_enable_capture(self.pg_interfaces)
3039 p = self.pg0.get_capture(1)
3042 self.assertEqual(packet[IP].src, host_nat_ip)
3043 self.assertEqual(packet[IP].dst, server.ip4)
3044 self.assertTrue(packet.haslayer(GRE))
3045 self.assert_packet_checksums_valid(packet)
3047 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3051 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3052 IP(src=server.ip4, dst=host_nat_ip) /
3054 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3055 TCP(sport=1234, dport=1234))
3056 self.pg0.add_stream(p)
3057 self.pg_enable_capture(self.pg_interfaces)
3059 p = self.pg0.get_capture(1)
3062 self.assertEqual(packet[IP].src, server_nat_ip)
3063 self.assertEqual(packet[IP].dst, host.ip4)
3064 self.assertTrue(packet.haslayer(GRE))
3065 self.assert_packet_checksums_valid(packet)
3067 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3070 def test_output_feature(self):
3071 """ NAT44 interface output feature (in2out postrouting) """
3072 self.nat44_add_address(self.nat_addr)
3073 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3074 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3075 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3079 pkts = self.create_stream_in(self.pg0, self.pg3)
3080 self.pg0.add_stream(pkts)
3081 self.pg_enable_capture(self.pg_interfaces)
3083 capture = self.pg3.get_capture(len(pkts))
3084 self.verify_capture_out(capture)
3087 pkts = self.create_stream_out(self.pg3)
3088 self.pg3.add_stream(pkts)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 capture = self.pg0.get_capture(len(pkts))
3092 self.verify_capture_in(capture, self.pg0)
3094 # from non-NAT interface to NAT inside interface
3095 pkts = self.create_stream_in(self.pg2, self.pg0)
3096 self.pg2.add_stream(pkts)
3097 self.pg_enable_capture(self.pg_interfaces)
3099 capture = self.pg0.get_capture(len(pkts))
3100 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3102 def test_output_feature_vrf_aware(self):
3103 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3104 nat_ip_vrf10 = "10.0.0.10"
3105 nat_ip_vrf20 = "10.0.0.20"
3107 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3108 dst_address_length=32,
3109 next_hop_address=self.pg3.remote_ip4n,
3110 next_hop_sw_if_index=self.pg3.sw_if_index,
3112 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3113 dst_address_length=32,
3114 next_hop_address=self.pg3.remote_ip4n,
3115 next_hop_sw_if_index=self.pg3.sw_if_index,
3118 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3119 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3120 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3121 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3122 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3126 pkts = self.create_stream_in(self.pg4, self.pg3)
3127 self.pg4.add_stream(pkts)
3128 self.pg_enable_capture(self.pg_interfaces)
3130 capture = self.pg3.get_capture(len(pkts))
3131 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3134 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3135 self.pg3.add_stream(pkts)
3136 self.pg_enable_capture(self.pg_interfaces)
3138 capture = self.pg4.get_capture(len(pkts))
3139 self.verify_capture_in(capture, self.pg4)
3142 pkts = self.create_stream_in(self.pg6, self.pg3)
3143 self.pg6.add_stream(pkts)
3144 self.pg_enable_capture(self.pg_interfaces)
3146 capture = self.pg3.get_capture(len(pkts))
3147 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3150 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3151 self.pg3.add_stream(pkts)
3152 self.pg_enable_capture(self.pg_interfaces)
3154 capture = self.pg6.get_capture(len(pkts))
3155 self.verify_capture_in(capture, self.pg6)
3157 def test_output_feature_hairpinning(self):
3158 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3159 host = self.pg0.remote_hosts[0]
3160 server = self.pg0.remote_hosts[1]
3163 server_in_port = 5678
3164 server_out_port = 8765
3166 self.nat44_add_address(self.nat_addr)
3167 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3168 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3171 # add static mapping for server
3172 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3173 server_in_port, server_out_port,
3174 proto=IP_PROTOS.tcp)
3176 # send packet from host to server
3177 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3178 IP(src=host.ip4, dst=self.nat_addr) /
3179 TCP(sport=host_in_port, dport=server_out_port))
3180 self.pg0.add_stream(p)
3181 self.pg_enable_capture(self.pg_interfaces)
3183 capture = self.pg0.get_capture(1)
3188 self.assertEqual(ip.src, self.nat_addr)
3189 self.assertEqual(ip.dst, server.ip4)
3190 self.assertNotEqual(tcp.sport, host_in_port)
3191 self.assertEqual(tcp.dport, server_in_port)
3192 self.assert_packet_checksums_valid(p)
3193 host_out_port = tcp.sport
3195 self.logger.error(ppp("Unexpected or invalid packet:", p))
3198 # send reply from server to host
3199 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3200 IP(src=server.ip4, dst=self.nat_addr) /
3201 TCP(sport=server_in_port, dport=host_out_port))
3202 self.pg0.add_stream(p)
3203 self.pg_enable_capture(self.pg_interfaces)
3205 capture = self.pg0.get_capture(1)
3210 self.assertEqual(ip.src, self.nat_addr)
3211 self.assertEqual(ip.dst, host.ip4)
3212 self.assertEqual(tcp.sport, server_out_port)
3213 self.assertEqual(tcp.dport, host_in_port)
3214 self.assert_packet_checksums_valid(p)
3216 self.logger.error(ppp("Unexpected or invalid packet:", p))
3219 def test_one_armed_nat44(self):
3220 """ One armed NAT44 """
3221 remote_host = self.pg9.remote_hosts[0]
3222 local_host = self.pg9.remote_hosts[1]
3225 self.nat44_add_address(self.nat_addr)
3226 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3227 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3231 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3232 IP(src=local_host.ip4, dst=remote_host.ip4) /
3233 TCP(sport=12345, dport=80))
3234 self.pg9.add_stream(p)
3235 self.pg_enable_capture(self.pg_interfaces)
3237 capture = self.pg9.get_capture(1)
3242 self.assertEqual(ip.src, self.nat_addr)
3243 self.assertEqual(ip.dst, remote_host.ip4)
3244 self.assertNotEqual(tcp.sport, 12345)
3245 external_port = tcp.sport
3246 self.assertEqual(tcp.dport, 80)
3247 self.assert_packet_checksums_valid(p)
3249 self.logger.error(ppp("Unexpected or invalid packet:", p))
3253 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3254 IP(src=remote_host.ip4, dst=self.nat_addr) /
3255 TCP(sport=80, dport=external_port))
3256 self.pg9.add_stream(p)
3257 self.pg_enable_capture(self.pg_interfaces)
3259 capture = self.pg9.get_capture(1)
3264 self.assertEqual(ip.src, remote_host.ip4)
3265 self.assertEqual(ip.dst, local_host.ip4)
3266 self.assertEqual(tcp.sport, 80)
3267 self.assertEqual(tcp.dport, 12345)
3268 self.assert_packet_checksums_valid(p)
3270 self.logger.error(ppp("Unexpected or invalid packet:", p))
3273 def test_del_session(self):
3274 """ Delete NAT44 session """
3275 self.nat44_add_address(self.nat_addr)
3276 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3277 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3280 pkts = self.create_stream_in(self.pg0, self.pg1)
3281 self.pg0.add_stream(pkts)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 self.pg1.get_capture(len(pkts))
3286 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3287 nsessions = len(sessions)
3289 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3290 sessions[0].inside_port,
3291 sessions[0].protocol)
3292 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3293 sessions[1].outside_port,
3294 sessions[1].protocol,
3297 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3298 self.assertEqual(nsessions - len(sessions), 2)
3300 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3301 sessions[0].inside_port,
3302 sessions[0].protocol)
3304 self.verify_no_nat44_user()
3306 def test_set_get_reass(self):
3307 """ NAT44 set/get virtual fragmentation reassembly """
3308 reas_cfg1 = self.vapi.nat_get_reass()
3310 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3311 max_reass=reas_cfg1.ip4_max_reass * 2,
3312 max_frag=reas_cfg1.ip4_max_frag * 2)
3314 reas_cfg2 = self.vapi.nat_get_reass()
3316 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3317 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3318 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3320 self.vapi.nat_set_reass(drop_frag=1)
3321 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3323 def test_frag_in_order(self):
3324 """ NAT44 translate fragments arriving in order """
3326 self.nat44_add_address(self.nat_addr)
3327 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3328 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3331 data = "A" * 4 + "B" * 16 + "C" * 3
3332 self.tcp_port_in = random.randint(1025, 65535)
3334 reass = self.vapi.nat_reass_dump()
3335 reass_n_start = len(reass)
3338 pkts = self.create_stream_frag(self.pg0,
3339 self.pg1.remote_ip4,
3343 self.pg0.add_stream(pkts)
3344 self.pg_enable_capture(self.pg_interfaces)
3346 frags = self.pg1.get_capture(len(pkts))
3347 p = self.reass_frags_and_verify(frags,
3349 self.pg1.remote_ip4)
3350 self.assertEqual(p[TCP].dport, 20)
3351 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3352 self.tcp_port_out = p[TCP].sport
3353 self.assertEqual(data, p[Raw].load)
3356 pkts = self.create_stream_frag(self.pg1,
3361 self.pg1.add_stream(pkts)
3362 self.pg_enable_capture(self.pg_interfaces)
3364 frags = self.pg0.get_capture(len(pkts))
3365 p = self.reass_frags_and_verify(frags,
3366 self.pg1.remote_ip4,
3367 self.pg0.remote_ip4)
3368 self.assertEqual(p[TCP].sport, 20)
3369 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3370 self.assertEqual(data, p[Raw].load)
3372 reass = self.vapi.nat_reass_dump()
3373 reass_n_end = len(reass)
3375 self.assertEqual(reass_n_end - reass_n_start, 2)
3377 def test_reass_hairpinning(self):
3378 """ NAT44 fragments hairpinning """
3380 server = self.pg0.remote_hosts[1]
3381 host_in_port = random.randint(1025, 65535)
3382 server_in_port = random.randint(1025, 65535)
3383 server_out_port = random.randint(1025, 65535)
3384 data = "A" * 4 + "B" * 16 + "C" * 3
3386 self.nat44_add_address(self.nat_addr)
3387 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3388 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3390 # add static mapping for server
3391 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3392 server_in_port, server_out_port,
3393 proto=IP_PROTOS.tcp)
3395 # send packet from host to server
3396 pkts = self.create_stream_frag(self.pg0,
3401 self.pg0.add_stream(pkts)
3402 self.pg_enable_capture(self.pg_interfaces)
3404 frags = self.pg0.get_capture(len(pkts))
3405 p = self.reass_frags_and_verify(frags,
3408 self.assertNotEqual(p[TCP].sport, host_in_port)
3409 self.assertEqual(p[TCP].dport, server_in_port)
3410 self.assertEqual(data, p[Raw].load)
3412 def test_frag_out_of_order(self):
3413 """ NAT44 translate fragments arriving out of order """
3415 self.nat44_add_address(self.nat_addr)
3416 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3417 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3420 data = "A" * 4 + "B" * 16 + "C" * 3
3421 random.randint(1025, 65535)
3424 pkts = self.create_stream_frag(self.pg0,
3425 self.pg1.remote_ip4,
3430 self.pg0.add_stream(pkts)
3431 self.pg_enable_capture(self.pg_interfaces)
3433 frags = self.pg1.get_capture(len(pkts))
3434 p = self.reass_frags_and_verify(frags,
3436 self.pg1.remote_ip4)
3437 self.assertEqual(p[TCP].dport, 20)
3438 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3439 self.tcp_port_out = p[TCP].sport
3440 self.assertEqual(data, p[Raw].load)
3443 pkts = self.create_stream_frag(self.pg1,
3449 self.pg1.add_stream(pkts)
3450 self.pg_enable_capture(self.pg_interfaces)
3452 frags = self.pg0.get_capture(len(pkts))
3453 p = self.reass_frags_and_verify(frags,
3454 self.pg1.remote_ip4,
3455 self.pg0.remote_ip4)
3456 self.assertEqual(p[TCP].sport, 20)
3457 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3458 self.assertEqual(data, p[Raw].load)
3460 def test_port_restricted(self):
3461 """ Port restricted NAT44 (MAP-E CE) """
3462 self.nat44_add_address(self.nat_addr)
3463 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3464 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3466 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3471 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3472 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3473 TCP(sport=4567, dport=22))
3474 self.pg0.add_stream(p)
3475 self.pg_enable_capture(self.pg_interfaces)
3477 capture = self.pg1.get_capture(1)
3482 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3483 self.assertEqual(ip.src, self.nat_addr)
3484 self.assertEqual(tcp.dport, 22)
3485 self.assertNotEqual(tcp.sport, 4567)
3486 self.assertEqual((tcp.sport >> 6) & 63, 10)
3487 self.assert_packet_checksums_valid(p)
3489 self.logger.error(ppp("Unexpected or invalid packet:", p))
3492 def test_port_range(self):
3493 """ External address port range """
3494 self.nat44_add_address(self.nat_addr)
3495 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3496 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3498 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3503 for port in range(0, 5):
3504 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3505 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3506 TCP(sport=1125 + port))
3508 self.pg0.add_stream(pkts)
3509 self.pg_enable_capture(self.pg_interfaces)
3511 capture = self.pg1.get_capture(3)
3514 self.assertGreaterEqual(tcp.sport, 1025)
3515 self.assertLessEqual(tcp.sport, 1027)
3517 def test_ipfix_max_frags(self):
3518 """ IPFIX logging maximum fragments pending reassembly exceeded """
3519 self.nat44_add_address(self.nat_addr)
3520 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3521 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3523 self.vapi.nat_set_reass(max_frag=1)
3524 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3525 src_address=self.pg3.local_ip4n,
3527 template_interval=10)
3528 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3529 src_port=self.ipfix_src_port)
3531 data = "A" * 4 + "B" * 16 + "C" * 3
3532 self.tcp_port_in = random.randint(1025, 65535)
3533 pkts = self.create_stream_frag(self.pg0,
3534 self.pg1.remote_ip4,
3539 self.pg0.add_stream(pkts)
3540 self.pg_enable_capture(self.pg_interfaces)
3542 self.pg1.assert_nothing_captured()
3544 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3545 capture = self.pg3.get_capture(9)
3546 ipfix = IPFIXDecoder()
3547 # first load template
3549 self.assertTrue(p.haslayer(IPFIX))
3550 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3551 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3552 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3553 self.assertEqual(p[UDP].dport, 4739)
3554 self.assertEqual(p[IPFIX].observationDomainID,
3555 self.ipfix_domain_id)
3556 if p.haslayer(Template):
3557 ipfix.add_template(p.getlayer(Template))
3558 # verify events in data set
3560 if p.haslayer(Data):
3561 data = ipfix.decode_data_set(p.getlayer(Set))
3562 self.verify_ipfix_max_fragments_ip4(data, 1,
3563 self.pg0.remote_ip4n)
3565 def test_multiple_outside_vrf(self):
3566 """ Multiple outside VRF """
3570 self.pg1.unconfig_ip4()
3571 self.pg2.unconfig_ip4()
3572 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3573 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3574 self.pg1.set_table_ip4(vrf_id1)
3575 self.pg2.set_table_ip4(vrf_id2)
3576 self.pg1.config_ip4()
3577 self.pg2.config_ip4()
3578 self.pg1.resolve_arp()
3579 self.pg2.resolve_arp()
3581 self.nat44_add_address(self.nat_addr)
3582 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3583 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3585 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3590 pkts = self.create_stream_in(self.pg0, self.pg1)
3591 self.pg0.add_stream(pkts)
3592 self.pg_enable_capture(self.pg_interfaces)
3594 capture = self.pg1.get_capture(len(pkts))
3595 self.verify_capture_out(capture, self.nat_addr)
3597 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3598 self.pg1.add_stream(pkts)
3599 self.pg_enable_capture(self.pg_interfaces)
3601 capture = self.pg0.get_capture(len(pkts))
3602 self.verify_capture_in(capture, self.pg0)
3604 self.tcp_port_in = 60303
3605 self.udp_port_in = 60304
3606 self.icmp_id_in = 60305
3609 pkts = self.create_stream_in(self.pg0, self.pg2)
3610 self.pg0.add_stream(pkts)
3611 self.pg_enable_capture(self.pg_interfaces)
3613 capture = self.pg2.get_capture(len(pkts))
3614 self.verify_capture_out(capture, self.nat_addr)
3616 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3617 self.pg2.add_stream(pkts)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 capture = self.pg0.get_capture(len(pkts))
3621 self.verify_capture_in(capture, self.pg0)
3624 self.pg1.unconfig_ip4()
3625 self.pg2.unconfig_ip4()
3626 self.pg1.set_table_ip4(0)
3627 self.pg2.set_table_ip4(0)
3628 self.pg1.config_ip4()
3629 self.pg2.config_ip4()
3630 self.pg1.resolve_arp()
3631 self.pg2.resolve_arp()
3633 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3634 def test_session_timeout(self):
3635 """ NAT44 session timeouts """
3636 self.nat44_add_address(self.nat_addr)
3637 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3638 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3640 self.vapi.nat_set_timeouts(udp=5)
3644 for i in range(0, max_sessions):
3645 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3647 IP(src=src, dst=self.pg1.remote_ip4) /
3648 UDP(sport=1025, dport=53))
3650 self.pg0.add_stream(pkts)
3651 self.pg_enable_capture(self.pg_interfaces)
3653 self.pg1.get_capture(max_sessions)
3658 for i in range(0, max_sessions):
3659 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3660 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3661 IP(src=src, dst=self.pg1.remote_ip4) /
3662 UDP(sport=1026, dport=53))
3664 self.pg0.add_stream(pkts)
3665 self.pg_enable_capture(self.pg_interfaces)
3667 self.pg1.get_capture(max_sessions)
3670 users = self.vapi.nat44_user_dump()
3672 nsessions = nsessions + user.nsessions
3673 self.assertLess(nsessions, 2 * max_sessions)
3675 def test_mss_clamping(self):
3676 """ TCP MSS clamping """
3677 self.nat44_add_address(self.nat_addr)
3678 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3679 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3682 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3683 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3684 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3685 flags="S", options=[('MSS', 1400)]))
3687 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3688 self.pg0.add_stream(p)
3689 self.pg_enable_capture(self.pg_interfaces)
3691 capture = self.pg1.get_capture(1)
3692 # Negotiated MSS value greater than configured - changed
3693 self.verify_mss_value(capture[0], 1000)
3695 self.vapi.nat_set_mss_clamping(enable=0)
3696 self.pg0.add_stream(p)
3697 self.pg_enable_capture(self.pg_interfaces)
3699 capture = self.pg1.get_capture(1)
3700 # MSS clamping disabled - negotiated MSS unchanged
3701 self.verify_mss_value(capture[0], 1400)
3703 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3704 self.pg0.add_stream(p)
3705 self.pg_enable_capture(self.pg_interfaces)
3707 capture = self.pg1.get_capture(1)
3708 # Negotiated MSS value smaller than configured - unchanged
3709 self.verify_mss_value(capture[0], 1400)
3712 super(TestNAT44, self).tearDown()
3713 if not self.vpp_dead:
3714 self.logger.info(self.vapi.cli("show nat44 addresses"))
3715 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3716 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3717 self.logger.info(self.vapi.cli("show nat44 interface address"))
3718 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3719 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3720 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3721 self.logger.info(self.vapi.cli("show nat timeouts"))
3723 self.vapi.cli("show nat addr-port-assignment-alg"))
3725 self.vapi.cli("clear logging")
3728 class TestNAT44EndpointDependent(MethodHolder):
3729 """ Endpoint-Dependent mapping and filtering test cases """
3732 def setUpConstants(cls):
3733 super(TestNAT44EndpointDependent, cls).setUpConstants()
3734 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3737 def setUpClass(cls):
3738 super(TestNAT44EndpointDependent, cls).setUpClass()
3739 cls.vapi.cli("set log class nat level debug")
3741 cls.tcp_port_in = 6303
3742 cls.tcp_port_out = 6303
3743 cls.udp_port_in = 6304
3744 cls.udp_port_out = 6304
3745 cls.icmp_id_in = 6305
3746 cls.icmp_id_out = 6305
3747 cls.nat_addr = '10.0.0.3'
3748 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3749 cls.ipfix_src_port = 4739
3750 cls.ipfix_domain_id = 1
3751 cls.tcp_external_port = 80
3753 cls.create_pg_interfaces(range(7))
3754 cls.interfaces = list(cls.pg_interfaces[0:3])
3756 for i in cls.interfaces:
3761 cls.pg0.generate_remote_hosts(3)
3762 cls.pg0.configure_ipv4_neighbors()
3766 cls.pg4.generate_remote_hosts(2)
3767 cls.pg4.config_ip4()
3768 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3769 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3773 cls.pg4.resolve_arp()
3774 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3775 cls.pg4.resolve_arp()
3777 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3778 cls.vapi.ip_table_add_del(1, is_add=1)
3780 cls.pg5._local_ip4 = "10.1.1.1"
3781 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3783 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3784 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3785 socket.AF_INET, cls.pg5.remote_ip4)
3786 cls.pg5.set_table_ip4(1)
3787 cls.pg5.config_ip4()
3789 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3790 dst_address_length=32,
3792 next_hop_sw_if_index=cls.pg5.sw_if_index,
3793 next_hop_address=zero_ip4n)
3795 cls.pg6._local_ip4 = "10.1.2.1"
3796 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3798 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3799 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3800 socket.AF_INET, cls.pg6.remote_ip4)
3801 cls.pg6.set_table_ip4(1)
3802 cls.pg6.config_ip4()
3804 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3805 dst_address_length=32,
3807 next_hop_sw_if_index=cls.pg6.sw_if_index,
3808 next_hop_address=zero_ip4n)
3810 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3811 dst_address_length=16,
3812 next_hop_address=zero_ip4n,
3814 next_hop_table_id=1)
3815 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3816 dst_address_length=0,
3817 next_hop_address=zero_ip4n,
3819 next_hop_table_id=0)
3820 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3821 dst_address_length=0,
3823 next_hop_sw_if_index=cls.pg1.sw_if_index,
3824 next_hop_address=cls.pg1.local_ip4n)
3826 cls.pg5.resolve_arp()
3827 cls.pg6.resolve_arp()
3830 super(TestNAT44EndpointDependent, cls).tearDownClass()
3833 def test_frag_in_order(self):
3834 """ NAT44 translate fragments arriving in order """
3835 self.nat44_add_address(self.nat_addr)
3836 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3837 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3839 self.frag_in_order(proto=IP_PROTOS.tcp)
3840 self.frag_in_order(proto=IP_PROTOS.udp)
3841 self.frag_in_order(proto=IP_PROTOS.icmp)
3843 def test_frag_in_order_dont_translate(self):
3844 """ NAT44 don't translate fragments arriving in order """
3845 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3846 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3848 self.vapi.nat44_forwarding_enable_disable(enable=True)
3849 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3851 def test_frag_out_of_order(self):
3852 """ NAT44 translate fragments arriving out of order """
3853 self.nat44_add_address(self.nat_addr)
3854 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3855 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3857 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3858 self.frag_out_of_order(proto=IP_PROTOS.udp)
3859 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3861 def test_frag_out_of_order_dont_translate(self):
3862 """ NAT44 don't translate fragments arriving out of order """
3863 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3864 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3866 self.vapi.nat44_forwarding_enable_disable(enable=True)
3867 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3869 def test_frag_in_order_in_plus_out(self):
3870 """ in+out interface fragments in order """
3871 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3872 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3874 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3875 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3878 self.server = self.pg1.remote_hosts[0]
3880 self.server_in_addr = self.server.ip4
3881 self.server_out_addr = '11.11.11.11'
3882 self.server_in_port = random.randint(1025, 65535)
3883 self.server_out_port = random.randint(1025, 65535)
3885 self.nat44_add_address(self.server_out_addr)
3887 # add static mappings for server
3888 self.nat44_add_static_mapping(self.server_in_addr,
3889 self.server_out_addr,
3890 self.server_in_port,
3891 self.server_out_port,
3892 proto=IP_PROTOS.tcp)
3893 self.nat44_add_static_mapping(self.server_in_addr,
3894 self.server_out_addr,
3895 self.server_in_port,
3896 self.server_out_port,
3897 proto=IP_PROTOS.udp)
3898 self.nat44_add_static_mapping(self.server_in_addr,
3899 self.server_out_addr,
3900 proto=IP_PROTOS.icmp)
3902 self.vapi.nat_set_reass(timeout=10)
3904 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3905 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3906 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3908 def test_frag_out_of_order_in_plus_out(self):
3909 """ in+out interface fragments out of order """
3910 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3911 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3913 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3914 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3917 self.server = self.pg1.remote_hosts[0]
3919 self.server_in_addr = self.server.ip4
3920 self.server_out_addr = '11.11.11.11'
3921 self.server_in_port = random.randint(1025, 65535)
3922 self.server_out_port = random.randint(1025, 65535)
3924 self.nat44_add_address(self.server_out_addr)
3926 # add static mappings for server
3927 self.nat44_add_static_mapping(self.server_in_addr,
3928 self.server_out_addr,
3929 self.server_in_port,
3930 self.server_out_port,
3931 proto=IP_PROTOS.tcp)
3932 self.nat44_add_static_mapping(self.server_in_addr,
3933 self.server_out_addr,
3934 self.server_in_port,
3935 self.server_out_port,
3936 proto=IP_PROTOS.udp)
3937 self.nat44_add_static_mapping(self.server_in_addr,
3938 self.server_out_addr,
3939 proto=IP_PROTOS.icmp)
3941 self.vapi.nat_set_reass(timeout=10)
3943 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3944 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3945 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3947 def test_reass_hairpinning(self):
3948 """ NAT44 fragments hairpinning """
3949 self.server = self.pg0.remote_hosts[1]
3950 self.host_in_port = random.randint(1025, 65535)
3951 self.server_in_port = random.randint(1025, 65535)
3952 self.server_out_port = random.randint(1025, 65535)
3954 self.nat44_add_address(self.nat_addr)
3955 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3956 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3958 # add static mapping for server
3959 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3960 self.server_in_port,
3961 self.server_out_port,
3962 proto=IP_PROTOS.tcp)
3963 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3964 self.server_in_port,
3965 self.server_out_port,
3966 proto=IP_PROTOS.udp)
3967 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3968 proto=IP_PROTOS.icmp)
3970 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3971 self.reass_hairpinning(proto=IP_PROTOS.udp)
3972 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3974 def test_dynamic(self):
3975 """ NAT44 dynamic translation test """
3977 self.nat44_add_address(self.nat_addr)
3978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3979 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3982 nat_config = self.vapi.nat_show_config()
3983 self.assertEqual(1, nat_config.endpoint_dependent)
3986 pkts = self.create_stream_in(self.pg0, self.pg1)
3987 self.pg0.add_stream(pkts)
3988 self.pg_enable_capture(self.pg_interfaces)
3990 capture = self.pg1.get_capture(len(pkts))
3991 self.verify_capture_out(capture)
3994 pkts = self.create_stream_out(self.pg1)
3995 self.pg1.add_stream(pkts)
3996 self.pg_enable_capture(self.pg_interfaces)
3998 capture = self.pg0.get_capture(len(pkts))
3999 self.verify_capture_in(capture, self.pg0)
4001 def test_forwarding(self):
4002 """ NAT44 forwarding test """
4004 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4005 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4007 self.vapi.nat44_forwarding_enable_disable(1)
4009 real_ip = self.pg0.remote_ip4n
4010 alias_ip = self.nat_addr_n
4011 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4012 external_ip=alias_ip)
4015 # in2out - static mapping match
4017 pkts = self.create_stream_out(self.pg1)
4018 self.pg1.add_stream(pkts)
4019 self.pg_enable_capture(self.pg_interfaces)
4021 capture = self.pg0.get_capture(len(pkts))
4022 self.verify_capture_in(capture, self.pg0)
4024 pkts = self.create_stream_in(self.pg0, self.pg1)
4025 self.pg0.add_stream(pkts)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 capture = self.pg1.get_capture(len(pkts))
4029 self.verify_capture_out(capture, same_port=True)
4031 # in2out - no static mapping match
4033 host0 = self.pg0.remote_hosts[0]
4034 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4036 pkts = self.create_stream_out(self.pg1,
4037 dst_ip=self.pg0.remote_ip4,
4038 use_inside_ports=True)
4039 self.pg1.add_stream(pkts)
4040 self.pg_enable_capture(self.pg_interfaces)
4042 capture = self.pg0.get_capture(len(pkts))
4043 self.verify_capture_in(capture, self.pg0)
4045 pkts = self.create_stream_in(self.pg0, self.pg1)
4046 self.pg0.add_stream(pkts)
4047 self.pg_enable_capture(self.pg_interfaces)
4049 capture = self.pg1.get_capture(len(pkts))
4050 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4053 self.pg0.remote_hosts[0] = host0
4055 user = self.pg0.remote_hosts[1]
4056 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4057 self.assertEqual(len(sessions), 3)
4058 self.assertTrue(sessions[0].ext_host_valid)
4059 self.vapi.nat44_del_session(
4060 sessions[0].inside_ip_address,
4061 sessions[0].inside_port,
4062 sessions[0].protocol,
4063 ext_host_address=sessions[0].ext_host_address,
4064 ext_host_port=sessions[0].ext_host_port)
4065 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4066 self.assertEqual(len(sessions), 2)
4069 self.vapi.nat44_forwarding_enable_disable(0)
4070 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4071 external_ip=alias_ip,
4074 def test_static_lb(self):
4075 """ NAT44 local service load balancing """
4076 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4079 server1 = self.pg0.remote_hosts[0]
4080 server2 = self.pg0.remote_hosts[1]
4082 locals = [{'addr': server1.ip4n,
4086 {'addr': server2.ip4n,
4091 self.nat44_add_address(self.nat_addr)
4092 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4095 local_num=len(locals),
4097 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4098 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4101 # from client to service
4102 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4103 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4104 TCP(sport=12345, dport=external_port))
4105 self.pg1.add_stream(p)
4106 self.pg_enable_capture(self.pg_interfaces)
4108 capture = self.pg0.get_capture(1)
4114 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4115 if ip.dst == server1.ip4:
4119 self.assertEqual(tcp.dport, local_port)
4120 self.assert_packet_checksums_valid(p)
4122 self.logger.error(ppp("Unexpected or invalid packet:", p))
4125 # from service back to client
4126 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4127 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4128 TCP(sport=local_port, dport=12345))
4129 self.pg0.add_stream(p)
4130 self.pg_enable_capture(self.pg_interfaces)
4132 capture = self.pg1.get_capture(1)
4137 self.assertEqual(ip.src, self.nat_addr)
4138 self.assertEqual(tcp.sport, external_port)
4139 self.assert_packet_checksums_valid(p)
4141 self.logger.error(ppp("Unexpected or invalid packet:", p))
4144 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4145 self.assertEqual(len(sessions), 1)
4146 self.assertTrue(sessions[0].ext_host_valid)
4147 self.vapi.nat44_del_session(
4148 sessions[0].inside_ip_address,
4149 sessions[0].inside_port,
4150 sessions[0].protocol,
4151 ext_host_address=sessions[0].ext_host_address,
4152 ext_host_port=sessions[0].ext_host_port)
4153 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4154 self.assertEqual(len(sessions), 0)
4156 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4157 def test_static_lb_multi_clients(self):
4158 """ NAT44 local service load balancing - multiple clients"""
4160 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4163 server1 = self.pg0.remote_hosts[0]
4164 server2 = self.pg0.remote_hosts[1]
4166 locals = [{'addr': server1.ip4n,
4170 {'addr': server2.ip4n,
4175 self.nat44_add_address(self.nat_addr)
4176 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4179 local_num=len(locals),
4181 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4182 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4187 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4189 for client in clients:
4190 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4191 IP(src=client, dst=self.nat_addr) /
4192 TCP(sport=12345, dport=external_port))
4194 self.pg1.add_stream(pkts)
4195 self.pg_enable_capture(self.pg_interfaces)
4197 capture = self.pg0.get_capture(len(pkts))
4199 if p[IP].dst == server1.ip4:
4203 self.assertTrue(server1_n > server2_n)
4205 def test_static_lb_2(self):
4206 """ NAT44 local service load balancing (asymmetrical rule) """
4207 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4210 server1 = self.pg0.remote_hosts[0]
4211 server2 = self.pg0.remote_hosts[1]
4213 locals = [{'addr': server1.ip4n,
4217 {'addr': server2.ip4n,
4222 self.vapi.nat44_forwarding_enable_disable(1)
4223 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4227 local_num=len(locals),
4229 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4230 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4233 # from client to service
4234 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4235 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4236 TCP(sport=12345, dport=external_port))
4237 self.pg1.add_stream(p)
4238 self.pg_enable_capture(self.pg_interfaces)
4240 capture = self.pg0.get_capture(1)
4246 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4247 if ip.dst == server1.ip4:
4251 self.assertEqual(tcp.dport, local_port)
4252 self.assert_packet_checksums_valid(p)
4254 self.logger.error(ppp("Unexpected or invalid packet:", p))
4257 # from service back to client
4258 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4259 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4260 TCP(sport=local_port, dport=12345))
4261 self.pg0.add_stream(p)
4262 self.pg_enable_capture(self.pg_interfaces)
4264 capture = self.pg1.get_capture(1)
4269 self.assertEqual(ip.src, self.nat_addr)
4270 self.assertEqual(tcp.sport, external_port)
4271 self.assert_packet_checksums_valid(p)
4273 self.logger.error(ppp("Unexpected or invalid packet:", p))
4276 # from client to server (no translation)
4277 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4278 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4279 TCP(sport=12346, dport=local_port))
4280 self.pg1.add_stream(p)
4281 self.pg_enable_capture(self.pg_interfaces)
4283 capture = self.pg0.get_capture(1)
4289 self.assertEqual(ip.dst, server1.ip4)
4290 self.assertEqual(tcp.dport, local_port)
4291 self.assert_packet_checksums_valid(p)
4293 self.logger.error(ppp("Unexpected or invalid packet:", p))
4296 # from service back to client (no translation)
4297 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4298 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4299 TCP(sport=local_port, dport=12346))
4300 self.pg0.add_stream(p)
4301 self.pg_enable_capture(self.pg_interfaces)
4303 capture = self.pg1.get_capture(1)
4308 self.assertEqual(ip.src, server1.ip4)
4309 self.assertEqual(tcp.sport, local_port)
4310 self.assert_packet_checksums_valid(p)
4312 self.logger.error(ppp("Unexpected or invalid packet:", p))
4315 def test_lb_affinity(self):
4316 """ NAT44 local service load balancing affinity """
4317 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4320 server1 = self.pg0.remote_hosts[0]
4321 server2 = self.pg0.remote_hosts[1]
4323 locals = [{'addr': server1.ip4n,
4327 {'addr': server2.ip4n,
4332 self.nat44_add_address(self.nat_addr)
4333 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4337 local_num=len(locals),
4339 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4340 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4343 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4344 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4345 TCP(sport=1025, dport=external_port))
4346 self.pg1.add_stream(p)
4347 self.pg_enable_capture(self.pg_interfaces)
4349 capture = self.pg0.get_capture(1)
4350 backend = capture[0][IP].dst
4352 sessions = self.vapi.nat44_user_session_dump(
4353 socket.inet_pton(socket.AF_INET, backend), 0)
4354 self.assertEqual(len(sessions), 1)
4355 self.assertTrue(sessions[0].ext_host_valid)
4356 self.vapi.nat44_del_session(
4357 sessions[0].inside_ip_address,
4358 sessions[0].inside_port,
4359 sessions[0].protocol,
4360 ext_host_address=sessions[0].ext_host_address,
4361 ext_host_port=sessions[0].ext_host_port)
4364 for port in range(1030, 1100):
4365 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4366 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4367 TCP(sport=port, dport=external_port))
4369 self.pg1.add_stream(pkts)
4370 self.pg_enable_capture(self.pg_interfaces)
4372 capture = self.pg0.get_capture(len(pkts))
4374 self.assertEqual(p[IP].dst, backend)
4376 def test_unknown_proto(self):
4377 """ NAT44 translate packet with unknown protocol """
4378 self.nat44_add_address(self.nat_addr)
4379 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4380 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4384 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4385 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4386 TCP(sport=self.tcp_port_in, dport=20))
4387 self.pg0.add_stream(p)
4388 self.pg_enable_capture(self.pg_interfaces)
4390 p = self.pg1.get_capture(1)
4392 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4393 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4395 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4396 TCP(sport=1234, dport=1234))
4397 self.pg0.add_stream(p)
4398 self.pg_enable_capture(self.pg_interfaces)
4400 p = self.pg1.get_capture(1)
4403 self.assertEqual(packet[IP].src, self.nat_addr)
4404 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4405 self.assertTrue(packet.haslayer(GRE))
4406 self.assert_packet_checksums_valid(packet)
4408 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4412 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4413 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4415 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4416 TCP(sport=1234, dport=1234))
4417 self.pg1.add_stream(p)
4418 self.pg_enable_capture(self.pg_interfaces)
4420 p = self.pg0.get_capture(1)
4423 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4424 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4425 self.assertTrue(packet.haslayer(GRE))
4426 self.assert_packet_checksums_valid(packet)
4428 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4431 def test_hairpinning_unknown_proto(self):
4432 """ NAT44 translate packet with unknown protocol - hairpinning """
4433 host = self.pg0.remote_hosts[0]
4434 server = self.pg0.remote_hosts[1]
4436 server_out_port = 8765
4437 server_nat_ip = "10.0.0.11"
4439 self.nat44_add_address(self.nat_addr)
4440 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4441 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4444 # add static mapping for server
4445 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4448 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4449 IP(src=host.ip4, dst=server_nat_ip) /
4450 TCP(sport=host_in_port, dport=server_out_port))
4451 self.pg0.add_stream(p)
4452 self.pg_enable_capture(self.pg_interfaces)
4454 self.pg0.get_capture(1)
4456 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4457 IP(src=host.ip4, dst=server_nat_ip) /
4459 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4460 TCP(sport=1234, dport=1234))
4461 self.pg0.add_stream(p)
4462 self.pg_enable_capture(self.pg_interfaces)
4464 p = self.pg0.get_capture(1)
4467 self.assertEqual(packet[IP].src, self.nat_addr)
4468 self.assertEqual(packet[IP].dst, server.ip4)
4469 self.assertTrue(packet.haslayer(GRE))
4470 self.assert_packet_checksums_valid(packet)
4472 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4476 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4477 IP(src=server.ip4, dst=self.nat_addr) /
4479 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4480 TCP(sport=1234, dport=1234))
4481 self.pg0.add_stream(p)
4482 self.pg_enable_capture(self.pg_interfaces)
4484 p = self.pg0.get_capture(1)
4487 self.assertEqual(packet[IP].src, server_nat_ip)
4488 self.assertEqual(packet[IP].dst, host.ip4)
4489 self.assertTrue(packet.haslayer(GRE))
4490 self.assert_packet_checksums_valid(packet)
4492 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4495 def test_output_feature_and_service(self):
4496 """ NAT44 interface output feature and services """
4497 external_addr = '1.2.3.4'
4501 self.vapi.nat44_forwarding_enable_disable(1)
4502 self.nat44_add_address(self.nat_addr)
4503 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4504 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4505 local_port, external_port,
4506 proto=IP_PROTOS.tcp, out2in_only=1)
4507 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4508 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4510 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4513 # from client to service
4514 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4515 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4516 TCP(sport=12345, dport=external_port))
4517 self.pg1.add_stream(p)
4518 self.pg_enable_capture(self.pg_interfaces)
4520 capture = self.pg0.get_capture(1)
4525 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4526 self.assertEqual(tcp.dport, local_port)
4527 self.assert_packet_checksums_valid(p)
4529 self.logger.error(ppp("Unexpected or invalid packet:", p))
4532 # from service back to client
4533 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4534 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4535 TCP(sport=local_port, dport=12345))
4536 self.pg0.add_stream(p)
4537 self.pg_enable_capture(self.pg_interfaces)
4539 capture = self.pg1.get_capture(1)
4544 self.assertEqual(ip.src, external_addr)
4545 self.assertEqual(tcp.sport, external_port)
4546 self.assert_packet_checksums_valid(p)
4548 self.logger.error(ppp("Unexpected or invalid packet:", p))
4551 # from local network host to external network
4552 pkts = self.create_stream_in(self.pg0, self.pg1)
4553 self.pg0.add_stream(pkts)
4554 self.pg_enable_capture(self.pg_interfaces)
4556 capture = self.pg1.get_capture(len(pkts))
4557 self.verify_capture_out(capture)
4558 pkts = self.create_stream_in(self.pg0, self.pg1)
4559 self.pg0.add_stream(pkts)
4560 self.pg_enable_capture(self.pg_interfaces)
4562 capture = self.pg1.get_capture(len(pkts))
4563 self.verify_capture_out(capture)
4565 # from external network back to local network host
4566 pkts = self.create_stream_out(self.pg1)
4567 self.pg1.add_stream(pkts)
4568 self.pg_enable_capture(self.pg_interfaces)
4570 capture = self.pg0.get_capture(len(pkts))
4571 self.verify_capture_in(capture, self.pg0)
4573 def test_output_feature_and_service2(self):
4574 """ NAT44 interface output feature and service host direct access """
4575 self.vapi.nat44_forwarding_enable_disable(1)
4576 self.nat44_add_address(self.nat_addr)
4577 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4580 # session initiaded from service host - translate
4581 pkts = self.create_stream_in(self.pg0, self.pg1)
4582 self.pg0.add_stream(pkts)
4583 self.pg_enable_capture(self.pg_interfaces)
4585 capture = self.pg1.get_capture(len(pkts))
4586 self.verify_capture_out(capture)
4588 pkts = self.create_stream_out(self.pg1)
4589 self.pg1.add_stream(pkts)
4590 self.pg_enable_capture(self.pg_interfaces)
4592 capture = self.pg0.get_capture(len(pkts))
4593 self.verify_capture_in(capture, self.pg0)
4595 # session initiaded from remote host - do not translate
4596 self.tcp_port_in = 60303
4597 self.udp_port_in = 60304
4598 self.icmp_id_in = 60305
4599 pkts = self.create_stream_out(self.pg1,
4600 self.pg0.remote_ip4,
4601 use_inside_ports=True)
4602 self.pg1.add_stream(pkts)
4603 self.pg_enable_capture(self.pg_interfaces)
4605 capture = self.pg0.get_capture(len(pkts))
4606 self.verify_capture_in(capture, self.pg0)
4608 pkts = self.create_stream_in(self.pg0, self.pg1)
4609 self.pg0.add_stream(pkts)
4610 self.pg_enable_capture(self.pg_interfaces)
4612 capture = self.pg1.get_capture(len(pkts))
4613 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4616 def test_output_feature_and_service3(self):
4617 """ NAT44 interface output feature and DST NAT """
4618 external_addr = '1.2.3.4'
4622 self.vapi.nat44_forwarding_enable_disable(1)
4623 self.nat44_add_address(self.nat_addr)
4624 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4625 local_port, external_port,
4626 proto=IP_PROTOS.tcp, out2in_only=1)
4627 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4628 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4630 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4633 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4634 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4635 TCP(sport=12345, dport=external_port))
4636 self.pg0.add_stream(p)
4637 self.pg_enable_capture(self.pg_interfaces)
4639 capture = self.pg1.get_capture(1)
4644 self.assertEqual(ip.src, self.pg0.remote_ip4)
4645 self.assertEqual(tcp.sport, 12345)
4646 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4647 self.assertEqual(tcp.dport, local_port)
4648 self.assert_packet_checksums_valid(p)
4650 self.logger.error(ppp("Unexpected or invalid packet:", p))
4653 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4654 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4655 TCP(sport=local_port, dport=12345))
4656 self.pg1.add_stream(p)
4657 self.pg_enable_capture(self.pg_interfaces)
4659 capture = self.pg0.get_capture(1)
4664 self.assertEqual(ip.src, external_addr)
4665 self.assertEqual(tcp.sport, external_port)
4666 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4667 self.assertEqual(tcp.dport, 12345)
4668 self.assert_packet_checksums_valid(p)
4670 self.logger.error(ppp("Unexpected or invalid packet:", p))
4673 def test_next_src_nat(self):
4674 """ On way back forward packet to nat44-in2out node. """
4675 twice_nat_addr = '10.0.1.3'
4678 post_twice_nat_port = 0
4680 self.vapi.nat44_forwarding_enable_disable(1)
4681 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4682 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4683 local_port, external_port,
4684 proto=IP_PROTOS.tcp, out2in_only=1,
4685 self_twice_nat=1, vrf_id=1)
4686 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4689 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4690 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4691 TCP(sport=12345, dport=external_port))
4692 self.pg6.add_stream(p)
4693 self.pg_enable_capture(self.pg_interfaces)
4695 capture = self.pg6.get_capture(1)
4700 self.assertEqual(ip.src, twice_nat_addr)
4701 self.assertNotEqual(tcp.sport, 12345)
4702 post_twice_nat_port = tcp.sport
4703 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4704 self.assertEqual(tcp.dport, local_port)
4705 self.assert_packet_checksums_valid(p)
4707 self.logger.error(ppp("Unexpected or invalid packet:", p))
4710 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4711 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4712 TCP(sport=local_port, dport=post_twice_nat_port))
4713 self.pg6.add_stream(p)
4714 self.pg_enable_capture(self.pg_interfaces)
4716 capture = self.pg6.get_capture(1)
4721 self.assertEqual(ip.src, self.pg1.remote_ip4)
4722 self.assertEqual(tcp.sport, external_port)
4723 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4724 self.assertEqual(tcp.dport, 12345)
4725 self.assert_packet_checksums_valid(p)
4727 self.logger.error(ppp("Unexpected or invalid packet:", p))
4730 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4732 twice_nat_addr = '10.0.1.3'
4740 port_in1 = port_in+1
4741 port_in2 = port_in+2
4746 server1 = self.pg0.remote_hosts[0]
4747 server2 = self.pg0.remote_hosts[1]
4759 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4762 self.nat44_add_address(self.nat_addr)
4763 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4765 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4767 proto=IP_PROTOS.tcp,
4768 twice_nat=int(not self_twice_nat),
4769 self_twice_nat=int(self_twice_nat))
4771 locals = [{'addr': server1.ip4n,
4775 {'addr': server2.ip4n,
4779 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4780 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4784 not self_twice_nat),
4787 local_num=len(locals),
4789 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4790 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4797 assert client_id is not None
4799 client = self.pg0.remote_hosts[0]
4800 elif client_id == 2:
4801 client = self.pg0.remote_hosts[1]
4803 client = pg1.remote_hosts[0]
4804 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4805 IP(src=client.ip4, dst=self.nat_addr) /
4806 TCP(sport=eh_port_out, dport=port_out))
4808 self.pg_enable_capture(self.pg_interfaces)
4810 capture = pg0.get_capture(1)
4816 if ip.dst == server1.ip4:
4822 self.assertEqual(ip.dst, server.ip4)
4824 self.assertIn(tcp.dport, [port_in1, port_in2])
4826 self.assertEqual(tcp.dport, port_in)
4828 self.assertEqual(ip.src, twice_nat_addr)
4829 self.assertNotEqual(tcp.sport, eh_port_out)
4831 self.assertEqual(ip.src, client.ip4)
4832 self.assertEqual(tcp.sport, eh_port_out)
4834 eh_port_in = tcp.sport
4835 saved_port_in = tcp.dport
4836 self.assert_packet_checksums_valid(p)
4838 self.logger.error(ppp("Unexpected or invalid packet:", p))
4841 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4842 IP(src=server.ip4, dst=eh_addr_in) /
4843 TCP(sport=saved_port_in, dport=eh_port_in))
4845 self.pg_enable_capture(self.pg_interfaces)
4847 capture = pg1.get_capture(1)
4852 self.assertEqual(ip.dst, client.ip4)
4853 self.assertEqual(ip.src, self.nat_addr)
4854 self.assertEqual(tcp.dport, eh_port_out)
4855 self.assertEqual(tcp.sport, port_out)
4856 self.assert_packet_checksums_valid(p)
4858 self.logger.error(ppp("Unexpected or invalid packet:", p))
4862 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4863 self.assertEqual(len(sessions), 1)
4864 self.assertTrue(sessions[0].ext_host_valid)
4865 self.assertTrue(sessions[0].is_twicenat)
4866 self.vapi.nat44_del_session(
4867 sessions[0].inside_ip_address,
4868 sessions[0].inside_port,
4869 sessions[0].protocol,
4870 ext_host_address=sessions[0].ext_host_nat_address,
4871 ext_host_port=sessions[0].ext_host_nat_port)
4872 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4873 self.assertEqual(len(sessions), 0)
4875 def test_twice_nat(self):
4877 self.twice_nat_common()
4879 def test_self_twice_nat_positive(self):
4880 """ Self Twice NAT44 (positive test) """
4881 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4883 def test_self_twice_nat_negative(self):
4884 """ Self Twice NAT44 (negative test) """
4885 self.twice_nat_common(self_twice_nat=True)
4887 def test_twice_nat_lb(self):
4888 """ Twice NAT44 local service load balancing """
4889 self.twice_nat_common(lb=True)
4891 def test_self_twice_nat_lb_positive(self):
4892 """ Self Twice NAT44 local service load balancing (positive test) """
4893 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4896 def test_self_twice_nat_lb_negative(self):
4897 """ Self Twice NAT44 local service load balancing (negative test) """
4898 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4901 def test_twice_nat_interface_addr(self):
4902 """ Acquire twice NAT44 addresses from interface """
4903 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4905 # no address in NAT pool
4906 adresses = self.vapi.nat44_address_dump()
4907 self.assertEqual(0, len(adresses))
4909 # configure interface address and check NAT address pool
4910 self.pg3.config_ip4()
4911 adresses = self.vapi.nat44_address_dump()
4912 self.assertEqual(1, len(adresses))
4913 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4914 self.assertEqual(adresses[0].twice_nat, 1)
4916 # remove interface address and check NAT address pool
4917 self.pg3.unconfig_ip4()
4918 adresses = self.vapi.nat44_address_dump()
4919 self.assertEqual(0, len(adresses))
4921 def test_tcp_session_close_in(self):
4922 """ Close TCP session from inside network """
4923 self.tcp_port_out = 10505
4924 self.nat44_add_address(self.nat_addr)
4925 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4929 proto=IP_PROTOS.tcp,
4931 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4932 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4935 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4936 start_sessnum = len(sessions)
4938 self.initiate_tcp_session(self.pg0, self.pg1)
4940 # FIN packet in -> out
4941 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4942 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4943 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4944 flags="FA", seq=100, ack=300))
4945 self.pg0.add_stream(p)
4946 self.pg_enable_capture(self.pg_interfaces)
4948 self.pg1.get_capture(1)
4952 # ACK packet out -> in
4953 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4954 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4955 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4956 flags="A", seq=300, ack=101))
4959 # FIN packet out -> in
4960 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4961 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4962 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4963 flags="FA", seq=300, ack=101))
4966 self.pg1.add_stream(pkts)
4967 self.pg_enable_capture(self.pg_interfaces)
4969 self.pg0.get_capture(2)
4971 # ACK packet in -> out
4972 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4973 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4974 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4975 flags="A", seq=101, ack=301))
4976 self.pg0.add_stream(p)
4977 self.pg_enable_capture(self.pg_interfaces)
4979 self.pg1.get_capture(1)
4981 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4983 self.assertEqual(len(sessions) - start_sessnum, 0)
4985 def test_tcp_session_close_out(self):
4986 """ Close TCP session from outside network """
4987 self.tcp_port_out = 10505
4988 self.nat44_add_address(self.nat_addr)
4989 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4993 proto=IP_PROTOS.tcp,
4995 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4996 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4999 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5000 start_sessnum = len(sessions)
5002 self.initiate_tcp_session(self.pg0, self.pg1)
5004 # FIN packet out -> in
5005 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5006 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5007 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5008 flags="FA", seq=100, ack=300))
5009 self.pg1.add_stream(p)
5010 self.pg_enable_capture(self.pg_interfaces)
5012 self.pg0.get_capture(1)
5014 # FIN+ACK packet in -> out
5015 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5016 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5017 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5018 flags="FA", seq=300, ack=101))
5020 self.pg0.add_stream(p)
5021 self.pg_enable_capture(self.pg_interfaces)
5023 self.pg1.get_capture(1)
5025 # ACK packet out -> in
5026 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5027 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5028 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5029 flags="A", seq=101, ack=301))
5030 self.pg1.add_stream(p)
5031 self.pg_enable_capture(self.pg_interfaces)
5033 self.pg0.get_capture(1)
5035 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5037 self.assertEqual(len(sessions) - start_sessnum, 0)
5039 def test_tcp_session_close_simultaneous(self):
5040 """ Close TCP session from inside network """
5041 self.tcp_port_out = 10505
5042 self.nat44_add_address(self.nat_addr)
5043 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5047 proto=IP_PROTOS.tcp,
5049 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5050 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5053 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5054 start_sessnum = len(sessions)
5056 self.initiate_tcp_session(self.pg0, self.pg1)
5058 # FIN packet in -> out
5059 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5060 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5061 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5062 flags="FA", seq=100, ack=300))
5063 self.pg0.add_stream(p)
5064 self.pg_enable_capture(self.pg_interfaces)
5066 self.pg1.get_capture(1)
5068 # FIN packet out -> in
5069 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5070 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5071 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5072 flags="FA", seq=300, ack=100))
5073 self.pg1.add_stream(p)
5074 self.pg_enable_capture(self.pg_interfaces)
5076 self.pg0.get_capture(1)
5078 # ACK packet in -> out
5079 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5080 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5081 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5082 flags="A", seq=101, ack=301))
5083 self.pg0.add_stream(p)
5084 self.pg_enable_capture(self.pg_interfaces)
5086 self.pg1.get_capture(1)
5088 # ACK packet out -> in
5089 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5090 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5091 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5092 flags="A", seq=301, ack=101))
5093 self.pg1.add_stream(p)
5094 self.pg_enable_capture(self.pg_interfaces)
5096 self.pg0.get_capture(1)
5098 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5100 self.assertEqual(len(sessions) - start_sessnum, 0)
5102 def test_one_armed_nat44_static(self):
5103 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5104 remote_host = self.pg4.remote_hosts[0]
5105 local_host = self.pg4.remote_hosts[1]
5110 self.vapi.nat44_forwarding_enable_disable(1)
5111 self.nat44_add_address(self.nat_addr, twice_nat=1)
5112 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5113 local_port, external_port,
5114 proto=IP_PROTOS.tcp, out2in_only=1,
5116 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5117 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5120 # from client to service
5121 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5122 IP(src=remote_host.ip4, dst=self.nat_addr) /
5123 TCP(sport=12345, dport=external_port))
5124 self.pg4.add_stream(p)
5125 self.pg_enable_capture(self.pg_interfaces)
5127 capture = self.pg4.get_capture(1)
5132 self.assertEqual(ip.dst, local_host.ip4)
5133 self.assertEqual(ip.src, self.nat_addr)
5134 self.assertEqual(tcp.dport, local_port)
5135 self.assertNotEqual(tcp.sport, 12345)
5136 eh_port_in = tcp.sport
5137 self.assert_packet_checksums_valid(p)
5139 self.logger.error(ppp("Unexpected or invalid packet:", p))
5142 # from service back to client
5143 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5144 IP(src=local_host.ip4, dst=self.nat_addr) /
5145 TCP(sport=local_port, dport=eh_port_in))
5146 self.pg4.add_stream(p)
5147 self.pg_enable_capture(self.pg_interfaces)
5149 capture = self.pg4.get_capture(1)
5154 self.assertEqual(ip.src, self.nat_addr)
5155 self.assertEqual(ip.dst, remote_host.ip4)
5156 self.assertEqual(tcp.sport, external_port)
5157 self.assertEqual(tcp.dport, 12345)
5158 self.assert_packet_checksums_valid(p)
5160 self.logger.error(ppp("Unexpected or invalid packet:", p))
5163 def test_static_with_port_out2(self):
5164 """ 1:1 NAPT asymmetrical rule """
5169 self.vapi.nat44_forwarding_enable_disable(1)
5170 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5171 local_port, external_port,
5172 proto=IP_PROTOS.tcp, out2in_only=1)
5173 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5174 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5177 # from client to service
5178 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5179 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5180 TCP(sport=12345, dport=external_port))
5181 self.pg1.add_stream(p)
5182 self.pg_enable_capture(self.pg_interfaces)
5184 capture = self.pg0.get_capture(1)
5189 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5190 self.assertEqual(tcp.dport, local_port)
5191 self.assert_packet_checksums_valid(p)
5193 self.logger.error(ppp("Unexpected or invalid packet:", p))
5197 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5198 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5199 ICMP(type=11) / capture[0][IP])
5200 self.pg0.add_stream(p)
5201 self.pg_enable_capture(self.pg_interfaces)
5203 capture = self.pg1.get_capture(1)
5206 self.assertEqual(p[IP].src, self.nat_addr)
5208 self.assertEqual(inner.dst, self.nat_addr)
5209 self.assertEqual(inner[TCPerror].dport, external_port)
5211 self.logger.error(ppp("Unexpected or invalid packet:", p))
5214 # from service back to client
5215 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5216 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5217 TCP(sport=local_port, dport=12345))
5218 self.pg0.add_stream(p)
5219 self.pg_enable_capture(self.pg_interfaces)
5221 capture = self.pg1.get_capture(1)
5226 self.assertEqual(ip.src, self.nat_addr)
5227 self.assertEqual(tcp.sport, external_port)
5228 self.assert_packet_checksums_valid(p)
5230 self.logger.error(ppp("Unexpected or invalid packet:", p))
5234 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5235 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5236 ICMP(type=11) / capture[0][IP])
5237 self.pg1.add_stream(p)
5238 self.pg_enable_capture(self.pg_interfaces)
5240 capture = self.pg0.get_capture(1)
5243 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5245 self.assertEqual(inner.src, self.pg0.remote_ip4)
5246 self.assertEqual(inner[TCPerror].sport, local_port)
5248 self.logger.error(ppp("Unexpected or invalid packet:", p))
5251 # from client to server (no translation)
5252 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5253 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5254 TCP(sport=12346, dport=local_port))
5255 self.pg1.add_stream(p)
5256 self.pg_enable_capture(self.pg_interfaces)
5258 capture = self.pg0.get_capture(1)
5263 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5264 self.assertEqual(tcp.dport, local_port)
5265 self.assert_packet_checksums_valid(p)
5267 self.logger.error(ppp("Unexpected or invalid packet:", p))
5270 # from service back to client (no translation)
5271 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5272 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5273 TCP(sport=local_port, dport=12346))
5274 self.pg0.add_stream(p)
5275 self.pg_enable_capture(self.pg_interfaces)
5277 capture = self.pg1.get_capture(1)
5282 self.assertEqual(ip.src, self.pg0.remote_ip4)
5283 self.assertEqual(tcp.sport, local_port)
5284 self.assert_packet_checksums_valid(p)
5286 self.logger.error(ppp("Unexpected or invalid packet:", p))
5289 def test_output_feature(self):
5290 """ NAT44 interface output feature (in2out postrouting) """
5291 self.vapi.nat44_forwarding_enable_disable(1)
5292 self.nat44_add_address(self.nat_addr)
5293 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5295 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5299 pkts = self.create_stream_in(self.pg0, self.pg1)
5300 self.pg0.add_stream(pkts)
5301 self.pg_enable_capture(self.pg_interfaces)
5303 capture = self.pg1.get_capture(len(pkts))
5304 self.verify_capture_out(capture)
5307 pkts = self.create_stream_out(self.pg1)
5308 self.pg1.add_stream(pkts)
5309 self.pg_enable_capture(self.pg_interfaces)
5311 capture = self.pg0.get_capture(len(pkts))
5312 self.verify_capture_in(capture, self.pg0)
5314 def test_multiple_vrf(self):
5315 """ Multiple VRF setup """
5316 external_addr = '1.2.3.4'
5321 self.vapi.nat44_forwarding_enable_disable(1)
5322 self.nat44_add_address(self.nat_addr)
5323 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5324 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5326 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5328 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5329 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5331 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5333 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5334 local_port, external_port, vrf_id=1,
5335 proto=IP_PROTOS.tcp, out2in_only=1)
5336 self.nat44_add_static_mapping(
5337 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5338 local_port=local_port, vrf_id=0, external_port=external_port,
5339 proto=IP_PROTOS.tcp, out2in_only=1)
5341 # from client to service (both VRF1)
5342 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5343 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5344 TCP(sport=12345, dport=external_port))
5345 self.pg6.add_stream(p)
5346 self.pg_enable_capture(self.pg_interfaces)
5348 capture = self.pg5.get_capture(1)
5353 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5354 self.assertEqual(tcp.dport, local_port)
5355 self.assert_packet_checksums_valid(p)
5357 self.logger.error(ppp("Unexpected or invalid packet:", p))
5360 # from service back to client (both VRF1)
5361 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5362 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5363 TCP(sport=local_port, dport=12345))
5364 self.pg5.add_stream(p)
5365 self.pg_enable_capture(self.pg_interfaces)
5367 capture = self.pg6.get_capture(1)
5372 self.assertEqual(ip.src, external_addr)
5373 self.assertEqual(tcp.sport, external_port)
5374 self.assert_packet_checksums_valid(p)
5376 self.logger.error(ppp("Unexpected or invalid packet:", p))
5379 # dynamic NAT from VRF1 to VRF0 (output-feature)
5380 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5381 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5382 TCP(sport=2345, dport=22))
5383 self.pg5.add_stream(p)
5384 self.pg_enable_capture(self.pg_interfaces)
5386 capture = self.pg1.get_capture(1)
5391 self.assertEqual(ip.src, self.nat_addr)
5392 self.assertNotEqual(tcp.sport, 2345)
5393 self.assert_packet_checksums_valid(p)
5396 self.logger.error(ppp("Unexpected or invalid packet:", p))
5399 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5400 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5401 TCP(sport=22, dport=port))
5402 self.pg1.add_stream(p)
5403 self.pg_enable_capture(self.pg_interfaces)
5405 capture = self.pg5.get_capture(1)
5410 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5411 self.assertEqual(tcp.dport, 2345)
5412 self.assert_packet_checksums_valid(p)
5414 self.logger.error(ppp("Unexpected or invalid packet:", p))
5417 # from client VRF1 to service VRF0
5418 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5419 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5420 TCP(sport=12346, dport=external_port))
5421 self.pg6.add_stream(p)
5422 self.pg_enable_capture(self.pg_interfaces)
5424 capture = self.pg0.get_capture(1)
5429 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5430 self.assertEqual(tcp.dport, local_port)
5431 self.assert_packet_checksums_valid(p)
5433 self.logger.error(ppp("Unexpected or invalid packet:", p))
5436 # from service VRF0 back to client VRF1
5437 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5438 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5439 TCP(sport=local_port, dport=12346))
5440 self.pg0.add_stream(p)
5441 self.pg_enable_capture(self.pg_interfaces)
5443 capture = self.pg6.get_capture(1)
5448 self.assertEqual(ip.src, self.pg0.local_ip4)
5449 self.assertEqual(tcp.sport, external_port)
5450 self.assert_packet_checksums_valid(p)
5452 self.logger.error(ppp("Unexpected or invalid packet:", p))
5455 # from client VRF0 to service VRF1
5456 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5457 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5458 TCP(sport=12347, dport=external_port))
5459 self.pg0.add_stream(p)
5460 self.pg_enable_capture(self.pg_interfaces)
5462 capture = self.pg5.get_capture(1)
5467 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5468 self.assertEqual(tcp.dport, local_port)
5469 self.assert_packet_checksums_valid(p)
5471 self.logger.error(ppp("Unexpected or invalid packet:", p))
5474 # from service VRF1 back to client VRF0
5475 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5476 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5477 TCP(sport=local_port, dport=12347))
5478 self.pg5.add_stream(p)
5479 self.pg_enable_capture(self.pg_interfaces)
5481 capture = self.pg0.get_capture(1)
5486 self.assertEqual(ip.src, external_addr)
5487 self.assertEqual(tcp.sport, external_port)
5488 self.assert_packet_checksums_valid(p)
5490 self.logger.error(ppp("Unexpected or invalid packet:", p))
5493 # from client to server (both VRF1, no translation)
5494 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5495 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5496 TCP(sport=12348, dport=local_port))
5497 self.pg6.add_stream(p)
5498 self.pg_enable_capture(self.pg_interfaces)
5500 capture = self.pg5.get_capture(1)
5505 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5506 self.assertEqual(tcp.dport, local_port)
5507 self.assert_packet_checksums_valid(p)
5509 self.logger.error(ppp("Unexpected or invalid packet:", p))
5512 # from server back to client (both VRF1, no translation)
5513 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5514 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5515 TCP(sport=local_port, dport=12348))
5516 self.pg5.add_stream(p)
5517 self.pg_enable_capture(self.pg_interfaces)
5519 capture = self.pg6.get_capture(1)
5524 self.assertEqual(ip.src, self.pg5.remote_ip4)
5525 self.assertEqual(tcp.sport, local_port)
5526 self.assert_packet_checksums_valid(p)
5528 self.logger.error(ppp("Unexpected or invalid packet:", p))
5531 # from client VRF1 to server VRF0 (no translation)
5532 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5533 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5534 TCP(sport=local_port, dport=12349))
5535 self.pg0.add_stream(p)
5536 self.pg_enable_capture(self.pg_interfaces)
5538 capture = self.pg6.get_capture(1)
5543 self.assertEqual(ip.src, self.pg0.remote_ip4)
5544 self.assertEqual(tcp.sport, local_port)
5545 self.assert_packet_checksums_valid(p)
5547 self.logger.error(ppp("Unexpected or invalid packet:", p))
5550 # from server VRF0 back to client VRF1 (no translation)
5551 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5552 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5553 TCP(sport=local_port, dport=12349))
5554 self.pg0.add_stream(p)
5555 self.pg_enable_capture(self.pg_interfaces)
5557 capture = self.pg6.get_capture(1)
5562 self.assertEqual(ip.src, self.pg0.remote_ip4)
5563 self.assertEqual(tcp.sport, local_port)
5564 self.assert_packet_checksums_valid(p)
5566 self.logger.error(ppp("Unexpected or invalid packet:", p))
5569 # from client VRF0 to server VRF1 (no translation)
5570 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5571 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5572 TCP(sport=12344, dport=local_port))
5573 self.pg0.add_stream(p)
5574 self.pg_enable_capture(self.pg_interfaces)
5576 capture = self.pg5.get_capture(1)
5581 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5582 self.assertEqual(tcp.dport, local_port)
5583 self.assert_packet_checksums_valid(p)
5585 self.logger.error(ppp("Unexpected or invalid packet:", p))
5588 # from server VRF1 back to client VRF0 (no translation)
5589 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5590 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5591 TCP(sport=local_port, dport=12344))
5592 self.pg5.add_stream(p)
5593 self.pg_enable_capture(self.pg_interfaces)
5595 capture = self.pg0.get_capture(1)
5600 self.assertEqual(ip.src, self.pg5.remote_ip4)
5601 self.assertEqual(tcp.sport, local_port)
5602 self.assert_packet_checksums_valid(p)
5604 self.logger.error(ppp("Unexpected or invalid packet:", p))
5607 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5608 def test_session_timeout(self):
5609 """ NAT44 session timeouts """
5610 self.nat44_add_address(self.nat_addr)
5611 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5612 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5614 self.vapi.nat_set_timeouts(icmp=5)
5618 for i in range(0, max_sessions):
5619 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5620 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5621 IP(src=src, dst=self.pg1.remote_ip4) /
5622 ICMP(id=1025, type='echo-request'))
5624 self.pg0.add_stream(pkts)
5625 self.pg_enable_capture(self.pg_interfaces)
5627 self.pg1.get_capture(max_sessions)
5632 for i in range(0, max_sessions):
5633 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5634 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5635 IP(src=src, dst=self.pg1.remote_ip4) /
5636 ICMP(id=1026, type='echo-request'))
5638 self.pg0.add_stream(pkts)
5639 self.pg_enable_capture(self.pg_interfaces)
5641 self.pg1.get_capture(max_sessions)
5644 users = self.vapi.nat44_user_dump()
5646 nsessions = nsessions + user.nsessions
5647 self.assertLess(nsessions, 2 * max_sessions)
5649 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5650 def test_session_limit_per_user(self):
5651 """ Maximum sessions per user limit """
5652 self.nat44_add_address(self.nat_addr)
5653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5654 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5656 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5657 src_address=self.pg2.local_ip4n,
5659 template_interval=10)
5660 self.vapi.nat_set_timeouts(udp=5)
5662 # get maximum number of translations per user
5663 nat44_config = self.vapi.nat_show_config()
5666 for port in range(0, nat44_config.max_translations_per_user):
5667 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5668 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5669 UDP(sport=1025 + port, dport=1025 + port))
5672 self.pg0.add_stream(pkts)
5673 self.pg_enable_capture(self.pg_interfaces)
5675 capture = self.pg1.get_capture(len(pkts))
5677 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5678 src_port=self.ipfix_src_port)
5680 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5681 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5682 UDP(sport=3001, dport=3002))
5683 self.pg0.add_stream(p)
5684 self.pg_enable_capture(self.pg_interfaces)
5686 capture = self.pg1.assert_nothing_captured()
5688 # verify IPFIX logging
5689 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5691 capture = self.pg2.get_capture(10)
5692 ipfix = IPFIXDecoder()
5693 # first load template
5695 self.assertTrue(p.haslayer(IPFIX))
5696 if p.haslayer(Template):
5697 ipfix.add_template(p.getlayer(Template))
5698 # verify events in data set
5700 if p.haslayer(Data):
5701 data = ipfix.decode_data_set(p.getlayer(Set))
5702 self.verify_ipfix_max_entries_per_user(
5704 nat44_config.max_translations_per_user,
5705 self.pg0.remote_ip4n)
5708 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5709 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5710 UDP(sport=3001, dport=3002))
5711 self.pg0.add_stream(p)
5712 self.pg_enable_capture(self.pg_interfaces)
5714 self.pg1.get_capture(1)
5717 super(TestNAT44EndpointDependent, self).tearDown()
5718 if not self.vpp_dead:
5719 self.logger.info(self.vapi.cli("show nat44 addresses"))
5720 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5721 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5722 self.logger.info(self.vapi.cli("show nat44 interface address"))
5723 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5724 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5725 self.logger.info(self.vapi.cli("show nat timeouts"))
5727 self.vapi.cli("clear logging")
5730 class TestNAT44Out2InDPO(MethodHolder):
5731 """ NAT44 Test Cases using out2in DPO """
5734 def setUpConstants(cls):
5735 super(TestNAT44Out2InDPO, cls).setUpConstants()
5736 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5739 def setUpClass(cls):
5740 super(TestNAT44Out2InDPO, cls).setUpClass()
5741 cls.vapi.cli("set log class nat level debug")
5744 cls.tcp_port_in = 6303
5745 cls.tcp_port_out = 6303
5746 cls.udp_port_in = 6304
5747 cls.udp_port_out = 6304
5748 cls.icmp_id_in = 6305
5749 cls.icmp_id_out = 6305
5750 cls.nat_addr = '10.0.0.3'
5751 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5752 cls.dst_ip4 = '192.168.70.1'
5754 cls.create_pg_interfaces(range(2))
5757 cls.pg0.config_ip4()
5758 cls.pg0.resolve_arp()
5761 cls.pg1.config_ip6()
5762 cls.pg1.resolve_ndp()
5764 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5765 dst_address_length=0,
5766 next_hop_address=cls.pg1.remote_ip6n,
5767 next_hop_sw_if_index=cls.pg1.sw_if_index)
5770 super(TestNAT44Out2InDPO, cls).tearDownClass()
5773 def configure_xlat(self):
5774 self.dst_ip6_pfx = '1:2:3::'
5775 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5777 self.dst_ip6_pfx_len = 96
5778 self.src_ip6_pfx = '4:5:6::'
5779 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5781 self.src_ip6_pfx_len = 96
5782 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5783 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5784 '\x00\x00\x00\x00', 0, is_translation=1,
5787 def test_464xlat_ce(self):
5788 """ Test 464XLAT CE with NAT44 """
5790 nat_config = self.vapi.nat_show_config()
5791 self.assertEqual(1, nat_config.out2in_dpo)
5793 self.configure_xlat()
5795 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5796 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5798 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5799 self.dst_ip6_pfx_len)
5800 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5801 self.src_ip6_pfx_len)
5804 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5805 self.pg0.add_stream(pkts)
5806 self.pg_enable_capture(self.pg_interfaces)
5808 capture = self.pg1.get_capture(len(pkts))
5809 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5812 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5814 self.pg1.add_stream(pkts)
5815 self.pg_enable_capture(self.pg_interfaces)
5817 capture = self.pg0.get_capture(len(pkts))
5818 self.verify_capture_in(capture, self.pg0)
5820 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5822 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5823 self.nat_addr_n, is_add=0)
5825 def test_464xlat_ce_no_nat(self):
5826 """ Test 464XLAT CE without NAT44 """
5828 self.configure_xlat()
5830 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5831 self.dst_ip6_pfx_len)
5832 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5833 self.src_ip6_pfx_len)
5835 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5836 self.pg0.add_stream(pkts)
5837 self.pg_enable_capture(self.pg_interfaces)
5839 capture = self.pg1.get_capture(len(pkts))
5840 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5841 nat_ip=out_dst_ip6, same_port=True)
5843 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5844 self.pg1.add_stream(pkts)
5845 self.pg_enable_capture(self.pg_interfaces)
5847 capture = self.pg0.get_capture(len(pkts))
5848 self.verify_capture_in(capture, self.pg0)
5851 class TestDeterministicNAT(MethodHolder):
5852 """ Deterministic NAT Test Cases """
5855 def setUpConstants(cls):
5856 super(TestDeterministicNAT, cls).setUpConstants()
5857 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5860 def setUpClass(cls):
5861 super(TestDeterministicNAT, cls).setUpClass()
5862 cls.vapi.cli("set log class nat level debug")
5865 cls.tcp_port_in = 6303
5866 cls.tcp_external_port = 6303
5867 cls.udp_port_in = 6304
5868 cls.udp_external_port = 6304
5869 cls.icmp_id_in = 6305
5870 cls.nat_addr = '10.0.0.3'
5872 cls.create_pg_interfaces(range(3))
5873 cls.interfaces = list(cls.pg_interfaces)
5875 for i in cls.interfaces:
5880 cls.pg0.generate_remote_hosts(2)
5881 cls.pg0.configure_ipv4_neighbors()
5884 super(TestDeterministicNAT, cls).tearDownClass()
5887 def create_stream_in(self, in_if, out_if, ttl=64):
5889 Create packet stream for inside network
5891 :param in_if: Inside interface
5892 :param out_if: Outside interface
5893 :param ttl: TTL of generated packets
5897 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5898 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5899 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5903 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5904 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5905 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5909 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5910 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5911 ICMP(id=self.icmp_id_in, type='echo-request'))
5916 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5918 Create packet stream for outside network
5920 :param out_if: Outside interface
5921 :param dst_ip: Destination IP address (Default use global NAT address)
5922 :param ttl: TTL of generated packets
5925 dst_ip = self.nat_addr
5928 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5929 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5930 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
5934 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5935 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5936 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
5940 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5941 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5942 ICMP(id=self.icmp_external_id, type='echo-reply'))
5947 def verify_capture_out(self, capture, nat_ip=None):
5949 Verify captured packets on outside network
5951 :param capture: Captured packets
5952 :param nat_ip: Translated IP address (Default use global NAT address)
5953 :param same_port: Sorce port number is not translated (Default False)
5956 nat_ip = self.nat_addr
5957 for packet in capture:
5959 self.assertEqual(packet[IP].src, nat_ip)
5960 if packet.haslayer(TCP):
5961 self.tcp_port_out = packet[TCP].sport
5962 elif packet.haslayer(UDP):
5963 self.udp_port_out = packet[UDP].sport
5965 self.icmp_external_id = packet[ICMP].id
5967 self.logger.error(ppp("Unexpected or invalid packet "
5968 "(outside network):", packet))
5971 def test_deterministic_mode(self):
5972 """ NAT plugin run deterministic mode """
5973 in_addr = '172.16.255.0'
5974 out_addr = '172.17.255.50'
5975 in_addr_t = '172.16.255.20'
5976 in_addr_n = socket.inet_aton(in_addr)
5977 out_addr_n = socket.inet_aton(out_addr)
5978 in_addr_t_n = socket.inet_aton(in_addr_t)
5982 nat_config = self.vapi.nat_show_config()
5983 self.assertEqual(1, nat_config.deterministic)
5985 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
5987 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
5988 self.assertEqual(rep1.out_addr[:4], out_addr_n)
5989 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
5990 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5992 deterministic_mappings = self.vapi.nat_det_map_dump()
5993 self.assertEqual(len(deterministic_mappings), 1)
5994 dsm = deterministic_mappings[0]
5995 self.assertEqual(in_addr_n, dsm.in_addr[:4])
5996 self.assertEqual(in_plen, dsm.in_plen)
5997 self.assertEqual(out_addr_n, dsm.out_addr[:4])
5998 self.assertEqual(out_plen, dsm.out_plen)
6000 self.clear_nat_det()
6001 deterministic_mappings = self.vapi.nat_det_map_dump()
6002 self.assertEqual(len(deterministic_mappings), 0)
6004 def test_set_timeouts(self):
6005 """ Set deterministic NAT timeouts """
6006 timeouts_before = self.vapi.nat_get_timeouts()
6008 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6009 timeouts_before.tcp_established + 10,
6010 timeouts_before.tcp_transitory + 10,
6011 timeouts_before.icmp + 10)
6013 timeouts_after = self.vapi.nat_get_timeouts()
6015 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6016 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6017 self.assertNotEqual(timeouts_before.tcp_established,
6018 timeouts_after.tcp_established)
6019 self.assertNotEqual(timeouts_before.tcp_transitory,
6020 timeouts_after.tcp_transitory)
6022 def test_det_in(self):
6023 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6025 nat_ip = "10.0.0.10"
6027 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6029 socket.inet_aton(nat_ip),
6031 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6032 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6036 pkts = self.create_stream_in(self.pg0, self.pg1)
6037 self.pg0.add_stream(pkts)
6038 self.pg_enable_capture(self.pg_interfaces)
6040 capture = self.pg1.get_capture(len(pkts))
6041 self.verify_capture_out(capture, nat_ip)
6044 pkts = self.create_stream_out(self.pg1, nat_ip)
6045 self.pg1.add_stream(pkts)
6046 self.pg_enable_capture(self.pg_interfaces)
6048 capture = self.pg0.get_capture(len(pkts))
6049 self.verify_capture_in(capture, self.pg0)
6052 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6053 self.assertEqual(len(sessions), 3)
6057 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6058 self.assertEqual(s.in_port, self.tcp_port_in)
6059 self.assertEqual(s.out_port, self.tcp_port_out)
6060 self.assertEqual(s.ext_port, self.tcp_external_port)
6064 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6065 self.assertEqual(s.in_port, self.udp_port_in)
6066 self.assertEqual(s.out_port, self.udp_port_out)
6067 self.assertEqual(s.ext_port, self.udp_external_port)
6071 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6072 self.assertEqual(s.in_port, self.icmp_id_in)
6073 self.assertEqual(s.out_port, self.icmp_external_id)
6075 def test_multiple_users(self):
6076 """ Deterministic NAT multiple users """
6078 nat_ip = "10.0.0.10"
6080 external_port = 6303
6082 host0 = self.pg0.remote_hosts[0]
6083 host1 = self.pg0.remote_hosts[1]
6085 self.vapi.nat_det_add_del_map(host0.ip4n,
6087 socket.inet_aton(nat_ip),
6089 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6090 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6094 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6095 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6096 TCP(sport=port_in, dport=external_port))
6097 self.pg0.add_stream(p)
6098 self.pg_enable_capture(self.pg_interfaces)
6100 capture = self.pg1.get_capture(1)
6105 self.assertEqual(ip.src, nat_ip)
6106 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6107 self.assertEqual(tcp.dport, external_port)
6108 port_out0 = tcp.sport
6110 self.logger.error(ppp("Unexpected or invalid packet:", p))
6114 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6115 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6116 TCP(sport=port_in, dport=external_port))
6117 self.pg0.add_stream(p)
6118 self.pg_enable_capture(self.pg_interfaces)
6120 capture = self.pg1.get_capture(1)
6125 self.assertEqual(ip.src, nat_ip)
6126 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6127 self.assertEqual(tcp.dport, external_port)
6128 port_out1 = tcp.sport
6130 self.logger.error(ppp("Unexpected or invalid packet:", p))
6133 dms = self.vapi.nat_det_map_dump()
6134 self.assertEqual(1, len(dms))
6135 self.assertEqual(2, dms[0].ses_num)
6138 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6139 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6140 TCP(sport=external_port, dport=port_out0))
6141 self.pg1.add_stream(p)
6142 self.pg_enable_capture(self.pg_interfaces)
6144 capture = self.pg0.get_capture(1)
6149 self.assertEqual(ip.src, self.pg1.remote_ip4)
6150 self.assertEqual(ip.dst, host0.ip4)
6151 self.assertEqual(tcp.dport, port_in)
6152 self.assertEqual(tcp.sport, external_port)
6154 self.logger.error(ppp("Unexpected or invalid packet:", p))
6158 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6159 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6160 TCP(sport=external_port, dport=port_out1))
6161 self.pg1.add_stream(p)
6162 self.pg_enable_capture(self.pg_interfaces)
6164 capture = self.pg0.get_capture(1)
6169 self.assertEqual(ip.src, self.pg1.remote_ip4)
6170 self.assertEqual(ip.dst, host1.ip4)
6171 self.assertEqual(tcp.dport, port_in)
6172 self.assertEqual(tcp.sport, external_port)
6174 self.logger.error(ppp("Unexpected or invalid packet", p))
6177 # session close api test
6178 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6180 self.pg1.remote_ip4n,
6182 dms = self.vapi.nat_det_map_dump()
6183 self.assertEqual(dms[0].ses_num, 1)
6185 self.vapi.nat_det_close_session_in(host0.ip4n,
6187 self.pg1.remote_ip4n,
6189 dms = self.vapi.nat_det_map_dump()
6190 self.assertEqual(dms[0].ses_num, 0)
6192 def test_tcp_session_close_detection_in(self):
6193 """ Deterministic NAT TCP session close from inside network """
6194 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6196 socket.inet_aton(self.nat_addr),
6198 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6199 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6202 self.initiate_tcp_session(self.pg0, self.pg1)
6204 # close the session from inside
6206 # FIN packet in -> out
6207 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6208 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6209 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6211 self.pg0.add_stream(p)
6212 self.pg_enable_capture(self.pg_interfaces)
6214 self.pg1.get_capture(1)
6218 # ACK packet out -> in
6219 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6220 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6221 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6225 # FIN packet out -> in
6226 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6227 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6228 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6232 self.pg1.add_stream(pkts)
6233 self.pg_enable_capture(self.pg_interfaces)
6235 self.pg0.get_capture(2)
6237 # ACK packet in -> out
6238 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6239 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6240 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6242 self.pg0.add_stream(p)
6243 self.pg_enable_capture(self.pg_interfaces)
6245 self.pg1.get_capture(1)
6247 # Check if deterministic NAT44 closed the session
6248 dms = self.vapi.nat_det_map_dump()
6249 self.assertEqual(0, dms[0].ses_num)
6251 self.logger.error("TCP session termination failed")
6254 def test_tcp_session_close_detection_out(self):
6255 """ Deterministic NAT TCP session close from outside network """
6256 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6258 socket.inet_aton(self.nat_addr),
6260 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6261 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6264 self.initiate_tcp_session(self.pg0, self.pg1)
6266 # close the session from outside
6268 # FIN packet out -> in
6269 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6270 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6271 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6273 self.pg1.add_stream(p)
6274 self.pg_enable_capture(self.pg_interfaces)
6276 self.pg0.get_capture(1)
6280 # ACK packet in -> out
6281 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6282 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6283 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6287 # ACK packet in -> out
6288 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6289 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6290 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6294 self.pg0.add_stream(pkts)
6295 self.pg_enable_capture(self.pg_interfaces)
6297 self.pg1.get_capture(2)
6299 # ACK packet out -> in
6300 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6301 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6302 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6304 self.pg1.add_stream(p)
6305 self.pg_enable_capture(self.pg_interfaces)
6307 self.pg0.get_capture(1)
6309 # Check if deterministic NAT44 closed the session
6310 dms = self.vapi.nat_det_map_dump()
6311 self.assertEqual(0, dms[0].ses_num)
6313 self.logger.error("TCP session termination failed")
6316 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6317 def test_session_timeout(self):
6318 """ Deterministic NAT session timeouts """
6319 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6321 socket.inet_aton(self.nat_addr),
6323 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6324 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6327 self.initiate_tcp_session(self.pg0, self.pg1)
6328 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6329 pkts = self.create_stream_in(self.pg0, self.pg1)
6330 self.pg0.add_stream(pkts)
6331 self.pg_enable_capture(self.pg_interfaces)
6333 capture = self.pg1.get_capture(len(pkts))
6336 dms = self.vapi.nat_det_map_dump()
6337 self.assertEqual(0, dms[0].ses_num)
6339 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6340 def test_session_limit_per_user(self):
6341 """ Deterministic NAT maximum sessions per user limit """
6342 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6344 socket.inet_aton(self.nat_addr),
6346 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6347 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6349 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6350 src_address=self.pg2.local_ip4n,
6352 template_interval=10)
6353 self.vapi.nat_ipfix()
6356 for port in range(1025, 2025):
6357 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6358 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6359 UDP(sport=port, dport=port))
6362 self.pg0.add_stream(pkts)
6363 self.pg_enable_capture(self.pg_interfaces)
6365 capture = self.pg1.get_capture(len(pkts))
6367 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6368 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6369 UDP(sport=3001, dport=3002))
6370 self.pg0.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6373 capture = self.pg1.assert_nothing_captured()
6375 # verify ICMP error packet
6376 capture = self.pg0.get_capture(1)
6378 self.assertTrue(p.haslayer(ICMP))
6380 self.assertEqual(icmp.type, 3)
6381 self.assertEqual(icmp.code, 1)
6382 self.assertTrue(icmp.haslayer(IPerror))
6383 inner_ip = icmp[IPerror]
6384 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6385 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6387 dms = self.vapi.nat_det_map_dump()
6389 self.assertEqual(1000, dms[0].ses_num)
6391 # verify IPFIX logging
6392 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6394 capture = self.pg2.get_capture(2)
6395 ipfix = IPFIXDecoder()
6396 # first load template
6398 self.assertTrue(p.haslayer(IPFIX))
6399 if p.haslayer(Template):
6400 ipfix.add_template(p.getlayer(Template))
6401 # verify events in data set
6403 if p.haslayer(Data):
6404 data = ipfix.decode_data_set(p.getlayer(Set))
6405 self.verify_ipfix_max_entries_per_user(data,
6407 self.pg0.remote_ip4n)
6409 def clear_nat_det(self):
6411 Clear deterministic NAT configuration.
6413 self.vapi.nat_ipfix(enable=0)
6414 self.vapi.nat_set_timeouts()
6415 deterministic_mappings = self.vapi.nat_det_map_dump()
6416 for dsm in deterministic_mappings:
6417 self.vapi.nat_det_add_del_map(dsm.in_addr,
6423 interfaces = self.vapi.nat44_interface_dump()
6424 for intf in interfaces:
6425 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6430 super(TestDeterministicNAT, self).tearDown()
6431 if not self.vpp_dead:
6432 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6433 self.logger.info(self.vapi.cli("show nat timeouts"))
6435 self.vapi.cli("show nat44 deterministic mappings"))
6437 self.vapi.cli("show nat44 deterministic sessions"))
6438 self.clear_nat_det()
6441 class TestNAT64(MethodHolder):
6442 """ NAT64 Test Cases """
6445 def setUpConstants(cls):
6446 super(TestNAT64, cls).setUpConstants()
6447 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6448 "nat64 st hash buckets 256", "}"])
6451 def setUpClass(cls):
6452 super(TestNAT64, cls).setUpClass()
6455 cls.tcp_port_in = 6303
6456 cls.tcp_port_out = 6303
6457 cls.udp_port_in = 6304
6458 cls.udp_port_out = 6304
6459 cls.icmp_id_in = 6305
6460 cls.icmp_id_out = 6305
6461 cls.nat_addr = '10.0.0.3'
6462 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6464 cls.vrf1_nat_addr = '10.0.10.3'
6465 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6467 cls.ipfix_src_port = 4739
6468 cls.ipfix_domain_id = 1
6470 cls.create_pg_interfaces(range(6))
6471 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6472 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6473 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6475 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6477 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6479 cls.pg0.generate_remote_hosts(2)
6481 for i in cls.ip6_interfaces:
6484 i.configure_ipv6_neighbors()
6486 for i in cls.ip4_interfaces:
6492 cls.pg3.config_ip4()
6493 cls.pg3.resolve_arp()
6494 cls.pg3.config_ip6()
6495 cls.pg3.configure_ipv6_neighbors()
6498 cls.pg5.config_ip6()
6501 super(TestNAT64, cls).tearDownClass()
6504 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6505 """ NAT64 inside interface handles Neighbor Advertisement """
6507 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6510 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6511 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6512 ICMPv6EchoRequest())
6514 self.pg5.add_stream(pkts)
6515 self.pg_enable_capture(self.pg_interfaces)
6518 # Wait for Neighbor Solicitation
6519 capture = self.pg5.get_capture(len(pkts))
6522 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6523 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6524 tgt = packet[ICMPv6ND_NS].tgt
6526 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6529 # Send Neighbor Advertisement
6530 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6531 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6532 ICMPv6ND_NA(tgt=tgt) /
6533 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6535 self.pg5.add_stream(pkts)
6536 self.pg_enable_capture(self.pg_interfaces)
6539 # Try to send ping again
6541 self.pg5.add_stream(pkts)
6542 self.pg_enable_capture(self.pg_interfaces)
6545 # Wait for ping reply
6546 capture = self.pg5.get_capture(len(pkts))
6549 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6550 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6551 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6553 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6556 def test_pool(self):
6557 """ Add/delete address to NAT64 pool """
6558 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6560 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6562 addresses = self.vapi.nat64_pool_addr_dump()
6563 self.assertEqual(len(addresses), 1)
6564 self.assertEqual(addresses[0].address, nat_addr)
6566 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6568 addresses = self.vapi.nat64_pool_addr_dump()
6569 self.assertEqual(len(addresses), 0)
6571 def test_interface(self):
6572 """ Enable/disable NAT64 feature on the interface """
6573 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6574 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6576 interfaces = self.vapi.nat64_interface_dump()
6577 self.assertEqual(len(interfaces), 2)
6580 for intf in interfaces:
6581 if intf.sw_if_index == self.pg0.sw_if_index:
6582 self.assertEqual(intf.is_inside, 1)
6584 elif intf.sw_if_index == self.pg1.sw_if_index:
6585 self.assertEqual(intf.is_inside, 0)
6587 self.assertTrue(pg0_found)
6588 self.assertTrue(pg1_found)
6590 features = self.vapi.cli("show interface features pg0")
6591 self.assertNotEqual(features.find('nat64-in2out'), -1)
6592 features = self.vapi.cli("show interface features pg1")
6593 self.assertNotEqual(features.find('nat64-out2in'), -1)
6595 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6596 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6598 interfaces = self.vapi.nat64_interface_dump()
6599 self.assertEqual(len(interfaces), 0)
6601 def test_static_bib(self):
6602 """ Add/delete static BIB entry """
6603 in_addr = socket.inet_pton(socket.AF_INET6,
6604 '2001:db8:85a3::8a2e:370:7334')
6605 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6608 proto = IP_PROTOS.tcp
6610 self.vapi.nat64_add_del_static_bib(in_addr,
6615 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6620 self.assertEqual(bibe.i_addr, in_addr)
6621 self.assertEqual(bibe.o_addr, out_addr)
6622 self.assertEqual(bibe.i_port, in_port)
6623 self.assertEqual(bibe.o_port, out_port)
6624 self.assertEqual(static_bib_num, 1)
6626 self.vapi.nat64_add_del_static_bib(in_addr,
6632 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6637 self.assertEqual(static_bib_num, 0)
6639 def test_set_timeouts(self):
6640 """ Set NAT64 timeouts """
6641 # verify default values
6642 timeouts = self.vapi.nat_get_timeouts()
6643 self.assertEqual(timeouts.udp, 300)
6644 self.assertEqual(timeouts.icmp, 60)
6645 self.assertEqual(timeouts.tcp_transitory, 240)
6646 self.assertEqual(timeouts.tcp_established, 7440)
6648 # set and verify custom values
6649 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6650 tcp_established=7450)
6651 timeouts = self.vapi.nat_get_timeouts()
6652 self.assertEqual(timeouts.udp, 200)
6653 self.assertEqual(timeouts.icmp, 30)
6654 self.assertEqual(timeouts.tcp_transitory, 250)
6655 self.assertEqual(timeouts.tcp_established, 7450)
6657 def test_dynamic(self):
6658 """ NAT64 dynamic translation test """
6659 self.tcp_port_in = 6303
6660 self.udp_port_in = 6304
6661 self.icmp_id_in = 6305
6663 ses_num_start = self.nat64_get_ses_num()
6665 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6667 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6668 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6671 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6672 self.pg0.add_stream(pkts)
6673 self.pg_enable_capture(self.pg_interfaces)
6675 capture = self.pg1.get_capture(len(pkts))
6676 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6677 dst_ip=self.pg1.remote_ip4)
6680 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6681 self.pg1.add_stream(pkts)
6682 self.pg_enable_capture(self.pg_interfaces)
6684 capture = self.pg0.get_capture(len(pkts))
6685 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6686 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6689 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6690 self.pg0.add_stream(pkts)
6691 self.pg_enable_capture(self.pg_interfaces)
6693 capture = self.pg1.get_capture(len(pkts))
6694 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6695 dst_ip=self.pg1.remote_ip4)
6698 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6699 self.pg1.add_stream(pkts)
6700 self.pg_enable_capture(self.pg_interfaces)
6702 capture = self.pg0.get_capture(len(pkts))
6703 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6705 ses_num_end = self.nat64_get_ses_num()
6707 self.assertEqual(ses_num_end - ses_num_start, 3)
6709 # tenant with specific VRF
6710 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6711 self.vrf1_nat_addr_n,
6712 vrf_id=self.vrf1_id)
6713 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6715 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6716 self.pg2.add_stream(pkts)
6717 self.pg_enable_capture(self.pg_interfaces)
6719 capture = self.pg1.get_capture(len(pkts))
6720 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6721 dst_ip=self.pg1.remote_ip4)
6723 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6724 self.pg1.add_stream(pkts)
6725 self.pg_enable_capture(self.pg_interfaces)
6727 capture = self.pg2.get_capture(len(pkts))
6728 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6730 def test_static(self):
6731 """ NAT64 static translation test """
6732 self.tcp_port_in = 60303
6733 self.udp_port_in = 60304
6734 self.icmp_id_in = 60305
6735 self.tcp_port_out = 60303
6736 self.udp_port_out = 60304
6737 self.icmp_id_out = 60305
6739 ses_num_start = self.nat64_get_ses_num()
6741 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6743 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6744 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6746 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6751 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6756 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6763 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6764 self.pg0.add_stream(pkts)
6765 self.pg_enable_capture(self.pg_interfaces)
6767 capture = self.pg1.get_capture(len(pkts))
6768 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6769 dst_ip=self.pg1.remote_ip4, same_port=True)
6772 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6773 self.pg1.add_stream(pkts)
6774 self.pg_enable_capture(self.pg_interfaces)
6776 capture = self.pg0.get_capture(len(pkts))
6777 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6778 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6780 ses_num_end = self.nat64_get_ses_num()
6782 self.assertEqual(ses_num_end - ses_num_start, 3)
6784 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6785 def test_session_timeout(self):
6786 """ NAT64 session timeout """
6787 self.icmp_id_in = 1234
6788 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6790 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6791 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6792 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6794 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6795 self.pg0.add_stream(pkts)
6796 self.pg_enable_capture(self.pg_interfaces)
6798 capture = self.pg1.get_capture(len(pkts))
6800 ses_num_before_timeout = self.nat64_get_ses_num()
6804 # ICMP and TCP session after timeout
6805 ses_num_after_timeout = self.nat64_get_ses_num()
6806 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6808 def test_icmp_error(self):
6809 """ NAT64 ICMP Error message translation """
6810 self.tcp_port_in = 6303
6811 self.udp_port_in = 6304
6812 self.icmp_id_in = 6305
6814 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6816 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6817 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6819 # send some packets to create sessions
6820 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6821 self.pg0.add_stream(pkts)
6822 self.pg_enable_capture(self.pg_interfaces)
6824 capture_ip4 = self.pg1.get_capture(len(pkts))
6825 self.verify_capture_out(capture_ip4,
6826 nat_ip=self.nat_addr,
6827 dst_ip=self.pg1.remote_ip4)
6829 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6830 self.pg1.add_stream(pkts)
6831 self.pg_enable_capture(self.pg_interfaces)
6833 capture_ip6 = self.pg0.get_capture(len(pkts))
6834 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6835 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6836 self.pg0.remote_ip6)
6839 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6840 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6841 ICMPv6DestUnreach(code=1) /
6842 packet[IPv6] for packet in capture_ip6]
6843 self.pg0.add_stream(pkts)
6844 self.pg_enable_capture(self.pg_interfaces)
6846 capture = self.pg1.get_capture(len(pkts))
6847 for packet in capture:
6849 self.assertEqual(packet[IP].src, self.nat_addr)
6850 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6851 self.assertEqual(packet[ICMP].type, 3)
6852 self.assertEqual(packet[ICMP].code, 13)
6853 inner = packet[IPerror]
6854 self.assertEqual(inner.src, self.pg1.remote_ip4)
6855 self.assertEqual(inner.dst, self.nat_addr)
6856 self.assert_packet_checksums_valid(packet)
6857 if inner.haslayer(TCPerror):
6858 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6859 elif inner.haslayer(UDPerror):
6860 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6862 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6864 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6868 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6869 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6870 ICMP(type=3, code=13) /
6871 packet[IP] for packet in capture_ip4]
6872 self.pg1.add_stream(pkts)
6873 self.pg_enable_capture(self.pg_interfaces)
6875 capture = self.pg0.get_capture(len(pkts))
6876 for packet in capture:
6878 self.assertEqual(packet[IPv6].src, ip.src)
6879 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6880 icmp = packet[ICMPv6DestUnreach]
6881 self.assertEqual(icmp.code, 1)
6882 inner = icmp[IPerror6]
6883 self.assertEqual(inner.src, self.pg0.remote_ip6)
6884 self.assertEqual(inner.dst, ip.src)
6885 self.assert_icmpv6_checksum_valid(packet)
6886 if inner.haslayer(TCPerror):
6887 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6888 elif inner.haslayer(UDPerror):
6889 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6891 self.assertEqual(inner[ICMPv6EchoRequest].id,
6894 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6897 def test_hairpinning(self):
6898 """ NAT64 hairpinning """
6900 client = self.pg0.remote_hosts[0]
6901 server = self.pg0.remote_hosts[1]
6902 server_tcp_in_port = 22
6903 server_tcp_out_port = 4022
6904 server_udp_in_port = 23
6905 server_udp_out_port = 4023
6906 client_tcp_in_port = 1234
6907 client_udp_in_port = 1235
6908 client_tcp_out_port = 0
6909 client_udp_out_port = 0
6910 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6911 nat_addr_ip6 = ip.src
6913 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6915 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6916 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6918 self.vapi.nat64_add_del_static_bib(server.ip6n,
6921 server_tcp_out_port,
6923 self.vapi.nat64_add_del_static_bib(server.ip6n,
6926 server_udp_out_port,
6931 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6932 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6933 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6935 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6936 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6937 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6939 self.pg0.add_stream(pkts)
6940 self.pg_enable_capture(self.pg_interfaces)
6942 capture = self.pg0.get_capture(len(pkts))
6943 for packet in capture:
6945 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6946 self.assertEqual(packet[IPv6].dst, server.ip6)
6947 self.assert_packet_checksums_valid(packet)
6948 if packet.haslayer(TCP):
6949 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6950 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
6951 client_tcp_out_port = packet[TCP].sport
6953 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6954 self.assertEqual(packet[UDP].dport, server_udp_in_port)
6955 client_udp_out_port = packet[UDP].sport
6957 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6962 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6963 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6964 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6966 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6967 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6968 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6970 self.pg0.add_stream(pkts)
6971 self.pg_enable_capture(self.pg_interfaces)
6973 capture = self.pg0.get_capture(len(pkts))
6974 for packet in capture:
6976 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6977 self.assertEqual(packet[IPv6].dst, client.ip6)
6978 self.assert_packet_checksums_valid(packet)
6979 if packet.haslayer(TCP):
6980 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6981 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
6983 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6984 self.assertEqual(packet[UDP].dport, client_udp_in_port)
6986 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6991 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6992 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6993 ICMPv6DestUnreach(code=1) /
6994 packet[IPv6] for packet in capture]
6995 self.pg0.add_stream(pkts)
6996 self.pg_enable_capture(self.pg_interfaces)
6998 capture = self.pg0.get_capture(len(pkts))
6999 for packet in capture:
7001 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7002 self.assertEqual(packet[IPv6].dst, server.ip6)
7003 icmp = packet[ICMPv6DestUnreach]
7004 self.assertEqual(icmp.code, 1)
7005 inner = icmp[IPerror6]
7006 self.assertEqual(inner.src, server.ip6)
7007 self.assertEqual(inner.dst, nat_addr_ip6)
7008 self.assert_packet_checksums_valid(packet)
7009 if inner.haslayer(TCPerror):
7010 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7011 self.assertEqual(inner[TCPerror].dport,
7012 client_tcp_out_port)
7014 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7015 self.assertEqual(inner[UDPerror].dport,
7016 client_udp_out_port)
7018 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7021 def test_prefix(self):
7022 """ NAT64 Network-Specific Prefix """
7024 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7026 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7027 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7028 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7029 self.vrf1_nat_addr_n,
7030 vrf_id=self.vrf1_id)
7031 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7034 global_pref64 = "2001:db8::"
7035 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7036 global_pref64_len = 32
7037 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7039 prefix = self.vapi.nat64_prefix_dump()
7040 self.assertEqual(len(prefix), 1)
7041 self.assertEqual(prefix[0].prefix, global_pref64_n)
7042 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7043 self.assertEqual(prefix[0].vrf_id, 0)
7045 # Add tenant specific prefix
7046 vrf1_pref64 = "2001:db8:122:300::"
7047 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7048 vrf1_pref64_len = 56
7049 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7051 vrf_id=self.vrf1_id)
7052 prefix = self.vapi.nat64_prefix_dump()
7053 self.assertEqual(len(prefix), 2)
7056 pkts = self.create_stream_in_ip6(self.pg0,
7059 plen=global_pref64_len)
7060 self.pg0.add_stream(pkts)
7061 self.pg_enable_capture(self.pg_interfaces)
7063 capture = self.pg1.get_capture(len(pkts))
7064 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7065 dst_ip=self.pg1.remote_ip4)
7067 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7068 self.pg1.add_stream(pkts)
7069 self.pg_enable_capture(self.pg_interfaces)
7071 capture = self.pg0.get_capture(len(pkts))
7072 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7075 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7077 # Tenant specific prefix
7078 pkts = self.create_stream_in_ip6(self.pg2,
7081 plen=vrf1_pref64_len)
7082 self.pg2.add_stream(pkts)
7083 self.pg_enable_capture(self.pg_interfaces)
7085 capture = self.pg1.get_capture(len(pkts))
7086 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7087 dst_ip=self.pg1.remote_ip4)
7089 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7090 self.pg1.add_stream(pkts)
7091 self.pg_enable_capture(self.pg_interfaces)
7093 capture = self.pg2.get_capture(len(pkts))
7094 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7097 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7099 def test_unknown_proto(self):
7100 """ NAT64 translate packet with unknown protocol """
7102 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7104 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7105 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7106 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7109 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7110 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7111 TCP(sport=self.tcp_port_in, dport=20))
7112 self.pg0.add_stream(p)
7113 self.pg_enable_capture(self.pg_interfaces)
7115 p = self.pg1.get_capture(1)
7117 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7118 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7120 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7121 TCP(sport=1234, dport=1234))
7122 self.pg0.add_stream(p)
7123 self.pg_enable_capture(self.pg_interfaces)
7125 p = self.pg1.get_capture(1)
7128 self.assertEqual(packet[IP].src, self.nat_addr)
7129 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7130 self.assertTrue(packet.haslayer(GRE))
7131 self.assert_packet_checksums_valid(packet)
7133 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7137 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7138 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7140 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7141 TCP(sport=1234, dport=1234))
7142 self.pg1.add_stream(p)
7143 self.pg_enable_capture(self.pg_interfaces)
7145 p = self.pg0.get_capture(1)
7148 self.assertEqual(packet[IPv6].src, remote_ip6)
7149 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7150 self.assertEqual(packet[IPv6].nh, 47)
7152 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7155 def test_hairpinning_unknown_proto(self):
7156 """ NAT64 translate packet with unknown protocol - hairpinning """
7158 client = self.pg0.remote_hosts[0]
7159 server = self.pg0.remote_hosts[1]
7160 server_tcp_in_port = 22
7161 server_tcp_out_port = 4022
7162 client_tcp_in_port = 1234
7163 client_tcp_out_port = 1235
7164 server_nat_ip = "10.0.0.100"
7165 client_nat_ip = "10.0.0.110"
7166 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7167 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7168 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7169 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7171 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7173 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7174 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7176 self.vapi.nat64_add_del_static_bib(server.ip6n,
7179 server_tcp_out_port,
7182 self.vapi.nat64_add_del_static_bib(server.ip6n,
7188 self.vapi.nat64_add_del_static_bib(client.ip6n,
7191 client_tcp_out_port,
7195 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7196 IPv6(src=client.ip6, dst=server_nat_ip6) /
7197 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7198 self.pg0.add_stream(p)
7199 self.pg_enable_capture(self.pg_interfaces)
7201 p = self.pg0.get_capture(1)
7203 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7204 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7206 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7207 TCP(sport=1234, dport=1234))
7208 self.pg0.add_stream(p)
7209 self.pg_enable_capture(self.pg_interfaces)
7211 p = self.pg0.get_capture(1)
7214 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7215 self.assertEqual(packet[IPv6].dst, server.ip6)
7216 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7218 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7222 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7223 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7225 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7226 TCP(sport=1234, dport=1234))
7227 self.pg0.add_stream(p)
7228 self.pg_enable_capture(self.pg_interfaces)
7230 p = self.pg0.get_capture(1)
7233 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7234 self.assertEqual(packet[IPv6].dst, client.ip6)
7235 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7237 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7240 def test_one_armed_nat64(self):
7241 """ One armed NAT64 """
7243 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7247 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7249 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7250 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7253 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7254 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7255 TCP(sport=12345, dport=80))
7256 self.pg3.add_stream(p)
7257 self.pg_enable_capture(self.pg_interfaces)
7259 capture = self.pg3.get_capture(1)
7264 self.assertEqual(ip.src, self.nat_addr)
7265 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7266 self.assertNotEqual(tcp.sport, 12345)
7267 external_port = tcp.sport
7268 self.assertEqual(tcp.dport, 80)
7269 self.assert_packet_checksums_valid(p)
7271 self.logger.error(ppp("Unexpected or invalid packet:", p))
7275 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7276 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7277 TCP(sport=80, dport=external_port))
7278 self.pg3.add_stream(p)
7279 self.pg_enable_capture(self.pg_interfaces)
7281 capture = self.pg3.get_capture(1)
7286 self.assertEqual(ip.src, remote_host_ip6)
7287 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7288 self.assertEqual(tcp.sport, 80)
7289 self.assertEqual(tcp.dport, 12345)
7290 self.assert_packet_checksums_valid(p)
7292 self.logger.error(ppp("Unexpected or invalid packet:", p))
7295 def test_frag_in_order(self):
7296 """ NAT64 translate fragments arriving in order """
7297 self.tcp_port_in = random.randint(1025, 65535)
7299 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7301 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7302 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7304 reass = self.vapi.nat_reass_dump()
7305 reass_n_start = len(reass)
7309 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7310 self.tcp_port_in, 20, data)
7311 self.pg0.add_stream(pkts)
7312 self.pg_enable_capture(self.pg_interfaces)
7314 frags = self.pg1.get_capture(len(pkts))
7315 p = self.reass_frags_and_verify(frags,
7317 self.pg1.remote_ip4)
7318 self.assertEqual(p[TCP].dport, 20)
7319 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7320 self.tcp_port_out = p[TCP].sport
7321 self.assertEqual(data, p[Raw].load)
7324 data = "A" * 4 + "b" * 16 + "C" * 3
7325 pkts = self.create_stream_frag(self.pg1,
7330 self.pg1.add_stream(pkts)
7331 self.pg_enable_capture(self.pg_interfaces)
7333 frags = self.pg0.get_capture(len(pkts))
7334 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7335 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7336 self.assertEqual(p[TCP].sport, 20)
7337 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7338 self.assertEqual(data, p[Raw].load)
7340 reass = self.vapi.nat_reass_dump()
7341 reass_n_end = len(reass)
7343 self.assertEqual(reass_n_end - reass_n_start, 2)
7345 def test_reass_hairpinning(self):
7346 """ NAT64 fragments hairpinning """
7348 server = self.pg0.remote_hosts[1]
7349 server_in_port = random.randint(1025, 65535)
7350 server_out_port = random.randint(1025, 65535)
7351 client_in_port = random.randint(1025, 65535)
7352 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7353 nat_addr_ip6 = ip.src
7355 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7357 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7358 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7360 # add static BIB entry for server
7361 self.vapi.nat64_add_del_static_bib(server.ip6n,
7367 # send packet from host to server
7368 pkts = self.create_stream_frag_ip6(self.pg0,
7373 self.pg0.add_stream(pkts)
7374 self.pg_enable_capture(self.pg_interfaces)
7376 frags = self.pg0.get_capture(len(pkts))
7377 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7378 self.assertNotEqual(p[TCP].sport, client_in_port)
7379 self.assertEqual(p[TCP].dport, server_in_port)
7380 self.assertEqual(data, p[Raw].load)
7382 def test_frag_out_of_order(self):
7383 """ NAT64 translate fragments arriving out of order """
7384 self.tcp_port_in = random.randint(1025, 65535)
7386 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7388 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7389 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7393 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7394 self.tcp_port_in, 20, data)
7396 self.pg0.add_stream(pkts)
7397 self.pg_enable_capture(self.pg_interfaces)
7399 frags = self.pg1.get_capture(len(pkts))
7400 p = self.reass_frags_and_verify(frags,
7402 self.pg1.remote_ip4)
7403 self.assertEqual(p[TCP].dport, 20)
7404 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7405 self.tcp_port_out = p[TCP].sport
7406 self.assertEqual(data, p[Raw].load)
7409 data = "A" * 4 + "B" * 16 + "C" * 3
7410 pkts = self.create_stream_frag(self.pg1,
7416 self.pg1.add_stream(pkts)
7417 self.pg_enable_capture(self.pg_interfaces)
7419 frags = self.pg0.get_capture(len(pkts))
7420 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7421 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7422 self.assertEqual(p[TCP].sport, 20)
7423 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7424 self.assertEqual(data, p[Raw].load)
7426 def test_interface_addr(self):
7427 """ Acquire NAT64 pool addresses from interface """
7428 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7430 # no address in NAT64 pool
7431 adresses = self.vapi.nat44_address_dump()
7432 self.assertEqual(0, len(adresses))
7434 # configure interface address and check NAT64 address pool
7435 self.pg4.config_ip4()
7436 addresses = self.vapi.nat64_pool_addr_dump()
7437 self.assertEqual(len(addresses), 1)
7438 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7440 # remove interface address and check NAT64 address pool
7441 self.pg4.unconfig_ip4()
7442 addresses = self.vapi.nat64_pool_addr_dump()
7443 self.assertEqual(0, len(adresses))
7445 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7446 def test_ipfix_max_bibs_sessions(self):
7447 """ IPFIX logging maximum session and BIB entries exceeded """
7450 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7454 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7456 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7457 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7461 for i in range(0, max_bibs):
7462 src = "fd01:aa::%x" % (i)
7463 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7464 IPv6(src=src, dst=remote_host_ip6) /
7465 TCP(sport=12345, dport=80))
7467 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7468 IPv6(src=src, dst=remote_host_ip6) /
7469 TCP(sport=12345, dport=22))
7471 self.pg0.add_stream(pkts)
7472 self.pg_enable_capture(self.pg_interfaces)
7474 self.pg1.get_capture(max_sessions)
7476 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7477 src_address=self.pg3.local_ip4n,
7479 template_interval=10)
7480 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7481 src_port=self.ipfix_src_port)
7483 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7484 IPv6(src=src, dst=remote_host_ip6) /
7485 TCP(sport=12345, dport=25))
7486 self.pg0.add_stream(p)
7487 self.pg_enable_capture(self.pg_interfaces)
7489 self.pg1.assert_nothing_captured()
7491 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7492 capture = self.pg3.get_capture(9)
7493 ipfix = IPFIXDecoder()
7494 # first load template
7496 self.assertTrue(p.haslayer(IPFIX))
7497 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7498 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7499 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7500 self.assertEqual(p[UDP].dport, 4739)
7501 self.assertEqual(p[IPFIX].observationDomainID,
7502 self.ipfix_domain_id)
7503 if p.haslayer(Template):
7504 ipfix.add_template(p.getlayer(Template))
7505 # verify events in data set
7507 if p.haslayer(Data):
7508 data = ipfix.decode_data_set(p.getlayer(Set))
7509 self.verify_ipfix_max_sessions(data, max_sessions)
7511 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7512 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7513 TCP(sport=12345, dport=80))
7514 self.pg0.add_stream(p)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 self.pg1.assert_nothing_captured()
7519 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7520 capture = self.pg3.get_capture(1)
7521 # verify events in data set
7523 self.assertTrue(p.haslayer(IPFIX))
7524 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7525 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7526 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7527 self.assertEqual(p[UDP].dport, 4739)
7528 self.assertEqual(p[IPFIX].observationDomainID,
7529 self.ipfix_domain_id)
7530 if p.haslayer(Data):
7531 data = ipfix.decode_data_set(p.getlayer(Set))
7532 self.verify_ipfix_max_bibs(data, max_bibs)
7534 def test_ipfix_max_frags(self):
7535 """ IPFIX logging maximum fragments pending reassembly exceeded """
7536 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7538 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7539 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7540 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7541 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7542 src_address=self.pg3.local_ip4n,
7544 template_interval=10)
7545 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7546 src_port=self.ipfix_src_port)
7549 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7550 self.tcp_port_in, 20, data)
7552 self.pg0.add_stream(pkts)
7553 self.pg_enable_capture(self.pg_interfaces)
7555 self.pg1.assert_nothing_captured()
7557 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7558 capture = self.pg3.get_capture(9)
7559 ipfix = IPFIXDecoder()
7560 # first load template
7562 self.assertTrue(p.haslayer(IPFIX))
7563 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7564 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7565 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7566 self.assertEqual(p[UDP].dport, 4739)
7567 self.assertEqual(p[IPFIX].observationDomainID,
7568 self.ipfix_domain_id)
7569 if p.haslayer(Template):
7570 ipfix.add_template(p.getlayer(Template))
7571 # verify events in data set
7573 if p.haslayer(Data):
7574 data = ipfix.decode_data_set(p.getlayer(Set))
7575 self.verify_ipfix_max_fragments_ip6(data, 1,
7576 self.pg0.remote_ip6n)
7578 def test_ipfix_bib_ses(self):
7579 """ IPFIX logging NAT64 BIB/session create and delete events """
7580 self.tcp_port_in = random.randint(1025, 65535)
7581 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7585 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7587 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7588 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7589 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7590 src_address=self.pg3.local_ip4n,
7592 template_interval=10)
7593 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7594 src_port=self.ipfix_src_port)
7597 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7598 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7599 TCP(sport=self.tcp_port_in, dport=25))
7600 self.pg0.add_stream(p)
7601 self.pg_enable_capture(self.pg_interfaces)
7603 p = self.pg1.get_capture(1)
7604 self.tcp_port_out = p[0][TCP].sport
7605 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7606 capture = self.pg3.get_capture(10)
7607 ipfix = IPFIXDecoder()
7608 # first load template
7610 self.assertTrue(p.haslayer(IPFIX))
7611 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7612 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7613 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7614 self.assertEqual(p[UDP].dport, 4739)
7615 self.assertEqual(p[IPFIX].observationDomainID,
7616 self.ipfix_domain_id)
7617 if p.haslayer(Template):
7618 ipfix.add_template(p.getlayer(Template))
7619 # verify events in data set
7621 if p.haslayer(Data):
7622 data = ipfix.decode_data_set(p.getlayer(Set))
7623 if ord(data[0][230]) == 10:
7624 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7625 elif ord(data[0][230]) == 6:
7626 self.verify_ipfix_nat64_ses(data,
7628 self.pg0.remote_ip6n,
7629 self.pg1.remote_ip4,
7632 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7635 self.pg_enable_capture(self.pg_interfaces)
7636 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7639 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7640 capture = self.pg3.get_capture(2)
7641 # verify events in data set
7643 self.assertTrue(p.haslayer(IPFIX))
7644 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7645 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7646 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7647 self.assertEqual(p[UDP].dport, 4739)
7648 self.assertEqual(p[IPFIX].observationDomainID,
7649 self.ipfix_domain_id)
7650 if p.haslayer(Data):
7651 data = ipfix.decode_data_set(p.getlayer(Set))
7652 if ord(data[0][230]) == 11:
7653 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7654 elif ord(data[0][230]) == 7:
7655 self.verify_ipfix_nat64_ses(data,
7657 self.pg0.remote_ip6n,
7658 self.pg1.remote_ip4,
7661 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7663 def nat64_get_ses_num(self):
7665 Return number of active NAT64 sessions.
7667 st = self.vapi.nat64_st_dump()
7670 def clear_nat64(self):
7672 Clear NAT64 configuration.
7674 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7675 domain_id=self.ipfix_domain_id)
7676 self.ipfix_src_port = 4739
7677 self.ipfix_domain_id = 1
7679 self.vapi.nat_set_timeouts()
7681 interfaces = self.vapi.nat64_interface_dump()
7682 for intf in interfaces:
7683 if intf.is_inside > 1:
7684 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7687 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7691 bib = self.vapi.nat64_bib_dump(255)
7694 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7702 adresses = self.vapi.nat64_pool_addr_dump()
7703 for addr in adresses:
7704 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7709 prefixes = self.vapi.nat64_prefix_dump()
7710 for prefix in prefixes:
7711 self.vapi.nat64_add_del_prefix(prefix.prefix,
7713 vrf_id=prefix.vrf_id,
7717 super(TestNAT64, self).tearDown()
7718 if not self.vpp_dead:
7719 self.logger.info(self.vapi.cli("show nat64 pool"))
7720 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7721 self.logger.info(self.vapi.cli("show nat64 prefix"))
7722 self.logger.info(self.vapi.cli("show nat64 bib all"))
7723 self.logger.info(self.vapi.cli("show nat64 session table all"))
7724 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7728 class TestDSlite(MethodHolder):
7729 """ DS-Lite Test Cases """
7732 def setUpClass(cls):
7733 super(TestDSlite, cls).setUpClass()
7736 cls.nat_addr = '10.0.0.3'
7737 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7739 cls.create_pg_interfaces(range(2))
7741 cls.pg0.config_ip4()
7742 cls.pg0.resolve_arp()
7744 cls.pg1.config_ip6()
7745 cls.pg1.generate_remote_hosts(2)
7746 cls.pg1.configure_ipv6_neighbors()
7749 super(TestDSlite, cls).tearDownClass()
7752 def test_dslite(self):
7753 """ Test DS-Lite """
7754 nat_config = self.vapi.nat_show_config()
7755 self.assertEqual(0, nat_config.dslite_ce)
7757 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7759 aftr_ip4 = '192.0.0.1'
7760 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7761 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7762 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7763 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7766 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7767 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7768 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7769 UDP(sport=20000, dport=10000))
7770 self.pg1.add_stream(p)
7771 self.pg_enable_capture(self.pg_interfaces)
7773 capture = self.pg0.get_capture(1)
7774 capture = capture[0]
7775 self.assertFalse(capture.haslayer(IPv6))
7776 self.assertEqual(capture[IP].src, self.nat_addr)
7777 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7778 self.assertNotEqual(capture[UDP].sport, 20000)
7779 self.assertEqual(capture[UDP].dport, 10000)
7780 self.assert_packet_checksums_valid(capture)
7781 out_port = capture[UDP].sport
7783 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7784 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7785 UDP(sport=10000, dport=out_port))
7786 self.pg0.add_stream(p)
7787 self.pg_enable_capture(self.pg_interfaces)
7789 capture = self.pg1.get_capture(1)
7790 capture = capture[0]
7791 self.assertEqual(capture[IPv6].src, aftr_ip6)
7792 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7793 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7794 self.assertEqual(capture[IP].dst, '192.168.1.1')
7795 self.assertEqual(capture[UDP].sport, 10000)
7796 self.assertEqual(capture[UDP].dport, 20000)
7797 self.assert_packet_checksums_valid(capture)
7800 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7801 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7802 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7803 TCP(sport=20001, dport=10001))
7804 self.pg1.add_stream(p)
7805 self.pg_enable_capture(self.pg_interfaces)
7807 capture = self.pg0.get_capture(1)
7808 capture = capture[0]
7809 self.assertFalse(capture.haslayer(IPv6))
7810 self.assertEqual(capture[IP].src, self.nat_addr)
7811 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7812 self.assertNotEqual(capture[TCP].sport, 20001)
7813 self.assertEqual(capture[TCP].dport, 10001)
7814 self.assert_packet_checksums_valid(capture)
7815 out_port = capture[TCP].sport
7817 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7818 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7819 TCP(sport=10001, dport=out_port))
7820 self.pg0.add_stream(p)
7821 self.pg_enable_capture(self.pg_interfaces)
7823 capture = self.pg1.get_capture(1)
7824 capture = capture[0]
7825 self.assertEqual(capture[IPv6].src, aftr_ip6)
7826 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7827 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7828 self.assertEqual(capture[IP].dst, '192.168.1.1')
7829 self.assertEqual(capture[TCP].sport, 10001)
7830 self.assertEqual(capture[TCP].dport, 20001)
7831 self.assert_packet_checksums_valid(capture)
7834 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7835 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7836 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7837 ICMP(id=4000, type='echo-request'))
7838 self.pg1.add_stream(p)
7839 self.pg_enable_capture(self.pg_interfaces)
7841 capture = self.pg0.get_capture(1)
7842 capture = capture[0]
7843 self.assertFalse(capture.haslayer(IPv6))
7844 self.assertEqual(capture[IP].src, self.nat_addr)
7845 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7846 self.assertNotEqual(capture[ICMP].id, 4000)
7847 self.assert_packet_checksums_valid(capture)
7848 out_id = capture[ICMP].id
7850 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7851 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7852 ICMP(id=out_id, type='echo-reply'))
7853 self.pg0.add_stream(p)
7854 self.pg_enable_capture(self.pg_interfaces)
7856 capture = self.pg1.get_capture(1)
7857 capture = capture[0]
7858 self.assertEqual(capture[IPv6].src, aftr_ip6)
7859 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7860 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7861 self.assertEqual(capture[IP].dst, '192.168.1.1')
7862 self.assertEqual(capture[ICMP].id, 4000)
7863 self.assert_packet_checksums_valid(capture)
7865 # ping DS-Lite AFTR tunnel endpoint address
7866 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7867 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7868 ICMPv6EchoRequest())
7869 self.pg1.add_stream(p)
7870 self.pg_enable_capture(self.pg_interfaces)
7872 capture = self.pg1.get_capture(1)
7873 capture = capture[0]
7874 self.assertEqual(capture[IPv6].src, aftr_ip6)
7875 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7876 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7879 super(TestDSlite, self).tearDown()
7880 if not self.vpp_dead:
7881 self.logger.info(self.vapi.cli("show dslite pool"))
7883 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7884 self.logger.info(self.vapi.cli("show dslite sessions"))
7887 class TestDSliteCE(MethodHolder):
7888 """ DS-Lite CE Test Cases """
7891 def setUpConstants(cls):
7892 super(TestDSliteCE, cls).setUpConstants()
7893 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7896 def setUpClass(cls):
7897 super(TestDSliteCE, cls).setUpClass()
7900 cls.create_pg_interfaces(range(2))
7902 cls.pg0.config_ip4()
7903 cls.pg0.resolve_arp()
7905 cls.pg1.config_ip6()
7906 cls.pg1.generate_remote_hosts(1)
7907 cls.pg1.configure_ipv6_neighbors()
7910 super(TestDSliteCE, cls).tearDownClass()
7913 def test_dslite_ce(self):
7914 """ Test DS-Lite CE """
7916 nat_config = self.vapi.nat_show_config()
7917 self.assertEqual(1, nat_config.dslite_ce)
7919 b4_ip4 = '192.0.0.2'
7920 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7921 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7922 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7923 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7925 aftr_ip4 = '192.0.0.1'
7926 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7927 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7928 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7929 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7931 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7932 dst_address_length=128,
7933 next_hop_address=self.pg1.remote_ip6n,
7934 next_hop_sw_if_index=self.pg1.sw_if_index,
7938 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7939 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7940 UDP(sport=10000, dport=20000))
7941 self.pg0.add_stream(p)
7942 self.pg_enable_capture(self.pg_interfaces)
7944 capture = self.pg1.get_capture(1)
7945 capture = capture[0]
7946 self.assertEqual(capture[IPv6].src, b4_ip6)
7947 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7948 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7949 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7950 self.assertEqual(capture[UDP].sport, 10000)
7951 self.assertEqual(capture[UDP].dport, 20000)
7952 self.assert_packet_checksums_valid(capture)
7955 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7956 IPv6(dst=b4_ip6, src=aftr_ip6) /
7957 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7958 UDP(sport=20000, dport=10000))
7959 self.pg1.add_stream(p)
7960 self.pg_enable_capture(self.pg_interfaces)
7962 capture = self.pg0.get_capture(1)
7963 capture = capture[0]
7964 self.assertFalse(capture.haslayer(IPv6))
7965 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7966 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7967 self.assertEqual(capture[UDP].sport, 20000)
7968 self.assertEqual(capture[UDP].dport, 10000)
7969 self.assert_packet_checksums_valid(capture)
7971 # ping DS-Lite B4 tunnel endpoint address
7972 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7973 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7974 ICMPv6EchoRequest())
7975 self.pg1.add_stream(p)
7976 self.pg_enable_capture(self.pg_interfaces)
7978 capture = self.pg1.get_capture(1)
7979 capture = capture[0]
7980 self.assertEqual(capture[IPv6].src, b4_ip6)
7981 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7982 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7985 super(TestDSliteCE, self).tearDown()
7986 if not self.vpp_dead:
7988 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7990 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
7993 class TestNAT66(MethodHolder):
7994 """ NAT66 Test Cases """
7997 def setUpClass(cls):
7998 super(TestNAT66, cls).setUpClass()
8001 cls.nat_addr = 'fd01:ff::2'
8002 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8004 cls.create_pg_interfaces(range(2))
8005 cls.interfaces = list(cls.pg_interfaces)
8007 for i in cls.interfaces:
8010 i.configure_ipv6_neighbors()
8013 super(TestNAT66, cls).tearDownClass()
8016 def test_static(self):
8017 """ 1:1 NAT66 test """
8018 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8019 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8020 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8025 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8026 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8029 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8030 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8033 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8034 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8035 ICMPv6EchoRequest())
8037 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8038 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8039 GRE() / IP() / TCP())
8041 self.pg0.add_stream(pkts)
8042 self.pg_enable_capture(self.pg_interfaces)
8044 capture = self.pg1.get_capture(len(pkts))
8045 for packet in capture:
8047 self.assertEqual(packet[IPv6].src, self.nat_addr)
8048 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8049 self.assert_packet_checksums_valid(packet)
8051 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8056 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8057 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8060 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8061 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8064 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8065 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8068 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8069 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8070 GRE() / IP() / TCP())
8072 self.pg1.add_stream(pkts)
8073 self.pg_enable_capture(self.pg_interfaces)
8075 capture = self.pg0.get_capture(len(pkts))
8076 for packet in capture:
8078 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8079 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8080 self.assert_packet_checksums_valid(packet)
8082 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8085 sm = self.vapi.nat66_static_mapping_dump()
8086 self.assertEqual(len(sm), 1)
8087 self.assertEqual(sm[0].total_pkts, 8)
8089 def test_check_no_translate(self):
8090 """ NAT66 translate only when egress interface is outside interface """
8091 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8092 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8093 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8097 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8098 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8100 self.pg0.add_stream([p])
8101 self.pg_enable_capture(self.pg_interfaces)
8103 capture = self.pg1.get_capture(1)
8106 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8107 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8109 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8112 def clear_nat66(self):
8114 Clear NAT66 configuration.
8116 interfaces = self.vapi.nat66_interface_dump()
8117 for intf in interfaces:
8118 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8122 static_mappings = self.vapi.nat66_static_mapping_dump()
8123 for sm in static_mappings:
8124 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8125 sm.external_ip_address,
8130 super(TestNAT66, self).tearDown()
8131 if not self.vpp_dead:
8132 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8133 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8137 if __name__ == '__main__':
8138 unittest.main(testRunner=VppTestRunner)