9 from framework import VppTestCase, VppTestRunner, running_extended_tests
10 from scapy.layers.inet import IP, TCP, UDP, ICMP
11 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
12 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
13 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr
14 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
15 from scapy.layers.l2 import Ether, ARP, GRE
16 from scapy.data import IP_PROTOS
17 from scapy.packet import bind_layers, Raw
18 from scapy.all import fragment6
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from util import mactobinary
26 class MethodHolder(VppTestCase):
27 """ NAT create capture and verify method holder """
29 def clear_nat44(self):
31 Clear NAT44 configuration.
33 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
34 # I found no elegant way to do this
35 self.vapi.ip_add_del_route(
36 dst_address=self.pg7.remote_ip4n,
37 dst_address_length=32,
38 next_hop_address=self.pg7.remote_ip4n,
39 next_hop_sw_if_index=self.pg7.sw_if_index,
41 self.vapi.ip_add_del_route(
42 dst_address=self.pg8.remote_ip4n,
43 dst_address_length=32,
44 next_hop_address=self.pg8.remote_ip4n,
45 next_hop_sw_if_index=self.pg8.sw_if_index,
48 for intf in [self.pg7, self.pg8]:
49 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
51 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
56 if self.pg7.has_ip4_config:
57 self.pg7.unconfig_ip4()
59 self.vapi.nat44_forwarding_enable_disable(0)
61 interfaces = self.vapi.nat44_interface_addr_dump()
62 for intf in interfaces:
63 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
64 twice_nat=intf.twice_nat,
67 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
68 domain_id=self.ipfix_domain_id)
69 self.ipfix_src_port = 4739
70 self.ipfix_domain_id = 1
72 interfaces = self.vapi.nat44_interface_dump()
73 for intf in interfaces:
74 if intf.is_inside > 1:
75 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
78 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
82 interfaces = self.vapi.nat44_interface_output_feature_dump()
83 for intf in interfaces:
84 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
88 static_mappings = self.vapi.nat44_static_mapping_dump()
89 for sm in static_mappings:
90 self.vapi.nat44_add_del_static_mapping(
92 sm.external_ip_address,
93 local_port=sm.local_port,
94 external_port=sm.external_port,
95 addr_only=sm.addr_only,
98 twice_nat=sm.twice_nat,
99 self_twice_nat=sm.self_twice_nat,
100 out2in_only=sm.out2in_only,
102 external_sw_if_index=sm.external_sw_if_index,
105 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
106 for lb_sm in lb_static_mappings:
107 self.vapi.nat44_add_del_lb_static_mapping(
111 twice_nat=lb_sm.twice_nat,
112 self_twice_nat=lb_sm.self_twice_nat,
113 out2in_only=lb_sm.out2in_only,
119 identity_mappings = self.vapi.nat44_identity_mapping_dump()
120 for id_m in identity_mappings:
121 self.vapi.nat44_add_del_identity_mapping(
122 addr_only=id_m.addr_only,
125 sw_if_index=id_m.sw_if_index,
127 protocol=id_m.protocol,
130 adresses = self.vapi.nat44_address_dump()
131 for addr in adresses:
132 self.vapi.nat44_add_del_address_range(addr.ip_address,
134 twice_nat=addr.twice_nat,
137 self.vapi.nat_set_reass()
138 self.vapi.nat_set_reass(is_ip6=1)
139 self.verify_no_nat44_user()
140 self.vapi.nat_set_timeouts()
141 self.vapi.nat_set_addr_and_port_alloc_alg()
142 self.vapi.nat_set_mss_clamping()
144 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
145 local_port=0, external_port=0, vrf_id=0,
146 is_add=1, external_sw_if_index=0xFFFFFFFF,
147 proto=0, twice_nat=0, self_twice_nat=0,
148 out2in_only=0, tag=""):
150 Add/delete NAT44 static mapping
152 :param local_ip: Local IP address
153 :param external_ip: External IP address
154 :param local_port: Local port number (Optional)
155 :param external_port: External port number (Optional)
156 :param vrf_id: VRF ID (Default 0)
157 :param is_add: 1 if add, 0 if delete (Default add)
158 :param external_sw_if_index: External interface instead of IP address
159 :param proto: IP protocol (Mandatory if port specified)
160 :param twice_nat: 1 if translate external host address and port
161 :param self_twice_nat: 1 if translate external host address and port
162 whenever external host address equals
163 local address of internal host
164 :param out2in_only: if 1 rule is matching only out2in direction
165 :param tag: Opaque string tag
168 if local_port and external_port:
170 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
171 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
172 self.vapi.nat44_add_del_static_mapping(
175 external_sw_if_index,
187 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
189 Add/delete NAT44 address
191 :param ip: IP address
192 :param is_add: 1 if add, 0 if delete (Default add)
193 :param twice_nat: twice NAT address for extenal hosts
195 nat_addr = socket.inet_pton(socket.AF_INET, ip)
196 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
200 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
202 Create packet stream for inside network
204 :param in_if: Inside interface
205 :param out_if: Outside interface
206 :param dst_ip: Destination address
207 :param ttl: TTL of generated packets
210 dst_ip = out_if.remote_ip4
214 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
215 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
216 TCP(sport=self.tcp_port_in, dport=20))
220 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
221 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
222 UDP(sport=self.udp_port_in, dport=20))
226 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
227 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
228 ICMP(id=self.icmp_id_in, type='echo-request'))
233 def compose_ip6(self, ip4, pref, plen):
235 Compose IPv4-embedded IPv6 addresses
237 :param ip4: IPv4 address
238 :param pref: IPv6 prefix
239 :param plen: IPv6 prefix length
240 :returns: IPv4-embedded IPv6 addresses
242 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
243 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
258 pref_n[10] = ip4_n[3]
262 pref_n[10] = ip4_n[2]
263 pref_n[11] = ip4_n[3]
266 pref_n[10] = ip4_n[1]
267 pref_n[11] = ip4_n[2]
268 pref_n[12] = ip4_n[3]
270 pref_n[12] = ip4_n[0]
271 pref_n[13] = ip4_n[1]
272 pref_n[14] = ip4_n[2]
273 pref_n[15] = ip4_n[3]
274 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
276 def extract_ip4(self, ip6, plen):
278 Extract IPv4 address embedded in IPv6 addresses
280 :param ip6: IPv6 address
281 :param plen: IPv6 prefix length
282 :returns: extracted IPv4 address
284 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
316 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
318 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
320 Create IPv6 packet stream for inside network
322 :param in_if: Inside interface
323 :param out_if: Outside interface
324 :param ttl: Hop Limit of generated packets
325 :param pref: NAT64 prefix
326 :param plen: NAT64 prefix length
330 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
332 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
335 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
336 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
337 TCP(sport=self.tcp_port_in, dport=20))
341 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
342 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
343 UDP(sport=self.udp_port_in, dport=20))
347 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
348 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
349 ICMPv6EchoRequest(id=self.icmp_id_in))
354 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
355 use_inside_ports=False):
357 Create packet stream for outside network
359 :param out_if: Outside interface
360 :param dst_ip: Destination IP address (Default use global NAT address)
361 :param ttl: TTL of generated packets
362 :param use_inside_ports: Use inside NAT ports as destination ports
363 instead of outside ports
366 dst_ip = self.nat_addr
367 if not use_inside_ports:
368 tcp_port = self.tcp_port_out
369 udp_port = self.udp_port_out
370 icmp_id = self.icmp_id_out
372 tcp_port = self.tcp_port_in
373 udp_port = self.udp_port_in
374 icmp_id = self.icmp_id_in
377 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
378 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
379 TCP(dport=tcp_port, sport=20))
383 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
384 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
385 UDP(dport=udp_port, sport=20))
389 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
390 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
391 ICMP(id=icmp_id, type='echo-reply'))
396 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
398 Create packet stream for outside network
400 :param out_if: Outside interface
401 :param dst_ip: Destination IP address (Default use global NAT address)
402 :param hl: HL of generated packets
406 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
407 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
408 TCP(dport=self.tcp_port_out, sport=20))
412 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
413 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
414 UDP(dport=self.udp_port_out, sport=20))
418 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
419 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
420 ICMPv6EchoReply(id=self.icmp_id_out))
425 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
426 dst_ip=None, is_ip6=False):
428 Verify captured packets on outside network
430 :param capture: Captured packets
431 :param nat_ip: Translated IP address (Default use global NAT address)
432 :param same_port: Sorce port number is not translated (Default False)
433 :param dst_ip: Destination IP address (Default do not verify)
434 :param is_ip6: If L3 protocol is IPv6 (Default False)
438 ICMP46 = ICMPv6EchoRequest
443 nat_ip = self.nat_addr
444 for packet in capture:
447 self.assert_packet_checksums_valid(packet)
448 self.assertEqual(packet[IP46].src, nat_ip)
449 if dst_ip is not None:
450 self.assertEqual(packet[IP46].dst, dst_ip)
451 if packet.haslayer(TCP):
453 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
456 packet[TCP].sport, self.tcp_port_in)
457 self.tcp_port_out = packet[TCP].sport
458 self.assert_packet_checksums_valid(packet)
459 elif packet.haslayer(UDP):
461 self.assertEqual(packet[UDP].sport, self.udp_port_in)
464 packet[UDP].sport, self.udp_port_in)
465 self.udp_port_out = packet[UDP].sport
468 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
470 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
471 self.icmp_id_out = packet[ICMP46].id
472 self.assert_packet_checksums_valid(packet)
474 self.logger.error(ppp("Unexpected or invalid packet "
475 "(outside network):", packet))
478 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
481 Verify captured packets on outside network
483 :param capture: Captured packets
484 :param nat_ip: Translated IP address
485 :param same_port: Sorce port number is not translated (Default False)
486 :param dst_ip: Destination IP address (Default do not verify)
488 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
491 def verify_capture_in(self, capture, in_if):
493 Verify captured packets on inside network
495 :param capture: Captured packets
496 :param in_if: Inside interface
498 for packet in capture:
500 self.assert_packet_checksums_valid(packet)
501 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
502 if packet.haslayer(TCP):
503 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
504 elif packet.haslayer(UDP):
505 self.assertEqual(packet[UDP].dport, self.udp_port_in)
507 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
509 self.logger.error(ppp("Unexpected or invalid packet "
510 "(inside network):", packet))
513 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
515 Verify captured IPv6 packets on inside network
517 :param capture: Captured packets
518 :param src_ip: Source IP
519 :param dst_ip: Destination IP address
521 for packet in capture:
523 self.assertEqual(packet[IPv6].src, src_ip)
524 self.assertEqual(packet[IPv6].dst, dst_ip)
525 self.assert_packet_checksums_valid(packet)
526 if packet.haslayer(TCP):
527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
528 elif packet.haslayer(UDP):
529 self.assertEqual(packet[UDP].dport, self.udp_port_in)
531 self.assertEqual(packet[ICMPv6EchoReply].id,
534 self.logger.error(ppp("Unexpected or invalid packet "
535 "(inside network):", packet))
538 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
540 Verify captured packet that don't have to be translated
542 :param capture: Captured packets
543 :param ingress_if: Ingress interface
544 :param egress_if: Egress interface
546 for packet in capture:
548 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
549 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
550 if packet.haslayer(TCP):
551 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
552 elif packet.haslayer(UDP):
553 self.assertEqual(packet[UDP].sport, self.udp_port_in)
555 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
557 self.logger.error(ppp("Unexpected or invalid packet "
558 "(inside network):", packet))
561 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
564 Verify captured packets with ICMP errors on outside network
566 :param capture: Captured packets
567 :param src_ip: Translated IP address or IP address of VPP
568 (Default use global NAT address)
569 :param icmp_type: Type of error ICMP packet
570 we are expecting (Default 11)
573 src_ip = self.nat_addr
574 for packet in capture:
576 self.assertEqual(packet[IP].src, src_ip)
577 self.assertTrue(packet.haslayer(ICMP))
579 self.assertEqual(icmp.type, icmp_type)
580 self.assertTrue(icmp.haslayer(IPerror))
581 inner_ip = icmp[IPerror]
582 if inner_ip.haslayer(TCPerror):
583 self.assertEqual(inner_ip[TCPerror].dport,
585 elif inner_ip.haslayer(UDPerror):
586 self.assertEqual(inner_ip[UDPerror].dport,
589 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
591 self.logger.error(ppp("Unexpected or invalid packet "
592 "(outside network):", packet))
595 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
597 Verify captured packets with ICMP errors on inside network
599 :param capture: Captured packets
600 :param in_if: Inside interface
601 :param icmp_type: Type of error ICMP packet
602 we are expecting (Default 11)
604 for packet in capture:
606 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
607 self.assertTrue(packet.haslayer(ICMP))
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].sport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].sport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(inside network):", packet))
625 def create_stream_frag(self, src_if, dst, sport, dport, data,
626 proto=IP_PROTOS.tcp, echo_reply=False):
628 Create fragmented packet stream
630 :param src_if: Source interface
631 :param dst: Destination IPv4 address
632 :param sport: Source port
633 :param dport: Destination port
634 :param data: Payload data
635 :param proto: protocol (TCP, UDP, ICMP)
636 :param echo_reply: use echo_reply if protocol is ICMP
639 if proto == IP_PROTOS.tcp:
640 p = (IP(src=src_if.remote_ip4, dst=dst) /
641 TCP(sport=sport, dport=dport) /
643 p = p.__class__(str(p))
644 chksum = p['TCP'].chksum
645 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
646 elif proto == IP_PROTOS.udp:
647 proto_header = UDP(sport=sport, dport=dport)
648 elif proto == IP_PROTOS.icmp:
650 proto_header = ICMP(id=sport, type='echo-request')
652 proto_header = ICMP(id=sport, type='echo-reply')
654 raise Exception("Unsupported protocol")
655 id = random.randint(0, 65535)
657 if proto == IP_PROTOS.tcp:
660 raw = Raw(data[0:16])
661 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
662 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
666 if proto == IP_PROTOS.tcp:
667 raw = Raw(data[4:20])
669 raw = Raw(data[16:32])
670 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
671 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
675 if proto == IP_PROTOS.tcp:
679 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
680 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
686 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
687 pref=None, plen=0, frag_size=128):
689 Create fragmented packet stream
691 :param src_if: Source interface
692 :param dst: Destination IPv4 address
693 :param sport: Source TCP port
694 :param dport: Destination TCP port
695 :param data: Payload data
696 :param pref: NAT64 prefix
697 :param plen: NAT64 prefix length
698 :param fragsize: size of fragments
702 dst_ip6 = ''.join(['64:ff9b::', dst])
704 dst_ip6 = self.compose_ip6(dst, pref, plen)
706 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
707 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
708 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
709 TCP(sport=sport, dport=dport) /
712 return fragment6(p, frag_size)
714 def reass_frags_and_verify(self, frags, src, dst):
716 Reassemble and verify fragmented packet
718 :param frags: Captured fragments
719 :param src: Source IPv4 address to verify
720 :param dst: Destination IPv4 address to verify
722 :returns: Reassembled IPv4 packet
724 buffer = StringIO.StringIO()
726 self.assertEqual(p[IP].src, src)
727 self.assertEqual(p[IP].dst, dst)
728 self.assert_ip_checksum_valid(p)
729 buffer.seek(p[IP].frag * 8)
730 buffer.write(p[IP].payload)
731 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
732 proto=frags[0][IP].proto)
733 if ip.proto == IP_PROTOS.tcp:
734 p = (ip / TCP(buffer.getvalue()))
735 self.assert_tcp_checksum_valid(p)
736 elif ip.proto == IP_PROTOS.udp:
737 p = (ip / UDP(buffer.getvalue()[:8]) /
738 Raw(buffer.getvalue()[8:]))
739 elif ip.proto == IP_PROTOS.icmp:
740 p = (ip / ICMP(buffer.getvalue()))
743 def reass_frags_and_verify_ip6(self, frags, src, dst):
745 Reassemble and verify fragmented packet
747 :param frags: Captured fragments
748 :param src: Source IPv6 address to verify
749 :param dst: Destination IPv6 address to verify
751 :returns: Reassembled IPv6 packet
753 buffer = StringIO.StringIO()
755 self.assertEqual(p[IPv6].src, src)
756 self.assertEqual(p[IPv6].dst, dst)
757 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
758 buffer.write(p[IPv6ExtHdrFragment].payload)
759 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
760 nh=frags[0][IPv6ExtHdrFragment].nh)
761 if ip.nh == IP_PROTOS.tcp:
762 p = (ip / TCP(buffer.getvalue()))
763 elif ip.nh == IP_PROTOS.udp:
764 p = (ip / UDP(buffer.getvalue()))
765 self.assert_packet_checksums_valid(p)
768 def initiate_tcp_session(self, in_if, out_if):
770 Initiates TCP session
772 :param in_if: Inside interface
773 :param out_if: Outside interface
777 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
778 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
779 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
782 self.pg_enable_capture(self.pg_interfaces)
784 capture = out_if.get_capture(1)
786 self.tcp_port_out = p[TCP].sport
788 # SYN + ACK packet out->in
789 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
790 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
791 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
794 self.pg_enable_capture(self.pg_interfaces)
799 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
800 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
801 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
804 self.pg_enable_capture(self.pg_interfaces)
806 out_if.get_capture(1)
809 self.logger.error("TCP 3 way handshake failed")
812 def verify_ipfix_nat44_ses(self, data):
814 Verify IPFIX NAT44 session create/delete event
816 :param data: Decoded IPFIX data records
818 nat44_ses_create_num = 0
819 nat44_ses_delete_num = 0
820 self.assertEqual(6, len(data))
823 self.assertIn(ord(record[230]), [4, 5])
824 if ord(record[230]) == 4:
825 nat44_ses_create_num += 1
827 nat44_ses_delete_num += 1
829 self.assertEqual(self.pg0.remote_ip4n, record[8])
830 # postNATSourceIPv4Address
831 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
834 self.assertEqual(struct.pack("!I", 0), record[234])
835 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
836 if IP_PROTOS.icmp == ord(record[4]):
837 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
838 self.assertEqual(struct.pack("!H", self.icmp_id_out),
840 elif IP_PROTOS.tcp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.tcp_port_in),
843 self.assertEqual(struct.pack("!H", self.tcp_port_out),
845 elif IP_PROTOS.udp == ord(record[4]):
846 self.assertEqual(struct.pack("!H", self.udp_port_in),
848 self.assertEqual(struct.pack("!H", self.udp_port_out),
851 self.fail("Invalid protocol")
852 self.assertEqual(3, nat44_ses_create_num)
853 self.assertEqual(3, nat44_ses_delete_num)
855 def verify_ipfix_addr_exhausted(self, data):
857 Verify IPFIX NAT addresses event
859 :param data: Decoded IPFIX data records
861 self.assertEqual(1, len(data))
864 self.assertEqual(ord(record[230]), 3)
866 self.assertEqual(struct.pack("!I", 0), record[283])
868 def verify_ipfix_max_sessions(self, data, limit):
870 Verify IPFIX maximum session entries exceeded event
872 :param data: Decoded IPFIX data records
873 :param limit: Number of maximum session entries that can be created.
875 self.assertEqual(1, len(data))
878 self.assertEqual(ord(record[230]), 13)
879 # natQuotaExceededEvent
880 self.assertEqual(struct.pack("I", 1), record[466])
882 self.assertEqual(struct.pack("I", limit), record[471])
884 def verify_ipfix_max_bibs(self, data, limit):
886 Verify IPFIX maximum BIB entries exceeded event
888 :param data: Decoded IPFIX data records
889 :param limit: Number of maximum BIB entries that can be created.
891 self.assertEqual(1, len(data))
894 self.assertEqual(ord(record[230]), 13)
895 # natQuotaExceededEvent
896 self.assertEqual(struct.pack("I", 2), record[466])
898 self.assertEqual(struct.pack("I", limit), record[472])
900 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
902 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum fragments pending reassembly
906 :param src_addr: IPv6 source address
908 self.assertEqual(1, len(data))
911 self.assertEqual(ord(record[230]), 13)
912 # natQuotaExceededEvent
913 self.assertEqual(struct.pack("I", 5), record[466])
914 # maxFragmentsPendingReassembly
915 self.assertEqual(struct.pack("I", limit), record[475])
917 self.assertEqual(src_addr, record[27])
919 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
921 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
923 :param data: Decoded IPFIX data records
924 :param limit: Number of maximum fragments pending reassembly
925 :param src_addr: IPv4 source address
927 self.assertEqual(1, len(data))
930 self.assertEqual(ord(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 5), record[466])
933 # maxFragmentsPendingReassembly
934 self.assertEqual(struct.pack("I", limit), record[475])
936 self.assertEqual(src_addr, record[8])
938 def verify_ipfix_bib(self, data, is_create, src_addr):
940 Verify IPFIX NAT64 BIB create and delete events
942 :param data: Decoded IPFIX data records
943 :param is_create: Create event if nonzero value otherwise delete event
944 :param src_addr: IPv6 source address
946 self.assertEqual(1, len(data))
950 self.assertEqual(ord(record[230]), 10)
952 self.assertEqual(ord(record[230]), 11)
954 self.assertEqual(src_addr, record[27])
955 # postNATSourceIPv4Address
956 self.assertEqual(self.nat_addr_n, record[225])
958 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
960 self.assertEqual(struct.pack("!I", 0), record[234])
961 # sourceTransportPort
962 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
963 # postNAPTSourceTransportPort
964 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
966 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
969 Verify IPFIX NAT64 session create and delete events
971 :param data: Decoded IPFIX data records
972 :param is_create: Create event if nonzero value otherwise delete event
973 :param src_addr: IPv6 source address
974 :param dst_addr: IPv4 destination address
975 :param dst_port: destination TCP port
977 self.assertEqual(1, len(data))
981 self.assertEqual(ord(record[230]), 6)
983 self.assertEqual(ord(record[230]), 7)
985 self.assertEqual(src_addr, record[27])
986 # destinationIPv6Address
987 self.assertEqual(socket.inet_pton(socket.AF_INET6,
988 self.compose_ip6(dst_addr,
992 # postNATSourceIPv4Address
993 self.assertEqual(self.nat_addr_n, record[225])
994 # postNATDestinationIPv4Address
995 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
998 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1000 self.assertEqual(struct.pack("!I", 0), record[234])
1001 # sourceTransportPort
1002 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1003 # postNAPTSourceTransportPort
1004 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1005 # destinationTransportPort
1006 self.assertEqual(struct.pack("!H", dst_port), record[11])
1007 # postNAPTDestinationTransportPort
1008 self.assertEqual(struct.pack("!H", dst_port), record[228])
1010 def verify_no_nat44_user(self):
1011 """ Verify that there is no NAT44 user """
1012 users = self.vapi.nat44_user_dump()
1013 self.assertEqual(len(users), 0)
1015 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1017 Verify IPFIX maximum entries per user exceeded event
1019 :param data: Decoded IPFIX data records
1020 :param limit: Number of maximum entries per user
1021 :param src_addr: IPv4 source address
1023 self.assertEqual(1, len(data))
1026 self.assertEqual(ord(record[230]), 13)
1027 # natQuotaExceededEvent
1028 self.assertEqual(struct.pack("I", 3), record[466])
1030 self.assertEqual(struct.pack("I", limit), record[473])
1032 self.assertEqual(src_addr, record[8])
1034 def verify_mss_value(self, pkt, mss):
1036 Verify TCP MSS value
1041 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1042 raise TypeError("Not a TCP/IP packet")
1044 for option in pkt[TCP].options:
1045 if option[0] == 'MSS':
1046 self.assertEqual(option[1], mss)
1047 self.assert_tcp_checksum_valid(pkt)
1050 def proto2layer(proto):
1051 if proto == IP_PROTOS.tcp:
1053 elif proto == IP_PROTOS.udp:
1055 elif proto == IP_PROTOS.icmp:
1058 raise Exception("Unsupported protocol")
1060 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1061 layer = self.proto2layer(proto)
1063 if proto == IP_PROTOS.tcp:
1064 data = "A" * 4 + "B" * 16 + "C" * 3
1066 data = "A" * 16 + "B" * 16 + "C" * 3
1067 self.port_in = random.randint(1025, 65535)
1069 reass = self.vapi.nat_reass_dump()
1070 reass_n_start = len(reass)
1073 pkts = self.create_stream_frag(self.pg0,
1074 self.pg1.remote_ip4,
1079 self.pg0.add_stream(pkts)
1080 self.pg_enable_capture(self.pg_interfaces)
1082 frags = self.pg1.get_capture(len(pkts))
1083 if not dont_translate:
1084 p = self.reass_frags_and_verify(frags,
1086 self.pg1.remote_ip4)
1088 p = self.reass_frags_and_verify(frags,
1089 self.pg0.remote_ip4,
1090 self.pg1.remote_ip4)
1091 if proto != IP_PROTOS.icmp:
1092 if not dont_translate:
1093 self.assertEqual(p[layer].dport, 20)
1094 self.assertNotEqual(p[layer].sport, self.port_in)
1096 self.assertEqual(p[layer].sport, self.port_in)
1098 if not dont_translate:
1099 self.assertNotEqual(p[layer].id, self.port_in)
1101 self.assertEqual(p[layer].id, self.port_in)
1102 self.assertEqual(data, p[Raw].load)
1105 if not dont_translate:
1106 dst_addr = self.nat_addr
1108 dst_addr = self.pg0.remote_ip4
1109 if proto != IP_PROTOS.icmp:
1111 dport = p[layer].sport
1115 pkts = self.create_stream_frag(self.pg1,
1122 self.pg1.add_stream(pkts)
1123 self.pg_enable_capture(self.pg_interfaces)
1125 frags = self.pg0.get_capture(len(pkts))
1126 p = self.reass_frags_and_verify(frags,
1127 self.pg1.remote_ip4,
1128 self.pg0.remote_ip4)
1129 if proto != IP_PROTOS.icmp:
1130 self.assertEqual(p[layer].sport, 20)
1131 self.assertEqual(p[layer].dport, self.port_in)
1133 self.assertEqual(p[layer].id, self.port_in)
1134 self.assertEqual(data, p[Raw].load)
1136 reass = self.vapi.nat_reass_dump()
1137 reass_n_end = len(reass)
1139 self.assertEqual(reass_n_end - reass_n_start, 2)
1141 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1142 layer = self.proto2layer(proto)
1144 if proto == IP_PROTOS.tcp:
1145 data = "A" * 4 + "B" * 16 + "C" * 3
1147 data = "A" * 16 + "B" * 16 + "C" * 3
1148 self.port_in = random.randint(1025, 65535)
1151 reass = self.vapi.nat_reass_dump()
1152 reass_n_start = len(reass)
1155 pkts = self.create_stream_frag(self.pg0,
1156 self.server_out_addr,
1158 self.server_out_port,
1161 self.pg0.add_stream(pkts)
1162 self.pg_enable_capture(self.pg_interfaces)
1164 frags = self.pg1.get_capture(len(pkts))
1165 p = self.reass_frags_and_verify(frags,
1166 self.pg0.remote_ip4,
1167 self.server_in_addr)
1168 if proto != IP_PROTOS.icmp:
1169 self.assertEqual(p[layer].sport, self.port_in)
1170 self.assertEqual(p[layer].dport, self.server_in_port)
1172 self.assertEqual(p[layer].id, self.port_in)
1173 self.assertEqual(data, p[Raw].load)
1176 if proto != IP_PROTOS.icmp:
1177 pkts = self.create_stream_frag(self.pg1,
1178 self.pg0.remote_ip4,
1179 self.server_in_port,
1184 pkts = self.create_stream_frag(self.pg1,
1185 self.pg0.remote_ip4,
1191 self.pg1.add_stream(pkts)
1192 self.pg_enable_capture(self.pg_interfaces)
1194 frags = self.pg0.get_capture(len(pkts))
1195 p = self.reass_frags_and_verify(frags,
1196 self.server_out_addr,
1197 self.pg0.remote_ip4)
1198 if proto != IP_PROTOS.icmp:
1199 self.assertEqual(p[layer].sport, self.server_out_port)
1200 self.assertEqual(p[layer].dport, self.port_in)
1202 self.assertEqual(p[layer].id, self.port_in)
1203 self.assertEqual(data, p[Raw].load)
1205 reass = self.vapi.nat_reass_dump()
1206 reass_n_end = len(reass)
1208 self.assertEqual(reass_n_end - reass_n_start, 2)
1210 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1211 layer = self.proto2layer(proto)
1213 if proto == IP_PROTOS.tcp:
1214 data = "A" * 4 + "B" * 16 + "C" * 3
1216 data = "A" * 16 + "B" * 16 + "C" * 3
1218 # send packet from host to server
1219 pkts = self.create_stream_frag(self.pg0,
1222 self.server_out_port,
1225 self.pg0.add_stream(pkts)
1226 self.pg_enable_capture(self.pg_interfaces)
1228 frags = self.pg0.get_capture(len(pkts))
1229 p = self.reass_frags_and_verify(frags,
1232 if proto != IP_PROTOS.icmp:
1233 self.assertNotEqual(p[layer].sport, self.host_in_port)
1234 self.assertEqual(p[layer].dport, self.server_in_port)
1236 self.assertNotEqual(p[layer].id, self.host_in_port)
1237 self.assertEqual(data, p[Raw].load)
1239 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1240 layer = self.proto2layer(proto)
1242 if proto == IP_PROTOS.tcp:
1243 data = "A" * 4 + "B" * 16 + "C" * 3
1245 data = "A" * 16 + "B" * 16 + "C" * 3
1246 self.port_in = random.randint(1025, 65535)
1250 pkts = self.create_stream_frag(self.pg0,
1251 self.pg1.remote_ip4,
1257 self.pg0.add_stream(pkts)
1258 self.pg_enable_capture(self.pg_interfaces)
1260 frags = self.pg1.get_capture(len(pkts))
1261 if not dont_translate:
1262 p = self.reass_frags_and_verify(frags,
1264 self.pg1.remote_ip4)
1266 p = self.reass_frags_and_verify(frags,
1267 self.pg0.remote_ip4,
1268 self.pg1.remote_ip4)
1269 if proto != IP_PROTOS.icmp:
1270 if not dont_translate:
1271 self.assertEqual(p[layer].dport, 20)
1272 self.assertNotEqual(p[layer].sport, self.port_in)
1274 self.assertEqual(p[layer].sport, self.port_in)
1276 if not dont_translate:
1277 self.assertNotEqual(p[layer].id, self.port_in)
1279 self.assertEqual(p[layer].id, self.port_in)
1280 self.assertEqual(data, p[Raw].load)
1283 if not dont_translate:
1284 dst_addr = self.nat_addr
1286 dst_addr = self.pg0.remote_ip4
1287 if proto != IP_PROTOS.icmp:
1289 dport = p[layer].sport
1293 pkts = self.create_stream_frag(self.pg1,
1301 self.pg1.add_stream(pkts)
1302 self.pg_enable_capture(self.pg_interfaces)
1304 frags = self.pg0.get_capture(len(pkts))
1305 p = self.reass_frags_and_verify(frags,
1306 self.pg1.remote_ip4,
1307 self.pg0.remote_ip4)
1308 if proto != IP_PROTOS.icmp:
1309 self.assertEqual(p[layer].sport, 20)
1310 self.assertEqual(p[layer].dport, self.port_in)
1312 self.assertEqual(p[layer].id, self.port_in)
1313 self.assertEqual(data, p[Raw].load)
1315 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1316 layer = self.proto2layer(proto)
1318 if proto == IP_PROTOS.tcp:
1319 data = "A" * 4 + "B" * 16 + "C" * 3
1321 data = "A" * 16 + "B" * 16 + "C" * 3
1322 self.port_in = random.randint(1025, 65535)
1326 pkts = self.create_stream_frag(self.pg0,
1327 self.server_out_addr,
1329 self.server_out_port,
1333 self.pg0.add_stream(pkts)
1334 self.pg_enable_capture(self.pg_interfaces)
1336 frags = self.pg1.get_capture(len(pkts))
1337 p = self.reass_frags_and_verify(frags,
1338 self.pg0.remote_ip4,
1339 self.server_in_addr)
1340 if proto != IP_PROTOS.icmp:
1341 self.assertEqual(p[layer].dport, self.server_in_port)
1342 self.assertEqual(p[layer].sport, self.port_in)
1343 self.assertEqual(p[layer].dport, self.server_in_port)
1345 self.assertEqual(p[layer].id, self.port_in)
1346 self.assertEqual(data, p[Raw].load)
1349 if proto != IP_PROTOS.icmp:
1350 pkts = self.create_stream_frag(self.pg1,
1351 self.pg0.remote_ip4,
1352 self.server_in_port,
1357 pkts = self.create_stream_frag(self.pg1,
1358 self.pg0.remote_ip4,
1365 self.pg1.add_stream(pkts)
1366 self.pg_enable_capture(self.pg_interfaces)
1368 frags = self.pg0.get_capture(len(pkts))
1369 p = self.reass_frags_and_verify(frags,
1370 self.server_out_addr,
1371 self.pg0.remote_ip4)
1372 if proto != IP_PROTOS.icmp:
1373 self.assertEqual(p[layer].sport, self.server_out_port)
1374 self.assertEqual(p[layer].dport, self.port_in)
1376 self.assertEqual(p[layer].id, self.port_in)
1377 self.assertEqual(data, p[Raw].load)
1380 class TestNAT44(MethodHolder):
1381 """ NAT44 Test Cases """
1384 def setUpClass(cls):
1385 super(TestNAT44, cls).setUpClass()
1386 cls.vapi.cli("set log class nat level debug")
1389 cls.tcp_port_in = 6303
1390 cls.tcp_port_out = 6303
1391 cls.udp_port_in = 6304
1392 cls.udp_port_out = 6304
1393 cls.icmp_id_in = 6305
1394 cls.icmp_id_out = 6305
1395 cls.nat_addr = '10.0.0.3'
1396 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1397 cls.ipfix_src_port = 4739
1398 cls.ipfix_domain_id = 1
1399 cls.tcp_external_port = 80
1401 cls.create_pg_interfaces(range(10))
1402 cls.interfaces = list(cls.pg_interfaces[0:4])
1404 for i in cls.interfaces:
1409 cls.pg0.generate_remote_hosts(3)
1410 cls.pg0.configure_ipv4_neighbors()
1412 cls.pg1.generate_remote_hosts(1)
1413 cls.pg1.configure_ipv4_neighbors()
1415 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1416 cls.vapi.ip_table_add_del(10, is_add=1)
1417 cls.vapi.ip_table_add_del(20, is_add=1)
1419 cls.pg4._local_ip4 = "172.16.255.1"
1420 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1421 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1422 cls.pg4.set_table_ip4(10)
1423 cls.pg5._local_ip4 = "172.17.255.3"
1424 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1425 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1426 cls.pg5.set_table_ip4(10)
1427 cls.pg6._local_ip4 = "172.16.255.1"
1428 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1429 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1430 cls.pg6.set_table_ip4(20)
1431 for i in cls.overlapping_interfaces:
1439 cls.pg9.generate_remote_hosts(2)
1440 cls.pg9.config_ip4()
1441 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1442 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1446 cls.pg9.resolve_arp()
1447 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1448 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1449 cls.pg9.resolve_arp()
1452 super(TestNAT44, cls).tearDownClass()
1455 def test_dynamic(self):
1456 """ NAT44 dynamic translation test """
1458 self.nat44_add_address(self.nat_addr)
1459 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1460 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1464 pkts = self.create_stream_in(self.pg0, self.pg1)
1465 self.pg0.add_stream(pkts)
1466 self.pg_enable_capture(self.pg_interfaces)
1468 capture = self.pg1.get_capture(len(pkts))
1469 self.verify_capture_out(capture)
1472 pkts = self.create_stream_out(self.pg1)
1473 self.pg1.add_stream(pkts)
1474 self.pg_enable_capture(self.pg_interfaces)
1476 capture = self.pg0.get_capture(len(pkts))
1477 self.verify_capture_in(capture, self.pg0)
1479 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1480 """ NAT44 handling of client packets with TTL=1 """
1482 self.nat44_add_address(self.nat_addr)
1483 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1484 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1487 # Client side - generate traffic
1488 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1489 self.pg0.add_stream(pkts)
1490 self.pg_enable_capture(self.pg_interfaces)
1493 # Client side - verify ICMP type 11 packets
1494 capture = self.pg0.get_capture(len(pkts))
1495 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1497 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1498 """ NAT44 handling of server packets with TTL=1 """
1500 self.nat44_add_address(self.nat_addr)
1501 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1502 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1505 # Client side - create sessions
1506 pkts = self.create_stream_in(self.pg0, self.pg1)
1507 self.pg0.add_stream(pkts)
1508 self.pg_enable_capture(self.pg_interfaces)
1511 # Server side - generate traffic
1512 capture = self.pg1.get_capture(len(pkts))
1513 self.verify_capture_out(capture)
1514 pkts = self.create_stream_out(self.pg1, ttl=1)
1515 self.pg1.add_stream(pkts)
1516 self.pg_enable_capture(self.pg_interfaces)
1519 # Server side - verify ICMP type 11 packets
1520 capture = self.pg1.get_capture(len(pkts))
1521 self.verify_capture_out_with_icmp_errors(capture,
1522 src_ip=self.pg1.local_ip4)
1524 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1525 """ NAT44 handling of error responses to client packets with TTL=2 """
1527 self.nat44_add_address(self.nat_addr)
1528 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1529 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1532 # Client side - generate traffic
1533 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1534 self.pg0.add_stream(pkts)
1535 self.pg_enable_capture(self.pg_interfaces)
1538 # Server side - simulate ICMP type 11 response
1539 capture = self.pg1.get_capture(len(pkts))
1540 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1541 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1542 ICMP(type=11) / packet[IP] for packet in capture]
1543 self.pg1.add_stream(pkts)
1544 self.pg_enable_capture(self.pg_interfaces)
1547 # Client side - verify ICMP type 11 packets
1548 capture = self.pg0.get_capture(len(pkts))
1549 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1551 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1552 """ NAT44 handling of error responses to server packets with TTL=2 """
1554 self.nat44_add_address(self.nat_addr)
1555 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1556 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1559 # Client side - create sessions
1560 pkts = self.create_stream_in(self.pg0, self.pg1)
1561 self.pg0.add_stream(pkts)
1562 self.pg_enable_capture(self.pg_interfaces)
1565 # Server side - generate traffic
1566 capture = self.pg1.get_capture(len(pkts))
1567 self.verify_capture_out(capture)
1568 pkts = self.create_stream_out(self.pg1, ttl=2)
1569 self.pg1.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1573 # Client side - simulate ICMP type 11 response
1574 capture = self.pg0.get_capture(len(pkts))
1575 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1576 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1577 ICMP(type=11) / packet[IP] for packet in capture]
1578 self.pg0.add_stream(pkts)
1579 self.pg_enable_capture(self.pg_interfaces)
1582 # Server side - verify ICMP type 11 packets
1583 capture = self.pg1.get_capture(len(pkts))
1584 self.verify_capture_out_with_icmp_errors(capture)
1586 def test_ping_out_interface_from_outside(self):
1587 """ Ping NAT44 out interface from outside network """
1589 self.nat44_add_address(self.nat_addr)
1590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1594 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1595 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1596 ICMP(id=self.icmp_id_out, type='echo-request'))
1598 self.pg1.add_stream(pkts)
1599 self.pg_enable_capture(self.pg_interfaces)
1601 capture = self.pg1.get_capture(len(pkts))
1604 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1605 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1606 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1607 self.assertEqual(packet[ICMP].type, 0) # echo reply
1609 self.logger.error(ppp("Unexpected or invalid packet "
1610 "(outside network):", packet))
1613 def test_ping_internal_host_from_outside(self):
1614 """ Ping internal host from outside network """
1616 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1617 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1618 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1622 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1623 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1624 ICMP(id=self.icmp_id_out, type='echo-request'))
1625 self.pg1.add_stream(pkt)
1626 self.pg_enable_capture(self.pg_interfaces)
1628 capture = self.pg0.get_capture(1)
1629 self.verify_capture_in(capture, self.pg0)
1630 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1633 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1634 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1635 ICMP(id=self.icmp_id_in, type='echo-reply'))
1636 self.pg0.add_stream(pkt)
1637 self.pg_enable_capture(self.pg_interfaces)
1639 capture = self.pg1.get_capture(1)
1640 self.verify_capture_out(capture, same_port=True)
1641 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1643 def test_forwarding(self):
1644 """ NAT44 forwarding test """
1646 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1647 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1649 self.vapi.nat44_forwarding_enable_disable(1)
1651 real_ip = self.pg0.remote_ip4n
1652 alias_ip = self.nat_addr_n
1653 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1654 external_ip=alias_ip)
1657 # static mapping match
1659 pkts = self.create_stream_out(self.pg1)
1660 self.pg1.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1663 capture = self.pg0.get_capture(len(pkts))
1664 self.verify_capture_in(capture, self.pg0)
1666 pkts = self.create_stream_in(self.pg0, self.pg1)
1667 self.pg0.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1670 capture = self.pg1.get_capture(len(pkts))
1671 self.verify_capture_out(capture, same_port=True)
1673 # no static mapping match
1675 host0 = self.pg0.remote_hosts[0]
1676 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1678 pkts = self.create_stream_out(self.pg1,
1679 dst_ip=self.pg0.remote_ip4,
1680 use_inside_ports=True)
1681 self.pg1.add_stream(pkts)
1682 self.pg_enable_capture(self.pg_interfaces)
1684 capture = self.pg0.get_capture(len(pkts))
1685 self.verify_capture_in(capture, self.pg0)
1687 pkts = self.create_stream_in(self.pg0, self.pg1)
1688 self.pg0.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1691 capture = self.pg1.get_capture(len(pkts))
1692 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1695 self.pg0.remote_hosts[0] = host0
1698 self.vapi.nat44_forwarding_enable_disable(0)
1699 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1700 external_ip=alias_ip,
1703 def test_static_in(self):
1704 """ 1:1 NAT initialized from inside network """
1706 nat_ip = "10.0.0.10"
1707 self.tcp_port_out = 6303
1708 self.udp_port_out = 6304
1709 self.icmp_id_out = 6305
1711 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1712 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1713 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1715 sm = self.vapi.nat44_static_mapping_dump()
1716 self.assertEqual(len(sm), 1)
1717 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1718 self.assertEqual(sm[0].protocol, 0)
1719 self.assertEqual(sm[0].local_port, 0)
1720 self.assertEqual(sm[0].external_port, 0)
1723 pkts = self.create_stream_in(self.pg0, self.pg1)
1724 self.pg0.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1727 capture = self.pg1.get_capture(len(pkts))
1728 self.verify_capture_out(capture, nat_ip, True)
1731 pkts = self.create_stream_out(self.pg1, nat_ip)
1732 self.pg1.add_stream(pkts)
1733 self.pg_enable_capture(self.pg_interfaces)
1735 capture = self.pg0.get_capture(len(pkts))
1736 self.verify_capture_in(capture, self.pg0)
1738 def test_static_out(self):
1739 """ 1:1 NAT initialized from outside network """
1741 nat_ip = "10.0.0.20"
1742 self.tcp_port_out = 6303
1743 self.udp_port_out = 6304
1744 self.icmp_id_out = 6305
1747 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1748 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1749 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1751 sm = self.vapi.nat44_static_mapping_dump()
1752 self.assertEqual(len(sm), 1)
1753 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1756 pkts = self.create_stream_out(self.pg1, nat_ip)
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg0.get_capture(len(pkts))
1761 self.verify_capture_in(capture, self.pg0)
1764 pkts = self.create_stream_in(self.pg0, self.pg1)
1765 self.pg0.add_stream(pkts)
1766 self.pg_enable_capture(self.pg_interfaces)
1768 capture = self.pg1.get_capture(len(pkts))
1769 self.verify_capture_out(capture, nat_ip, True)
1771 def test_static_with_port_in(self):
1772 """ 1:1 NAPT initialized from inside network """
1774 self.tcp_port_out = 3606
1775 self.udp_port_out = 3607
1776 self.icmp_id_out = 3608
1778 self.nat44_add_address(self.nat_addr)
1779 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1780 self.tcp_port_in, self.tcp_port_out,
1781 proto=IP_PROTOS.tcp)
1782 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1783 self.udp_port_in, self.udp_port_out,
1784 proto=IP_PROTOS.udp)
1785 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1786 self.icmp_id_in, self.icmp_id_out,
1787 proto=IP_PROTOS.icmp)
1788 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1789 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1793 pkts = self.create_stream_in(self.pg0, self.pg1)
1794 self.pg0.add_stream(pkts)
1795 self.pg_enable_capture(self.pg_interfaces)
1797 capture = self.pg1.get_capture(len(pkts))
1798 self.verify_capture_out(capture)
1801 pkts = self.create_stream_out(self.pg1)
1802 self.pg1.add_stream(pkts)
1803 self.pg_enable_capture(self.pg_interfaces)
1805 capture = self.pg0.get_capture(len(pkts))
1806 self.verify_capture_in(capture, self.pg0)
1808 def test_static_with_port_out(self):
1809 """ 1:1 NAPT initialized from outside network """
1811 self.tcp_port_out = 30606
1812 self.udp_port_out = 30607
1813 self.icmp_id_out = 30608
1815 self.nat44_add_address(self.nat_addr)
1816 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1817 self.tcp_port_in, self.tcp_port_out,
1818 proto=IP_PROTOS.tcp)
1819 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1820 self.udp_port_in, self.udp_port_out,
1821 proto=IP_PROTOS.udp)
1822 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1823 self.icmp_id_in, self.icmp_id_out,
1824 proto=IP_PROTOS.icmp)
1825 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1826 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1838 pkts = self.create_stream_in(self.pg0, self.pg1)
1839 self.pg0.add_stream(pkts)
1840 self.pg_enable_capture(self.pg_interfaces)
1842 capture = self.pg1.get_capture(len(pkts))
1843 self.verify_capture_out(capture)
1845 def test_static_vrf_aware(self):
1846 """ 1:1 NAT VRF awareness """
1848 nat_ip1 = "10.0.0.30"
1849 nat_ip2 = "10.0.0.40"
1850 self.tcp_port_out = 6303
1851 self.udp_port_out = 6304
1852 self.icmp_id_out = 6305
1854 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1856 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1858 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1861 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1863 # inside interface VRF match NAT44 static mapping VRF
1864 pkts = self.create_stream_in(self.pg4, self.pg3)
1865 self.pg4.add_stream(pkts)
1866 self.pg_enable_capture(self.pg_interfaces)
1868 capture = self.pg3.get_capture(len(pkts))
1869 self.verify_capture_out(capture, nat_ip1, True)
1871 # inside interface VRF don't match NAT44 static mapping VRF (packets
1873 pkts = self.create_stream_in(self.pg0, self.pg3)
1874 self.pg0.add_stream(pkts)
1875 self.pg_enable_capture(self.pg_interfaces)
1877 self.pg3.assert_nothing_captured()
1879 def test_dynamic_to_static(self):
1880 """ Switch from dynamic translation to 1:1NAT """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_address(self.nat_addr)
1887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg1.get_capture(len(pkts))
1897 self.verify_capture_out(capture)
1900 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1902 self.assertEqual(len(sessions), 0)
1903 pkts = self.create_stream_in(self.pg0, self.pg1)
1904 self.pg0.add_stream(pkts)
1905 self.pg_enable_capture(self.pg_interfaces)
1907 capture = self.pg1.get_capture(len(pkts))
1908 self.verify_capture_out(capture, nat_ip, True)
1910 def test_identity_nat(self):
1911 """ Identity NAT """
1913 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1915 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1918 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1919 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1920 TCP(sport=12345, dport=56789))
1921 self.pg1.add_stream(p)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg0.get_capture(1)
1929 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1930 self.assertEqual(ip.src, self.pg1.remote_ip4)
1931 self.assertEqual(tcp.dport, 56789)
1932 self.assertEqual(tcp.sport, 12345)
1933 self.assert_packet_checksums_valid(p)
1935 self.logger.error(ppp("Unexpected or invalid packet:", p))
1938 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1939 self.assertEqual(len(sessions), 0)
1940 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
1942 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1943 self.assertEqual(len(identity_mappings), 2)
1945 def test_multiple_inside_interfaces(self):
1946 """ NAT44 multiple non-overlapping address space inside interfaces """
1948 self.nat44_add_address(self.nat_addr)
1949 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1950 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1951 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1954 # between two NAT44 inside interfaces (no translation)
1955 pkts = self.create_stream_in(self.pg0, self.pg1)
1956 self.pg0.add_stream(pkts)
1957 self.pg_enable_capture(self.pg_interfaces)
1959 capture = self.pg1.get_capture(len(pkts))
1960 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1962 # from NAT44 inside to interface without NAT44 feature (no translation)
1963 pkts = self.create_stream_in(self.pg0, self.pg2)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 capture = self.pg2.get_capture(len(pkts))
1968 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1970 # in2out 1st interface
1971 pkts = self.create_stream_in(self.pg0, self.pg3)
1972 self.pg0.add_stream(pkts)
1973 self.pg_enable_capture(self.pg_interfaces)
1975 capture = self.pg3.get_capture(len(pkts))
1976 self.verify_capture_out(capture)
1978 # out2in 1st interface
1979 pkts = self.create_stream_out(self.pg3)
1980 self.pg3.add_stream(pkts)
1981 self.pg_enable_capture(self.pg_interfaces)
1983 capture = self.pg0.get_capture(len(pkts))
1984 self.verify_capture_in(capture, self.pg0)
1986 # in2out 2nd interface
1987 pkts = self.create_stream_in(self.pg1, self.pg3)
1988 self.pg1.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1991 capture = self.pg3.get_capture(len(pkts))
1992 self.verify_capture_out(capture)
1994 # out2in 2nd interface
1995 pkts = self.create_stream_out(self.pg3)
1996 self.pg3.add_stream(pkts)
1997 self.pg_enable_capture(self.pg_interfaces)
1999 capture = self.pg1.get_capture(len(pkts))
2000 self.verify_capture_in(capture, self.pg1)
2002 def test_inside_overlapping_interfaces(self):
2003 """ NAT44 multiple inside interfaces with overlapping address space """
2005 static_nat_ip = "10.0.0.10"
2006 self.nat44_add_address(self.nat_addr)
2007 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2009 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2010 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2011 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2012 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2015 # between NAT44 inside interfaces with same VRF (no translation)
2016 pkts = self.create_stream_in(self.pg4, self.pg5)
2017 self.pg4.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2020 capture = self.pg5.get_capture(len(pkts))
2021 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2023 # between NAT44 inside interfaces with different VRF (hairpinning)
2024 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2025 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2026 TCP(sport=1234, dport=5678))
2027 self.pg4.add_stream(p)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg6.get_capture(1)
2035 self.assertEqual(ip.src, self.nat_addr)
2036 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2037 self.assertNotEqual(tcp.sport, 1234)
2038 self.assertEqual(tcp.dport, 5678)
2040 self.logger.error(ppp("Unexpected or invalid packet:", p))
2043 # in2out 1st interface
2044 pkts = self.create_stream_in(self.pg4, self.pg3)
2045 self.pg4.add_stream(pkts)
2046 self.pg_enable_capture(self.pg_interfaces)
2048 capture = self.pg3.get_capture(len(pkts))
2049 self.verify_capture_out(capture)
2051 # out2in 1st interface
2052 pkts = self.create_stream_out(self.pg3)
2053 self.pg3.add_stream(pkts)
2054 self.pg_enable_capture(self.pg_interfaces)
2056 capture = self.pg4.get_capture(len(pkts))
2057 self.verify_capture_in(capture, self.pg4)
2059 # in2out 2nd interface
2060 pkts = self.create_stream_in(self.pg5, self.pg3)
2061 self.pg5.add_stream(pkts)
2062 self.pg_enable_capture(self.pg_interfaces)
2064 capture = self.pg3.get_capture(len(pkts))
2065 self.verify_capture_out(capture)
2067 # out2in 2nd interface
2068 pkts = self.create_stream_out(self.pg3)
2069 self.pg3.add_stream(pkts)
2070 self.pg_enable_capture(self.pg_interfaces)
2072 capture = self.pg5.get_capture(len(pkts))
2073 self.verify_capture_in(capture, self.pg5)
2076 addresses = self.vapi.nat44_address_dump()
2077 self.assertEqual(len(addresses), 1)
2078 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2079 self.assertEqual(len(sessions), 3)
2080 for session in sessions:
2081 self.assertFalse(session.is_static)
2082 self.assertEqual(session.inside_ip_address[0:4],
2083 self.pg5.remote_ip4n)
2084 self.assertEqual(session.outside_ip_address,
2085 addresses[0].ip_address)
2086 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2087 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2088 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2089 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2090 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2091 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2092 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2093 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2094 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2096 # in2out 3rd interface
2097 pkts = self.create_stream_in(self.pg6, self.pg3)
2098 self.pg6.add_stream(pkts)
2099 self.pg_enable_capture(self.pg_interfaces)
2101 capture = self.pg3.get_capture(len(pkts))
2102 self.verify_capture_out(capture, static_nat_ip, True)
2104 # out2in 3rd interface
2105 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2106 self.pg3.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg6.get_capture(len(pkts))
2110 self.verify_capture_in(capture, self.pg6)
2112 # general user and session dump verifications
2113 users = self.vapi.nat44_user_dump()
2114 self.assertTrue(len(users) >= 3)
2115 addresses = self.vapi.nat44_address_dump()
2116 self.assertEqual(len(addresses), 1)
2118 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2120 for session in sessions:
2121 self.assertEqual(user.ip_address, session.inside_ip_address)
2122 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2123 self.assertTrue(session.protocol in
2124 [IP_PROTOS.tcp, IP_PROTOS.udp,
2126 self.assertFalse(session.ext_host_valid)
2129 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2130 self.assertTrue(len(sessions) >= 4)
2131 for session in sessions:
2132 self.assertFalse(session.is_static)
2133 self.assertEqual(session.inside_ip_address[0:4],
2134 self.pg4.remote_ip4n)
2135 self.assertEqual(session.outside_ip_address,
2136 addresses[0].ip_address)
2139 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2140 self.assertTrue(len(sessions) >= 3)
2141 for session in sessions:
2142 self.assertTrue(session.is_static)
2143 self.assertEqual(session.inside_ip_address[0:4],
2144 self.pg6.remote_ip4n)
2145 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2146 map(int, static_nat_ip.split('.')))
2147 self.assertTrue(session.inside_port in
2148 [self.tcp_port_in, self.udp_port_in,
2151 def test_hairpinning(self):
2152 """ NAT44 hairpinning - 1:1 NAPT """
2154 host = self.pg0.remote_hosts[0]
2155 server = self.pg0.remote_hosts[1]
2158 server_in_port = 5678
2159 server_out_port = 8765
2161 self.nat44_add_address(self.nat_addr)
2162 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2163 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2165 # add static mapping for server
2166 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2167 server_in_port, server_out_port,
2168 proto=IP_PROTOS.tcp)
2170 # send packet from host to server
2171 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2172 IP(src=host.ip4, dst=self.nat_addr) /
2173 TCP(sport=host_in_port, dport=server_out_port))
2174 self.pg0.add_stream(p)
2175 self.pg_enable_capture(self.pg_interfaces)
2177 capture = self.pg0.get_capture(1)
2182 self.assertEqual(ip.src, self.nat_addr)
2183 self.assertEqual(ip.dst, server.ip4)
2184 self.assertNotEqual(tcp.sport, host_in_port)
2185 self.assertEqual(tcp.dport, server_in_port)
2186 self.assert_packet_checksums_valid(p)
2187 host_out_port = tcp.sport
2189 self.logger.error(ppp("Unexpected or invalid packet:", p))
2192 # send reply from server to host
2193 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2194 IP(src=server.ip4, dst=self.nat_addr) /
2195 TCP(sport=server_in_port, dport=host_out_port))
2196 self.pg0.add_stream(p)
2197 self.pg_enable_capture(self.pg_interfaces)
2199 capture = self.pg0.get_capture(1)
2204 self.assertEqual(ip.src, self.nat_addr)
2205 self.assertEqual(ip.dst, host.ip4)
2206 self.assertEqual(tcp.sport, server_out_port)
2207 self.assertEqual(tcp.dport, host_in_port)
2208 self.assert_packet_checksums_valid(p)
2210 self.logger.error(ppp("Unexpected or invalid packet:", p))
2213 def test_hairpinning2(self):
2214 """ NAT44 hairpinning - 1:1 NAT"""
2216 server1_nat_ip = "10.0.0.10"
2217 server2_nat_ip = "10.0.0.11"
2218 host = self.pg0.remote_hosts[0]
2219 server1 = self.pg0.remote_hosts[1]
2220 server2 = self.pg0.remote_hosts[2]
2221 server_tcp_port = 22
2222 server_udp_port = 20
2224 self.nat44_add_address(self.nat_addr)
2225 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2226 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2229 # add static mapping for servers
2230 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2231 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2235 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2236 IP(src=host.ip4, dst=server1_nat_ip) /
2237 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2240 IP(src=host.ip4, dst=server1_nat_ip) /
2241 UDP(sport=self.udp_port_in, dport=server_udp_port))
2243 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2244 IP(src=host.ip4, dst=server1_nat_ip) /
2245 ICMP(id=self.icmp_id_in, type='echo-request'))
2247 self.pg0.add_stream(pkts)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg0.get_capture(len(pkts))
2251 for packet in capture:
2253 self.assertEqual(packet[IP].src, self.nat_addr)
2254 self.assertEqual(packet[IP].dst, server1.ip4)
2255 if packet.haslayer(TCP):
2256 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2257 self.assertEqual(packet[TCP].dport, server_tcp_port)
2258 self.tcp_port_out = packet[TCP].sport
2259 self.assert_packet_checksums_valid(packet)
2260 elif packet.haslayer(UDP):
2261 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2262 self.assertEqual(packet[UDP].dport, server_udp_port)
2263 self.udp_port_out = packet[UDP].sport
2265 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2266 self.icmp_id_out = packet[ICMP].id
2268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2274 IP(src=server1.ip4, dst=self.nat_addr) /
2275 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2278 IP(src=server1.ip4, dst=self.nat_addr) /
2279 UDP(sport=server_udp_port, dport=self.udp_port_out))
2281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2282 IP(src=server1.ip4, dst=self.nat_addr) /
2283 ICMP(id=self.icmp_id_out, type='echo-reply'))
2285 self.pg0.add_stream(pkts)
2286 self.pg_enable_capture(self.pg_interfaces)
2288 capture = self.pg0.get_capture(len(pkts))
2289 for packet in capture:
2291 self.assertEqual(packet[IP].src, server1_nat_ip)
2292 self.assertEqual(packet[IP].dst, host.ip4)
2293 if packet.haslayer(TCP):
2294 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2295 self.assertEqual(packet[TCP].sport, server_tcp_port)
2296 self.assert_packet_checksums_valid(packet)
2297 elif packet.haslayer(UDP):
2298 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2299 self.assertEqual(packet[UDP].sport, server_udp_port)
2301 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2306 # server2 to server1
2308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2309 IP(src=server2.ip4, dst=server1_nat_ip) /
2310 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2313 IP(src=server2.ip4, dst=server1_nat_ip) /
2314 UDP(sport=self.udp_port_in, dport=server_udp_port))
2316 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2317 IP(src=server2.ip4, dst=server1_nat_ip) /
2318 ICMP(id=self.icmp_id_in, type='echo-request'))
2320 self.pg0.add_stream(pkts)
2321 self.pg_enable_capture(self.pg_interfaces)
2323 capture = self.pg0.get_capture(len(pkts))
2324 for packet in capture:
2326 self.assertEqual(packet[IP].src, server2_nat_ip)
2327 self.assertEqual(packet[IP].dst, server1.ip4)
2328 if packet.haslayer(TCP):
2329 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2330 self.assertEqual(packet[TCP].dport, server_tcp_port)
2331 self.tcp_port_out = packet[TCP].sport
2332 self.assert_packet_checksums_valid(packet)
2333 elif packet.haslayer(UDP):
2334 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2335 self.assertEqual(packet[UDP].dport, server_udp_port)
2336 self.udp_port_out = packet[UDP].sport
2338 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2339 self.icmp_id_out = packet[ICMP].id
2341 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2344 # server1 to server2
2346 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2347 IP(src=server1.ip4, dst=server2_nat_ip) /
2348 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2350 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2351 IP(src=server1.ip4, dst=server2_nat_ip) /
2352 UDP(sport=server_udp_port, dport=self.udp_port_out))
2354 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2355 IP(src=server1.ip4, dst=server2_nat_ip) /
2356 ICMP(id=self.icmp_id_out, type='echo-reply'))
2358 self.pg0.add_stream(pkts)
2359 self.pg_enable_capture(self.pg_interfaces)
2361 capture = self.pg0.get_capture(len(pkts))
2362 for packet in capture:
2364 self.assertEqual(packet[IP].src, server1_nat_ip)
2365 self.assertEqual(packet[IP].dst, server2.ip4)
2366 if packet.haslayer(TCP):
2367 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2368 self.assertEqual(packet[TCP].sport, server_tcp_port)
2369 self.assert_packet_checksums_valid(packet)
2370 elif packet.haslayer(UDP):
2371 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2372 self.assertEqual(packet[UDP].sport, server_udp_port)
2374 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2376 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2379 def test_max_translations_per_user(self):
2380 """ MAX translations per user - recycle the least recently used """
2382 self.nat44_add_address(self.nat_addr)
2383 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2384 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2387 # get maximum number of translations per user
2388 nat44_config = self.vapi.nat_show_config()
2390 # send more than maximum number of translations per user packets
2391 pkts_num = nat44_config.max_translations_per_user + 5
2393 for port in range(0, pkts_num):
2394 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2395 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2396 TCP(sport=1025 + port))
2398 self.pg0.add_stream(pkts)
2399 self.pg_enable_capture(self.pg_interfaces)
2402 # verify number of translated packet
2403 self.pg1.get_capture(pkts_num)
2405 users = self.vapi.nat44_user_dump()
2407 if user.ip_address == self.pg0.remote_ip4n:
2408 self.assertEqual(user.nsessions,
2409 nat44_config.max_translations_per_user)
2410 self.assertEqual(user.nstaticsessions, 0)
2413 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2415 proto=IP_PROTOS.tcp)
2416 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2417 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2418 TCP(sport=tcp_port))
2419 self.pg0.add_stream(p)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 self.pg1.get_capture(1)
2423 users = self.vapi.nat44_user_dump()
2425 if user.ip_address == self.pg0.remote_ip4n:
2426 self.assertEqual(user.nsessions,
2427 nat44_config.max_translations_per_user - 1)
2428 self.assertEqual(user.nstaticsessions, 1)
2430 def test_interface_addr(self):
2431 """ Acquire NAT44 addresses from interface """
2432 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2434 # no address in NAT pool
2435 adresses = self.vapi.nat44_address_dump()
2436 self.assertEqual(0, len(adresses))
2438 # configure interface address and check NAT address pool
2439 self.pg7.config_ip4()
2440 adresses = self.vapi.nat44_address_dump()
2441 self.assertEqual(1, len(adresses))
2442 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2444 # remove interface address and check NAT address pool
2445 self.pg7.unconfig_ip4()
2446 adresses = self.vapi.nat44_address_dump()
2447 self.assertEqual(0, len(adresses))
2449 def test_interface_addr_static_mapping(self):
2450 """ Static mapping with addresses from interface """
2453 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2454 self.nat44_add_static_mapping(
2456 external_sw_if_index=self.pg7.sw_if_index,
2459 # static mappings with external interface
2460 static_mappings = self.vapi.nat44_static_mapping_dump()
2461 self.assertEqual(1, len(static_mappings))
2462 self.assertEqual(self.pg7.sw_if_index,
2463 static_mappings[0].external_sw_if_index)
2464 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2466 # configure interface address and check static mappings
2467 self.pg7.config_ip4()
2468 static_mappings = self.vapi.nat44_static_mapping_dump()
2469 self.assertEqual(2, len(static_mappings))
2471 for sm in static_mappings:
2472 if sm.external_sw_if_index == 0xFFFFFFFF:
2473 self.assertEqual(sm.external_ip_address[0:4],
2474 self.pg7.local_ip4n)
2475 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2477 self.assertTrue(resolved)
2479 # remove interface address and check static mappings
2480 self.pg7.unconfig_ip4()
2481 static_mappings = self.vapi.nat44_static_mapping_dump()
2482 self.assertEqual(1, len(static_mappings))
2483 self.assertEqual(self.pg7.sw_if_index,
2484 static_mappings[0].external_sw_if_index)
2485 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2487 # configure interface address again and check static mappings
2488 self.pg7.config_ip4()
2489 static_mappings = self.vapi.nat44_static_mapping_dump()
2490 self.assertEqual(2, len(static_mappings))
2492 for sm in static_mappings:
2493 if sm.external_sw_if_index == 0xFFFFFFFF:
2494 self.assertEqual(sm.external_ip_address[0:4],
2495 self.pg7.local_ip4n)
2496 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2498 self.assertTrue(resolved)
2500 # remove static mapping
2501 self.nat44_add_static_mapping(
2503 external_sw_if_index=self.pg7.sw_if_index,
2506 static_mappings = self.vapi.nat44_static_mapping_dump()
2507 self.assertEqual(0, len(static_mappings))
2509 def test_interface_addr_identity_nat(self):
2510 """ Identity NAT with addresses from interface """
2513 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2514 self.vapi.nat44_add_del_identity_mapping(
2515 sw_if_index=self.pg7.sw_if_index,
2517 protocol=IP_PROTOS.tcp,
2520 # identity mappings with external interface
2521 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2522 self.assertEqual(1, len(identity_mappings))
2523 self.assertEqual(self.pg7.sw_if_index,
2524 identity_mappings[0].sw_if_index)
2526 # configure interface address and check identity mappings
2527 self.pg7.config_ip4()
2528 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2530 self.assertEqual(2, len(identity_mappings))
2531 for sm in identity_mappings:
2532 if sm.sw_if_index == 0xFFFFFFFF:
2533 self.assertEqual(identity_mappings[0].ip_address,
2534 self.pg7.local_ip4n)
2535 self.assertEqual(port, identity_mappings[0].port)
2536 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2538 self.assertTrue(resolved)
2540 # remove interface address and check identity mappings
2541 self.pg7.unconfig_ip4()
2542 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2543 self.assertEqual(1, len(identity_mappings))
2544 self.assertEqual(self.pg7.sw_if_index,
2545 identity_mappings[0].sw_if_index)
2547 def test_ipfix_nat44_sess(self):
2548 """ IPFIX logging NAT44 session created/delted """
2549 self.ipfix_domain_id = 10
2550 self.ipfix_src_port = 20202
2551 colector_port = 30303
2552 bind_layers(UDP, IPFIX, dport=30303)
2553 self.nat44_add_address(self.nat_addr)
2554 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2555 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2557 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2558 src_address=self.pg3.local_ip4n,
2560 template_interval=10,
2561 collector_port=colector_port)
2562 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2563 src_port=self.ipfix_src_port)
2565 pkts = self.create_stream_in(self.pg0, self.pg1)
2566 self.pg0.add_stream(pkts)
2567 self.pg_enable_capture(self.pg_interfaces)
2569 capture = self.pg1.get_capture(len(pkts))
2570 self.verify_capture_out(capture)
2571 self.nat44_add_address(self.nat_addr, is_add=0)
2572 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2573 capture = self.pg3.get_capture(9)
2574 ipfix = IPFIXDecoder()
2575 # first load template
2577 self.assertTrue(p.haslayer(IPFIX))
2578 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2579 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2580 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2581 self.assertEqual(p[UDP].dport, colector_port)
2582 self.assertEqual(p[IPFIX].observationDomainID,
2583 self.ipfix_domain_id)
2584 if p.haslayer(Template):
2585 ipfix.add_template(p.getlayer(Template))
2586 # verify events in data set
2588 if p.haslayer(Data):
2589 data = ipfix.decode_data_set(p.getlayer(Set))
2590 self.verify_ipfix_nat44_ses(data)
2592 def test_ipfix_addr_exhausted(self):
2593 """ IPFIX logging NAT addresses exhausted """
2594 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2595 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2597 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2598 src_address=self.pg3.local_ip4n,
2600 template_interval=10)
2601 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2602 src_port=self.ipfix_src_port)
2604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2605 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2607 self.pg0.add_stream(p)
2608 self.pg_enable_capture(self.pg_interfaces)
2610 self.pg1.assert_nothing_captured()
2612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2613 capture = self.pg3.get_capture(9)
2614 ipfix = IPFIXDecoder()
2615 # first load template
2617 self.assertTrue(p.haslayer(IPFIX))
2618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2621 self.assertEqual(p[UDP].dport, 4739)
2622 self.assertEqual(p[IPFIX].observationDomainID,
2623 self.ipfix_domain_id)
2624 if p.haslayer(Template):
2625 ipfix.add_template(p.getlayer(Template))
2626 # verify events in data set
2628 if p.haslayer(Data):
2629 data = ipfix.decode_data_set(p.getlayer(Set))
2630 self.verify_ipfix_addr_exhausted(data)
2632 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2633 def test_ipfix_max_sessions(self):
2634 """ IPFIX logging maximum session entries exceeded """
2635 self.nat44_add_address(self.nat_addr)
2636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2640 nat44_config = self.vapi.nat_show_config()
2641 max_sessions = 10 * nat44_config.translation_buckets
2644 for i in range(0, max_sessions):
2645 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2647 IP(src=src, dst=self.pg1.remote_ip4) /
2650 self.pg0.add_stream(pkts)
2651 self.pg_enable_capture(self.pg_interfaces)
2654 self.pg1.get_capture(max_sessions)
2655 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2656 src_address=self.pg3.local_ip4n,
2658 template_interval=10)
2659 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2660 src_port=self.ipfix_src_port)
2662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2663 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2665 self.pg0.add_stream(p)
2666 self.pg_enable_capture(self.pg_interfaces)
2668 self.pg1.assert_nothing_captured()
2670 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2671 capture = self.pg3.get_capture(9)
2672 ipfix = IPFIXDecoder()
2673 # first load template
2675 self.assertTrue(p.haslayer(IPFIX))
2676 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2677 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2678 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2679 self.assertEqual(p[UDP].dport, 4739)
2680 self.assertEqual(p[IPFIX].observationDomainID,
2681 self.ipfix_domain_id)
2682 if p.haslayer(Template):
2683 ipfix.add_template(p.getlayer(Template))
2684 # verify events in data set
2686 if p.haslayer(Data):
2687 data = ipfix.decode_data_set(p.getlayer(Set))
2688 self.verify_ipfix_max_sessions(data, max_sessions)
2690 def test_pool_addr_fib(self):
2691 """ NAT44 add pool addresses to FIB """
2692 static_addr = '10.0.0.10'
2693 self.nat44_add_address(self.nat_addr)
2694 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2695 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2697 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2700 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2701 ARP(op=ARP.who_has, pdst=self.nat_addr,
2702 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2703 self.pg1.add_stream(p)
2704 self.pg_enable_capture(self.pg_interfaces)
2706 capture = self.pg1.get_capture(1)
2707 self.assertTrue(capture[0].haslayer(ARP))
2708 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2711 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2712 ARP(op=ARP.who_has, pdst=static_addr,
2713 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2714 self.pg1.add_stream(p)
2715 self.pg_enable_capture(self.pg_interfaces)
2717 capture = self.pg1.get_capture(1)
2718 self.assertTrue(capture[0].haslayer(ARP))
2719 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2721 # send ARP to non-NAT44 interface
2722 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2723 ARP(op=ARP.who_has, pdst=self.nat_addr,
2724 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2725 self.pg2.add_stream(p)
2726 self.pg_enable_capture(self.pg_interfaces)
2728 self.pg1.assert_nothing_captured()
2730 # remove addresses and verify
2731 self.nat44_add_address(self.nat_addr, is_add=0)
2732 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2735 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2736 ARP(op=ARP.who_has, pdst=self.nat_addr,
2737 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2738 self.pg1.add_stream(p)
2739 self.pg_enable_capture(self.pg_interfaces)
2741 self.pg1.assert_nothing_captured()
2743 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2744 ARP(op=ARP.who_has, pdst=static_addr,
2745 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2746 self.pg1.add_stream(p)
2747 self.pg_enable_capture(self.pg_interfaces)
2749 self.pg1.assert_nothing_captured()
2751 def test_vrf_mode(self):
2752 """ NAT44 tenant VRF aware address pool mode """
2756 nat_ip1 = "10.0.0.10"
2757 nat_ip2 = "10.0.0.11"
2759 self.pg0.unconfig_ip4()
2760 self.pg1.unconfig_ip4()
2761 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2762 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2763 self.pg0.set_table_ip4(vrf_id1)
2764 self.pg1.set_table_ip4(vrf_id2)
2765 self.pg0.config_ip4()
2766 self.pg1.config_ip4()
2767 self.pg0.resolve_arp()
2768 self.pg1.resolve_arp()
2770 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2771 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2772 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2773 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2774 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2779 pkts = self.create_stream_in(self.pg0, self.pg2)
2780 self.pg0.add_stream(pkts)
2781 self.pg_enable_capture(self.pg_interfaces)
2783 capture = self.pg2.get_capture(len(pkts))
2784 self.verify_capture_out(capture, nat_ip1)
2787 pkts = self.create_stream_in(self.pg1, self.pg2)
2788 self.pg1.add_stream(pkts)
2789 self.pg_enable_capture(self.pg_interfaces)
2791 capture = self.pg2.get_capture(len(pkts))
2792 self.verify_capture_out(capture, nat_ip2)
2795 self.pg0.unconfig_ip4()
2796 self.pg1.unconfig_ip4()
2797 self.pg0.set_table_ip4(0)
2798 self.pg1.set_table_ip4(0)
2799 self.pg0.config_ip4()
2800 self.pg1.config_ip4()
2801 self.pg0.resolve_arp()
2802 self.pg1.resolve_arp()
2803 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2804 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2806 def test_vrf_feature_independent(self):
2807 """ NAT44 tenant VRF independent address pool mode """
2809 nat_ip1 = "10.0.0.10"
2810 nat_ip2 = "10.0.0.11"
2812 self.nat44_add_address(nat_ip1)
2813 self.nat44_add_address(nat_ip2, vrf_id=99)
2814 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2815 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2816 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2820 pkts = self.create_stream_in(self.pg0, self.pg2)
2821 self.pg0.add_stream(pkts)
2822 self.pg_enable_capture(self.pg_interfaces)
2824 capture = self.pg2.get_capture(len(pkts))
2825 self.verify_capture_out(capture, nat_ip1)
2828 pkts = self.create_stream_in(self.pg1, self.pg2)
2829 self.pg1.add_stream(pkts)
2830 self.pg_enable_capture(self.pg_interfaces)
2832 capture = self.pg2.get_capture(len(pkts))
2833 self.verify_capture_out(capture, nat_ip1)
2835 def test_dynamic_ipless_interfaces(self):
2836 """ NAT44 interfaces without configured IP address """
2838 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2839 mactobinary(self.pg7.remote_mac),
2840 self.pg7.remote_ip4n,
2842 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2843 mactobinary(self.pg8.remote_mac),
2844 self.pg8.remote_ip4n,
2847 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2848 dst_address_length=32,
2849 next_hop_address=self.pg7.remote_ip4n,
2850 next_hop_sw_if_index=self.pg7.sw_if_index)
2851 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2852 dst_address_length=32,
2853 next_hop_address=self.pg8.remote_ip4n,
2854 next_hop_sw_if_index=self.pg8.sw_if_index)
2856 self.nat44_add_address(self.nat_addr)
2857 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2858 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2862 pkts = self.create_stream_in(self.pg7, self.pg8)
2863 self.pg7.add_stream(pkts)
2864 self.pg_enable_capture(self.pg_interfaces)
2866 capture = self.pg8.get_capture(len(pkts))
2867 self.verify_capture_out(capture)
2870 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2871 self.pg8.add_stream(pkts)
2872 self.pg_enable_capture(self.pg_interfaces)
2874 capture = self.pg7.get_capture(len(pkts))
2875 self.verify_capture_in(capture, self.pg7)
2877 def test_static_ipless_interfaces(self):
2878 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2880 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2881 mactobinary(self.pg7.remote_mac),
2882 self.pg7.remote_ip4n,
2884 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2885 mactobinary(self.pg8.remote_mac),
2886 self.pg8.remote_ip4n,
2889 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2890 dst_address_length=32,
2891 next_hop_address=self.pg7.remote_ip4n,
2892 next_hop_sw_if_index=self.pg7.sw_if_index)
2893 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2894 dst_address_length=32,
2895 next_hop_address=self.pg8.remote_ip4n,
2896 next_hop_sw_if_index=self.pg8.sw_if_index)
2898 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2899 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2900 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2904 pkts = self.create_stream_out(self.pg8)
2905 self.pg8.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2908 capture = self.pg7.get_capture(len(pkts))
2909 self.verify_capture_in(capture, self.pg7)
2912 pkts = self.create_stream_in(self.pg7, self.pg8)
2913 self.pg7.add_stream(pkts)
2914 self.pg_enable_capture(self.pg_interfaces)
2916 capture = self.pg8.get_capture(len(pkts))
2917 self.verify_capture_out(capture, self.nat_addr, True)
2919 def test_static_with_port_ipless_interfaces(self):
2920 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2922 self.tcp_port_out = 30606
2923 self.udp_port_out = 30607
2924 self.icmp_id_out = 30608
2926 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2927 mactobinary(self.pg7.remote_mac),
2928 self.pg7.remote_ip4n,
2930 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2931 mactobinary(self.pg8.remote_mac),
2932 self.pg8.remote_ip4n,
2935 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2936 dst_address_length=32,
2937 next_hop_address=self.pg7.remote_ip4n,
2938 next_hop_sw_if_index=self.pg7.sw_if_index)
2939 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2940 dst_address_length=32,
2941 next_hop_address=self.pg8.remote_ip4n,
2942 next_hop_sw_if_index=self.pg8.sw_if_index)
2944 self.nat44_add_address(self.nat_addr)
2945 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2946 self.tcp_port_in, self.tcp_port_out,
2947 proto=IP_PROTOS.tcp)
2948 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2949 self.udp_port_in, self.udp_port_out,
2950 proto=IP_PROTOS.udp)
2951 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2952 self.icmp_id_in, self.icmp_id_out,
2953 proto=IP_PROTOS.icmp)
2954 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2955 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2959 pkts = self.create_stream_out(self.pg8)
2960 self.pg8.add_stream(pkts)
2961 self.pg_enable_capture(self.pg_interfaces)
2963 capture = self.pg7.get_capture(len(pkts))
2964 self.verify_capture_in(capture, self.pg7)
2967 pkts = self.create_stream_in(self.pg7, self.pg8)
2968 self.pg7.add_stream(pkts)
2969 self.pg_enable_capture(self.pg_interfaces)
2971 capture = self.pg8.get_capture(len(pkts))
2972 self.verify_capture_out(capture)
2974 def test_static_unknown_proto(self):
2975 """ 1:1 NAT translate packet with unknown protocol """
2976 nat_ip = "10.0.0.10"
2977 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2979 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2983 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2986 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2987 TCP(sport=1234, dport=1234))
2988 self.pg0.add_stream(p)
2989 self.pg_enable_capture(self.pg_interfaces)
2991 p = self.pg1.get_capture(1)
2994 self.assertEqual(packet[IP].src, nat_ip)
2995 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2996 self.assertTrue(packet.haslayer(GRE))
2997 self.assert_packet_checksums_valid(packet)
2999 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3003 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3004 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3006 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3007 TCP(sport=1234, dport=1234))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 p = self.pg0.get_capture(1)
3014 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3015 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3016 self.assertTrue(packet.haslayer(GRE))
3017 self.assert_packet_checksums_valid(packet)
3019 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3022 def test_hairpinning_static_unknown_proto(self):
3023 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3025 host = self.pg0.remote_hosts[0]
3026 server = self.pg0.remote_hosts[1]
3028 host_nat_ip = "10.0.0.10"
3029 server_nat_ip = "10.0.0.11"
3031 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3032 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3033 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3034 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3038 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3039 IP(src=host.ip4, dst=server_nat_ip) /
3041 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3042 TCP(sport=1234, dport=1234))
3043 self.pg0.add_stream(p)
3044 self.pg_enable_capture(self.pg_interfaces)
3046 p = self.pg0.get_capture(1)
3049 self.assertEqual(packet[IP].src, host_nat_ip)
3050 self.assertEqual(packet[IP].dst, server.ip4)
3051 self.assertTrue(packet.haslayer(GRE))
3052 self.assert_packet_checksums_valid(packet)
3054 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3058 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3059 IP(src=server.ip4, dst=host_nat_ip) /
3061 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3062 TCP(sport=1234, dport=1234))
3063 self.pg0.add_stream(p)
3064 self.pg_enable_capture(self.pg_interfaces)
3066 p = self.pg0.get_capture(1)
3069 self.assertEqual(packet[IP].src, server_nat_ip)
3070 self.assertEqual(packet[IP].dst, host.ip4)
3071 self.assertTrue(packet.haslayer(GRE))
3072 self.assert_packet_checksums_valid(packet)
3074 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3077 def test_output_feature(self):
3078 """ NAT44 interface output feature (in2out postrouting) """
3079 self.nat44_add_address(self.nat_addr)
3080 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3081 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3082 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3086 pkts = self.create_stream_in(self.pg0, self.pg3)
3087 self.pg0.add_stream(pkts)
3088 self.pg_enable_capture(self.pg_interfaces)
3090 capture = self.pg3.get_capture(len(pkts))
3091 self.verify_capture_out(capture)
3094 pkts = self.create_stream_out(self.pg3)
3095 self.pg3.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg0.get_capture(len(pkts))
3099 self.verify_capture_in(capture, self.pg0)
3101 # from non-NAT interface to NAT inside interface
3102 pkts = self.create_stream_in(self.pg2, self.pg0)
3103 self.pg2.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg0.get_capture(len(pkts))
3107 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3109 def test_output_feature_vrf_aware(self):
3110 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3111 nat_ip_vrf10 = "10.0.0.10"
3112 nat_ip_vrf20 = "10.0.0.20"
3114 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3115 dst_address_length=32,
3116 next_hop_address=self.pg3.remote_ip4n,
3117 next_hop_sw_if_index=self.pg3.sw_if_index,
3119 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3120 dst_address_length=32,
3121 next_hop_address=self.pg3.remote_ip4n,
3122 next_hop_sw_if_index=self.pg3.sw_if_index,
3125 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3126 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3127 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3128 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3129 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3133 pkts = self.create_stream_in(self.pg4, self.pg3)
3134 self.pg4.add_stream(pkts)
3135 self.pg_enable_capture(self.pg_interfaces)
3137 capture = self.pg3.get_capture(len(pkts))
3138 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3141 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3142 self.pg3.add_stream(pkts)
3143 self.pg_enable_capture(self.pg_interfaces)
3145 capture = self.pg4.get_capture(len(pkts))
3146 self.verify_capture_in(capture, self.pg4)
3149 pkts = self.create_stream_in(self.pg6, self.pg3)
3150 self.pg6.add_stream(pkts)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 capture = self.pg3.get_capture(len(pkts))
3154 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3157 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3158 self.pg3.add_stream(pkts)
3159 self.pg_enable_capture(self.pg_interfaces)
3161 capture = self.pg6.get_capture(len(pkts))
3162 self.verify_capture_in(capture, self.pg6)
3164 def test_output_feature_hairpinning(self):
3165 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3166 host = self.pg0.remote_hosts[0]
3167 server = self.pg0.remote_hosts[1]
3170 server_in_port = 5678
3171 server_out_port = 8765
3173 self.nat44_add_address(self.nat_addr)
3174 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3175 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3178 # add static mapping for server
3179 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3180 server_in_port, server_out_port,
3181 proto=IP_PROTOS.tcp)
3183 # send packet from host to server
3184 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3185 IP(src=host.ip4, dst=self.nat_addr) /
3186 TCP(sport=host_in_port, dport=server_out_port))
3187 self.pg0.add_stream(p)
3188 self.pg_enable_capture(self.pg_interfaces)
3190 capture = self.pg0.get_capture(1)
3195 self.assertEqual(ip.src, self.nat_addr)
3196 self.assertEqual(ip.dst, server.ip4)
3197 self.assertNotEqual(tcp.sport, host_in_port)
3198 self.assertEqual(tcp.dport, server_in_port)
3199 self.assert_packet_checksums_valid(p)
3200 host_out_port = tcp.sport
3202 self.logger.error(ppp("Unexpected or invalid packet:", p))
3205 # send reply from server to host
3206 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3207 IP(src=server.ip4, dst=self.nat_addr) /
3208 TCP(sport=server_in_port, dport=host_out_port))
3209 self.pg0.add_stream(p)
3210 self.pg_enable_capture(self.pg_interfaces)
3212 capture = self.pg0.get_capture(1)
3217 self.assertEqual(ip.src, self.nat_addr)
3218 self.assertEqual(ip.dst, host.ip4)
3219 self.assertEqual(tcp.sport, server_out_port)
3220 self.assertEqual(tcp.dport, host_in_port)
3221 self.assert_packet_checksums_valid(p)
3223 self.logger.error(ppp("Unexpected or invalid packet:", p))
3226 def test_one_armed_nat44(self):
3227 """ One armed NAT44 """
3228 remote_host = self.pg9.remote_hosts[0]
3229 local_host = self.pg9.remote_hosts[1]
3232 self.nat44_add_address(self.nat_addr)
3233 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3234 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3238 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3239 IP(src=local_host.ip4, dst=remote_host.ip4) /
3240 TCP(sport=12345, dport=80))
3241 self.pg9.add_stream(p)
3242 self.pg_enable_capture(self.pg_interfaces)
3244 capture = self.pg9.get_capture(1)
3249 self.assertEqual(ip.src, self.nat_addr)
3250 self.assertEqual(ip.dst, remote_host.ip4)
3251 self.assertNotEqual(tcp.sport, 12345)
3252 external_port = tcp.sport
3253 self.assertEqual(tcp.dport, 80)
3254 self.assert_packet_checksums_valid(p)
3256 self.logger.error(ppp("Unexpected or invalid packet:", p))
3260 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3261 IP(src=remote_host.ip4, dst=self.nat_addr) /
3262 TCP(sport=80, dport=external_port))
3263 self.pg9.add_stream(p)
3264 self.pg_enable_capture(self.pg_interfaces)
3266 capture = self.pg9.get_capture(1)
3271 self.assertEqual(ip.src, remote_host.ip4)
3272 self.assertEqual(ip.dst, local_host.ip4)
3273 self.assertEqual(tcp.sport, 80)
3274 self.assertEqual(tcp.dport, 12345)
3275 self.assert_packet_checksums_valid(p)
3277 self.logger.error(ppp("Unexpected or invalid packet:", p))
3280 def test_del_session(self):
3281 """ Delete NAT44 session """
3282 self.nat44_add_address(self.nat_addr)
3283 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3284 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3287 pkts = self.create_stream_in(self.pg0, self.pg1)
3288 self.pg0.add_stream(pkts)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 self.pg1.get_capture(len(pkts))
3293 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3294 nsessions = len(sessions)
3296 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3297 sessions[0].inside_port,
3298 sessions[0].protocol)
3299 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3300 sessions[1].outside_port,
3301 sessions[1].protocol,
3304 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3305 self.assertEqual(nsessions - len(sessions), 2)
3307 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3308 sessions[0].inside_port,
3309 sessions[0].protocol)
3311 self.verify_no_nat44_user()
3313 def test_set_get_reass(self):
3314 """ NAT44 set/get virtual fragmentation reassembly """
3315 reas_cfg1 = self.vapi.nat_get_reass()
3317 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3318 max_reass=reas_cfg1.ip4_max_reass * 2,
3319 max_frag=reas_cfg1.ip4_max_frag * 2)
3321 reas_cfg2 = self.vapi.nat_get_reass()
3323 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3324 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3325 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3327 self.vapi.nat_set_reass(drop_frag=1)
3328 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3330 def test_frag_in_order(self):
3331 """ NAT44 translate fragments arriving in order """
3333 self.nat44_add_address(self.nat_addr)
3334 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3335 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3338 data = "A" * 4 + "B" * 16 + "C" * 3
3339 self.tcp_port_in = random.randint(1025, 65535)
3341 reass = self.vapi.nat_reass_dump()
3342 reass_n_start = len(reass)
3345 pkts = self.create_stream_frag(self.pg0,
3346 self.pg1.remote_ip4,
3350 self.pg0.add_stream(pkts)
3351 self.pg_enable_capture(self.pg_interfaces)
3353 frags = self.pg1.get_capture(len(pkts))
3354 p = self.reass_frags_and_verify(frags,
3356 self.pg1.remote_ip4)
3357 self.assertEqual(p[TCP].dport, 20)
3358 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3359 self.tcp_port_out = p[TCP].sport
3360 self.assertEqual(data, p[Raw].load)
3363 pkts = self.create_stream_frag(self.pg1,
3368 self.pg1.add_stream(pkts)
3369 self.pg_enable_capture(self.pg_interfaces)
3371 frags = self.pg0.get_capture(len(pkts))
3372 p = self.reass_frags_and_verify(frags,
3373 self.pg1.remote_ip4,
3374 self.pg0.remote_ip4)
3375 self.assertEqual(p[TCP].sport, 20)
3376 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3377 self.assertEqual(data, p[Raw].load)
3379 reass = self.vapi.nat_reass_dump()
3380 reass_n_end = len(reass)
3382 self.assertEqual(reass_n_end - reass_n_start, 2)
3384 def test_reass_hairpinning(self):
3385 """ NAT44 fragments hairpinning """
3387 server = self.pg0.remote_hosts[1]
3388 host_in_port = random.randint(1025, 65535)
3389 server_in_port = random.randint(1025, 65535)
3390 server_out_port = random.randint(1025, 65535)
3391 data = "A" * 4 + "B" * 16 + "C" * 3
3393 self.nat44_add_address(self.nat_addr)
3394 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3395 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3397 # add static mapping for server
3398 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3399 server_in_port, server_out_port,
3400 proto=IP_PROTOS.tcp)
3402 # send packet from host to server
3403 pkts = self.create_stream_frag(self.pg0,
3408 self.pg0.add_stream(pkts)
3409 self.pg_enable_capture(self.pg_interfaces)
3411 frags = self.pg0.get_capture(len(pkts))
3412 p = self.reass_frags_and_verify(frags,
3415 self.assertNotEqual(p[TCP].sport, host_in_port)
3416 self.assertEqual(p[TCP].dport, server_in_port)
3417 self.assertEqual(data, p[Raw].load)
3419 def test_frag_out_of_order(self):
3420 """ NAT44 translate fragments arriving out of order """
3422 self.nat44_add_address(self.nat_addr)
3423 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3424 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3427 data = "A" * 4 + "B" * 16 + "C" * 3
3428 random.randint(1025, 65535)
3431 pkts = self.create_stream_frag(self.pg0,
3432 self.pg1.remote_ip4,
3437 self.pg0.add_stream(pkts)
3438 self.pg_enable_capture(self.pg_interfaces)
3440 frags = self.pg1.get_capture(len(pkts))
3441 p = self.reass_frags_and_verify(frags,
3443 self.pg1.remote_ip4)
3444 self.assertEqual(p[TCP].dport, 20)
3445 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3446 self.tcp_port_out = p[TCP].sport
3447 self.assertEqual(data, p[Raw].load)
3450 pkts = self.create_stream_frag(self.pg1,
3456 self.pg1.add_stream(pkts)
3457 self.pg_enable_capture(self.pg_interfaces)
3459 frags = self.pg0.get_capture(len(pkts))
3460 p = self.reass_frags_and_verify(frags,
3461 self.pg1.remote_ip4,
3462 self.pg0.remote_ip4)
3463 self.assertEqual(p[TCP].sport, 20)
3464 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3465 self.assertEqual(data, p[Raw].load)
3467 def test_port_restricted(self):
3468 """ Port restricted NAT44 (MAP-E CE) """
3469 self.nat44_add_address(self.nat_addr)
3470 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3471 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3473 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3478 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3479 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3480 TCP(sport=4567, dport=22))
3481 self.pg0.add_stream(p)
3482 self.pg_enable_capture(self.pg_interfaces)
3484 capture = self.pg1.get_capture(1)
3489 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3490 self.assertEqual(ip.src, self.nat_addr)
3491 self.assertEqual(tcp.dport, 22)
3492 self.assertNotEqual(tcp.sport, 4567)
3493 self.assertEqual((tcp.sport >> 6) & 63, 10)
3494 self.assert_packet_checksums_valid(p)
3496 self.logger.error(ppp("Unexpected or invalid packet:", p))
3499 def test_port_range(self):
3500 """ External address port range """
3501 self.nat44_add_address(self.nat_addr)
3502 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3503 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3505 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3510 for port in range(0, 5):
3511 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3512 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3513 TCP(sport=1125 + port))
3515 self.pg0.add_stream(pkts)
3516 self.pg_enable_capture(self.pg_interfaces)
3518 capture = self.pg1.get_capture(3)
3521 self.assertGreaterEqual(tcp.sport, 1025)
3522 self.assertLessEqual(tcp.sport, 1027)
3524 def test_ipfix_max_frags(self):
3525 """ IPFIX logging maximum fragments pending reassembly exceeded """
3526 self.nat44_add_address(self.nat_addr)
3527 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3528 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3530 self.vapi.nat_set_reass(max_frag=1)
3531 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3532 src_address=self.pg3.local_ip4n,
3534 template_interval=10)
3535 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3536 src_port=self.ipfix_src_port)
3538 data = "A" * 4 + "B" * 16 + "C" * 3
3539 self.tcp_port_in = random.randint(1025, 65535)
3540 pkts = self.create_stream_frag(self.pg0,
3541 self.pg1.remote_ip4,
3546 self.pg0.add_stream(pkts)
3547 self.pg_enable_capture(self.pg_interfaces)
3549 self.pg1.assert_nothing_captured()
3551 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3552 capture = self.pg3.get_capture(9)
3553 ipfix = IPFIXDecoder()
3554 # first load template
3556 self.assertTrue(p.haslayer(IPFIX))
3557 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3558 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3559 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3560 self.assertEqual(p[UDP].dport, 4739)
3561 self.assertEqual(p[IPFIX].observationDomainID,
3562 self.ipfix_domain_id)
3563 if p.haslayer(Template):
3564 ipfix.add_template(p.getlayer(Template))
3565 # verify events in data set
3567 if p.haslayer(Data):
3568 data = ipfix.decode_data_set(p.getlayer(Set))
3569 self.verify_ipfix_max_fragments_ip4(data, 1,
3570 self.pg0.remote_ip4n)
3572 def test_multiple_outside_vrf(self):
3573 """ Multiple outside VRF """
3577 self.pg1.unconfig_ip4()
3578 self.pg2.unconfig_ip4()
3579 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3580 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3581 self.pg1.set_table_ip4(vrf_id1)
3582 self.pg2.set_table_ip4(vrf_id2)
3583 self.pg1.config_ip4()
3584 self.pg2.config_ip4()
3585 self.pg1.resolve_arp()
3586 self.pg2.resolve_arp()
3588 self.nat44_add_address(self.nat_addr)
3589 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3590 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3592 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3597 pkts = self.create_stream_in(self.pg0, self.pg1)
3598 self.pg0.add_stream(pkts)
3599 self.pg_enable_capture(self.pg_interfaces)
3601 capture = self.pg1.get_capture(len(pkts))
3602 self.verify_capture_out(capture, self.nat_addr)
3604 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3605 self.pg1.add_stream(pkts)
3606 self.pg_enable_capture(self.pg_interfaces)
3608 capture = self.pg0.get_capture(len(pkts))
3609 self.verify_capture_in(capture, self.pg0)
3611 self.tcp_port_in = 60303
3612 self.udp_port_in = 60304
3613 self.icmp_id_in = 60305
3616 pkts = self.create_stream_in(self.pg0, self.pg2)
3617 self.pg0.add_stream(pkts)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 capture = self.pg2.get_capture(len(pkts))
3621 self.verify_capture_out(capture, self.nat_addr)
3623 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3624 self.pg2.add_stream(pkts)
3625 self.pg_enable_capture(self.pg_interfaces)
3627 capture = self.pg0.get_capture(len(pkts))
3628 self.verify_capture_in(capture, self.pg0)
3631 self.pg1.unconfig_ip4()
3632 self.pg2.unconfig_ip4()
3633 self.pg1.set_table_ip4(0)
3634 self.pg2.set_table_ip4(0)
3635 self.pg1.config_ip4()
3636 self.pg2.config_ip4()
3637 self.pg1.resolve_arp()
3638 self.pg2.resolve_arp()
3640 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3641 def test_session_timeout(self):
3642 """ NAT44 session timeouts """
3643 self.nat44_add_address(self.nat_addr)
3644 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3645 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3647 self.vapi.nat_set_timeouts(udp=5)
3651 for i in range(0, max_sessions):
3652 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3653 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3654 IP(src=src, dst=self.pg1.remote_ip4) /
3655 UDP(sport=1025, dport=53))
3657 self.pg0.add_stream(pkts)
3658 self.pg_enable_capture(self.pg_interfaces)
3660 self.pg1.get_capture(max_sessions)
3665 for i in range(0, max_sessions):
3666 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3667 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3668 IP(src=src, dst=self.pg1.remote_ip4) /
3669 UDP(sport=1026, dport=53))
3671 self.pg0.add_stream(pkts)
3672 self.pg_enable_capture(self.pg_interfaces)
3674 self.pg1.get_capture(max_sessions)
3677 users = self.vapi.nat44_user_dump()
3679 nsessions = nsessions + user.nsessions
3680 self.assertLess(nsessions, 2 * max_sessions)
3682 def test_mss_clamping(self):
3683 """ TCP MSS clamping """
3684 self.nat44_add_address(self.nat_addr)
3685 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3686 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3689 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3690 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3691 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3692 flags="S", options=[('MSS', 1400)]))
3694 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3695 self.pg0.add_stream(p)
3696 self.pg_enable_capture(self.pg_interfaces)
3698 capture = self.pg1.get_capture(1)
3699 # Negotiated MSS value greater than configured - changed
3700 self.verify_mss_value(capture[0], 1000)
3702 self.vapi.nat_set_mss_clamping(enable=0)
3703 self.pg0.add_stream(p)
3704 self.pg_enable_capture(self.pg_interfaces)
3706 capture = self.pg1.get_capture(1)
3707 # MSS clamping disabled - negotiated MSS unchanged
3708 self.verify_mss_value(capture[0], 1400)
3710 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3711 self.pg0.add_stream(p)
3712 self.pg_enable_capture(self.pg_interfaces)
3714 capture = self.pg1.get_capture(1)
3715 # Negotiated MSS value smaller than configured - unchanged
3716 self.verify_mss_value(capture[0], 1400)
3719 super(TestNAT44, self).tearDown()
3720 if not self.vpp_dead:
3721 self.logger.info(self.vapi.cli("show nat44 addresses"))
3722 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3723 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3724 self.logger.info(self.vapi.cli("show nat44 interface address"))
3725 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3726 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3727 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3728 self.logger.info(self.vapi.cli("show nat timeouts"))
3730 self.vapi.cli("show nat addr-port-assignment-alg"))
3732 self.vapi.cli("clear logging")
3735 class TestNAT44EndpointDependent(MethodHolder):
3736 """ Endpoint-Dependent mapping and filtering test cases """
3739 def setUpConstants(cls):
3740 super(TestNAT44EndpointDependent, cls).setUpConstants()
3741 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3744 def setUpClass(cls):
3745 super(TestNAT44EndpointDependent, cls).setUpClass()
3746 cls.vapi.cli("set log class nat level debug")
3748 cls.tcp_port_in = 6303
3749 cls.tcp_port_out = 6303
3750 cls.udp_port_in = 6304
3751 cls.udp_port_out = 6304
3752 cls.icmp_id_in = 6305
3753 cls.icmp_id_out = 6305
3754 cls.nat_addr = '10.0.0.3'
3755 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3756 cls.ipfix_src_port = 4739
3757 cls.ipfix_domain_id = 1
3758 cls.tcp_external_port = 80
3760 cls.create_pg_interfaces(range(7))
3761 cls.interfaces = list(cls.pg_interfaces[0:3])
3763 for i in cls.interfaces:
3768 cls.pg0.generate_remote_hosts(3)
3769 cls.pg0.configure_ipv4_neighbors()
3773 cls.pg4.generate_remote_hosts(2)
3774 cls.pg4.config_ip4()
3775 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3776 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3780 cls.pg4.resolve_arp()
3781 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3782 cls.pg4.resolve_arp()
3784 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3785 cls.vapi.ip_table_add_del(1, is_add=1)
3787 cls.pg5._local_ip4 = "10.1.1.1"
3788 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3790 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3791 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3792 socket.AF_INET, cls.pg5.remote_ip4)
3793 cls.pg5.set_table_ip4(1)
3794 cls.pg5.config_ip4()
3796 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3797 dst_address_length=32,
3799 next_hop_sw_if_index=cls.pg5.sw_if_index,
3800 next_hop_address=zero_ip4n)
3802 cls.pg6._local_ip4 = "10.1.2.1"
3803 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3805 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3806 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3807 socket.AF_INET, cls.pg6.remote_ip4)
3808 cls.pg6.set_table_ip4(1)
3809 cls.pg6.config_ip4()
3811 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3812 dst_address_length=32,
3814 next_hop_sw_if_index=cls.pg6.sw_if_index,
3815 next_hop_address=zero_ip4n)
3817 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3818 dst_address_length=16,
3819 next_hop_address=zero_ip4n,
3821 next_hop_table_id=1)
3822 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3823 dst_address_length=0,
3824 next_hop_address=zero_ip4n,
3826 next_hop_table_id=0)
3827 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3828 dst_address_length=0,
3830 next_hop_sw_if_index=cls.pg1.sw_if_index,
3831 next_hop_address=cls.pg1.local_ip4n)
3833 cls.pg5.resolve_arp()
3834 cls.pg6.resolve_arp()
3837 super(TestNAT44EndpointDependent, cls).tearDownClass()
3840 def test_frag_in_order(self):
3841 """ NAT44 translate fragments arriving in order """
3842 self.nat44_add_address(self.nat_addr)
3843 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3844 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3846 self.frag_in_order(proto=IP_PROTOS.tcp)
3847 self.frag_in_order(proto=IP_PROTOS.udp)
3848 self.frag_in_order(proto=IP_PROTOS.icmp)
3850 def test_frag_in_order_dont_translate(self):
3851 """ NAT44 don't translate fragments arriving in order """
3852 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3853 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3855 self.vapi.nat44_forwarding_enable_disable(enable=True)
3856 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3858 def test_frag_out_of_order(self):
3859 """ NAT44 translate fragments arriving out of order """
3860 self.nat44_add_address(self.nat_addr)
3861 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3862 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3864 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3865 self.frag_out_of_order(proto=IP_PROTOS.udp)
3866 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3868 def test_frag_out_of_order_dont_translate(self):
3869 """ NAT44 don't translate fragments arriving out of order """
3870 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3871 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3873 self.vapi.nat44_forwarding_enable_disable(enable=True)
3874 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3876 def test_frag_in_order_in_plus_out(self):
3877 """ in+out interface fragments in order """
3878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3879 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3881 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3882 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3885 self.server = self.pg1.remote_hosts[0]
3887 self.server_in_addr = self.server.ip4
3888 self.server_out_addr = '11.11.11.11'
3889 self.server_in_port = random.randint(1025, 65535)
3890 self.server_out_port = random.randint(1025, 65535)
3892 self.nat44_add_address(self.server_out_addr)
3894 # add static mappings for server
3895 self.nat44_add_static_mapping(self.server_in_addr,
3896 self.server_out_addr,
3897 self.server_in_port,
3898 self.server_out_port,
3899 proto=IP_PROTOS.tcp)
3900 self.nat44_add_static_mapping(self.server_in_addr,
3901 self.server_out_addr,
3902 self.server_in_port,
3903 self.server_out_port,
3904 proto=IP_PROTOS.udp)
3905 self.nat44_add_static_mapping(self.server_in_addr,
3906 self.server_out_addr,
3907 proto=IP_PROTOS.icmp)
3909 self.vapi.nat_set_reass(timeout=10)
3911 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3912 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3913 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3915 def test_frag_out_of_order_in_plus_out(self):
3916 """ in+out interface fragments out of order """
3917 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3918 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3920 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3921 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3924 self.server = self.pg1.remote_hosts[0]
3926 self.server_in_addr = self.server.ip4
3927 self.server_out_addr = '11.11.11.11'
3928 self.server_in_port = random.randint(1025, 65535)
3929 self.server_out_port = random.randint(1025, 65535)
3931 self.nat44_add_address(self.server_out_addr)
3933 # add static mappings for server
3934 self.nat44_add_static_mapping(self.server_in_addr,
3935 self.server_out_addr,
3936 self.server_in_port,
3937 self.server_out_port,
3938 proto=IP_PROTOS.tcp)
3939 self.nat44_add_static_mapping(self.server_in_addr,
3940 self.server_out_addr,
3941 self.server_in_port,
3942 self.server_out_port,
3943 proto=IP_PROTOS.udp)
3944 self.nat44_add_static_mapping(self.server_in_addr,
3945 self.server_out_addr,
3946 proto=IP_PROTOS.icmp)
3948 self.vapi.nat_set_reass(timeout=10)
3950 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3951 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3952 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3954 def test_reass_hairpinning(self):
3955 """ NAT44 fragments hairpinning """
3956 self.server = self.pg0.remote_hosts[1]
3957 self.host_in_port = random.randint(1025, 65535)
3958 self.server_in_port = random.randint(1025, 65535)
3959 self.server_out_port = random.randint(1025, 65535)
3961 self.nat44_add_address(self.nat_addr)
3962 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3963 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3965 # add static mapping for server
3966 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3967 self.server_in_port,
3968 self.server_out_port,
3969 proto=IP_PROTOS.tcp)
3970 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3971 self.server_in_port,
3972 self.server_out_port,
3973 proto=IP_PROTOS.udp)
3974 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3975 proto=IP_PROTOS.icmp)
3977 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3978 self.reass_hairpinning(proto=IP_PROTOS.udp)
3979 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3981 def test_dynamic(self):
3982 """ NAT44 dynamic translation test """
3984 self.nat44_add_address(self.nat_addr)
3985 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3986 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3989 nat_config = self.vapi.nat_show_config()
3990 self.assertEqual(1, nat_config.endpoint_dependent)
3993 pkts = self.create_stream_in(self.pg0, self.pg1)
3994 self.pg0.add_stream(pkts)
3995 self.pg_enable_capture(self.pg_interfaces)
3997 capture = self.pg1.get_capture(len(pkts))
3998 self.verify_capture_out(capture)
4001 pkts = self.create_stream_out(self.pg1)
4002 self.pg1.add_stream(pkts)
4003 self.pg_enable_capture(self.pg_interfaces)
4005 capture = self.pg0.get_capture(len(pkts))
4006 self.verify_capture_in(capture, self.pg0)
4008 def test_forwarding(self):
4009 """ NAT44 forwarding test """
4011 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4012 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4014 self.vapi.nat44_forwarding_enable_disable(1)
4016 real_ip = self.pg0.remote_ip4n
4017 alias_ip = self.nat_addr_n
4018 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4019 external_ip=alias_ip)
4022 # in2out - static mapping match
4024 pkts = self.create_stream_out(self.pg1)
4025 self.pg1.add_stream(pkts)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 capture = self.pg0.get_capture(len(pkts))
4029 self.verify_capture_in(capture, self.pg0)
4031 pkts = self.create_stream_in(self.pg0, self.pg1)
4032 self.pg0.add_stream(pkts)
4033 self.pg_enable_capture(self.pg_interfaces)
4035 capture = self.pg1.get_capture(len(pkts))
4036 self.verify_capture_out(capture, same_port=True)
4038 # in2out - no static mapping match
4040 host0 = self.pg0.remote_hosts[0]
4041 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4043 pkts = self.create_stream_out(self.pg1,
4044 dst_ip=self.pg0.remote_ip4,
4045 use_inside_ports=True)
4046 self.pg1.add_stream(pkts)
4047 self.pg_enable_capture(self.pg_interfaces)
4049 capture = self.pg0.get_capture(len(pkts))
4050 self.verify_capture_in(capture, self.pg0)
4052 pkts = self.create_stream_in(self.pg0, self.pg1)
4053 self.pg0.add_stream(pkts)
4054 self.pg_enable_capture(self.pg_interfaces)
4056 capture = self.pg1.get_capture(len(pkts))
4057 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4060 self.pg0.remote_hosts[0] = host0
4062 user = self.pg0.remote_hosts[1]
4063 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4064 self.assertEqual(len(sessions), 3)
4065 self.assertTrue(sessions[0].ext_host_valid)
4066 self.vapi.nat44_del_session(
4067 sessions[0].inside_ip_address,
4068 sessions[0].inside_port,
4069 sessions[0].protocol,
4070 ext_host_address=sessions[0].ext_host_address,
4071 ext_host_port=sessions[0].ext_host_port)
4072 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4073 self.assertEqual(len(sessions), 2)
4076 self.vapi.nat44_forwarding_enable_disable(0)
4077 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4078 external_ip=alias_ip,
4081 def test_static_lb(self):
4082 """ NAT44 local service load balancing """
4083 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4086 server1 = self.pg0.remote_hosts[0]
4087 server2 = self.pg0.remote_hosts[1]
4089 locals = [{'addr': server1.ip4n,
4093 {'addr': server2.ip4n,
4098 self.nat44_add_address(self.nat_addr)
4099 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4102 local_num=len(locals),
4104 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4105 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4108 # from client to service
4109 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4110 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4111 TCP(sport=12345, dport=external_port))
4112 self.pg1.add_stream(p)
4113 self.pg_enable_capture(self.pg_interfaces)
4115 capture = self.pg0.get_capture(1)
4121 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4122 if ip.dst == server1.ip4:
4126 self.assertEqual(tcp.dport, local_port)
4127 self.assert_packet_checksums_valid(p)
4129 self.logger.error(ppp("Unexpected or invalid packet:", p))
4132 # from service back to client
4133 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4134 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4135 TCP(sport=local_port, dport=12345))
4136 self.pg0.add_stream(p)
4137 self.pg_enable_capture(self.pg_interfaces)
4139 capture = self.pg1.get_capture(1)
4144 self.assertEqual(ip.src, self.nat_addr)
4145 self.assertEqual(tcp.sport, external_port)
4146 self.assert_packet_checksums_valid(p)
4148 self.logger.error(ppp("Unexpected or invalid packet:", p))
4151 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4152 self.assertEqual(len(sessions), 1)
4153 self.assertTrue(sessions[0].ext_host_valid)
4154 self.vapi.nat44_del_session(
4155 sessions[0].inside_ip_address,
4156 sessions[0].inside_port,
4157 sessions[0].protocol,
4158 ext_host_address=sessions[0].ext_host_address,
4159 ext_host_port=sessions[0].ext_host_port)
4160 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4161 self.assertEqual(len(sessions), 0)
4163 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4164 def test_static_lb_multi_clients(self):
4165 """ NAT44 local service load balancing - multiple clients"""
4167 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4170 server1 = self.pg0.remote_hosts[0]
4171 server2 = self.pg0.remote_hosts[1]
4173 locals = [{'addr': server1.ip4n,
4177 {'addr': server2.ip4n,
4182 self.nat44_add_address(self.nat_addr)
4183 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4186 local_num=len(locals),
4188 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4189 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4194 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4196 for client in clients:
4197 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4198 IP(src=client, dst=self.nat_addr) /
4199 TCP(sport=12345, dport=external_port))
4201 self.pg1.add_stream(pkts)
4202 self.pg_enable_capture(self.pg_interfaces)
4204 capture = self.pg0.get_capture(len(pkts))
4206 if p[IP].dst == server1.ip4:
4210 self.assertTrue(server1_n > server2_n)
4212 def test_static_lb_2(self):
4213 """ NAT44 local service load balancing (asymmetrical rule) """
4214 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4217 server1 = self.pg0.remote_hosts[0]
4218 server2 = self.pg0.remote_hosts[1]
4220 locals = [{'addr': server1.ip4n,
4224 {'addr': server2.ip4n,
4229 self.vapi.nat44_forwarding_enable_disable(1)
4230 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4234 local_num=len(locals),
4236 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4237 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4240 # from client to service
4241 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4242 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4243 TCP(sport=12345, dport=external_port))
4244 self.pg1.add_stream(p)
4245 self.pg_enable_capture(self.pg_interfaces)
4247 capture = self.pg0.get_capture(1)
4253 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4254 if ip.dst == server1.ip4:
4258 self.assertEqual(tcp.dport, local_port)
4259 self.assert_packet_checksums_valid(p)
4261 self.logger.error(ppp("Unexpected or invalid packet:", p))
4264 # from service back to client
4265 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4266 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4267 TCP(sport=local_port, dport=12345))
4268 self.pg0.add_stream(p)
4269 self.pg_enable_capture(self.pg_interfaces)
4271 capture = self.pg1.get_capture(1)
4276 self.assertEqual(ip.src, self.nat_addr)
4277 self.assertEqual(tcp.sport, external_port)
4278 self.assert_packet_checksums_valid(p)
4280 self.logger.error(ppp("Unexpected or invalid packet:", p))
4283 # from client to server (no translation)
4284 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4285 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4286 TCP(sport=12346, dport=local_port))
4287 self.pg1.add_stream(p)
4288 self.pg_enable_capture(self.pg_interfaces)
4290 capture = self.pg0.get_capture(1)
4296 self.assertEqual(ip.dst, server1.ip4)
4297 self.assertEqual(tcp.dport, local_port)
4298 self.assert_packet_checksums_valid(p)
4300 self.logger.error(ppp("Unexpected or invalid packet:", p))
4303 # from service back to client (no translation)
4304 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4305 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4306 TCP(sport=local_port, dport=12346))
4307 self.pg0.add_stream(p)
4308 self.pg_enable_capture(self.pg_interfaces)
4310 capture = self.pg1.get_capture(1)
4315 self.assertEqual(ip.src, server1.ip4)
4316 self.assertEqual(tcp.sport, local_port)
4317 self.assert_packet_checksums_valid(p)
4319 self.logger.error(ppp("Unexpected or invalid packet:", p))
4322 def test_lb_affinity(self):
4323 """ NAT44 local service load balancing affinity """
4324 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4327 server1 = self.pg0.remote_hosts[0]
4328 server2 = self.pg0.remote_hosts[1]
4330 locals = [{'addr': server1.ip4n,
4334 {'addr': server2.ip4n,
4339 self.nat44_add_address(self.nat_addr)
4340 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4344 local_num=len(locals),
4346 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4347 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4350 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4351 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4352 TCP(sport=1025, dport=external_port))
4353 self.pg1.add_stream(p)
4354 self.pg_enable_capture(self.pg_interfaces)
4356 capture = self.pg0.get_capture(1)
4357 backend = capture[0][IP].dst
4359 sessions = self.vapi.nat44_user_session_dump(
4360 socket.inet_pton(socket.AF_INET, backend), 0)
4361 self.assertEqual(len(sessions), 1)
4362 self.assertTrue(sessions[0].ext_host_valid)
4363 self.vapi.nat44_del_session(
4364 sessions[0].inside_ip_address,
4365 sessions[0].inside_port,
4366 sessions[0].protocol,
4367 ext_host_address=sessions[0].ext_host_address,
4368 ext_host_port=sessions[0].ext_host_port)
4371 for port in range(1030, 1100):
4372 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4373 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4374 TCP(sport=port, dport=external_port))
4376 self.pg1.add_stream(pkts)
4377 self.pg_enable_capture(self.pg_interfaces)
4379 capture = self.pg0.get_capture(len(pkts))
4381 self.assertEqual(p[IP].dst, backend)
4383 def test_unknown_proto(self):
4384 """ NAT44 translate packet with unknown protocol """
4385 self.nat44_add_address(self.nat_addr)
4386 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4387 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4392 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4393 TCP(sport=self.tcp_port_in, dport=20))
4394 self.pg0.add_stream(p)
4395 self.pg_enable_capture(self.pg_interfaces)
4397 p = self.pg1.get_capture(1)
4399 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4400 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4402 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4403 TCP(sport=1234, dport=1234))
4404 self.pg0.add_stream(p)
4405 self.pg_enable_capture(self.pg_interfaces)
4407 p = self.pg1.get_capture(1)
4410 self.assertEqual(packet[IP].src, self.nat_addr)
4411 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4412 self.assertTrue(packet.haslayer(GRE))
4413 self.assert_packet_checksums_valid(packet)
4415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4419 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4420 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4422 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4423 TCP(sport=1234, dport=1234))
4424 self.pg1.add_stream(p)
4425 self.pg_enable_capture(self.pg_interfaces)
4427 p = self.pg0.get_capture(1)
4430 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4431 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4432 self.assertTrue(packet.haslayer(GRE))
4433 self.assert_packet_checksums_valid(packet)
4435 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4438 def test_hairpinning_unknown_proto(self):
4439 """ NAT44 translate packet with unknown protocol - hairpinning """
4440 host = self.pg0.remote_hosts[0]
4441 server = self.pg0.remote_hosts[1]
4443 server_out_port = 8765
4444 server_nat_ip = "10.0.0.11"
4446 self.nat44_add_address(self.nat_addr)
4447 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4448 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4451 # add static mapping for server
4452 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4455 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4456 IP(src=host.ip4, dst=server_nat_ip) /
4457 TCP(sport=host_in_port, dport=server_out_port))
4458 self.pg0.add_stream(p)
4459 self.pg_enable_capture(self.pg_interfaces)
4461 self.pg0.get_capture(1)
4463 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4464 IP(src=host.ip4, dst=server_nat_ip) /
4466 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4467 TCP(sport=1234, dport=1234))
4468 self.pg0.add_stream(p)
4469 self.pg_enable_capture(self.pg_interfaces)
4471 p = self.pg0.get_capture(1)
4474 self.assertEqual(packet[IP].src, self.nat_addr)
4475 self.assertEqual(packet[IP].dst, server.ip4)
4476 self.assertTrue(packet.haslayer(GRE))
4477 self.assert_packet_checksums_valid(packet)
4479 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4483 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4484 IP(src=server.ip4, dst=self.nat_addr) /
4486 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4487 TCP(sport=1234, dport=1234))
4488 self.pg0.add_stream(p)
4489 self.pg_enable_capture(self.pg_interfaces)
4491 p = self.pg0.get_capture(1)
4494 self.assertEqual(packet[IP].src, server_nat_ip)
4495 self.assertEqual(packet[IP].dst, host.ip4)
4496 self.assertTrue(packet.haslayer(GRE))
4497 self.assert_packet_checksums_valid(packet)
4499 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4502 def test_output_feature_and_service(self):
4503 """ NAT44 interface output feature and services """
4504 external_addr = '1.2.3.4'
4508 self.vapi.nat44_forwarding_enable_disable(1)
4509 self.nat44_add_address(self.nat_addr)
4510 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4511 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4512 local_port, external_port,
4513 proto=IP_PROTOS.tcp, out2in_only=1)
4514 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4515 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4517 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4520 # from client to service
4521 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4522 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4523 TCP(sport=12345, dport=external_port))
4524 self.pg1.add_stream(p)
4525 self.pg_enable_capture(self.pg_interfaces)
4527 capture = self.pg0.get_capture(1)
4532 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4533 self.assertEqual(tcp.dport, local_port)
4534 self.assert_packet_checksums_valid(p)
4536 self.logger.error(ppp("Unexpected or invalid packet:", p))
4539 # from service back to client
4540 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4541 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4542 TCP(sport=local_port, dport=12345))
4543 self.pg0.add_stream(p)
4544 self.pg_enable_capture(self.pg_interfaces)
4546 capture = self.pg1.get_capture(1)
4551 self.assertEqual(ip.src, external_addr)
4552 self.assertEqual(tcp.sport, external_port)
4553 self.assert_packet_checksums_valid(p)
4555 self.logger.error(ppp("Unexpected or invalid packet:", p))
4558 # from local network host to external network
4559 pkts = self.create_stream_in(self.pg0, self.pg1)
4560 self.pg0.add_stream(pkts)
4561 self.pg_enable_capture(self.pg_interfaces)
4563 capture = self.pg1.get_capture(len(pkts))
4564 self.verify_capture_out(capture)
4565 pkts = self.create_stream_in(self.pg0, self.pg1)
4566 self.pg0.add_stream(pkts)
4567 self.pg_enable_capture(self.pg_interfaces)
4569 capture = self.pg1.get_capture(len(pkts))
4570 self.verify_capture_out(capture)
4572 # from external network back to local network host
4573 pkts = self.create_stream_out(self.pg1)
4574 self.pg1.add_stream(pkts)
4575 self.pg_enable_capture(self.pg_interfaces)
4577 capture = self.pg0.get_capture(len(pkts))
4578 self.verify_capture_in(capture, self.pg0)
4580 def test_output_feature_and_service2(self):
4581 """ NAT44 interface output feature and service host direct access """
4582 self.vapi.nat44_forwarding_enable_disable(1)
4583 self.nat44_add_address(self.nat_addr)
4584 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4587 # session initiaded from service host - translate
4588 pkts = self.create_stream_in(self.pg0, self.pg1)
4589 self.pg0.add_stream(pkts)
4590 self.pg_enable_capture(self.pg_interfaces)
4592 capture = self.pg1.get_capture(len(pkts))
4593 self.verify_capture_out(capture)
4595 pkts = self.create_stream_out(self.pg1)
4596 self.pg1.add_stream(pkts)
4597 self.pg_enable_capture(self.pg_interfaces)
4599 capture = self.pg0.get_capture(len(pkts))
4600 self.verify_capture_in(capture, self.pg0)
4602 # session initiaded from remote host - do not translate
4603 self.tcp_port_in = 60303
4604 self.udp_port_in = 60304
4605 self.icmp_id_in = 60305
4606 pkts = self.create_stream_out(self.pg1,
4607 self.pg0.remote_ip4,
4608 use_inside_ports=True)
4609 self.pg1.add_stream(pkts)
4610 self.pg_enable_capture(self.pg_interfaces)
4612 capture = self.pg0.get_capture(len(pkts))
4613 self.verify_capture_in(capture, self.pg0)
4615 pkts = self.create_stream_in(self.pg0, self.pg1)
4616 self.pg0.add_stream(pkts)
4617 self.pg_enable_capture(self.pg_interfaces)
4619 capture = self.pg1.get_capture(len(pkts))
4620 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4623 def test_output_feature_and_service3(self):
4624 """ NAT44 interface output feature and DST NAT """
4625 external_addr = '1.2.3.4'
4629 self.vapi.nat44_forwarding_enable_disable(1)
4630 self.nat44_add_address(self.nat_addr)
4631 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4632 local_port, external_port,
4633 proto=IP_PROTOS.tcp, out2in_only=1)
4634 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4635 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4637 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4640 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4641 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4642 TCP(sport=12345, dport=external_port))
4643 self.pg0.add_stream(p)
4644 self.pg_enable_capture(self.pg_interfaces)
4646 capture = self.pg1.get_capture(1)
4651 self.assertEqual(ip.src, self.pg0.remote_ip4)
4652 self.assertEqual(tcp.sport, 12345)
4653 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4654 self.assertEqual(tcp.dport, local_port)
4655 self.assert_packet_checksums_valid(p)
4657 self.logger.error(ppp("Unexpected or invalid packet:", p))
4660 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4661 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4662 TCP(sport=local_port, dport=12345))
4663 self.pg1.add_stream(p)
4664 self.pg_enable_capture(self.pg_interfaces)
4666 capture = self.pg0.get_capture(1)
4671 self.assertEqual(ip.src, external_addr)
4672 self.assertEqual(tcp.sport, external_port)
4673 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4674 self.assertEqual(tcp.dport, 12345)
4675 self.assert_packet_checksums_valid(p)
4677 self.logger.error(ppp("Unexpected or invalid packet:", p))
4680 def test_next_src_nat(self):
4681 """ On way back forward packet to nat44-in2out node. """
4682 twice_nat_addr = '10.0.1.3'
4685 post_twice_nat_port = 0
4687 self.vapi.nat44_forwarding_enable_disable(1)
4688 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4689 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4690 local_port, external_port,
4691 proto=IP_PROTOS.tcp, out2in_only=1,
4692 self_twice_nat=1, vrf_id=1)
4693 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4696 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4697 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4698 TCP(sport=12345, dport=external_port))
4699 self.pg6.add_stream(p)
4700 self.pg_enable_capture(self.pg_interfaces)
4702 capture = self.pg6.get_capture(1)
4707 self.assertEqual(ip.src, twice_nat_addr)
4708 self.assertNotEqual(tcp.sport, 12345)
4709 post_twice_nat_port = tcp.sport
4710 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4711 self.assertEqual(tcp.dport, local_port)
4712 self.assert_packet_checksums_valid(p)
4714 self.logger.error(ppp("Unexpected or invalid packet:", p))
4717 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4718 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4719 TCP(sport=local_port, dport=post_twice_nat_port))
4720 self.pg6.add_stream(p)
4721 self.pg_enable_capture(self.pg_interfaces)
4723 capture = self.pg6.get_capture(1)
4728 self.assertEqual(ip.src, self.pg1.remote_ip4)
4729 self.assertEqual(tcp.sport, external_port)
4730 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4731 self.assertEqual(tcp.dport, 12345)
4732 self.assert_packet_checksums_valid(p)
4734 self.logger.error(ppp("Unexpected or invalid packet:", p))
4737 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4739 twice_nat_addr = '10.0.1.3'
4747 port_in1 = port_in+1
4748 port_in2 = port_in+2
4753 server1 = self.pg0.remote_hosts[0]
4754 server2 = self.pg0.remote_hosts[1]
4766 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4769 self.nat44_add_address(self.nat_addr)
4770 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4772 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4774 proto=IP_PROTOS.tcp,
4775 twice_nat=int(not self_twice_nat),
4776 self_twice_nat=int(self_twice_nat))
4778 locals = [{'addr': server1.ip4n,
4782 {'addr': server2.ip4n,
4786 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4787 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4791 not self_twice_nat),
4794 local_num=len(locals),
4796 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4797 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4804 assert client_id is not None
4806 client = self.pg0.remote_hosts[0]
4807 elif client_id == 2:
4808 client = self.pg0.remote_hosts[1]
4810 client = pg1.remote_hosts[0]
4811 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4812 IP(src=client.ip4, dst=self.nat_addr) /
4813 TCP(sport=eh_port_out, dport=port_out))
4815 self.pg_enable_capture(self.pg_interfaces)
4817 capture = pg0.get_capture(1)
4823 if ip.dst == server1.ip4:
4829 self.assertEqual(ip.dst, server.ip4)
4831 self.assertIn(tcp.dport, [port_in1, port_in2])
4833 self.assertEqual(tcp.dport, port_in)
4835 self.assertEqual(ip.src, twice_nat_addr)
4836 self.assertNotEqual(tcp.sport, eh_port_out)
4838 self.assertEqual(ip.src, client.ip4)
4839 self.assertEqual(tcp.sport, eh_port_out)
4841 eh_port_in = tcp.sport
4842 saved_port_in = tcp.dport
4843 self.assert_packet_checksums_valid(p)
4845 self.logger.error(ppp("Unexpected or invalid packet:", p))
4848 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4849 IP(src=server.ip4, dst=eh_addr_in) /
4850 TCP(sport=saved_port_in, dport=eh_port_in))
4852 self.pg_enable_capture(self.pg_interfaces)
4854 capture = pg1.get_capture(1)
4859 self.assertEqual(ip.dst, client.ip4)
4860 self.assertEqual(ip.src, self.nat_addr)
4861 self.assertEqual(tcp.dport, eh_port_out)
4862 self.assertEqual(tcp.sport, port_out)
4863 self.assert_packet_checksums_valid(p)
4865 self.logger.error(ppp("Unexpected or invalid packet:", p))
4869 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4870 self.assertEqual(len(sessions), 1)
4871 self.assertTrue(sessions[0].ext_host_valid)
4872 self.assertTrue(sessions[0].is_twicenat)
4873 self.vapi.nat44_del_session(
4874 sessions[0].inside_ip_address,
4875 sessions[0].inside_port,
4876 sessions[0].protocol,
4877 ext_host_address=sessions[0].ext_host_nat_address,
4878 ext_host_port=sessions[0].ext_host_nat_port)
4879 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4880 self.assertEqual(len(sessions), 0)
4882 def test_twice_nat(self):
4884 self.twice_nat_common()
4886 def test_self_twice_nat_positive(self):
4887 """ Self Twice NAT44 (positive test) """
4888 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4890 def test_self_twice_nat_negative(self):
4891 """ Self Twice NAT44 (negative test) """
4892 self.twice_nat_common(self_twice_nat=True)
4894 def test_twice_nat_lb(self):
4895 """ Twice NAT44 local service load balancing """
4896 self.twice_nat_common(lb=True)
4898 def test_self_twice_nat_lb_positive(self):
4899 """ Self Twice NAT44 local service load balancing (positive test) """
4900 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4903 def test_self_twice_nat_lb_negative(self):
4904 """ Self Twice NAT44 local service load balancing (negative test) """
4905 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4908 def test_twice_nat_interface_addr(self):
4909 """ Acquire twice NAT44 addresses from interface """
4910 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4912 # no address in NAT pool
4913 adresses = self.vapi.nat44_address_dump()
4914 self.assertEqual(0, len(adresses))
4916 # configure interface address and check NAT address pool
4917 self.pg3.config_ip4()
4918 adresses = self.vapi.nat44_address_dump()
4919 self.assertEqual(1, len(adresses))
4920 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4921 self.assertEqual(adresses[0].twice_nat, 1)
4923 # remove interface address and check NAT address pool
4924 self.pg3.unconfig_ip4()
4925 adresses = self.vapi.nat44_address_dump()
4926 self.assertEqual(0, len(adresses))
4928 def test_tcp_session_close_in(self):
4929 """ Close TCP session from inside network """
4930 self.tcp_port_out = 10505
4931 self.nat44_add_address(self.nat_addr)
4932 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4936 proto=IP_PROTOS.tcp,
4938 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4939 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4942 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4943 start_sessnum = len(sessions)
4945 self.initiate_tcp_session(self.pg0, self.pg1)
4947 # FIN packet in -> out
4948 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4949 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4950 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4951 flags="FA", seq=100, ack=300))
4952 self.pg0.add_stream(p)
4953 self.pg_enable_capture(self.pg_interfaces)
4955 self.pg1.get_capture(1)
4959 # ACK 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="A", seq=300, ack=101))
4966 # FIN packet out -> in
4967 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4968 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4969 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4970 flags="FA", seq=300, ack=101))
4973 self.pg1.add_stream(pkts)
4974 self.pg_enable_capture(self.pg_interfaces)
4976 self.pg0.get_capture(2)
4978 # ACK packet in -> out
4979 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4980 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4981 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4982 flags="A", seq=101, ack=301))
4983 self.pg0.add_stream(p)
4984 self.pg_enable_capture(self.pg_interfaces)
4986 self.pg1.get_capture(1)
4988 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4990 self.assertEqual(len(sessions) - start_sessnum, 0)
4992 def test_tcp_session_close_out(self):
4993 """ Close TCP session from outside network """
4994 self.tcp_port_out = 10505
4995 self.nat44_add_address(self.nat_addr)
4996 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5000 proto=IP_PROTOS.tcp,
5002 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5003 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5006 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5007 start_sessnum = len(sessions)
5009 self.initiate_tcp_session(self.pg0, self.pg1)
5011 # FIN packet out -> in
5012 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5013 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5014 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5015 flags="FA", seq=100, ack=300))
5016 self.pg1.add_stream(p)
5017 self.pg_enable_capture(self.pg_interfaces)
5019 self.pg0.get_capture(1)
5021 # FIN+ACK packet in -> out
5022 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5023 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5024 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5025 flags="FA", seq=300, ack=101))
5027 self.pg0.add_stream(p)
5028 self.pg_enable_capture(self.pg_interfaces)
5030 self.pg1.get_capture(1)
5032 # ACK packet out -> in
5033 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5034 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5035 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5036 flags="A", seq=101, ack=301))
5037 self.pg1.add_stream(p)
5038 self.pg_enable_capture(self.pg_interfaces)
5040 self.pg0.get_capture(1)
5042 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5044 self.assertEqual(len(sessions) - start_sessnum, 0)
5046 def test_tcp_session_close_simultaneous(self):
5047 """ Close TCP session from inside network """
5048 self.tcp_port_out = 10505
5049 self.nat44_add_address(self.nat_addr)
5050 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5054 proto=IP_PROTOS.tcp,
5056 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5057 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5060 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5061 start_sessnum = len(sessions)
5063 self.initiate_tcp_session(self.pg0, self.pg1)
5065 # FIN packet in -> out
5066 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5067 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5068 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5069 flags="FA", seq=100, ack=300))
5070 self.pg0.add_stream(p)
5071 self.pg_enable_capture(self.pg_interfaces)
5073 self.pg1.get_capture(1)
5075 # FIN packet out -> in
5076 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5077 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5078 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5079 flags="FA", seq=300, ack=100))
5080 self.pg1.add_stream(p)
5081 self.pg_enable_capture(self.pg_interfaces)
5083 self.pg0.get_capture(1)
5085 # ACK packet in -> out
5086 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5087 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5088 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5089 flags="A", seq=101, ack=301))
5090 self.pg0.add_stream(p)
5091 self.pg_enable_capture(self.pg_interfaces)
5093 self.pg1.get_capture(1)
5095 # ACK packet out -> in
5096 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5097 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5098 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5099 flags="A", seq=301, ack=101))
5100 self.pg1.add_stream(p)
5101 self.pg_enable_capture(self.pg_interfaces)
5103 self.pg0.get_capture(1)
5105 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5107 self.assertEqual(len(sessions) - start_sessnum, 0)
5109 def test_one_armed_nat44_static(self):
5110 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5111 remote_host = self.pg4.remote_hosts[0]
5112 local_host = self.pg4.remote_hosts[1]
5117 self.vapi.nat44_forwarding_enable_disable(1)
5118 self.nat44_add_address(self.nat_addr, twice_nat=1)
5119 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5120 local_port, external_port,
5121 proto=IP_PROTOS.tcp, out2in_only=1,
5123 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5124 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5127 # from client to service
5128 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5129 IP(src=remote_host.ip4, dst=self.nat_addr) /
5130 TCP(sport=12345, dport=external_port))
5131 self.pg4.add_stream(p)
5132 self.pg_enable_capture(self.pg_interfaces)
5134 capture = self.pg4.get_capture(1)
5139 self.assertEqual(ip.dst, local_host.ip4)
5140 self.assertEqual(ip.src, self.nat_addr)
5141 self.assertEqual(tcp.dport, local_port)
5142 self.assertNotEqual(tcp.sport, 12345)
5143 eh_port_in = tcp.sport
5144 self.assert_packet_checksums_valid(p)
5146 self.logger.error(ppp("Unexpected or invalid packet:", p))
5149 # from service back to client
5150 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5151 IP(src=local_host.ip4, dst=self.nat_addr) /
5152 TCP(sport=local_port, dport=eh_port_in))
5153 self.pg4.add_stream(p)
5154 self.pg_enable_capture(self.pg_interfaces)
5156 capture = self.pg4.get_capture(1)
5161 self.assertEqual(ip.src, self.nat_addr)
5162 self.assertEqual(ip.dst, remote_host.ip4)
5163 self.assertEqual(tcp.sport, external_port)
5164 self.assertEqual(tcp.dport, 12345)
5165 self.assert_packet_checksums_valid(p)
5167 self.logger.error(ppp("Unexpected or invalid packet:", p))
5170 def test_static_with_port_out2(self):
5171 """ 1:1 NAPT asymmetrical rule """
5176 self.vapi.nat44_forwarding_enable_disable(1)
5177 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5178 local_port, external_port,
5179 proto=IP_PROTOS.tcp, out2in_only=1)
5180 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5181 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5184 # from client to service
5185 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5186 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5187 TCP(sport=12345, dport=external_port))
5188 self.pg1.add_stream(p)
5189 self.pg_enable_capture(self.pg_interfaces)
5191 capture = self.pg0.get_capture(1)
5196 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5197 self.assertEqual(tcp.dport, local_port)
5198 self.assert_packet_checksums_valid(p)
5200 self.logger.error(ppp("Unexpected or invalid packet:", p))
5204 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5205 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5206 ICMP(type=11) / capture[0][IP])
5207 self.pg0.add_stream(p)
5208 self.pg_enable_capture(self.pg_interfaces)
5210 capture = self.pg1.get_capture(1)
5213 self.assertEqual(p[IP].src, self.nat_addr)
5215 self.assertEqual(inner.dst, self.nat_addr)
5216 self.assertEqual(inner[TCPerror].dport, external_port)
5218 self.logger.error(ppp("Unexpected or invalid packet:", p))
5221 # from service back to client
5222 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5223 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5224 TCP(sport=local_port, dport=12345))
5225 self.pg0.add_stream(p)
5226 self.pg_enable_capture(self.pg_interfaces)
5228 capture = self.pg1.get_capture(1)
5233 self.assertEqual(ip.src, self.nat_addr)
5234 self.assertEqual(tcp.sport, external_port)
5235 self.assert_packet_checksums_valid(p)
5237 self.logger.error(ppp("Unexpected or invalid packet:", p))
5241 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5242 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5243 ICMP(type=11) / capture[0][IP])
5244 self.pg1.add_stream(p)
5245 self.pg_enable_capture(self.pg_interfaces)
5247 capture = self.pg0.get_capture(1)
5250 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5252 self.assertEqual(inner.src, self.pg0.remote_ip4)
5253 self.assertEqual(inner[TCPerror].sport, local_port)
5255 self.logger.error(ppp("Unexpected or invalid packet:", p))
5258 # from client to server (no translation)
5259 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5260 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5261 TCP(sport=12346, dport=local_port))
5262 self.pg1.add_stream(p)
5263 self.pg_enable_capture(self.pg_interfaces)
5265 capture = self.pg0.get_capture(1)
5270 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5271 self.assertEqual(tcp.dport, local_port)
5272 self.assert_packet_checksums_valid(p)
5274 self.logger.error(ppp("Unexpected or invalid packet:", p))
5277 # from service back to client (no translation)
5278 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5279 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5280 TCP(sport=local_port, dport=12346))
5281 self.pg0.add_stream(p)
5282 self.pg_enable_capture(self.pg_interfaces)
5284 capture = self.pg1.get_capture(1)
5289 self.assertEqual(ip.src, self.pg0.remote_ip4)
5290 self.assertEqual(tcp.sport, local_port)
5291 self.assert_packet_checksums_valid(p)
5293 self.logger.error(ppp("Unexpected or invalid packet:", p))
5296 def test_output_feature(self):
5297 """ NAT44 interface output feature (in2out postrouting) """
5298 self.vapi.nat44_forwarding_enable_disable(1)
5299 self.nat44_add_address(self.nat_addr)
5300 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5302 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5306 pkts = self.create_stream_in(self.pg0, self.pg1)
5307 self.pg0.add_stream(pkts)
5308 self.pg_enable_capture(self.pg_interfaces)
5310 capture = self.pg1.get_capture(len(pkts))
5311 self.verify_capture_out(capture)
5314 pkts = self.create_stream_out(self.pg1)
5315 self.pg1.add_stream(pkts)
5316 self.pg_enable_capture(self.pg_interfaces)
5318 capture = self.pg0.get_capture(len(pkts))
5319 self.verify_capture_in(capture, self.pg0)
5321 def test_multiple_vrf(self):
5322 """ Multiple VRF setup """
5323 external_addr = '1.2.3.4'
5328 self.vapi.nat44_forwarding_enable_disable(1)
5329 self.nat44_add_address(self.nat_addr)
5330 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5331 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5333 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5335 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5336 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5338 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5340 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5341 local_port, external_port, vrf_id=1,
5342 proto=IP_PROTOS.tcp, out2in_only=1)
5343 self.nat44_add_static_mapping(
5344 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5345 local_port=local_port, vrf_id=0, external_port=external_port,
5346 proto=IP_PROTOS.tcp, out2in_only=1)
5348 # from client to service (both VRF1)
5349 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5350 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5351 TCP(sport=12345, dport=external_port))
5352 self.pg6.add_stream(p)
5353 self.pg_enable_capture(self.pg_interfaces)
5355 capture = self.pg5.get_capture(1)
5360 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5361 self.assertEqual(tcp.dport, local_port)
5362 self.assert_packet_checksums_valid(p)
5364 self.logger.error(ppp("Unexpected or invalid packet:", p))
5367 # from service back to client (both VRF1)
5368 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5369 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5370 TCP(sport=local_port, dport=12345))
5371 self.pg5.add_stream(p)
5372 self.pg_enable_capture(self.pg_interfaces)
5374 capture = self.pg6.get_capture(1)
5379 self.assertEqual(ip.src, external_addr)
5380 self.assertEqual(tcp.sport, external_port)
5381 self.assert_packet_checksums_valid(p)
5383 self.logger.error(ppp("Unexpected or invalid packet:", p))
5386 # dynamic NAT from VRF1 to VRF0 (output-feature)
5387 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5388 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5389 TCP(sport=2345, dport=22))
5390 self.pg5.add_stream(p)
5391 self.pg_enable_capture(self.pg_interfaces)
5393 capture = self.pg1.get_capture(1)
5398 self.assertEqual(ip.src, self.nat_addr)
5399 self.assertNotEqual(tcp.sport, 2345)
5400 self.assert_packet_checksums_valid(p)
5403 self.logger.error(ppp("Unexpected or invalid packet:", p))
5406 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5407 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5408 TCP(sport=22, dport=port))
5409 self.pg1.add_stream(p)
5410 self.pg_enable_capture(self.pg_interfaces)
5412 capture = self.pg5.get_capture(1)
5417 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5418 self.assertEqual(tcp.dport, 2345)
5419 self.assert_packet_checksums_valid(p)
5421 self.logger.error(ppp("Unexpected or invalid packet:", p))
5424 # from client VRF1 to service VRF0
5425 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5426 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5427 TCP(sport=12346, dport=external_port))
5428 self.pg6.add_stream(p)
5429 self.pg_enable_capture(self.pg_interfaces)
5431 capture = self.pg0.get_capture(1)
5436 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5437 self.assertEqual(tcp.dport, local_port)
5438 self.assert_packet_checksums_valid(p)
5440 self.logger.error(ppp("Unexpected or invalid packet:", p))
5443 # from service VRF0 back to client VRF1
5444 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5445 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5446 TCP(sport=local_port, dport=12346))
5447 self.pg0.add_stream(p)
5448 self.pg_enable_capture(self.pg_interfaces)
5450 capture = self.pg6.get_capture(1)
5455 self.assertEqual(ip.src, self.pg0.local_ip4)
5456 self.assertEqual(tcp.sport, external_port)
5457 self.assert_packet_checksums_valid(p)
5459 self.logger.error(ppp("Unexpected or invalid packet:", p))
5462 # from client VRF0 to service VRF1
5463 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5464 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5465 TCP(sport=12347, dport=external_port))
5466 self.pg0.add_stream(p)
5467 self.pg_enable_capture(self.pg_interfaces)
5469 capture = self.pg5.get_capture(1)
5474 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5475 self.assertEqual(tcp.dport, local_port)
5476 self.assert_packet_checksums_valid(p)
5478 self.logger.error(ppp("Unexpected or invalid packet:", p))
5481 # from service VRF1 back to client VRF0
5482 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5483 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5484 TCP(sport=local_port, dport=12347))
5485 self.pg5.add_stream(p)
5486 self.pg_enable_capture(self.pg_interfaces)
5488 capture = self.pg0.get_capture(1)
5493 self.assertEqual(ip.src, external_addr)
5494 self.assertEqual(tcp.sport, external_port)
5495 self.assert_packet_checksums_valid(p)
5497 self.logger.error(ppp("Unexpected or invalid packet:", p))
5500 # from client to server (both VRF1, no translation)
5501 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5502 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5503 TCP(sport=12348, dport=local_port))
5504 self.pg6.add_stream(p)
5505 self.pg_enable_capture(self.pg_interfaces)
5507 capture = self.pg5.get_capture(1)
5512 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5513 self.assertEqual(tcp.dport, local_port)
5514 self.assert_packet_checksums_valid(p)
5516 self.logger.error(ppp("Unexpected or invalid packet:", p))
5519 # from server back to client (both VRF1, no translation)
5520 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5521 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5522 TCP(sport=local_port, dport=12348))
5523 self.pg5.add_stream(p)
5524 self.pg_enable_capture(self.pg_interfaces)
5526 capture = self.pg6.get_capture(1)
5531 self.assertEqual(ip.src, self.pg5.remote_ip4)
5532 self.assertEqual(tcp.sport, local_port)
5533 self.assert_packet_checksums_valid(p)
5535 self.logger.error(ppp("Unexpected or invalid packet:", p))
5538 # from client VRF1 to server VRF0 (no translation)
5539 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5540 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5541 TCP(sport=local_port, dport=12349))
5542 self.pg0.add_stream(p)
5543 self.pg_enable_capture(self.pg_interfaces)
5545 capture = self.pg6.get_capture(1)
5550 self.assertEqual(ip.src, self.pg0.remote_ip4)
5551 self.assertEqual(tcp.sport, local_port)
5552 self.assert_packet_checksums_valid(p)
5554 self.logger.error(ppp("Unexpected or invalid packet:", p))
5557 # from server VRF0 back to client VRF1 (no translation)
5558 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5559 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5560 TCP(sport=local_port, dport=12349))
5561 self.pg0.add_stream(p)
5562 self.pg_enable_capture(self.pg_interfaces)
5564 capture = self.pg6.get_capture(1)
5569 self.assertEqual(ip.src, self.pg0.remote_ip4)
5570 self.assertEqual(tcp.sport, local_port)
5571 self.assert_packet_checksums_valid(p)
5573 self.logger.error(ppp("Unexpected or invalid packet:", p))
5576 # from client VRF0 to server VRF1 (no translation)
5577 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5578 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5579 TCP(sport=12344, dport=local_port))
5580 self.pg0.add_stream(p)
5581 self.pg_enable_capture(self.pg_interfaces)
5583 capture = self.pg5.get_capture(1)
5588 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5589 self.assertEqual(tcp.dport, local_port)
5590 self.assert_packet_checksums_valid(p)
5592 self.logger.error(ppp("Unexpected or invalid packet:", p))
5595 # from server VRF1 back to client VRF0 (no translation)
5596 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5597 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5598 TCP(sport=local_port, dport=12344))
5599 self.pg5.add_stream(p)
5600 self.pg_enable_capture(self.pg_interfaces)
5602 capture = self.pg0.get_capture(1)
5607 self.assertEqual(ip.src, self.pg5.remote_ip4)
5608 self.assertEqual(tcp.sport, local_port)
5609 self.assert_packet_checksums_valid(p)
5611 self.logger.error(ppp("Unexpected or invalid packet:", p))
5614 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5615 def test_session_timeout(self):
5616 """ NAT44 session timeouts """
5617 self.nat44_add_address(self.nat_addr)
5618 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5619 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5621 self.vapi.nat_set_timeouts(icmp=5)
5625 for i in range(0, max_sessions):
5626 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5627 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5628 IP(src=src, dst=self.pg1.remote_ip4) /
5629 ICMP(id=1025, type='echo-request'))
5631 self.pg0.add_stream(pkts)
5632 self.pg_enable_capture(self.pg_interfaces)
5634 self.pg1.get_capture(max_sessions)
5639 for i in range(0, max_sessions):
5640 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5641 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5642 IP(src=src, dst=self.pg1.remote_ip4) /
5643 ICMP(id=1026, type='echo-request'))
5645 self.pg0.add_stream(pkts)
5646 self.pg_enable_capture(self.pg_interfaces)
5648 self.pg1.get_capture(max_sessions)
5651 users = self.vapi.nat44_user_dump()
5653 nsessions = nsessions + user.nsessions
5654 self.assertLess(nsessions, 2 * max_sessions)
5656 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5657 def test_session_limit_per_user(self):
5658 """ Maximum sessions per user limit """
5659 self.nat44_add_address(self.nat_addr)
5660 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5661 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5663 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5664 src_address=self.pg2.local_ip4n,
5666 template_interval=10)
5667 self.vapi.nat_set_timeouts(udp=5)
5669 # get maximum number of translations per user
5670 nat44_config = self.vapi.nat_show_config()
5673 for port in range(0, nat44_config.max_translations_per_user):
5674 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5675 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5676 UDP(sport=1025 + port, dport=1025 + port))
5679 self.pg0.add_stream(pkts)
5680 self.pg_enable_capture(self.pg_interfaces)
5682 capture = self.pg1.get_capture(len(pkts))
5684 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5685 src_port=self.ipfix_src_port)
5687 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5688 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5689 UDP(sport=3001, dport=3002))
5690 self.pg0.add_stream(p)
5691 self.pg_enable_capture(self.pg_interfaces)
5693 capture = self.pg1.assert_nothing_captured()
5695 # verify IPFIX logging
5696 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5698 capture = self.pg2.get_capture(10)
5699 ipfix = IPFIXDecoder()
5700 # first load template
5702 self.assertTrue(p.haslayer(IPFIX))
5703 if p.haslayer(Template):
5704 ipfix.add_template(p.getlayer(Template))
5705 # verify events in data set
5707 if p.haslayer(Data):
5708 data = ipfix.decode_data_set(p.getlayer(Set))
5709 self.verify_ipfix_max_entries_per_user(
5711 nat44_config.max_translations_per_user,
5712 self.pg0.remote_ip4n)
5715 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5716 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5717 UDP(sport=3001, dport=3002))
5718 self.pg0.add_stream(p)
5719 self.pg_enable_capture(self.pg_interfaces)
5721 self.pg1.get_capture(1)
5724 super(TestNAT44EndpointDependent, self).tearDown()
5725 if not self.vpp_dead:
5726 self.logger.info(self.vapi.cli("show nat44 addresses"))
5727 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5728 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5729 self.logger.info(self.vapi.cli("show nat44 interface address"))
5730 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5731 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5732 self.logger.info(self.vapi.cli("show nat timeouts"))
5734 self.vapi.cli("clear logging")
5737 class TestNAT44Out2InDPO(MethodHolder):
5738 """ NAT44 Test Cases using out2in DPO """
5741 def setUpConstants(cls):
5742 super(TestNAT44Out2InDPO, cls).setUpConstants()
5743 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5746 def setUpClass(cls):
5747 super(TestNAT44Out2InDPO, cls).setUpClass()
5748 cls.vapi.cli("set log class nat level debug")
5751 cls.tcp_port_in = 6303
5752 cls.tcp_port_out = 6303
5753 cls.udp_port_in = 6304
5754 cls.udp_port_out = 6304
5755 cls.icmp_id_in = 6305
5756 cls.icmp_id_out = 6305
5757 cls.nat_addr = '10.0.0.3'
5758 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5759 cls.dst_ip4 = '192.168.70.1'
5761 cls.create_pg_interfaces(range(2))
5764 cls.pg0.config_ip4()
5765 cls.pg0.resolve_arp()
5768 cls.pg1.config_ip6()
5769 cls.pg1.resolve_ndp()
5771 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5772 dst_address_length=0,
5773 next_hop_address=cls.pg1.remote_ip6n,
5774 next_hop_sw_if_index=cls.pg1.sw_if_index)
5777 super(TestNAT44Out2InDPO, cls).tearDownClass()
5780 def configure_xlat(self):
5781 self.dst_ip6_pfx = '1:2:3::'
5782 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5784 self.dst_ip6_pfx_len = 96
5785 self.src_ip6_pfx = '4:5:6::'
5786 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5788 self.src_ip6_pfx_len = 96
5789 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5790 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5791 '\x00\x00\x00\x00', 0, is_translation=1,
5794 def test_464xlat_ce(self):
5795 """ Test 464XLAT CE with NAT44 """
5797 nat_config = self.vapi.nat_show_config()
5798 self.assertEqual(1, nat_config.out2in_dpo)
5800 self.configure_xlat()
5802 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5803 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5805 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5806 self.dst_ip6_pfx_len)
5807 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5808 self.src_ip6_pfx_len)
5811 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5812 self.pg0.add_stream(pkts)
5813 self.pg_enable_capture(self.pg_interfaces)
5815 capture = self.pg1.get_capture(len(pkts))
5816 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5819 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5821 self.pg1.add_stream(pkts)
5822 self.pg_enable_capture(self.pg_interfaces)
5824 capture = self.pg0.get_capture(len(pkts))
5825 self.verify_capture_in(capture, self.pg0)
5827 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5829 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5830 self.nat_addr_n, is_add=0)
5832 def test_464xlat_ce_no_nat(self):
5833 """ Test 464XLAT CE without NAT44 """
5835 self.configure_xlat()
5837 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5838 self.dst_ip6_pfx_len)
5839 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5840 self.src_ip6_pfx_len)
5842 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5843 self.pg0.add_stream(pkts)
5844 self.pg_enable_capture(self.pg_interfaces)
5846 capture = self.pg1.get_capture(len(pkts))
5847 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5848 nat_ip=out_dst_ip6, same_port=True)
5850 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5851 self.pg1.add_stream(pkts)
5852 self.pg_enable_capture(self.pg_interfaces)
5854 capture = self.pg0.get_capture(len(pkts))
5855 self.verify_capture_in(capture, self.pg0)
5858 class TestDeterministicNAT(MethodHolder):
5859 """ Deterministic NAT Test Cases """
5862 def setUpConstants(cls):
5863 super(TestDeterministicNAT, cls).setUpConstants()
5864 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5867 def setUpClass(cls):
5868 super(TestDeterministicNAT, cls).setUpClass()
5869 cls.vapi.cli("set log class nat level debug")
5872 cls.tcp_port_in = 6303
5873 cls.tcp_external_port = 6303
5874 cls.udp_port_in = 6304
5875 cls.udp_external_port = 6304
5876 cls.icmp_id_in = 6305
5877 cls.nat_addr = '10.0.0.3'
5879 cls.create_pg_interfaces(range(3))
5880 cls.interfaces = list(cls.pg_interfaces)
5882 for i in cls.interfaces:
5887 cls.pg0.generate_remote_hosts(2)
5888 cls.pg0.configure_ipv4_neighbors()
5891 super(TestDeterministicNAT, cls).tearDownClass()
5894 def create_stream_in(self, in_if, out_if, ttl=64):
5896 Create packet stream for inside network
5898 :param in_if: Inside interface
5899 :param out_if: Outside interface
5900 :param ttl: TTL of generated packets
5904 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5905 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5906 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5910 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5911 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5912 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5916 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5917 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5918 ICMP(id=self.icmp_id_in, type='echo-request'))
5923 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5925 Create packet stream for outside network
5927 :param out_if: Outside interface
5928 :param dst_ip: Destination IP address (Default use global NAT address)
5929 :param ttl: TTL of generated packets
5932 dst_ip = self.nat_addr
5935 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5936 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5937 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
5941 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5942 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5943 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
5947 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5948 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5949 ICMP(id=self.icmp_external_id, type='echo-reply'))
5954 def verify_capture_out(self, capture, nat_ip=None):
5956 Verify captured packets on outside network
5958 :param capture: Captured packets
5959 :param nat_ip: Translated IP address (Default use global NAT address)
5960 :param same_port: Sorce port number is not translated (Default False)
5963 nat_ip = self.nat_addr
5964 for packet in capture:
5966 self.assertEqual(packet[IP].src, nat_ip)
5967 if packet.haslayer(TCP):
5968 self.tcp_port_out = packet[TCP].sport
5969 elif packet.haslayer(UDP):
5970 self.udp_port_out = packet[UDP].sport
5972 self.icmp_external_id = packet[ICMP].id
5974 self.logger.error(ppp("Unexpected or invalid packet "
5975 "(outside network):", packet))
5978 def test_deterministic_mode(self):
5979 """ NAT plugin run deterministic mode """
5980 in_addr = '172.16.255.0'
5981 out_addr = '172.17.255.50'
5982 in_addr_t = '172.16.255.20'
5983 in_addr_n = socket.inet_aton(in_addr)
5984 out_addr_n = socket.inet_aton(out_addr)
5985 in_addr_t_n = socket.inet_aton(in_addr_t)
5989 nat_config = self.vapi.nat_show_config()
5990 self.assertEqual(1, nat_config.deterministic)
5992 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
5994 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
5995 self.assertEqual(rep1.out_addr[:4], out_addr_n)
5996 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
5997 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5999 deterministic_mappings = self.vapi.nat_det_map_dump()
6000 self.assertEqual(len(deterministic_mappings), 1)
6001 dsm = deterministic_mappings[0]
6002 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6003 self.assertEqual(in_plen, dsm.in_plen)
6004 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6005 self.assertEqual(out_plen, dsm.out_plen)
6007 self.clear_nat_det()
6008 deterministic_mappings = self.vapi.nat_det_map_dump()
6009 self.assertEqual(len(deterministic_mappings), 0)
6011 def test_set_timeouts(self):
6012 """ Set deterministic NAT timeouts """
6013 timeouts_before = self.vapi.nat_get_timeouts()
6015 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6016 timeouts_before.tcp_established + 10,
6017 timeouts_before.tcp_transitory + 10,
6018 timeouts_before.icmp + 10)
6020 timeouts_after = self.vapi.nat_get_timeouts()
6022 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6023 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6024 self.assertNotEqual(timeouts_before.tcp_established,
6025 timeouts_after.tcp_established)
6026 self.assertNotEqual(timeouts_before.tcp_transitory,
6027 timeouts_after.tcp_transitory)
6029 def test_det_in(self):
6030 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6032 nat_ip = "10.0.0.10"
6034 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6036 socket.inet_aton(nat_ip),
6038 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6039 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6043 pkts = self.create_stream_in(self.pg0, self.pg1)
6044 self.pg0.add_stream(pkts)
6045 self.pg_enable_capture(self.pg_interfaces)
6047 capture = self.pg1.get_capture(len(pkts))
6048 self.verify_capture_out(capture, nat_ip)
6051 pkts = self.create_stream_out(self.pg1, nat_ip)
6052 self.pg1.add_stream(pkts)
6053 self.pg_enable_capture(self.pg_interfaces)
6055 capture = self.pg0.get_capture(len(pkts))
6056 self.verify_capture_in(capture, self.pg0)
6059 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6060 self.assertEqual(len(sessions), 3)
6064 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6065 self.assertEqual(s.in_port, self.tcp_port_in)
6066 self.assertEqual(s.out_port, self.tcp_port_out)
6067 self.assertEqual(s.ext_port, self.tcp_external_port)
6071 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6072 self.assertEqual(s.in_port, self.udp_port_in)
6073 self.assertEqual(s.out_port, self.udp_port_out)
6074 self.assertEqual(s.ext_port, self.udp_external_port)
6078 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6079 self.assertEqual(s.in_port, self.icmp_id_in)
6080 self.assertEqual(s.out_port, self.icmp_external_id)
6082 def test_multiple_users(self):
6083 """ Deterministic NAT multiple users """
6085 nat_ip = "10.0.0.10"
6087 external_port = 6303
6089 host0 = self.pg0.remote_hosts[0]
6090 host1 = self.pg0.remote_hosts[1]
6092 self.vapi.nat_det_add_del_map(host0.ip4n,
6094 socket.inet_aton(nat_ip),
6096 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6097 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6101 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6102 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6103 TCP(sport=port_in, dport=external_port))
6104 self.pg0.add_stream(p)
6105 self.pg_enable_capture(self.pg_interfaces)
6107 capture = self.pg1.get_capture(1)
6112 self.assertEqual(ip.src, nat_ip)
6113 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6114 self.assertEqual(tcp.dport, external_port)
6115 port_out0 = tcp.sport
6117 self.logger.error(ppp("Unexpected or invalid packet:", p))
6121 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6122 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6123 TCP(sport=port_in, dport=external_port))
6124 self.pg0.add_stream(p)
6125 self.pg_enable_capture(self.pg_interfaces)
6127 capture = self.pg1.get_capture(1)
6132 self.assertEqual(ip.src, nat_ip)
6133 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6134 self.assertEqual(tcp.dport, external_port)
6135 port_out1 = tcp.sport
6137 self.logger.error(ppp("Unexpected or invalid packet:", p))
6140 dms = self.vapi.nat_det_map_dump()
6141 self.assertEqual(1, len(dms))
6142 self.assertEqual(2, dms[0].ses_num)
6145 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6146 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6147 TCP(sport=external_port, dport=port_out0))
6148 self.pg1.add_stream(p)
6149 self.pg_enable_capture(self.pg_interfaces)
6151 capture = self.pg0.get_capture(1)
6156 self.assertEqual(ip.src, self.pg1.remote_ip4)
6157 self.assertEqual(ip.dst, host0.ip4)
6158 self.assertEqual(tcp.dport, port_in)
6159 self.assertEqual(tcp.sport, external_port)
6161 self.logger.error(ppp("Unexpected or invalid packet:", p))
6165 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6166 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6167 TCP(sport=external_port, dport=port_out1))
6168 self.pg1.add_stream(p)
6169 self.pg_enable_capture(self.pg_interfaces)
6171 capture = self.pg0.get_capture(1)
6176 self.assertEqual(ip.src, self.pg1.remote_ip4)
6177 self.assertEqual(ip.dst, host1.ip4)
6178 self.assertEqual(tcp.dport, port_in)
6179 self.assertEqual(tcp.sport, external_port)
6181 self.logger.error(ppp("Unexpected or invalid packet", p))
6184 # session close api test
6185 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6187 self.pg1.remote_ip4n,
6189 dms = self.vapi.nat_det_map_dump()
6190 self.assertEqual(dms[0].ses_num, 1)
6192 self.vapi.nat_det_close_session_in(host0.ip4n,
6194 self.pg1.remote_ip4n,
6196 dms = self.vapi.nat_det_map_dump()
6197 self.assertEqual(dms[0].ses_num, 0)
6199 def test_tcp_session_close_detection_in(self):
6200 """ Deterministic NAT TCP session close from inside network """
6201 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6203 socket.inet_aton(self.nat_addr),
6205 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6206 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6209 self.initiate_tcp_session(self.pg0, self.pg1)
6211 # close the session from inside
6213 # FIN packet in -> out
6214 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6215 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6216 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6218 self.pg0.add_stream(p)
6219 self.pg_enable_capture(self.pg_interfaces)
6221 self.pg1.get_capture(1)
6225 # ACK 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 # FIN packet out -> in
6233 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6234 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6235 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6239 self.pg1.add_stream(pkts)
6240 self.pg_enable_capture(self.pg_interfaces)
6242 self.pg0.get_capture(2)
6244 # ACK packet in -> out
6245 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6246 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6247 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6249 self.pg0.add_stream(p)
6250 self.pg_enable_capture(self.pg_interfaces)
6252 self.pg1.get_capture(1)
6254 # Check if deterministic NAT44 closed the session
6255 dms = self.vapi.nat_det_map_dump()
6256 self.assertEqual(0, dms[0].ses_num)
6258 self.logger.error("TCP session termination failed")
6261 def test_tcp_session_close_detection_out(self):
6262 """ Deterministic NAT TCP session close from outside network """
6263 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6265 socket.inet_aton(self.nat_addr),
6267 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6268 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6271 self.initiate_tcp_session(self.pg0, self.pg1)
6273 # close the session from outside
6275 # FIN packet out -> in
6276 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6277 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6278 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6280 self.pg1.add_stream(p)
6281 self.pg_enable_capture(self.pg_interfaces)
6283 self.pg0.get_capture(1)
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 # ACK packet in -> out
6295 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6296 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6297 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6301 self.pg0.add_stream(pkts)
6302 self.pg_enable_capture(self.pg_interfaces)
6304 self.pg1.get_capture(2)
6306 # ACK packet out -> in
6307 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6308 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6309 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6311 self.pg1.add_stream(p)
6312 self.pg_enable_capture(self.pg_interfaces)
6314 self.pg0.get_capture(1)
6316 # Check if deterministic NAT44 closed the session
6317 dms = self.vapi.nat_det_map_dump()
6318 self.assertEqual(0, dms[0].ses_num)
6320 self.logger.error("TCP session termination failed")
6323 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6324 def test_session_timeout(self):
6325 """ Deterministic NAT session timeouts """
6326 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6328 socket.inet_aton(self.nat_addr),
6330 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6331 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6334 self.initiate_tcp_session(self.pg0, self.pg1)
6335 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6336 pkts = self.create_stream_in(self.pg0, self.pg1)
6337 self.pg0.add_stream(pkts)
6338 self.pg_enable_capture(self.pg_interfaces)
6340 capture = self.pg1.get_capture(len(pkts))
6343 dms = self.vapi.nat_det_map_dump()
6344 self.assertEqual(0, dms[0].ses_num)
6346 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6347 def test_session_limit_per_user(self):
6348 """ Deterministic NAT maximum sessions per user limit """
6349 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6351 socket.inet_aton(self.nat_addr),
6353 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6354 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6356 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6357 src_address=self.pg2.local_ip4n,
6359 template_interval=10)
6360 self.vapi.nat_ipfix()
6363 for port in range(1025, 2025):
6364 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6365 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6366 UDP(sport=port, dport=port))
6369 self.pg0.add_stream(pkts)
6370 self.pg_enable_capture(self.pg_interfaces)
6372 capture = self.pg1.get_capture(len(pkts))
6374 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6375 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6376 UDP(sport=3001, dport=3002))
6377 self.pg0.add_stream(p)
6378 self.pg_enable_capture(self.pg_interfaces)
6380 capture = self.pg1.assert_nothing_captured()
6382 # verify ICMP error packet
6383 capture = self.pg0.get_capture(1)
6385 self.assertTrue(p.haslayer(ICMP))
6387 self.assertEqual(icmp.type, 3)
6388 self.assertEqual(icmp.code, 1)
6389 self.assertTrue(icmp.haslayer(IPerror))
6390 inner_ip = icmp[IPerror]
6391 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6392 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6394 dms = self.vapi.nat_det_map_dump()
6396 self.assertEqual(1000, dms[0].ses_num)
6398 # verify IPFIX logging
6399 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6401 capture = self.pg2.get_capture(2)
6402 ipfix = IPFIXDecoder()
6403 # first load template
6405 self.assertTrue(p.haslayer(IPFIX))
6406 if p.haslayer(Template):
6407 ipfix.add_template(p.getlayer(Template))
6408 # verify events in data set
6410 if p.haslayer(Data):
6411 data = ipfix.decode_data_set(p.getlayer(Set))
6412 self.verify_ipfix_max_entries_per_user(data,
6414 self.pg0.remote_ip4n)
6416 def clear_nat_det(self):
6418 Clear deterministic NAT configuration.
6420 self.vapi.nat_ipfix(enable=0)
6421 self.vapi.nat_set_timeouts()
6422 deterministic_mappings = self.vapi.nat_det_map_dump()
6423 for dsm in deterministic_mappings:
6424 self.vapi.nat_det_add_del_map(dsm.in_addr,
6430 interfaces = self.vapi.nat44_interface_dump()
6431 for intf in interfaces:
6432 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6437 super(TestDeterministicNAT, self).tearDown()
6438 if not self.vpp_dead:
6439 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6440 self.logger.info(self.vapi.cli("show nat timeouts"))
6442 self.vapi.cli("show nat44 deterministic mappings"))
6444 self.vapi.cli("show nat44 deterministic sessions"))
6445 self.clear_nat_det()
6448 class TestNAT64(MethodHolder):
6449 """ NAT64 Test Cases """
6452 def setUpConstants(cls):
6453 super(TestNAT64, cls).setUpConstants()
6454 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6455 "nat64 st hash buckets 256", "}"])
6458 def setUpClass(cls):
6459 super(TestNAT64, cls).setUpClass()
6462 cls.tcp_port_in = 6303
6463 cls.tcp_port_out = 6303
6464 cls.udp_port_in = 6304
6465 cls.udp_port_out = 6304
6466 cls.icmp_id_in = 6305
6467 cls.icmp_id_out = 6305
6468 cls.nat_addr = '10.0.0.3'
6469 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6471 cls.vrf1_nat_addr = '10.0.10.3'
6472 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6474 cls.ipfix_src_port = 4739
6475 cls.ipfix_domain_id = 1
6477 cls.create_pg_interfaces(range(6))
6478 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6479 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6480 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6482 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6484 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6486 cls.pg0.generate_remote_hosts(2)
6488 for i in cls.ip6_interfaces:
6491 i.configure_ipv6_neighbors()
6493 for i in cls.ip4_interfaces:
6499 cls.pg3.config_ip4()
6500 cls.pg3.resolve_arp()
6501 cls.pg3.config_ip6()
6502 cls.pg3.configure_ipv6_neighbors()
6505 cls.pg5.config_ip6()
6508 super(TestNAT64, cls).tearDownClass()
6511 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6512 """ NAT64 inside interface handles Neighbor Advertisement """
6514 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6517 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6518 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6519 ICMPv6EchoRequest())
6521 self.pg5.add_stream(pkts)
6522 self.pg_enable_capture(self.pg_interfaces)
6525 # Wait for Neighbor Solicitation
6526 capture = self.pg5.get_capture(len(pkts))
6529 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6530 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6531 tgt = packet[ICMPv6ND_NS].tgt
6533 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6536 # Send Neighbor Advertisement
6537 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6538 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6539 ICMPv6ND_NA(tgt=tgt) /
6540 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6542 self.pg5.add_stream(pkts)
6543 self.pg_enable_capture(self.pg_interfaces)
6546 # Try to send ping again
6548 self.pg5.add_stream(pkts)
6549 self.pg_enable_capture(self.pg_interfaces)
6552 # Wait for ping reply
6553 capture = self.pg5.get_capture(len(pkts))
6556 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6557 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6558 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6560 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6563 def test_pool(self):
6564 """ Add/delete address to NAT64 pool """
6565 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6567 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6569 addresses = self.vapi.nat64_pool_addr_dump()
6570 self.assertEqual(len(addresses), 1)
6571 self.assertEqual(addresses[0].address, nat_addr)
6573 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6575 addresses = self.vapi.nat64_pool_addr_dump()
6576 self.assertEqual(len(addresses), 0)
6578 def test_interface(self):
6579 """ Enable/disable NAT64 feature on the interface """
6580 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6581 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6583 interfaces = self.vapi.nat64_interface_dump()
6584 self.assertEqual(len(interfaces), 2)
6587 for intf in interfaces:
6588 if intf.sw_if_index == self.pg0.sw_if_index:
6589 self.assertEqual(intf.is_inside, 1)
6591 elif intf.sw_if_index == self.pg1.sw_if_index:
6592 self.assertEqual(intf.is_inside, 0)
6594 self.assertTrue(pg0_found)
6595 self.assertTrue(pg1_found)
6597 features = self.vapi.cli("show interface features pg0")
6598 self.assertNotEqual(features.find('nat64-in2out'), -1)
6599 features = self.vapi.cli("show interface features pg1")
6600 self.assertNotEqual(features.find('nat64-out2in'), -1)
6602 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6603 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6605 interfaces = self.vapi.nat64_interface_dump()
6606 self.assertEqual(len(interfaces), 0)
6608 def test_static_bib(self):
6609 """ Add/delete static BIB entry """
6610 in_addr = socket.inet_pton(socket.AF_INET6,
6611 '2001:db8:85a3::8a2e:370:7334')
6612 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6615 proto = IP_PROTOS.tcp
6617 self.vapi.nat64_add_del_static_bib(in_addr,
6622 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6627 self.assertEqual(bibe.i_addr, in_addr)
6628 self.assertEqual(bibe.o_addr, out_addr)
6629 self.assertEqual(bibe.i_port, in_port)
6630 self.assertEqual(bibe.o_port, out_port)
6631 self.assertEqual(static_bib_num, 1)
6633 self.vapi.nat64_add_del_static_bib(in_addr,
6639 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6644 self.assertEqual(static_bib_num, 0)
6646 def test_set_timeouts(self):
6647 """ Set NAT64 timeouts """
6648 # verify default values
6649 timeouts = self.vapi.nat_get_timeouts()
6650 self.assertEqual(timeouts.udp, 300)
6651 self.assertEqual(timeouts.icmp, 60)
6652 self.assertEqual(timeouts.tcp_transitory, 240)
6653 self.assertEqual(timeouts.tcp_established, 7440)
6655 # set and verify custom values
6656 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6657 tcp_established=7450)
6658 timeouts = self.vapi.nat_get_timeouts()
6659 self.assertEqual(timeouts.udp, 200)
6660 self.assertEqual(timeouts.icmp, 30)
6661 self.assertEqual(timeouts.tcp_transitory, 250)
6662 self.assertEqual(timeouts.tcp_established, 7450)
6664 def test_dynamic(self):
6665 """ NAT64 dynamic translation test """
6666 self.tcp_port_in = 6303
6667 self.udp_port_in = 6304
6668 self.icmp_id_in = 6305
6670 ses_num_start = self.nat64_get_ses_num()
6672 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6674 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6675 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6678 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6679 self.pg0.add_stream(pkts)
6680 self.pg_enable_capture(self.pg_interfaces)
6682 capture = self.pg1.get_capture(len(pkts))
6683 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6684 dst_ip=self.pg1.remote_ip4)
6687 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6688 self.pg1.add_stream(pkts)
6689 self.pg_enable_capture(self.pg_interfaces)
6691 capture = self.pg0.get_capture(len(pkts))
6692 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6693 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6696 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6697 self.pg0.add_stream(pkts)
6698 self.pg_enable_capture(self.pg_interfaces)
6700 capture = self.pg1.get_capture(len(pkts))
6701 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6702 dst_ip=self.pg1.remote_ip4)
6705 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6706 self.pg1.add_stream(pkts)
6707 self.pg_enable_capture(self.pg_interfaces)
6709 capture = self.pg0.get_capture(len(pkts))
6710 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6712 ses_num_end = self.nat64_get_ses_num()
6714 self.assertEqual(ses_num_end - ses_num_start, 3)
6716 # tenant with specific VRF
6717 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6718 self.vrf1_nat_addr_n,
6719 vrf_id=self.vrf1_id)
6720 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6722 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6723 self.pg2.add_stream(pkts)
6724 self.pg_enable_capture(self.pg_interfaces)
6726 capture = self.pg1.get_capture(len(pkts))
6727 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6728 dst_ip=self.pg1.remote_ip4)
6730 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6731 self.pg1.add_stream(pkts)
6732 self.pg_enable_capture(self.pg_interfaces)
6734 capture = self.pg2.get_capture(len(pkts))
6735 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6737 def test_static(self):
6738 """ NAT64 static translation test """
6739 self.tcp_port_in = 60303
6740 self.udp_port_in = 60304
6741 self.icmp_id_in = 60305
6742 self.tcp_port_out = 60303
6743 self.udp_port_out = 60304
6744 self.icmp_id_out = 60305
6746 ses_num_start = self.nat64_get_ses_num()
6748 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6750 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6751 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6753 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6758 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6763 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6770 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6771 self.pg0.add_stream(pkts)
6772 self.pg_enable_capture(self.pg_interfaces)
6774 capture = self.pg1.get_capture(len(pkts))
6775 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6776 dst_ip=self.pg1.remote_ip4, same_port=True)
6779 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6780 self.pg1.add_stream(pkts)
6781 self.pg_enable_capture(self.pg_interfaces)
6783 capture = self.pg0.get_capture(len(pkts))
6784 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6785 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6787 ses_num_end = self.nat64_get_ses_num()
6789 self.assertEqual(ses_num_end - ses_num_start, 3)
6791 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6792 def test_session_timeout(self):
6793 """ NAT64 session timeout """
6794 self.icmp_id_in = 1234
6795 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6797 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6798 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6799 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6801 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6802 self.pg0.add_stream(pkts)
6803 self.pg_enable_capture(self.pg_interfaces)
6805 capture = self.pg1.get_capture(len(pkts))
6807 ses_num_before_timeout = self.nat64_get_ses_num()
6811 # ICMP and TCP session after timeout
6812 ses_num_after_timeout = self.nat64_get_ses_num()
6813 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6815 def test_icmp_error(self):
6816 """ NAT64 ICMP Error message translation """
6817 self.tcp_port_in = 6303
6818 self.udp_port_in = 6304
6819 self.icmp_id_in = 6305
6821 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6823 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6824 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6826 # send some packets to create sessions
6827 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6828 self.pg0.add_stream(pkts)
6829 self.pg_enable_capture(self.pg_interfaces)
6831 capture_ip4 = self.pg1.get_capture(len(pkts))
6832 self.verify_capture_out(capture_ip4,
6833 nat_ip=self.nat_addr,
6834 dst_ip=self.pg1.remote_ip4)
6836 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6837 self.pg1.add_stream(pkts)
6838 self.pg_enable_capture(self.pg_interfaces)
6840 capture_ip6 = self.pg0.get_capture(len(pkts))
6841 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6842 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6843 self.pg0.remote_ip6)
6846 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6847 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6848 ICMPv6DestUnreach(code=1) /
6849 packet[IPv6] for packet in capture_ip6]
6850 self.pg0.add_stream(pkts)
6851 self.pg_enable_capture(self.pg_interfaces)
6853 capture = self.pg1.get_capture(len(pkts))
6854 for packet in capture:
6856 self.assertEqual(packet[IP].src, self.nat_addr)
6857 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6858 self.assertEqual(packet[ICMP].type, 3)
6859 self.assertEqual(packet[ICMP].code, 13)
6860 inner = packet[IPerror]
6861 self.assertEqual(inner.src, self.pg1.remote_ip4)
6862 self.assertEqual(inner.dst, self.nat_addr)
6863 self.assert_packet_checksums_valid(packet)
6864 if inner.haslayer(TCPerror):
6865 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6866 elif inner.haslayer(UDPerror):
6867 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6869 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6871 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6875 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6876 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6877 ICMP(type=3, code=13) /
6878 packet[IP] for packet in capture_ip4]
6879 self.pg1.add_stream(pkts)
6880 self.pg_enable_capture(self.pg_interfaces)
6882 capture = self.pg0.get_capture(len(pkts))
6883 for packet in capture:
6885 self.assertEqual(packet[IPv6].src, ip.src)
6886 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6887 icmp = packet[ICMPv6DestUnreach]
6888 self.assertEqual(icmp.code, 1)
6889 inner = icmp[IPerror6]
6890 self.assertEqual(inner.src, self.pg0.remote_ip6)
6891 self.assertEqual(inner.dst, ip.src)
6892 self.assert_icmpv6_checksum_valid(packet)
6893 if inner.haslayer(TCPerror):
6894 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6895 elif inner.haslayer(UDPerror):
6896 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6898 self.assertEqual(inner[ICMPv6EchoRequest].id,
6901 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6904 def test_hairpinning(self):
6905 """ NAT64 hairpinning """
6907 client = self.pg0.remote_hosts[0]
6908 server = self.pg0.remote_hosts[1]
6909 server_tcp_in_port = 22
6910 server_tcp_out_port = 4022
6911 server_udp_in_port = 23
6912 server_udp_out_port = 4023
6913 client_tcp_in_port = 1234
6914 client_udp_in_port = 1235
6915 client_tcp_out_port = 0
6916 client_udp_out_port = 0
6917 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6918 nat_addr_ip6 = ip.src
6920 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6922 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6923 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6925 self.vapi.nat64_add_del_static_bib(server.ip6n,
6928 server_tcp_out_port,
6930 self.vapi.nat64_add_del_static_bib(server.ip6n,
6933 server_udp_out_port,
6938 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6939 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6940 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6942 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6943 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6944 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6946 self.pg0.add_stream(pkts)
6947 self.pg_enable_capture(self.pg_interfaces)
6949 capture = self.pg0.get_capture(len(pkts))
6950 for packet in capture:
6952 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6953 self.assertEqual(packet[IPv6].dst, server.ip6)
6954 self.assert_packet_checksums_valid(packet)
6955 if packet.haslayer(TCP):
6956 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6957 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
6958 client_tcp_out_port = packet[TCP].sport
6960 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6961 self.assertEqual(packet[UDP].dport, server_udp_in_port)
6962 client_udp_out_port = packet[UDP].sport
6964 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6969 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6970 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6971 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6973 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6974 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6975 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6977 self.pg0.add_stream(pkts)
6978 self.pg_enable_capture(self.pg_interfaces)
6980 capture = self.pg0.get_capture(len(pkts))
6981 for packet in capture:
6983 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6984 self.assertEqual(packet[IPv6].dst, client.ip6)
6985 self.assert_packet_checksums_valid(packet)
6986 if packet.haslayer(TCP):
6987 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6988 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
6990 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6991 self.assertEqual(packet[UDP].dport, client_udp_in_port)
6993 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6998 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6999 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7000 ICMPv6DestUnreach(code=1) /
7001 packet[IPv6] for packet in capture]
7002 self.pg0.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 capture = self.pg0.get_capture(len(pkts))
7006 for packet in capture:
7008 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7009 self.assertEqual(packet[IPv6].dst, server.ip6)
7010 icmp = packet[ICMPv6DestUnreach]
7011 self.assertEqual(icmp.code, 1)
7012 inner = icmp[IPerror6]
7013 self.assertEqual(inner.src, server.ip6)
7014 self.assertEqual(inner.dst, nat_addr_ip6)
7015 self.assert_packet_checksums_valid(packet)
7016 if inner.haslayer(TCPerror):
7017 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7018 self.assertEqual(inner[TCPerror].dport,
7019 client_tcp_out_port)
7021 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7022 self.assertEqual(inner[UDPerror].dport,
7023 client_udp_out_port)
7025 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7028 def test_prefix(self):
7029 """ NAT64 Network-Specific Prefix """
7031 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7033 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7034 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7035 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7036 self.vrf1_nat_addr_n,
7037 vrf_id=self.vrf1_id)
7038 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7041 global_pref64 = "2001:db8::"
7042 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7043 global_pref64_len = 32
7044 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7046 prefix = self.vapi.nat64_prefix_dump()
7047 self.assertEqual(len(prefix), 1)
7048 self.assertEqual(prefix[0].prefix, global_pref64_n)
7049 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7050 self.assertEqual(prefix[0].vrf_id, 0)
7052 # Add tenant specific prefix
7053 vrf1_pref64 = "2001:db8:122:300::"
7054 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7055 vrf1_pref64_len = 56
7056 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7058 vrf_id=self.vrf1_id)
7059 prefix = self.vapi.nat64_prefix_dump()
7060 self.assertEqual(len(prefix), 2)
7063 pkts = self.create_stream_in_ip6(self.pg0,
7066 plen=global_pref64_len)
7067 self.pg0.add_stream(pkts)
7068 self.pg_enable_capture(self.pg_interfaces)
7070 capture = self.pg1.get_capture(len(pkts))
7071 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7072 dst_ip=self.pg1.remote_ip4)
7074 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7075 self.pg1.add_stream(pkts)
7076 self.pg_enable_capture(self.pg_interfaces)
7078 capture = self.pg0.get_capture(len(pkts))
7079 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7082 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7084 # Tenant specific prefix
7085 pkts = self.create_stream_in_ip6(self.pg2,
7088 plen=vrf1_pref64_len)
7089 self.pg2.add_stream(pkts)
7090 self.pg_enable_capture(self.pg_interfaces)
7092 capture = self.pg1.get_capture(len(pkts))
7093 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7094 dst_ip=self.pg1.remote_ip4)
7096 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7097 self.pg1.add_stream(pkts)
7098 self.pg_enable_capture(self.pg_interfaces)
7100 capture = self.pg2.get_capture(len(pkts))
7101 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7104 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7106 def test_unknown_proto(self):
7107 """ NAT64 translate packet with unknown protocol """
7109 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7111 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7112 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7113 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7116 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7117 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7118 TCP(sport=self.tcp_port_in, dport=20))
7119 self.pg0.add_stream(p)
7120 self.pg_enable_capture(self.pg_interfaces)
7122 p = self.pg1.get_capture(1)
7124 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7125 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7127 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7128 TCP(sport=1234, dport=1234))
7129 self.pg0.add_stream(p)
7130 self.pg_enable_capture(self.pg_interfaces)
7132 p = self.pg1.get_capture(1)
7135 self.assertEqual(packet[IP].src, self.nat_addr)
7136 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7137 self.assertTrue(packet.haslayer(GRE))
7138 self.assert_packet_checksums_valid(packet)
7140 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7144 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7145 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7147 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7148 TCP(sport=1234, dport=1234))
7149 self.pg1.add_stream(p)
7150 self.pg_enable_capture(self.pg_interfaces)
7152 p = self.pg0.get_capture(1)
7155 self.assertEqual(packet[IPv6].src, remote_ip6)
7156 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7157 self.assertEqual(packet[IPv6].nh, 47)
7159 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7162 def test_hairpinning_unknown_proto(self):
7163 """ NAT64 translate packet with unknown protocol - hairpinning """
7165 client = self.pg0.remote_hosts[0]
7166 server = self.pg0.remote_hosts[1]
7167 server_tcp_in_port = 22
7168 server_tcp_out_port = 4022
7169 client_tcp_in_port = 1234
7170 client_tcp_out_port = 1235
7171 server_nat_ip = "10.0.0.100"
7172 client_nat_ip = "10.0.0.110"
7173 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7174 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7175 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7176 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7178 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7180 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7181 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7183 self.vapi.nat64_add_del_static_bib(server.ip6n,
7186 server_tcp_out_port,
7189 self.vapi.nat64_add_del_static_bib(server.ip6n,
7195 self.vapi.nat64_add_del_static_bib(client.ip6n,
7198 client_tcp_out_port,
7202 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7203 IPv6(src=client.ip6, dst=server_nat_ip6) /
7204 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7205 self.pg0.add_stream(p)
7206 self.pg_enable_capture(self.pg_interfaces)
7208 p = self.pg0.get_capture(1)
7210 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7211 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7213 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7214 TCP(sport=1234, dport=1234))
7215 self.pg0.add_stream(p)
7216 self.pg_enable_capture(self.pg_interfaces)
7218 p = self.pg0.get_capture(1)
7221 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7222 self.assertEqual(packet[IPv6].dst, server.ip6)
7223 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7225 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7229 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7230 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7232 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7233 TCP(sport=1234, dport=1234))
7234 self.pg0.add_stream(p)
7235 self.pg_enable_capture(self.pg_interfaces)
7237 p = self.pg0.get_capture(1)
7240 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7241 self.assertEqual(packet[IPv6].dst, client.ip6)
7242 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7244 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7247 def test_one_armed_nat64(self):
7248 """ One armed NAT64 """
7250 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7254 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7256 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7257 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7260 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7261 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7262 TCP(sport=12345, dport=80))
7263 self.pg3.add_stream(p)
7264 self.pg_enable_capture(self.pg_interfaces)
7266 capture = self.pg3.get_capture(1)
7271 self.assertEqual(ip.src, self.nat_addr)
7272 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7273 self.assertNotEqual(tcp.sport, 12345)
7274 external_port = tcp.sport
7275 self.assertEqual(tcp.dport, 80)
7276 self.assert_packet_checksums_valid(p)
7278 self.logger.error(ppp("Unexpected or invalid packet:", p))
7282 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7283 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7284 TCP(sport=80, dport=external_port))
7285 self.pg3.add_stream(p)
7286 self.pg_enable_capture(self.pg_interfaces)
7288 capture = self.pg3.get_capture(1)
7293 self.assertEqual(ip.src, remote_host_ip6)
7294 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7295 self.assertEqual(tcp.sport, 80)
7296 self.assertEqual(tcp.dport, 12345)
7297 self.assert_packet_checksums_valid(p)
7299 self.logger.error(ppp("Unexpected or invalid packet:", p))
7302 def test_frag_in_order(self):
7303 """ NAT64 translate fragments arriving in order """
7304 self.tcp_port_in = random.randint(1025, 65535)
7306 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7308 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7309 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7311 reass = self.vapi.nat_reass_dump()
7312 reass_n_start = len(reass)
7316 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7317 self.tcp_port_in, 20, data)
7318 self.pg0.add_stream(pkts)
7319 self.pg_enable_capture(self.pg_interfaces)
7321 frags = self.pg1.get_capture(len(pkts))
7322 p = self.reass_frags_and_verify(frags,
7324 self.pg1.remote_ip4)
7325 self.assertEqual(p[TCP].dport, 20)
7326 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7327 self.tcp_port_out = p[TCP].sport
7328 self.assertEqual(data, p[Raw].load)
7331 data = "A" * 4 + "b" * 16 + "C" * 3
7332 pkts = self.create_stream_frag(self.pg1,
7337 self.pg1.add_stream(pkts)
7338 self.pg_enable_capture(self.pg_interfaces)
7340 frags = self.pg0.get_capture(len(pkts))
7341 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7342 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7343 self.assertEqual(p[TCP].sport, 20)
7344 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7345 self.assertEqual(data, p[Raw].load)
7347 reass = self.vapi.nat_reass_dump()
7348 reass_n_end = len(reass)
7350 self.assertEqual(reass_n_end - reass_n_start, 2)
7352 def test_reass_hairpinning(self):
7353 """ NAT64 fragments hairpinning """
7355 server = self.pg0.remote_hosts[1]
7356 server_in_port = random.randint(1025, 65535)
7357 server_out_port = random.randint(1025, 65535)
7358 client_in_port = random.randint(1025, 65535)
7359 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7360 nat_addr_ip6 = ip.src
7362 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7364 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7365 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7367 # add static BIB entry for server
7368 self.vapi.nat64_add_del_static_bib(server.ip6n,
7374 # send packet from host to server
7375 pkts = self.create_stream_frag_ip6(self.pg0,
7380 self.pg0.add_stream(pkts)
7381 self.pg_enable_capture(self.pg_interfaces)
7383 frags = self.pg0.get_capture(len(pkts))
7384 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7385 self.assertNotEqual(p[TCP].sport, client_in_port)
7386 self.assertEqual(p[TCP].dport, server_in_port)
7387 self.assertEqual(data, p[Raw].load)
7389 def test_frag_out_of_order(self):
7390 """ NAT64 translate fragments arriving out of order """
7391 self.tcp_port_in = random.randint(1025, 65535)
7393 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7395 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7396 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7400 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7401 self.tcp_port_in, 20, data)
7403 self.pg0.add_stream(pkts)
7404 self.pg_enable_capture(self.pg_interfaces)
7406 frags = self.pg1.get_capture(len(pkts))
7407 p = self.reass_frags_and_verify(frags,
7409 self.pg1.remote_ip4)
7410 self.assertEqual(p[TCP].dport, 20)
7411 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7412 self.tcp_port_out = p[TCP].sport
7413 self.assertEqual(data, p[Raw].load)
7416 data = "A" * 4 + "B" * 16 + "C" * 3
7417 pkts = self.create_stream_frag(self.pg1,
7423 self.pg1.add_stream(pkts)
7424 self.pg_enable_capture(self.pg_interfaces)
7426 frags = self.pg0.get_capture(len(pkts))
7427 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7428 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7429 self.assertEqual(p[TCP].sport, 20)
7430 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7431 self.assertEqual(data, p[Raw].load)
7433 def test_interface_addr(self):
7434 """ Acquire NAT64 pool addresses from interface """
7435 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7437 # no address in NAT64 pool
7438 adresses = self.vapi.nat44_address_dump()
7439 self.assertEqual(0, len(adresses))
7441 # configure interface address and check NAT64 address pool
7442 self.pg4.config_ip4()
7443 addresses = self.vapi.nat64_pool_addr_dump()
7444 self.assertEqual(len(addresses), 1)
7445 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7447 # remove interface address and check NAT64 address pool
7448 self.pg4.unconfig_ip4()
7449 addresses = self.vapi.nat64_pool_addr_dump()
7450 self.assertEqual(0, len(adresses))
7452 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7453 def test_ipfix_max_bibs_sessions(self):
7454 """ IPFIX logging maximum session and BIB entries exceeded """
7457 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7461 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7463 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7464 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7468 for i in range(0, max_bibs):
7469 src = "fd01:aa::%x" % (i)
7470 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7471 IPv6(src=src, dst=remote_host_ip6) /
7472 TCP(sport=12345, dport=80))
7474 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7475 IPv6(src=src, dst=remote_host_ip6) /
7476 TCP(sport=12345, dport=22))
7478 self.pg0.add_stream(pkts)
7479 self.pg_enable_capture(self.pg_interfaces)
7481 self.pg1.get_capture(max_sessions)
7483 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7484 src_address=self.pg3.local_ip4n,
7486 template_interval=10)
7487 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7488 src_port=self.ipfix_src_port)
7490 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7491 IPv6(src=src, dst=remote_host_ip6) /
7492 TCP(sport=12345, dport=25))
7493 self.pg0.add_stream(p)
7494 self.pg_enable_capture(self.pg_interfaces)
7496 self.pg1.assert_nothing_captured()
7498 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7499 capture = self.pg3.get_capture(9)
7500 ipfix = IPFIXDecoder()
7501 # first load template
7503 self.assertTrue(p.haslayer(IPFIX))
7504 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7505 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7506 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7507 self.assertEqual(p[UDP].dport, 4739)
7508 self.assertEqual(p[IPFIX].observationDomainID,
7509 self.ipfix_domain_id)
7510 if p.haslayer(Template):
7511 ipfix.add_template(p.getlayer(Template))
7512 # verify events in data set
7514 if p.haslayer(Data):
7515 data = ipfix.decode_data_set(p.getlayer(Set))
7516 self.verify_ipfix_max_sessions(data, max_sessions)
7518 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7519 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7520 TCP(sport=12345, dport=80))
7521 self.pg0.add_stream(p)
7522 self.pg_enable_capture(self.pg_interfaces)
7524 self.pg1.assert_nothing_captured()
7526 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7527 capture = self.pg3.get_capture(1)
7528 # verify events in data set
7530 self.assertTrue(p.haslayer(IPFIX))
7531 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7532 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7533 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7534 self.assertEqual(p[UDP].dport, 4739)
7535 self.assertEqual(p[IPFIX].observationDomainID,
7536 self.ipfix_domain_id)
7537 if p.haslayer(Data):
7538 data = ipfix.decode_data_set(p.getlayer(Set))
7539 self.verify_ipfix_max_bibs(data, max_bibs)
7541 def test_ipfix_max_frags(self):
7542 """ IPFIX logging maximum fragments pending reassembly exceeded """
7543 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7545 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7546 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7547 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7548 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7549 src_address=self.pg3.local_ip4n,
7551 template_interval=10)
7552 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7553 src_port=self.ipfix_src_port)
7556 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7557 self.tcp_port_in, 20, data)
7559 self.pg0.add_stream(pkts)
7560 self.pg_enable_capture(self.pg_interfaces)
7562 self.pg1.assert_nothing_captured()
7564 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7565 capture = self.pg3.get_capture(9)
7566 ipfix = IPFIXDecoder()
7567 # first load template
7569 self.assertTrue(p.haslayer(IPFIX))
7570 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7571 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7572 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7573 self.assertEqual(p[UDP].dport, 4739)
7574 self.assertEqual(p[IPFIX].observationDomainID,
7575 self.ipfix_domain_id)
7576 if p.haslayer(Template):
7577 ipfix.add_template(p.getlayer(Template))
7578 # verify events in data set
7580 if p.haslayer(Data):
7581 data = ipfix.decode_data_set(p.getlayer(Set))
7582 self.verify_ipfix_max_fragments_ip6(data, 1,
7583 self.pg0.remote_ip6n)
7585 def test_ipfix_bib_ses(self):
7586 """ IPFIX logging NAT64 BIB/session create and delete events """
7587 self.tcp_port_in = random.randint(1025, 65535)
7588 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7592 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7594 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7595 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7596 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7597 src_address=self.pg3.local_ip4n,
7599 template_interval=10)
7600 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7601 src_port=self.ipfix_src_port)
7604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7605 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7606 TCP(sport=self.tcp_port_in, dport=25))
7607 self.pg0.add_stream(p)
7608 self.pg_enable_capture(self.pg_interfaces)
7610 p = self.pg1.get_capture(1)
7611 self.tcp_port_out = p[0][TCP].sport
7612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7613 capture = self.pg3.get_capture(10)
7614 ipfix = IPFIXDecoder()
7615 # first load template
7617 self.assertTrue(p.haslayer(IPFIX))
7618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7621 self.assertEqual(p[UDP].dport, 4739)
7622 self.assertEqual(p[IPFIX].observationDomainID,
7623 self.ipfix_domain_id)
7624 if p.haslayer(Template):
7625 ipfix.add_template(p.getlayer(Template))
7626 # verify events in data set
7628 if p.haslayer(Data):
7629 data = ipfix.decode_data_set(p.getlayer(Set))
7630 if ord(data[0][230]) == 10:
7631 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7632 elif ord(data[0][230]) == 6:
7633 self.verify_ipfix_nat64_ses(data,
7635 self.pg0.remote_ip6n,
7636 self.pg1.remote_ip4,
7639 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7642 self.pg_enable_capture(self.pg_interfaces)
7643 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7646 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7647 capture = self.pg3.get_capture(2)
7648 # verify events in data set
7650 self.assertTrue(p.haslayer(IPFIX))
7651 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7652 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7653 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7654 self.assertEqual(p[UDP].dport, 4739)
7655 self.assertEqual(p[IPFIX].observationDomainID,
7656 self.ipfix_domain_id)
7657 if p.haslayer(Data):
7658 data = ipfix.decode_data_set(p.getlayer(Set))
7659 if ord(data[0][230]) == 11:
7660 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7661 elif ord(data[0][230]) == 7:
7662 self.verify_ipfix_nat64_ses(data,
7664 self.pg0.remote_ip6n,
7665 self.pg1.remote_ip4,
7668 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7670 def nat64_get_ses_num(self):
7672 Return number of active NAT64 sessions.
7674 st = self.vapi.nat64_st_dump()
7677 def clear_nat64(self):
7679 Clear NAT64 configuration.
7681 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7682 domain_id=self.ipfix_domain_id)
7683 self.ipfix_src_port = 4739
7684 self.ipfix_domain_id = 1
7686 self.vapi.nat_set_timeouts()
7688 interfaces = self.vapi.nat64_interface_dump()
7689 for intf in interfaces:
7690 if intf.is_inside > 1:
7691 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7694 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7698 bib = self.vapi.nat64_bib_dump(255)
7701 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7709 adresses = self.vapi.nat64_pool_addr_dump()
7710 for addr in adresses:
7711 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7716 prefixes = self.vapi.nat64_prefix_dump()
7717 for prefix in prefixes:
7718 self.vapi.nat64_add_del_prefix(prefix.prefix,
7720 vrf_id=prefix.vrf_id,
7724 super(TestNAT64, self).tearDown()
7725 if not self.vpp_dead:
7726 self.logger.info(self.vapi.cli("show nat64 pool"))
7727 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7728 self.logger.info(self.vapi.cli("show nat64 prefix"))
7729 self.logger.info(self.vapi.cli("show nat64 bib all"))
7730 self.logger.info(self.vapi.cli("show nat64 session table all"))
7731 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7735 class TestDSlite(MethodHolder):
7736 """ DS-Lite Test Cases """
7739 def setUpClass(cls):
7740 super(TestDSlite, cls).setUpClass()
7743 cls.nat_addr = '10.0.0.3'
7744 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7746 cls.create_pg_interfaces(range(2))
7748 cls.pg0.config_ip4()
7749 cls.pg0.resolve_arp()
7751 cls.pg1.config_ip6()
7752 cls.pg1.generate_remote_hosts(2)
7753 cls.pg1.configure_ipv6_neighbors()
7756 super(TestDSlite, cls).tearDownClass()
7759 def test_dslite(self):
7760 """ Test DS-Lite """
7761 nat_config = self.vapi.nat_show_config()
7762 self.assertEqual(0, nat_config.dslite_ce)
7764 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7766 aftr_ip4 = '192.0.0.1'
7767 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7768 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7769 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7770 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7773 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7774 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7775 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7776 UDP(sport=20000, dport=10000))
7777 self.pg1.add_stream(p)
7778 self.pg_enable_capture(self.pg_interfaces)
7780 capture = self.pg0.get_capture(1)
7781 capture = capture[0]
7782 self.assertFalse(capture.haslayer(IPv6))
7783 self.assertEqual(capture[IP].src, self.nat_addr)
7784 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7785 self.assertNotEqual(capture[UDP].sport, 20000)
7786 self.assertEqual(capture[UDP].dport, 10000)
7787 self.assert_packet_checksums_valid(capture)
7788 out_port = capture[UDP].sport
7790 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7791 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7792 UDP(sport=10000, dport=out_port))
7793 self.pg0.add_stream(p)
7794 self.pg_enable_capture(self.pg_interfaces)
7796 capture = self.pg1.get_capture(1)
7797 capture = capture[0]
7798 self.assertEqual(capture[IPv6].src, aftr_ip6)
7799 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7800 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7801 self.assertEqual(capture[IP].dst, '192.168.1.1')
7802 self.assertEqual(capture[UDP].sport, 10000)
7803 self.assertEqual(capture[UDP].dport, 20000)
7804 self.assert_packet_checksums_valid(capture)
7807 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7808 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7809 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7810 TCP(sport=20001, dport=10001))
7811 self.pg1.add_stream(p)
7812 self.pg_enable_capture(self.pg_interfaces)
7814 capture = self.pg0.get_capture(1)
7815 capture = capture[0]
7816 self.assertFalse(capture.haslayer(IPv6))
7817 self.assertEqual(capture[IP].src, self.nat_addr)
7818 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7819 self.assertNotEqual(capture[TCP].sport, 20001)
7820 self.assertEqual(capture[TCP].dport, 10001)
7821 self.assert_packet_checksums_valid(capture)
7822 out_port = capture[TCP].sport
7824 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7825 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7826 TCP(sport=10001, dport=out_port))
7827 self.pg0.add_stream(p)
7828 self.pg_enable_capture(self.pg_interfaces)
7830 capture = self.pg1.get_capture(1)
7831 capture = capture[0]
7832 self.assertEqual(capture[IPv6].src, aftr_ip6)
7833 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7834 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7835 self.assertEqual(capture[IP].dst, '192.168.1.1')
7836 self.assertEqual(capture[TCP].sport, 10001)
7837 self.assertEqual(capture[TCP].dport, 20001)
7838 self.assert_packet_checksums_valid(capture)
7841 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7842 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7843 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7844 ICMP(id=4000, type='echo-request'))
7845 self.pg1.add_stream(p)
7846 self.pg_enable_capture(self.pg_interfaces)
7848 capture = self.pg0.get_capture(1)
7849 capture = capture[0]
7850 self.assertFalse(capture.haslayer(IPv6))
7851 self.assertEqual(capture[IP].src, self.nat_addr)
7852 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7853 self.assertNotEqual(capture[ICMP].id, 4000)
7854 self.assert_packet_checksums_valid(capture)
7855 out_id = capture[ICMP].id
7857 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7858 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7859 ICMP(id=out_id, type='echo-reply'))
7860 self.pg0.add_stream(p)
7861 self.pg_enable_capture(self.pg_interfaces)
7863 capture = self.pg1.get_capture(1)
7864 capture = capture[0]
7865 self.assertEqual(capture[IPv6].src, aftr_ip6)
7866 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7867 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7868 self.assertEqual(capture[IP].dst, '192.168.1.1')
7869 self.assertEqual(capture[ICMP].id, 4000)
7870 self.assert_packet_checksums_valid(capture)
7872 # ping DS-Lite AFTR tunnel endpoint address
7873 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7874 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7875 ICMPv6EchoRequest())
7876 self.pg1.add_stream(p)
7877 self.pg_enable_capture(self.pg_interfaces)
7879 capture = self.pg1.get_capture(1)
7880 capture = capture[0]
7881 self.assertEqual(capture[IPv6].src, aftr_ip6)
7882 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7883 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7886 super(TestDSlite, self).tearDown()
7887 if not self.vpp_dead:
7888 self.logger.info(self.vapi.cli("show dslite pool"))
7890 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7891 self.logger.info(self.vapi.cli("show dslite sessions"))
7894 class TestDSliteCE(MethodHolder):
7895 """ DS-Lite CE Test Cases """
7898 def setUpConstants(cls):
7899 super(TestDSliteCE, cls).setUpConstants()
7900 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7903 def setUpClass(cls):
7904 super(TestDSliteCE, cls).setUpClass()
7907 cls.create_pg_interfaces(range(2))
7909 cls.pg0.config_ip4()
7910 cls.pg0.resolve_arp()
7912 cls.pg1.config_ip6()
7913 cls.pg1.generate_remote_hosts(1)
7914 cls.pg1.configure_ipv6_neighbors()
7917 super(TestDSliteCE, cls).tearDownClass()
7920 def test_dslite_ce(self):
7921 """ Test DS-Lite CE """
7923 nat_config = self.vapi.nat_show_config()
7924 self.assertEqual(1, nat_config.dslite_ce)
7926 b4_ip4 = '192.0.0.2'
7927 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7928 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7929 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7930 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7932 aftr_ip4 = '192.0.0.1'
7933 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7934 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7935 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7936 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7938 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7939 dst_address_length=128,
7940 next_hop_address=self.pg1.remote_ip6n,
7941 next_hop_sw_if_index=self.pg1.sw_if_index,
7945 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7946 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7947 UDP(sport=10000, dport=20000))
7948 self.pg0.add_stream(p)
7949 self.pg_enable_capture(self.pg_interfaces)
7951 capture = self.pg1.get_capture(1)
7952 capture = capture[0]
7953 self.assertEqual(capture[IPv6].src, b4_ip6)
7954 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7955 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7956 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7957 self.assertEqual(capture[UDP].sport, 10000)
7958 self.assertEqual(capture[UDP].dport, 20000)
7959 self.assert_packet_checksums_valid(capture)
7962 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7963 IPv6(dst=b4_ip6, src=aftr_ip6) /
7964 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7965 UDP(sport=20000, dport=10000))
7966 self.pg1.add_stream(p)
7967 self.pg_enable_capture(self.pg_interfaces)
7969 capture = self.pg0.get_capture(1)
7970 capture = capture[0]
7971 self.assertFalse(capture.haslayer(IPv6))
7972 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7973 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7974 self.assertEqual(capture[UDP].sport, 20000)
7975 self.assertEqual(capture[UDP].dport, 10000)
7976 self.assert_packet_checksums_valid(capture)
7978 # ping DS-Lite B4 tunnel endpoint address
7979 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7980 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7981 ICMPv6EchoRequest())
7982 self.pg1.add_stream(p)
7983 self.pg_enable_capture(self.pg_interfaces)
7985 capture = self.pg1.get_capture(1)
7986 capture = capture[0]
7987 self.assertEqual(capture[IPv6].src, b4_ip6)
7988 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7989 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7992 super(TestDSliteCE, self).tearDown()
7993 if not self.vpp_dead:
7995 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7997 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8000 class TestNAT66(MethodHolder):
8001 """ NAT66 Test Cases """
8004 def setUpClass(cls):
8005 super(TestNAT66, cls).setUpClass()
8008 cls.nat_addr = 'fd01:ff::2'
8009 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8011 cls.create_pg_interfaces(range(2))
8012 cls.interfaces = list(cls.pg_interfaces)
8014 for i in cls.interfaces:
8017 i.configure_ipv6_neighbors()
8020 super(TestNAT66, cls).tearDownClass()
8023 def test_static(self):
8024 """ 1:1 NAT66 test """
8025 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8026 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8027 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8032 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8033 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8036 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8037 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8040 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8041 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8042 ICMPv6EchoRequest())
8044 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8045 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8046 GRE() / IP() / TCP())
8048 self.pg0.add_stream(pkts)
8049 self.pg_enable_capture(self.pg_interfaces)
8051 capture = self.pg1.get_capture(len(pkts))
8052 for packet in capture:
8054 self.assertEqual(packet[IPv6].src, self.nat_addr)
8055 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8056 self.assert_packet_checksums_valid(packet)
8058 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8063 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8064 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8067 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8068 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8071 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8072 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8075 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8076 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8077 GRE() / IP() / TCP())
8079 self.pg1.add_stream(pkts)
8080 self.pg_enable_capture(self.pg_interfaces)
8082 capture = self.pg0.get_capture(len(pkts))
8083 for packet in capture:
8085 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8086 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8087 self.assert_packet_checksums_valid(packet)
8089 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8092 sm = self.vapi.nat66_static_mapping_dump()
8093 self.assertEqual(len(sm), 1)
8094 self.assertEqual(sm[0].total_pkts, 8)
8096 def test_check_no_translate(self):
8097 """ NAT66 translate only when egress interface is outside interface """
8098 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8099 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8100 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8104 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8105 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8107 self.pg0.add_stream([p])
8108 self.pg_enable_capture(self.pg_interfaces)
8110 capture = self.pg1.get_capture(1)
8113 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8114 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8116 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8119 def clear_nat66(self):
8121 Clear NAT66 configuration.
8123 interfaces = self.vapi.nat66_interface_dump()
8124 for intf in interfaces:
8125 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8129 static_mappings = self.vapi.nat66_static_mapping_dump()
8130 for sm in static_mappings:
8131 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8132 sm.external_ip_address,
8137 super(TestNAT66, self).tearDown()
8138 if not self.vpp_dead:
8139 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8140 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8144 if __name__ == '__main__':
8145 unittest.main(testRunner=VppTestRunner)