9 from framework import VppTestCase, VppTestRunner, running_extended_tests
10 from scapy.layers.inet import IP, TCP, UDP, ICMP
11 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
12 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
13 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr
14 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
15 from scapy.layers.l2 import Ether, ARP, GRE
16 from scapy.data import IP_PROTOS
17 from scapy.packet import bind_layers, Raw
18 from scapy.all import fragment6
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from util import mactobinary
26 class MethodHolder(VppTestCase):
27 """ NAT create capture and verify method holder """
29 def clear_nat44(self):
31 Clear NAT44 configuration.
33 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
34 # I found no elegant way to do this
35 self.vapi.ip_add_del_route(
36 dst_address=self.pg7.remote_ip4n,
37 dst_address_length=32,
38 next_hop_address=self.pg7.remote_ip4n,
39 next_hop_sw_if_index=self.pg7.sw_if_index,
41 self.vapi.ip_add_del_route(
42 dst_address=self.pg8.remote_ip4n,
43 dst_address_length=32,
44 next_hop_address=self.pg8.remote_ip4n,
45 next_hop_sw_if_index=self.pg8.sw_if_index,
48 for intf in [self.pg7, self.pg8]:
49 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
51 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
56 if self.pg7.has_ip4_config:
57 self.pg7.unconfig_ip4()
59 self.vapi.nat44_forwarding_enable_disable(0)
61 interfaces = self.vapi.nat44_interface_addr_dump()
62 for intf in interfaces:
63 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
64 twice_nat=intf.twice_nat,
67 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
68 domain_id=self.ipfix_domain_id)
69 self.ipfix_src_port = 4739
70 self.ipfix_domain_id = 1
72 interfaces = self.vapi.nat44_interface_dump()
73 for intf in interfaces:
74 if intf.is_inside > 1:
75 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
78 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
82 interfaces = self.vapi.nat44_interface_output_feature_dump()
83 for intf in interfaces:
84 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
88 static_mappings = self.vapi.nat44_static_mapping_dump()
89 for sm in static_mappings:
90 self.vapi.nat44_add_del_static_mapping(
92 sm.external_ip_address,
93 local_port=sm.local_port,
94 external_port=sm.external_port,
95 addr_only=sm.addr_only,
98 twice_nat=sm.twice_nat,
99 self_twice_nat=sm.self_twice_nat,
100 out2in_only=sm.out2in_only,
102 external_sw_if_index=sm.external_sw_if_index,
105 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
106 for lb_sm in lb_static_mappings:
107 self.vapi.nat44_add_del_lb_static_mapping(
111 twice_nat=lb_sm.twice_nat,
112 self_twice_nat=lb_sm.self_twice_nat,
113 out2in_only=lb_sm.out2in_only,
119 identity_mappings = self.vapi.nat44_identity_mapping_dump()
120 for id_m in identity_mappings:
121 self.vapi.nat44_add_del_identity_mapping(
122 addr_only=id_m.addr_only,
125 sw_if_index=id_m.sw_if_index,
127 protocol=id_m.protocol,
130 adresses = self.vapi.nat44_address_dump()
131 for addr in adresses:
132 self.vapi.nat44_add_del_address_range(addr.ip_address,
134 twice_nat=addr.twice_nat,
137 self.vapi.nat_set_reass()
138 self.vapi.nat_set_reass(is_ip6=1)
139 self.verify_no_nat44_user()
140 self.vapi.nat_set_timeouts()
141 self.vapi.nat_set_addr_and_port_alloc_alg()
142 self.vapi.nat_set_mss_clamping()
144 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
145 local_port=0, external_port=0, vrf_id=0,
146 is_add=1, external_sw_if_index=0xFFFFFFFF,
147 proto=0, twice_nat=0, self_twice_nat=0,
148 out2in_only=0, tag=""):
150 Add/delete NAT44 static mapping
152 :param local_ip: Local IP address
153 :param external_ip: External IP address
154 :param local_port: Local port number (Optional)
155 :param external_port: External port number (Optional)
156 :param vrf_id: VRF ID (Default 0)
157 :param is_add: 1 if add, 0 if delete (Default add)
158 :param external_sw_if_index: External interface instead of IP address
159 :param proto: IP protocol (Mandatory if port specified)
160 :param twice_nat: 1 if translate external host address and port
161 :param self_twice_nat: 1 if translate external host address and port
162 whenever external host address equals
163 local address of internal host
164 :param out2in_only: if 1 rule is matching only out2in direction
165 :param tag: Opaque string tag
168 if local_port and external_port:
170 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
171 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
172 self.vapi.nat44_add_del_static_mapping(
175 external_sw_if_index,
187 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
189 Add/delete NAT44 address
191 :param ip: IP address
192 :param is_add: 1 if add, 0 if delete (Default add)
193 :param twice_nat: twice NAT address for extenal hosts
195 nat_addr = socket.inet_pton(socket.AF_INET, ip)
196 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
200 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
202 Create packet stream for inside network
204 :param in_if: Inside interface
205 :param out_if: Outside interface
206 :param dst_ip: Destination address
207 :param ttl: TTL of generated packets
210 dst_ip = out_if.remote_ip4
214 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
215 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
216 TCP(sport=self.tcp_port_in, dport=20))
220 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
221 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
222 UDP(sport=self.udp_port_in, dport=20))
226 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
227 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
228 ICMP(id=self.icmp_id_in, type='echo-request'))
233 def compose_ip6(self, ip4, pref, plen):
235 Compose IPv4-embedded IPv6 addresses
237 :param ip4: IPv4 address
238 :param pref: IPv6 prefix
239 :param plen: IPv6 prefix length
240 :returns: IPv4-embedded IPv6 addresses
242 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
243 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
258 pref_n[10] = ip4_n[3]
262 pref_n[10] = ip4_n[2]
263 pref_n[11] = ip4_n[3]
266 pref_n[10] = ip4_n[1]
267 pref_n[11] = ip4_n[2]
268 pref_n[12] = ip4_n[3]
270 pref_n[12] = ip4_n[0]
271 pref_n[13] = ip4_n[1]
272 pref_n[14] = ip4_n[2]
273 pref_n[15] = ip4_n[3]
274 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
276 def extract_ip4(self, ip6, plen):
278 Extract IPv4 address embedded in IPv6 addresses
280 :param ip6: IPv6 address
281 :param plen: IPv6 prefix length
282 :returns: extracted IPv4 address
284 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
316 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
318 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
320 Create IPv6 packet stream for inside network
322 :param in_if: Inside interface
323 :param out_if: Outside interface
324 :param ttl: Hop Limit of generated packets
325 :param pref: NAT64 prefix
326 :param plen: NAT64 prefix length
330 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
332 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
335 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
336 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
337 TCP(sport=self.tcp_port_in, dport=20))
341 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
342 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
343 UDP(sport=self.udp_port_in, dport=20))
347 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
348 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
349 ICMPv6EchoRequest(id=self.icmp_id_in))
354 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
355 use_inside_ports=False):
357 Create packet stream for outside network
359 :param out_if: Outside interface
360 :param dst_ip: Destination IP address (Default use global NAT address)
361 :param ttl: TTL of generated packets
362 :param use_inside_ports: Use inside NAT ports as destination ports
363 instead of outside ports
366 dst_ip = self.nat_addr
367 if not use_inside_ports:
368 tcp_port = self.tcp_port_out
369 udp_port = self.udp_port_out
370 icmp_id = self.icmp_id_out
372 tcp_port = self.tcp_port_in
373 udp_port = self.udp_port_in
374 icmp_id = self.icmp_id_in
377 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
378 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
379 TCP(dport=tcp_port, sport=20))
383 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
384 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
385 UDP(dport=udp_port, sport=20))
389 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
390 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
391 ICMP(id=icmp_id, type='echo-reply'))
396 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
398 Create packet stream for outside network
400 :param out_if: Outside interface
401 :param dst_ip: Destination IP address (Default use global NAT address)
402 :param hl: HL of generated packets
406 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
407 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
408 TCP(dport=self.tcp_port_out, sport=20))
412 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
413 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
414 UDP(dport=self.udp_port_out, sport=20))
418 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
419 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
420 ICMPv6EchoReply(id=self.icmp_id_out))
425 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
426 dst_ip=None, is_ip6=False):
428 Verify captured packets on outside network
430 :param capture: Captured packets
431 :param nat_ip: Translated IP address (Default use global NAT address)
432 :param same_port: Sorce port number is not translated (Default False)
433 :param dst_ip: Destination IP address (Default do not verify)
434 :param is_ip6: If L3 protocol is IPv6 (Default False)
438 ICMP46 = ICMPv6EchoRequest
443 nat_ip = self.nat_addr
444 for packet in capture:
447 self.assert_packet_checksums_valid(packet)
448 self.assertEqual(packet[IP46].src, nat_ip)
449 if dst_ip is not None:
450 self.assertEqual(packet[IP46].dst, dst_ip)
451 if packet.haslayer(TCP):
453 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
456 packet[TCP].sport, self.tcp_port_in)
457 self.tcp_port_out = packet[TCP].sport
458 self.assert_packet_checksums_valid(packet)
459 elif packet.haslayer(UDP):
461 self.assertEqual(packet[UDP].sport, self.udp_port_in)
464 packet[UDP].sport, self.udp_port_in)
465 self.udp_port_out = packet[UDP].sport
468 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
470 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
471 self.icmp_id_out = packet[ICMP46].id
472 self.assert_packet_checksums_valid(packet)
474 self.logger.error(ppp("Unexpected or invalid packet "
475 "(outside network):", packet))
478 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
481 Verify captured packets on outside network
483 :param capture: Captured packets
484 :param nat_ip: Translated IP address
485 :param same_port: Sorce port number is not translated (Default False)
486 :param dst_ip: Destination IP address (Default do not verify)
488 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
491 def verify_capture_in(self, capture, in_if):
493 Verify captured packets on inside network
495 :param capture: Captured packets
496 :param in_if: Inside interface
498 for packet in capture:
500 self.assert_packet_checksums_valid(packet)
501 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
502 if packet.haslayer(TCP):
503 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
504 elif packet.haslayer(UDP):
505 self.assertEqual(packet[UDP].dport, self.udp_port_in)
507 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
509 self.logger.error(ppp("Unexpected or invalid packet "
510 "(inside network):", packet))
513 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
515 Verify captured IPv6 packets on inside network
517 :param capture: Captured packets
518 :param src_ip: Source IP
519 :param dst_ip: Destination IP address
521 for packet in capture:
523 self.assertEqual(packet[IPv6].src, src_ip)
524 self.assertEqual(packet[IPv6].dst, dst_ip)
525 self.assert_packet_checksums_valid(packet)
526 if packet.haslayer(TCP):
527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
528 elif packet.haslayer(UDP):
529 self.assertEqual(packet[UDP].dport, self.udp_port_in)
531 self.assertEqual(packet[ICMPv6EchoReply].id,
534 self.logger.error(ppp("Unexpected or invalid packet "
535 "(inside network):", packet))
538 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
540 Verify captured packet that don't have to be translated
542 :param capture: Captured packets
543 :param ingress_if: Ingress interface
544 :param egress_if: Egress interface
546 for packet in capture:
548 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
549 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
550 if packet.haslayer(TCP):
551 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
552 elif packet.haslayer(UDP):
553 self.assertEqual(packet[UDP].sport, self.udp_port_in)
555 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
557 self.logger.error(ppp("Unexpected or invalid packet "
558 "(inside network):", packet))
561 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
564 Verify captured packets with ICMP errors on outside network
566 :param capture: Captured packets
567 :param src_ip: Translated IP address or IP address of VPP
568 (Default use global NAT address)
569 :param icmp_type: Type of error ICMP packet
570 we are expecting (Default 11)
573 src_ip = self.nat_addr
574 for packet in capture:
576 self.assertEqual(packet[IP].src, src_ip)
577 self.assertTrue(packet.haslayer(ICMP))
579 self.assertEqual(icmp.type, icmp_type)
580 self.assertTrue(icmp.haslayer(IPerror))
581 inner_ip = icmp[IPerror]
582 if inner_ip.haslayer(TCPerror):
583 self.assertEqual(inner_ip[TCPerror].dport,
585 elif inner_ip.haslayer(UDPerror):
586 self.assertEqual(inner_ip[UDPerror].dport,
589 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
591 self.logger.error(ppp("Unexpected or invalid packet "
592 "(outside network):", packet))
595 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
597 Verify captured packets with ICMP errors on inside network
599 :param capture: Captured packets
600 :param in_if: Inside interface
601 :param icmp_type: Type of error ICMP packet
602 we are expecting (Default 11)
604 for packet in capture:
606 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
607 self.assertTrue(packet.haslayer(ICMP))
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].sport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].sport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(inside network):", packet))
625 def create_stream_frag(self, src_if, dst, sport, dport, data,
626 proto=IP_PROTOS.tcp, echo_reply=False):
628 Create fragmented packet stream
630 :param src_if: Source interface
631 :param dst: Destination IPv4 address
632 :param sport: Source port
633 :param dport: Destination port
634 :param data: Payload data
635 :param proto: protocol (TCP, UDP, ICMP)
636 :param echo_reply: use echo_reply if protocol is ICMP
639 if proto == IP_PROTOS.tcp:
640 p = (IP(src=src_if.remote_ip4, dst=dst) /
641 TCP(sport=sport, dport=dport) /
643 p = p.__class__(str(p))
644 chksum = p['TCP'].chksum
645 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
646 elif proto == IP_PROTOS.udp:
647 proto_header = UDP(sport=sport, dport=dport)
648 elif proto == IP_PROTOS.icmp:
650 proto_header = ICMP(id=sport, type='echo-request')
652 proto_header = ICMP(id=sport, type='echo-reply')
654 raise Exception("Unsupported protocol")
655 id = random.randint(0, 65535)
657 if proto == IP_PROTOS.tcp:
660 raw = Raw(data[0:16])
661 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
662 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
666 if proto == IP_PROTOS.tcp:
667 raw = Raw(data[4:20])
669 raw = Raw(data[16:32])
670 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
671 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
675 if proto == IP_PROTOS.tcp:
679 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
680 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
686 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
687 pref=None, plen=0, frag_size=128):
689 Create fragmented packet stream
691 :param src_if: Source interface
692 :param dst: Destination IPv4 address
693 :param sport: Source TCP port
694 :param dport: Destination TCP port
695 :param data: Payload data
696 :param pref: NAT64 prefix
697 :param plen: NAT64 prefix length
698 :param fragsize: size of fragments
702 dst_ip6 = ''.join(['64:ff9b::', dst])
704 dst_ip6 = self.compose_ip6(dst, pref, plen)
706 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
707 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
708 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
709 TCP(sport=sport, dport=dport) /
712 return fragment6(p, frag_size)
714 def reass_frags_and_verify(self, frags, src, dst):
716 Reassemble and verify fragmented packet
718 :param frags: Captured fragments
719 :param src: Source IPv4 address to verify
720 :param dst: Destination IPv4 address to verify
722 :returns: Reassembled IPv4 packet
724 buffer = StringIO.StringIO()
726 self.assertEqual(p[IP].src, src)
727 self.assertEqual(p[IP].dst, dst)
728 self.assert_ip_checksum_valid(p)
729 buffer.seek(p[IP].frag * 8)
730 buffer.write(p[IP].payload)
731 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
732 proto=frags[0][IP].proto)
733 if ip.proto == IP_PROTOS.tcp:
734 p = (ip / TCP(buffer.getvalue()))
735 self.assert_tcp_checksum_valid(p)
736 elif ip.proto == IP_PROTOS.udp:
737 p = (ip / UDP(buffer.getvalue()[:8]) /
738 Raw(buffer.getvalue()[8:]))
739 elif ip.proto == IP_PROTOS.icmp:
740 p = (ip / ICMP(buffer.getvalue()))
743 def reass_frags_and_verify_ip6(self, frags, src, dst):
745 Reassemble and verify fragmented packet
747 :param frags: Captured fragments
748 :param src: Source IPv6 address to verify
749 :param dst: Destination IPv6 address to verify
751 :returns: Reassembled IPv6 packet
753 buffer = StringIO.StringIO()
755 self.assertEqual(p[IPv6].src, src)
756 self.assertEqual(p[IPv6].dst, dst)
757 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
758 buffer.write(p[IPv6ExtHdrFragment].payload)
759 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
760 nh=frags[0][IPv6ExtHdrFragment].nh)
761 if ip.nh == IP_PROTOS.tcp:
762 p = (ip / TCP(buffer.getvalue()))
763 elif ip.nh == IP_PROTOS.udp:
764 p = (ip / UDP(buffer.getvalue()))
765 self.assert_packet_checksums_valid(p)
768 def initiate_tcp_session(self, in_if, out_if):
770 Initiates TCP session
772 :param in_if: Inside interface
773 :param out_if: Outside interface
777 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
778 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
779 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
782 self.pg_enable_capture(self.pg_interfaces)
784 capture = out_if.get_capture(1)
786 self.tcp_port_out = p[TCP].sport
788 # SYN + ACK packet out->in
789 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
790 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
791 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
794 self.pg_enable_capture(self.pg_interfaces)
799 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
800 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
801 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
804 self.pg_enable_capture(self.pg_interfaces)
806 out_if.get_capture(1)
809 self.logger.error("TCP 3 way handshake failed")
812 def verify_ipfix_nat44_ses(self, data):
814 Verify IPFIX NAT44 session create/delete event
816 :param data: Decoded IPFIX data records
818 nat44_ses_create_num = 0
819 nat44_ses_delete_num = 0
820 self.assertEqual(6, len(data))
823 self.assertIn(ord(record[230]), [4, 5])
824 if ord(record[230]) == 4:
825 nat44_ses_create_num += 1
827 nat44_ses_delete_num += 1
829 self.assertEqual(self.pg0.remote_ip4n, record[8])
830 # postNATSourceIPv4Address
831 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
834 self.assertEqual(struct.pack("!I", 0), record[234])
835 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
836 if IP_PROTOS.icmp == ord(record[4]):
837 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
838 self.assertEqual(struct.pack("!H", self.icmp_id_out),
840 elif IP_PROTOS.tcp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.tcp_port_in),
843 self.assertEqual(struct.pack("!H", self.tcp_port_out),
845 elif IP_PROTOS.udp == ord(record[4]):
846 self.assertEqual(struct.pack("!H", self.udp_port_in),
848 self.assertEqual(struct.pack("!H", self.udp_port_out),
851 self.fail("Invalid protocol")
852 self.assertEqual(3, nat44_ses_create_num)
853 self.assertEqual(3, nat44_ses_delete_num)
855 def verify_ipfix_addr_exhausted(self, data):
857 Verify IPFIX NAT addresses event
859 :param data: Decoded IPFIX data records
861 self.assertEqual(1, len(data))
864 self.assertEqual(ord(record[230]), 3)
866 self.assertEqual(struct.pack("!I", 0), record[283])
868 def verify_ipfix_max_sessions(self, data, limit):
870 Verify IPFIX maximum session entries exceeded event
872 :param data: Decoded IPFIX data records
873 :param limit: Number of maximum session entries that can be created.
875 self.assertEqual(1, len(data))
878 self.assertEqual(ord(record[230]), 13)
879 # natQuotaExceededEvent
880 self.assertEqual(struct.pack("I", 1), record[466])
882 self.assertEqual(struct.pack("I", limit), record[471])
884 def verify_ipfix_max_bibs(self, data, limit):
886 Verify IPFIX maximum BIB entries exceeded event
888 :param data: Decoded IPFIX data records
889 :param limit: Number of maximum BIB entries that can be created.
891 self.assertEqual(1, len(data))
894 self.assertEqual(ord(record[230]), 13)
895 # natQuotaExceededEvent
896 self.assertEqual(struct.pack("I", 2), record[466])
898 self.assertEqual(struct.pack("I", limit), record[472])
900 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
902 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum fragments pending reassembly
906 :param src_addr: IPv6 source address
908 self.assertEqual(1, len(data))
911 self.assertEqual(ord(record[230]), 13)
912 # natQuotaExceededEvent
913 self.assertEqual(struct.pack("I", 5), record[466])
914 # maxFragmentsPendingReassembly
915 self.assertEqual(struct.pack("I", limit), record[475])
917 self.assertEqual(src_addr, record[27])
919 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
921 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
923 :param data: Decoded IPFIX data records
924 :param limit: Number of maximum fragments pending reassembly
925 :param src_addr: IPv4 source address
927 self.assertEqual(1, len(data))
930 self.assertEqual(ord(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 5), record[466])
933 # maxFragmentsPendingReassembly
934 self.assertEqual(struct.pack("I", limit), record[475])
936 self.assertEqual(src_addr, record[8])
938 def verify_ipfix_bib(self, data, is_create, src_addr):
940 Verify IPFIX NAT64 BIB create and delete events
942 :param data: Decoded IPFIX data records
943 :param is_create: Create event if nonzero value otherwise delete event
944 :param src_addr: IPv6 source address
946 self.assertEqual(1, len(data))
950 self.assertEqual(ord(record[230]), 10)
952 self.assertEqual(ord(record[230]), 11)
954 self.assertEqual(src_addr, record[27])
955 # postNATSourceIPv4Address
956 self.assertEqual(self.nat_addr_n, record[225])
958 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
960 self.assertEqual(struct.pack("!I", 0), record[234])
961 # sourceTransportPort
962 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
963 # postNAPTSourceTransportPort
964 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
966 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
969 Verify IPFIX NAT64 session create and delete events
971 :param data: Decoded IPFIX data records
972 :param is_create: Create event if nonzero value otherwise delete event
973 :param src_addr: IPv6 source address
974 :param dst_addr: IPv4 destination address
975 :param dst_port: destination TCP port
977 self.assertEqual(1, len(data))
981 self.assertEqual(ord(record[230]), 6)
983 self.assertEqual(ord(record[230]), 7)
985 self.assertEqual(src_addr, record[27])
986 # destinationIPv6Address
987 self.assertEqual(socket.inet_pton(socket.AF_INET6,
988 self.compose_ip6(dst_addr,
992 # postNATSourceIPv4Address
993 self.assertEqual(self.nat_addr_n, record[225])
994 # postNATDestinationIPv4Address
995 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
998 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1000 self.assertEqual(struct.pack("!I", 0), record[234])
1001 # sourceTransportPort
1002 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1003 # postNAPTSourceTransportPort
1004 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1005 # destinationTransportPort
1006 self.assertEqual(struct.pack("!H", dst_port), record[11])
1007 # postNAPTDestinationTransportPort
1008 self.assertEqual(struct.pack("!H", dst_port), record[228])
1010 def verify_no_nat44_user(self):
1011 """ Verify that there is no NAT44 user """
1012 users = self.vapi.nat44_user_dump()
1013 self.assertEqual(len(users), 0)
1015 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1017 Verify IPFIX maximum entries per user exceeded event
1019 :param data: Decoded IPFIX data records
1020 :param limit: Number of maximum entries per user
1021 :param src_addr: IPv4 source address
1023 self.assertEqual(1, len(data))
1026 self.assertEqual(ord(record[230]), 13)
1027 # natQuotaExceededEvent
1028 self.assertEqual(struct.pack("I", 3), record[466])
1030 self.assertEqual(struct.pack("I", limit), record[473])
1032 self.assertEqual(src_addr, record[8])
1034 def verify_mss_value(self, pkt, mss):
1036 Verify TCP MSS value
1041 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1042 raise TypeError("Not a TCP/IP packet")
1044 for option in pkt[TCP].options:
1045 if option[0] == 'MSS':
1046 self.assertEqual(option[1], mss)
1047 self.assert_tcp_checksum_valid(pkt)
1050 def proto2layer(proto):
1051 if proto == IP_PROTOS.tcp:
1053 elif proto == IP_PROTOS.udp:
1055 elif proto == IP_PROTOS.icmp:
1058 raise Exception("Unsupported protocol")
1060 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1061 layer = self.proto2layer(proto)
1063 if proto == IP_PROTOS.tcp:
1064 data = "A" * 4 + "B" * 16 + "C" * 3
1066 data = "A" * 16 + "B" * 16 + "C" * 3
1067 self.port_in = random.randint(1025, 65535)
1069 reass = self.vapi.nat_reass_dump()
1070 reass_n_start = len(reass)
1073 pkts = self.create_stream_frag(self.pg0,
1074 self.pg1.remote_ip4,
1079 self.pg0.add_stream(pkts)
1080 self.pg_enable_capture(self.pg_interfaces)
1082 frags = self.pg1.get_capture(len(pkts))
1083 if not dont_translate:
1084 p = self.reass_frags_and_verify(frags,
1086 self.pg1.remote_ip4)
1088 p = self.reass_frags_and_verify(frags,
1089 self.pg0.remote_ip4,
1090 self.pg1.remote_ip4)
1091 if proto != IP_PROTOS.icmp:
1092 if not dont_translate:
1093 self.assertEqual(p[layer].dport, 20)
1094 self.assertNotEqual(p[layer].sport, self.port_in)
1096 self.assertEqual(p[layer].sport, self.port_in)
1098 if not dont_translate:
1099 self.assertNotEqual(p[layer].id, self.port_in)
1101 self.assertEqual(p[layer].id, self.port_in)
1102 self.assertEqual(data, p[Raw].load)
1105 if not dont_translate:
1106 dst_addr = self.nat_addr
1108 dst_addr = self.pg0.remote_ip4
1109 if proto != IP_PROTOS.icmp:
1111 dport = p[layer].sport
1115 pkts = self.create_stream_frag(self.pg1,
1122 self.pg1.add_stream(pkts)
1123 self.pg_enable_capture(self.pg_interfaces)
1125 frags = self.pg0.get_capture(len(pkts))
1126 p = self.reass_frags_and_verify(frags,
1127 self.pg1.remote_ip4,
1128 self.pg0.remote_ip4)
1129 if proto != IP_PROTOS.icmp:
1130 self.assertEqual(p[layer].sport, 20)
1131 self.assertEqual(p[layer].dport, self.port_in)
1133 self.assertEqual(p[layer].id, self.port_in)
1134 self.assertEqual(data, p[Raw].load)
1136 reass = self.vapi.nat_reass_dump()
1137 reass_n_end = len(reass)
1139 self.assertEqual(reass_n_end - reass_n_start, 2)
1141 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1142 layer = self.proto2layer(proto)
1144 if proto == IP_PROTOS.tcp:
1145 data = "A" * 4 + "B" * 16 + "C" * 3
1147 data = "A" * 16 + "B" * 16 + "C" * 3
1148 self.port_in = random.randint(1025, 65535)
1151 reass = self.vapi.nat_reass_dump()
1152 reass_n_start = len(reass)
1155 pkts = self.create_stream_frag(self.pg0,
1156 self.server_out_addr,
1158 self.server_out_port,
1161 self.pg0.add_stream(pkts)
1162 self.pg_enable_capture(self.pg_interfaces)
1164 frags = self.pg1.get_capture(len(pkts))
1165 p = self.reass_frags_and_verify(frags,
1166 self.pg0.remote_ip4,
1167 self.server_in_addr)
1168 if proto != IP_PROTOS.icmp:
1169 self.assertEqual(p[layer].sport, self.port_in)
1170 self.assertEqual(p[layer].dport, self.server_in_port)
1172 self.assertEqual(p[layer].id, self.port_in)
1173 self.assertEqual(data, p[Raw].load)
1176 if proto != IP_PROTOS.icmp:
1177 pkts = self.create_stream_frag(self.pg1,
1178 self.pg0.remote_ip4,
1179 self.server_in_port,
1184 pkts = self.create_stream_frag(self.pg1,
1185 self.pg0.remote_ip4,
1191 self.pg1.add_stream(pkts)
1192 self.pg_enable_capture(self.pg_interfaces)
1194 frags = self.pg0.get_capture(len(pkts))
1195 p = self.reass_frags_and_verify(frags,
1196 self.server_out_addr,
1197 self.pg0.remote_ip4)
1198 if proto != IP_PROTOS.icmp:
1199 self.assertEqual(p[layer].sport, self.server_out_port)
1200 self.assertEqual(p[layer].dport, self.port_in)
1202 self.assertEqual(p[layer].id, self.port_in)
1203 self.assertEqual(data, p[Raw].load)
1205 reass = self.vapi.nat_reass_dump()
1206 reass_n_end = len(reass)
1208 self.assertEqual(reass_n_end - reass_n_start, 2)
1210 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1211 layer = self.proto2layer(proto)
1213 if proto == IP_PROTOS.tcp:
1214 data = "A" * 4 + "B" * 16 + "C" * 3
1216 data = "A" * 16 + "B" * 16 + "C" * 3
1218 # send packet from host to server
1219 pkts = self.create_stream_frag(self.pg0,
1222 self.server_out_port,
1225 self.pg0.add_stream(pkts)
1226 self.pg_enable_capture(self.pg_interfaces)
1228 frags = self.pg0.get_capture(len(pkts))
1229 p = self.reass_frags_and_verify(frags,
1232 if proto != IP_PROTOS.icmp:
1233 self.assertNotEqual(p[layer].sport, self.host_in_port)
1234 self.assertEqual(p[layer].dport, self.server_in_port)
1236 self.assertNotEqual(p[layer].id, self.host_in_port)
1237 self.assertEqual(data, p[Raw].load)
1239 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1240 layer = self.proto2layer(proto)
1242 if proto == IP_PROTOS.tcp:
1243 data = "A" * 4 + "B" * 16 + "C" * 3
1245 data = "A" * 16 + "B" * 16 + "C" * 3
1246 self.port_in = random.randint(1025, 65535)
1250 pkts = self.create_stream_frag(self.pg0,
1251 self.pg1.remote_ip4,
1257 self.pg0.add_stream(pkts)
1258 self.pg_enable_capture(self.pg_interfaces)
1260 frags = self.pg1.get_capture(len(pkts))
1261 if not dont_translate:
1262 p = self.reass_frags_and_verify(frags,
1264 self.pg1.remote_ip4)
1266 p = self.reass_frags_and_verify(frags,
1267 self.pg0.remote_ip4,
1268 self.pg1.remote_ip4)
1269 if proto != IP_PROTOS.icmp:
1270 if not dont_translate:
1271 self.assertEqual(p[layer].dport, 20)
1272 self.assertNotEqual(p[layer].sport, self.port_in)
1274 self.assertEqual(p[layer].sport, self.port_in)
1276 if not dont_translate:
1277 self.assertNotEqual(p[layer].id, self.port_in)
1279 self.assertEqual(p[layer].id, self.port_in)
1280 self.assertEqual(data, p[Raw].load)
1283 if not dont_translate:
1284 dst_addr = self.nat_addr
1286 dst_addr = self.pg0.remote_ip4
1287 if proto != IP_PROTOS.icmp:
1289 dport = p[layer].sport
1293 pkts = self.create_stream_frag(self.pg1,
1301 self.pg1.add_stream(pkts)
1302 self.pg_enable_capture(self.pg_interfaces)
1304 frags = self.pg0.get_capture(len(pkts))
1305 p = self.reass_frags_and_verify(frags,
1306 self.pg1.remote_ip4,
1307 self.pg0.remote_ip4)
1308 if proto != IP_PROTOS.icmp:
1309 self.assertEqual(p[layer].sport, 20)
1310 self.assertEqual(p[layer].dport, self.port_in)
1312 self.assertEqual(p[layer].id, self.port_in)
1313 self.assertEqual(data, p[Raw].load)
1315 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1316 layer = self.proto2layer(proto)
1318 if proto == IP_PROTOS.tcp:
1319 data = "A" * 4 + "B" * 16 + "C" * 3
1321 data = "A" * 16 + "B" * 16 + "C" * 3
1322 self.port_in = random.randint(1025, 65535)
1326 pkts = self.create_stream_frag(self.pg0,
1327 self.server_out_addr,
1329 self.server_out_port,
1333 self.pg0.add_stream(pkts)
1334 self.pg_enable_capture(self.pg_interfaces)
1336 frags = self.pg1.get_capture(len(pkts))
1337 p = self.reass_frags_and_verify(frags,
1338 self.pg0.remote_ip4,
1339 self.server_in_addr)
1340 if proto != IP_PROTOS.icmp:
1341 self.assertEqual(p[layer].dport, self.server_in_port)
1342 self.assertEqual(p[layer].sport, self.port_in)
1343 self.assertEqual(p[layer].dport, self.server_in_port)
1345 self.assertEqual(p[layer].id, self.port_in)
1346 self.assertEqual(data, p[Raw].load)
1349 if proto != IP_PROTOS.icmp:
1350 pkts = self.create_stream_frag(self.pg1,
1351 self.pg0.remote_ip4,
1352 self.server_in_port,
1357 pkts = self.create_stream_frag(self.pg1,
1358 self.pg0.remote_ip4,
1365 self.pg1.add_stream(pkts)
1366 self.pg_enable_capture(self.pg_interfaces)
1368 frags = self.pg0.get_capture(len(pkts))
1369 p = self.reass_frags_and_verify(frags,
1370 self.server_out_addr,
1371 self.pg0.remote_ip4)
1372 if proto != IP_PROTOS.icmp:
1373 self.assertEqual(p[layer].sport, self.server_out_port)
1374 self.assertEqual(p[layer].dport, self.port_in)
1376 self.assertEqual(p[layer].id, self.port_in)
1377 self.assertEqual(data, p[Raw].load)
1380 class TestNAT44(MethodHolder):
1381 """ NAT44 Test Cases """
1384 def setUpClass(cls):
1385 super(TestNAT44, cls).setUpClass()
1386 cls.vapi.cli("set log class nat level debug")
1389 cls.tcp_port_in = 6303
1390 cls.tcp_port_out = 6303
1391 cls.udp_port_in = 6304
1392 cls.udp_port_out = 6304
1393 cls.icmp_id_in = 6305
1394 cls.icmp_id_out = 6305
1395 cls.nat_addr = '10.0.0.3'
1396 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1397 cls.ipfix_src_port = 4739
1398 cls.ipfix_domain_id = 1
1399 cls.tcp_external_port = 80
1401 cls.create_pg_interfaces(range(10))
1402 cls.interfaces = list(cls.pg_interfaces[0:4])
1404 for i in cls.interfaces:
1409 cls.pg0.generate_remote_hosts(3)
1410 cls.pg0.configure_ipv4_neighbors()
1412 cls.pg1.generate_remote_hosts(1)
1413 cls.pg1.configure_ipv4_neighbors()
1415 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1416 cls.vapi.ip_table_add_del(10, is_add=1)
1417 cls.vapi.ip_table_add_del(20, is_add=1)
1419 cls.pg4._local_ip4 = "172.16.255.1"
1420 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1421 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1422 cls.pg4.set_table_ip4(10)
1423 cls.pg5._local_ip4 = "172.17.255.3"
1424 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1425 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1426 cls.pg5.set_table_ip4(10)
1427 cls.pg6._local_ip4 = "172.16.255.1"
1428 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1429 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1430 cls.pg6.set_table_ip4(20)
1431 for i in cls.overlapping_interfaces:
1439 cls.pg9.generate_remote_hosts(2)
1440 cls.pg9.config_ip4()
1441 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1442 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1446 cls.pg9.resolve_arp()
1447 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1448 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1449 cls.pg9.resolve_arp()
1452 super(TestNAT44, cls).tearDownClass()
1455 def test_dynamic(self):
1456 """ NAT44 dynamic translation test """
1458 self.nat44_add_address(self.nat_addr)
1459 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1460 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1464 pkts = self.create_stream_in(self.pg0, self.pg1)
1465 self.pg0.add_stream(pkts)
1466 self.pg_enable_capture(self.pg_interfaces)
1468 capture = self.pg1.get_capture(len(pkts))
1469 self.verify_capture_out(capture)
1472 pkts = self.create_stream_out(self.pg1)
1473 self.pg1.add_stream(pkts)
1474 self.pg_enable_capture(self.pg_interfaces)
1476 capture = self.pg0.get_capture(len(pkts))
1477 self.verify_capture_in(capture, self.pg0)
1479 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1480 """ NAT44 handling of client packets with TTL=1 """
1482 self.nat44_add_address(self.nat_addr)
1483 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1484 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1487 # Client side - generate traffic
1488 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1489 self.pg0.add_stream(pkts)
1490 self.pg_enable_capture(self.pg_interfaces)
1493 # Client side - verify ICMP type 11 packets
1494 capture = self.pg0.get_capture(len(pkts))
1495 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1497 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1498 """ NAT44 handling of server packets with TTL=1 """
1500 self.nat44_add_address(self.nat_addr)
1501 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1502 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1505 # Client side - create sessions
1506 pkts = self.create_stream_in(self.pg0, self.pg1)
1507 self.pg0.add_stream(pkts)
1508 self.pg_enable_capture(self.pg_interfaces)
1511 # Server side - generate traffic
1512 capture = self.pg1.get_capture(len(pkts))
1513 self.verify_capture_out(capture)
1514 pkts = self.create_stream_out(self.pg1, ttl=1)
1515 self.pg1.add_stream(pkts)
1516 self.pg_enable_capture(self.pg_interfaces)
1519 # Server side - verify ICMP type 11 packets
1520 capture = self.pg1.get_capture(len(pkts))
1521 self.verify_capture_out_with_icmp_errors(capture,
1522 src_ip=self.pg1.local_ip4)
1524 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1525 """ NAT44 handling of error responses to client packets with TTL=2 """
1527 self.nat44_add_address(self.nat_addr)
1528 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1529 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1532 # Client side - generate traffic
1533 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1534 self.pg0.add_stream(pkts)
1535 self.pg_enable_capture(self.pg_interfaces)
1538 # Server side - simulate ICMP type 11 response
1539 capture = self.pg1.get_capture(len(pkts))
1540 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1541 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1542 ICMP(type=11) / packet[IP] for packet in capture]
1543 self.pg1.add_stream(pkts)
1544 self.pg_enable_capture(self.pg_interfaces)
1547 # Client side - verify ICMP type 11 packets
1548 capture = self.pg0.get_capture(len(pkts))
1549 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1551 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1552 """ NAT44 handling of error responses to server packets with TTL=2 """
1554 self.nat44_add_address(self.nat_addr)
1555 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1556 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1559 # Client side - create sessions
1560 pkts = self.create_stream_in(self.pg0, self.pg1)
1561 self.pg0.add_stream(pkts)
1562 self.pg_enable_capture(self.pg_interfaces)
1565 # Server side - generate traffic
1566 capture = self.pg1.get_capture(len(pkts))
1567 self.verify_capture_out(capture)
1568 pkts = self.create_stream_out(self.pg1, ttl=2)
1569 self.pg1.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1573 # Client side - simulate ICMP type 11 response
1574 capture = self.pg0.get_capture(len(pkts))
1575 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1576 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1577 ICMP(type=11) / packet[IP] for packet in capture]
1578 self.pg0.add_stream(pkts)
1579 self.pg_enable_capture(self.pg_interfaces)
1582 # Server side - verify ICMP type 11 packets
1583 capture = self.pg1.get_capture(len(pkts))
1584 self.verify_capture_out_with_icmp_errors(capture)
1586 def test_ping_out_interface_from_outside(self):
1587 """ Ping NAT44 out interface from outside network """
1589 self.nat44_add_address(self.nat_addr)
1590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1594 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1595 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1596 ICMP(id=self.icmp_id_out, type='echo-request'))
1598 self.pg1.add_stream(pkts)
1599 self.pg_enable_capture(self.pg_interfaces)
1601 capture = self.pg1.get_capture(len(pkts))
1604 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1605 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1606 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1607 self.assertEqual(packet[ICMP].type, 0) # echo reply
1609 self.logger.error(ppp("Unexpected or invalid packet "
1610 "(outside network):", packet))
1613 def test_ping_internal_host_from_outside(self):
1614 """ Ping internal host from outside network """
1616 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1617 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1618 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1622 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1623 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1624 ICMP(id=self.icmp_id_out, type='echo-request'))
1625 self.pg1.add_stream(pkt)
1626 self.pg_enable_capture(self.pg_interfaces)
1628 capture = self.pg0.get_capture(1)
1629 self.verify_capture_in(capture, self.pg0)
1630 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1633 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1634 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1635 ICMP(id=self.icmp_id_in, type='echo-reply'))
1636 self.pg0.add_stream(pkt)
1637 self.pg_enable_capture(self.pg_interfaces)
1639 capture = self.pg1.get_capture(1)
1640 self.verify_capture_out(capture, same_port=True)
1641 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1643 def test_forwarding(self):
1644 """ NAT44 forwarding test """
1646 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1647 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1649 self.vapi.nat44_forwarding_enable_disable(1)
1651 real_ip = self.pg0.remote_ip4n
1652 alias_ip = self.nat_addr_n
1653 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1654 external_ip=alias_ip)
1657 # static mapping match
1659 pkts = self.create_stream_out(self.pg1)
1660 self.pg1.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1663 capture = self.pg0.get_capture(len(pkts))
1664 self.verify_capture_in(capture, self.pg0)
1666 pkts = self.create_stream_in(self.pg0, self.pg1)
1667 self.pg0.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1670 capture = self.pg1.get_capture(len(pkts))
1671 self.verify_capture_out(capture, same_port=True)
1673 # no static mapping match
1675 host0 = self.pg0.remote_hosts[0]
1676 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1678 pkts = self.create_stream_out(self.pg1,
1679 dst_ip=self.pg0.remote_ip4,
1680 use_inside_ports=True)
1681 self.pg1.add_stream(pkts)
1682 self.pg_enable_capture(self.pg_interfaces)
1684 capture = self.pg0.get_capture(len(pkts))
1685 self.verify_capture_in(capture, self.pg0)
1687 pkts = self.create_stream_in(self.pg0, self.pg1)
1688 self.pg0.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1691 capture = self.pg1.get_capture(len(pkts))
1692 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1695 self.pg0.remote_hosts[0] = host0
1698 self.vapi.nat44_forwarding_enable_disable(0)
1699 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1700 external_ip=alias_ip,
1703 def test_static_in(self):
1704 """ 1:1 NAT initialized from inside network """
1706 nat_ip = "10.0.0.10"
1707 self.tcp_port_out = 6303
1708 self.udp_port_out = 6304
1709 self.icmp_id_out = 6305
1711 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1712 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1713 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1715 sm = self.vapi.nat44_static_mapping_dump()
1716 self.assertEqual(len(sm), 1)
1717 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1718 self.assertEqual(sm[0].protocol, 0)
1719 self.assertEqual(sm[0].local_port, 0)
1720 self.assertEqual(sm[0].external_port, 0)
1723 pkts = self.create_stream_in(self.pg0, self.pg1)
1724 self.pg0.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1727 capture = self.pg1.get_capture(len(pkts))
1728 self.verify_capture_out(capture, nat_ip, True)
1731 pkts = self.create_stream_out(self.pg1, nat_ip)
1732 self.pg1.add_stream(pkts)
1733 self.pg_enable_capture(self.pg_interfaces)
1735 capture = self.pg0.get_capture(len(pkts))
1736 self.verify_capture_in(capture, self.pg0)
1738 def test_static_out(self):
1739 """ 1:1 NAT initialized from outside network """
1741 nat_ip = "10.0.0.20"
1742 self.tcp_port_out = 6303
1743 self.udp_port_out = 6304
1744 self.icmp_id_out = 6305
1747 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1748 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1749 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1751 sm = self.vapi.nat44_static_mapping_dump()
1752 self.assertEqual(len(sm), 1)
1753 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1756 pkts = self.create_stream_out(self.pg1, nat_ip)
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg0.get_capture(len(pkts))
1761 self.verify_capture_in(capture, self.pg0)
1764 pkts = self.create_stream_in(self.pg0, self.pg1)
1765 self.pg0.add_stream(pkts)
1766 self.pg_enable_capture(self.pg_interfaces)
1768 capture = self.pg1.get_capture(len(pkts))
1769 self.verify_capture_out(capture, nat_ip, True)
1771 def test_static_with_port_in(self):
1772 """ 1:1 NAPT initialized from inside network """
1774 self.tcp_port_out = 3606
1775 self.udp_port_out = 3607
1776 self.icmp_id_out = 3608
1778 self.nat44_add_address(self.nat_addr)
1779 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1780 self.tcp_port_in, self.tcp_port_out,
1781 proto=IP_PROTOS.tcp)
1782 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1783 self.udp_port_in, self.udp_port_out,
1784 proto=IP_PROTOS.udp)
1785 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1786 self.icmp_id_in, self.icmp_id_out,
1787 proto=IP_PROTOS.icmp)
1788 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1789 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1793 pkts = self.create_stream_in(self.pg0, self.pg1)
1794 self.pg0.add_stream(pkts)
1795 self.pg_enable_capture(self.pg_interfaces)
1797 capture = self.pg1.get_capture(len(pkts))
1798 self.verify_capture_out(capture)
1801 pkts = self.create_stream_out(self.pg1)
1802 self.pg1.add_stream(pkts)
1803 self.pg_enable_capture(self.pg_interfaces)
1805 capture = self.pg0.get_capture(len(pkts))
1806 self.verify_capture_in(capture, self.pg0)
1808 def test_static_with_port_out(self):
1809 """ 1:1 NAPT initialized from outside network """
1811 self.tcp_port_out = 30606
1812 self.udp_port_out = 30607
1813 self.icmp_id_out = 30608
1815 self.nat44_add_address(self.nat_addr)
1816 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1817 self.tcp_port_in, self.tcp_port_out,
1818 proto=IP_PROTOS.tcp)
1819 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1820 self.udp_port_in, self.udp_port_out,
1821 proto=IP_PROTOS.udp)
1822 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1823 self.icmp_id_in, self.icmp_id_out,
1824 proto=IP_PROTOS.icmp)
1825 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1826 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1838 pkts = self.create_stream_in(self.pg0, self.pg1)
1839 self.pg0.add_stream(pkts)
1840 self.pg_enable_capture(self.pg_interfaces)
1842 capture = self.pg1.get_capture(len(pkts))
1843 self.verify_capture_out(capture)
1845 def test_static_vrf_aware(self):
1846 """ 1:1 NAT VRF awareness """
1848 nat_ip1 = "10.0.0.30"
1849 nat_ip2 = "10.0.0.40"
1850 self.tcp_port_out = 6303
1851 self.udp_port_out = 6304
1852 self.icmp_id_out = 6305
1854 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1856 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1858 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1861 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1863 # inside interface VRF match NAT44 static mapping VRF
1864 pkts = self.create_stream_in(self.pg4, self.pg3)
1865 self.pg4.add_stream(pkts)
1866 self.pg_enable_capture(self.pg_interfaces)
1868 capture = self.pg3.get_capture(len(pkts))
1869 self.verify_capture_out(capture, nat_ip1, True)
1871 # inside interface VRF don't match NAT44 static mapping VRF (packets
1873 pkts = self.create_stream_in(self.pg0, self.pg3)
1874 self.pg0.add_stream(pkts)
1875 self.pg_enable_capture(self.pg_interfaces)
1877 self.pg3.assert_nothing_captured()
1879 def test_dynamic_to_static(self):
1880 """ Switch from dynamic translation to 1:1NAT """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_address(self.nat_addr)
1887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg1.get_capture(len(pkts))
1897 self.verify_capture_out(capture)
1900 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1902 self.assertEqual(len(sessions), 0)
1903 pkts = self.create_stream_in(self.pg0, self.pg1)
1904 self.pg0.add_stream(pkts)
1905 self.pg_enable_capture(self.pg_interfaces)
1907 capture = self.pg1.get_capture(len(pkts))
1908 self.verify_capture_out(capture, nat_ip, True)
1910 def test_identity_nat(self):
1911 """ Identity NAT """
1913 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1915 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1918 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1919 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1920 TCP(sport=12345, dport=56789))
1921 self.pg1.add_stream(p)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg0.get_capture(1)
1929 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1930 self.assertEqual(ip.src, self.pg1.remote_ip4)
1931 self.assertEqual(tcp.dport, 56789)
1932 self.assertEqual(tcp.sport, 12345)
1933 self.assert_packet_checksums_valid(p)
1935 self.logger.error(ppp("Unexpected or invalid packet:", p))
1938 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1939 self.assertEqual(len(sessions), 0)
1940 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
1942 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1943 self.assertEqual(len(identity_mappings), 2)
1945 def test_multiple_inside_interfaces(self):
1946 """ NAT44 multiple non-overlapping address space inside interfaces """
1948 self.nat44_add_address(self.nat_addr)
1949 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1950 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1951 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1954 # between two NAT44 inside interfaces (no translation)
1955 pkts = self.create_stream_in(self.pg0, self.pg1)
1956 self.pg0.add_stream(pkts)
1957 self.pg_enable_capture(self.pg_interfaces)
1959 capture = self.pg1.get_capture(len(pkts))
1960 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1962 # from NAT44 inside to interface without NAT44 feature (no translation)
1963 pkts = self.create_stream_in(self.pg0, self.pg2)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 capture = self.pg2.get_capture(len(pkts))
1968 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1970 # in2out 1st interface
1971 pkts = self.create_stream_in(self.pg0, self.pg3)
1972 self.pg0.add_stream(pkts)
1973 self.pg_enable_capture(self.pg_interfaces)
1975 capture = self.pg3.get_capture(len(pkts))
1976 self.verify_capture_out(capture)
1978 # out2in 1st interface
1979 pkts = self.create_stream_out(self.pg3)
1980 self.pg3.add_stream(pkts)
1981 self.pg_enable_capture(self.pg_interfaces)
1983 capture = self.pg0.get_capture(len(pkts))
1984 self.verify_capture_in(capture, self.pg0)
1986 # in2out 2nd interface
1987 pkts = self.create_stream_in(self.pg1, self.pg3)
1988 self.pg1.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1991 capture = self.pg3.get_capture(len(pkts))
1992 self.verify_capture_out(capture)
1994 # out2in 2nd interface
1995 pkts = self.create_stream_out(self.pg3)
1996 self.pg3.add_stream(pkts)
1997 self.pg_enable_capture(self.pg_interfaces)
1999 capture = self.pg1.get_capture(len(pkts))
2000 self.verify_capture_in(capture, self.pg1)
2002 def test_inside_overlapping_interfaces(self):
2003 """ NAT44 multiple inside interfaces with overlapping address space """
2005 static_nat_ip = "10.0.0.10"
2006 self.nat44_add_address(self.nat_addr)
2007 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2009 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2010 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2011 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2012 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2015 # between NAT44 inside interfaces with same VRF (no translation)
2016 pkts = self.create_stream_in(self.pg4, self.pg5)
2017 self.pg4.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2020 capture = self.pg5.get_capture(len(pkts))
2021 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2023 # between NAT44 inside interfaces with different VRF (hairpinning)
2024 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2025 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2026 TCP(sport=1234, dport=5678))
2027 self.pg4.add_stream(p)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg6.get_capture(1)
2035 self.assertEqual(ip.src, self.nat_addr)
2036 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2037 self.assertNotEqual(tcp.sport, 1234)
2038 self.assertEqual(tcp.dport, 5678)
2040 self.logger.error(ppp("Unexpected or invalid packet:", p))
2043 # in2out 1st interface
2044 pkts = self.create_stream_in(self.pg4, self.pg3)
2045 self.pg4.add_stream(pkts)
2046 self.pg_enable_capture(self.pg_interfaces)
2048 capture = self.pg3.get_capture(len(pkts))
2049 self.verify_capture_out(capture)
2051 # out2in 1st interface
2052 pkts = self.create_stream_out(self.pg3)
2053 self.pg3.add_stream(pkts)
2054 self.pg_enable_capture(self.pg_interfaces)
2056 capture = self.pg4.get_capture(len(pkts))
2057 self.verify_capture_in(capture, self.pg4)
2059 # in2out 2nd interface
2060 pkts = self.create_stream_in(self.pg5, self.pg3)
2061 self.pg5.add_stream(pkts)
2062 self.pg_enable_capture(self.pg_interfaces)
2064 capture = self.pg3.get_capture(len(pkts))
2065 self.verify_capture_out(capture)
2067 # out2in 2nd interface
2068 pkts = self.create_stream_out(self.pg3)
2069 self.pg3.add_stream(pkts)
2070 self.pg_enable_capture(self.pg_interfaces)
2072 capture = self.pg5.get_capture(len(pkts))
2073 self.verify_capture_in(capture, self.pg5)
2076 addresses = self.vapi.nat44_address_dump()
2077 self.assertEqual(len(addresses), 1)
2078 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2079 self.assertEqual(len(sessions), 3)
2080 for session in sessions:
2081 self.assertFalse(session.is_static)
2082 self.assertEqual(session.inside_ip_address[0:4],
2083 self.pg5.remote_ip4n)
2084 self.assertEqual(session.outside_ip_address,
2085 addresses[0].ip_address)
2086 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2087 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2088 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2089 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2090 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2091 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2092 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2093 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2094 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2096 # in2out 3rd interface
2097 pkts = self.create_stream_in(self.pg6, self.pg3)
2098 self.pg6.add_stream(pkts)
2099 self.pg_enable_capture(self.pg_interfaces)
2101 capture = self.pg3.get_capture(len(pkts))
2102 self.verify_capture_out(capture, static_nat_ip, True)
2104 # out2in 3rd interface
2105 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2106 self.pg3.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg6.get_capture(len(pkts))
2110 self.verify_capture_in(capture, self.pg6)
2112 # general user and session dump verifications
2113 users = self.vapi.nat44_user_dump()
2114 self.assertTrue(len(users) >= 3)
2115 addresses = self.vapi.nat44_address_dump()
2116 self.assertEqual(len(addresses), 1)
2118 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2120 for session in sessions:
2121 self.assertEqual(user.ip_address, session.inside_ip_address)
2122 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2123 self.assertTrue(session.protocol in
2124 [IP_PROTOS.tcp, IP_PROTOS.udp,
2126 self.assertFalse(session.ext_host_valid)
2129 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2130 self.assertTrue(len(sessions) >= 4)
2131 for session in sessions:
2132 self.assertFalse(session.is_static)
2133 self.assertEqual(session.inside_ip_address[0:4],
2134 self.pg4.remote_ip4n)
2135 self.assertEqual(session.outside_ip_address,
2136 addresses[0].ip_address)
2139 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2140 self.assertTrue(len(sessions) >= 3)
2141 for session in sessions:
2142 self.assertTrue(session.is_static)
2143 self.assertEqual(session.inside_ip_address[0:4],
2144 self.pg6.remote_ip4n)
2145 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2146 map(int, static_nat_ip.split('.')))
2147 self.assertTrue(session.inside_port in
2148 [self.tcp_port_in, self.udp_port_in,
2151 def test_hairpinning(self):
2152 """ NAT44 hairpinning - 1:1 NAPT """
2154 host = self.pg0.remote_hosts[0]
2155 server = self.pg0.remote_hosts[1]
2158 server_in_port = 5678
2159 server_out_port = 8765
2161 self.nat44_add_address(self.nat_addr)
2162 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2163 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2165 # add static mapping for server
2166 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2167 server_in_port, server_out_port,
2168 proto=IP_PROTOS.tcp)
2170 # send packet from host to server
2171 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2172 IP(src=host.ip4, dst=self.nat_addr) /
2173 TCP(sport=host_in_port, dport=server_out_port))
2174 self.pg0.add_stream(p)
2175 self.pg_enable_capture(self.pg_interfaces)
2177 capture = self.pg0.get_capture(1)
2182 self.assertEqual(ip.src, self.nat_addr)
2183 self.assertEqual(ip.dst, server.ip4)
2184 self.assertNotEqual(tcp.sport, host_in_port)
2185 self.assertEqual(tcp.dport, server_in_port)
2186 self.assert_packet_checksums_valid(p)
2187 host_out_port = tcp.sport
2189 self.logger.error(ppp("Unexpected or invalid packet:", p))
2192 # send reply from server to host
2193 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2194 IP(src=server.ip4, dst=self.nat_addr) /
2195 TCP(sport=server_in_port, dport=host_out_port))
2196 self.pg0.add_stream(p)
2197 self.pg_enable_capture(self.pg_interfaces)
2199 capture = self.pg0.get_capture(1)
2204 self.assertEqual(ip.src, self.nat_addr)
2205 self.assertEqual(ip.dst, host.ip4)
2206 self.assertEqual(tcp.sport, server_out_port)
2207 self.assertEqual(tcp.dport, host_in_port)
2208 self.assert_packet_checksums_valid(p)
2210 self.logger.error(ppp("Unexpected or invalid packet:", p))
2213 def test_hairpinning2(self):
2214 """ NAT44 hairpinning - 1:1 NAT"""
2216 server1_nat_ip = "10.0.0.10"
2217 server2_nat_ip = "10.0.0.11"
2218 host = self.pg0.remote_hosts[0]
2219 server1 = self.pg0.remote_hosts[1]
2220 server2 = self.pg0.remote_hosts[2]
2221 server_tcp_port = 22
2222 server_udp_port = 20
2224 self.nat44_add_address(self.nat_addr)
2225 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2226 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2229 # add static mapping for servers
2230 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2231 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2235 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2236 IP(src=host.ip4, dst=server1_nat_ip) /
2237 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2240 IP(src=host.ip4, dst=server1_nat_ip) /
2241 UDP(sport=self.udp_port_in, dport=server_udp_port))
2243 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2244 IP(src=host.ip4, dst=server1_nat_ip) /
2245 ICMP(id=self.icmp_id_in, type='echo-request'))
2247 self.pg0.add_stream(pkts)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg0.get_capture(len(pkts))
2251 for packet in capture:
2253 self.assertEqual(packet[IP].src, self.nat_addr)
2254 self.assertEqual(packet[IP].dst, server1.ip4)
2255 if packet.haslayer(TCP):
2256 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2257 self.assertEqual(packet[TCP].dport, server_tcp_port)
2258 self.tcp_port_out = packet[TCP].sport
2259 self.assert_packet_checksums_valid(packet)
2260 elif packet.haslayer(UDP):
2261 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2262 self.assertEqual(packet[UDP].dport, server_udp_port)
2263 self.udp_port_out = packet[UDP].sport
2265 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2266 self.icmp_id_out = packet[ICMP].id
2268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2274 IP(src=server1.ip4, dst=self.nat_addr) /
2275 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2278 IP(src=server1.ip4, dst=self.nat_addr) /
2279 UDP(sport=server_udp_port, dport=self.udp_port_out))
2281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2282 IP(src=server1.ip4, dst=self.nat_addr) /
2283 ICMP(id=self.icmp_id_out, type='echo-reply'))
2285 self.pg0.add_stream(pkts)
2286 self.pg_enable_capture(self.pg_interfaces)
2288 capture = self.pg0.get_capture(len(pkts))
2289 for packet in capture:
2291 self.assertEqual(packet[IP].src, server1_nat_ip)
2292 self.assertEqual(packet[IP].dst, host.ip4)
2293 if packet.haslayer(TCP):
2294 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2295 self.assertEqual(packet[TCP].sport, server_tcp_port)
2296 self.assert_packet_checksums_valid(packet)
2297 elif packet.haslayer(UDP):
2298 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2299 self.assertEqual(packet[UDP].sport, server_udp_port)
2301 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2306 # server2 to server1
2308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2309 IP(src=server2.ip4, dst=server1_nat_ip) /
2310 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2313 IP(src=server2.ip4, dst=server1_nat_ip) /
2314 UDP(sport=self.udp_port_in, dport=server_udp_port))
2316 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2317 IP(src=server2.ip4, dst=server1_nat_ip) /
2318 ICMP(id=self.icmp_id_in, type='echo-request'))
2320 self.pg0.add_stream(pkts)
2321 self.pg_enable_capture(self.pg_interfaces)
2323 capture = self.pg0.get_capture(len(pkts))
2324 for packet in capture:
2326 self.assertEqual(packet[IP].src, server2_nat_ip)
2327 self.assertEqual(packet[IP].dst, server1.ip4)
2328 if packet.haslayer(TCP):
2329 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2330 self.assertEqual(packet[TCP].dport, server_tcp_port)
2331 self.tcp_port_out = packet[TCP].sport
2332 self.assert_packet_checksums_valid(packet)
2333 elif packet.haslayer(UDP):
2334 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2335 self.assertEqual(packet[UDP].dport, server_udp_port)
2336 self.udp_port_out = packet[UDP].sport
2338 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2339 self.icmp_id_out = packet[ICMP].id
2341 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2344 # server1 to server2
2346 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2347 IP(src=server1.ip4, dst=server2_nat_ip) /
2348 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2350 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2351 IP(src=server1.ip4, dst=server2_nat_ip) /
2352 UDP(sport=server_udp_port, dport=self.udp_port_out))
2354 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2355 IP(src=server1.ip4, dst=server2_nat_ip) /
2356 ICMP(id=self.icmp_id_out, type='echo-reply'))
2358 self.pg0.add_stream(pkts)
2359 self.pg_enable_capture(self.pg_interfaces)
2361 capture = self.pg0.get_capture(len(pkts))
2362 for packet in capture:
2364 self.assertEqual(packet[IP].src, server1_nat_ip)
2365 self.assertEqual(packet[IP].dst, server2.ip4)
2366 if packet.haslayer(TCP):
2367 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2368 self.assertEqual(packet[TCP].sport, server_tcp_port)
2369 self.assert_packet_checksums_valid(packet)
2370 elif packet.haslayer(UDP):
2371 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2372 self.assertEqual(packet[UDP].sport, server_udp_port)
2374 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2376 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2379 def test_max_translations_per_user(self):
2380 """ MAX translations per user - recycle the least recently used """
2382 self.nat44_add_address(self.nat_addr)
2383 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2384 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2387 # get maximum number of translations per user
2388 nat44_config = self.vapi.nat_show_config()
2390 # send more than maximum number of translations per user packets
2391 pkts_num = nat44_config.max_translations_per_user + 5
2393 for port in range(0, pkts_num):
2394 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2395 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2396 TCP(sport=1025 + port))
2398 self.pg0.add_stream(pkts)
2399 self.pg_enable_capture(self.pg_interfaces)
2402 # verify number of translated packet
2403 self.pg1.get_capture(pkts_num)
2405 users = self.vapi.nat44_user_dump()
2407 if user.ip_address == self.pg0.remote_ip4n:
2408 self.assertEqual(user.nsessions,
2409 nat44_config.max_translations_per_user)
2410 self.assertEqual(user.nstaticsessions, 0)
2413 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2415 proto=IP_PROTOS.tcp)
2416 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2417 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2418 TCP(sport=tcp_port))
2419 self.pg0.add_stream(p)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 self.pg1.get_capture(1)
2423 users = self.vapi.nat44_user_dump()
2425 if user.ip_address == self.pg0.remote_ip4n:
2426 self.assertEqual(user.nsessions,
2427 nat44_config.max_translations_per_user - 1)
2428 self.assertEqual(user.nstaticsessions, 1)
2430 def test_interface_addr(self):
2431 """ Acquire NAT44 addresses from interface """
2432 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2434 # no address in NAT pool
2435 adresses = self.vapi.nat44_address_dump()
2436 self.assertEqual(0, len(adresses))
2438 # configure interface address and check NAT address pool
2439 self.pg7.config_ip4()
2440 adresses = self.vapi.nat44_address_dump()
2441 self.assertEqual(1, len(adresses))
2442 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2444 # remove interface address and check NAT address pool
2445 self.pg7.unconfig_ip4()
2446 adresses = self.vapi.nat44_address_dump()
2447 self.assertEqual(0, len(adresses))
2449 def test_interface_addr_static_mapping(self):
2450 """ Static mapping with addresses from interface """
2453 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2454 self.nat44_add_static_mapping(
2456 external_sw_if_index=self.pg7.sw_if_index,
2459 # static mappings with external interface
2460 static_mappings = self.vapi.nat44_static_mapping_dump()
2461 self.assertEqual(1, len(static_mappings))
2462 self.assertEqual(self.pg7.sw_if_index,
2463 static_mappings[0].external_sw_if_index)
2464 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2466 # configure interface address and check static mappings
2467 self.pg7.config_ip4()
2468 static_mappings = self.vapi.nat44_static_mapping_dump()
2469 self.assertEqual(2, len(static_mappings))
2471 for sm in static_mappings:
2472 if sm.external_sw_if_index == 0xFFFFFFFF:
2473 self.assertEqual(sm.external_ip_address[0:4],
2474 self.pg7.local_ip4n)
2475 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2477 self.assertTrue(resolved)
2479 # remove interface address and check static mappings
2480 self.pg7.unconfig_ip4()
2481 static_mappings = self.vapi.nat44_static_mapping_dump()
2482 self.assertEqual(1, len(static_mappings))
2483 self.assertEqual(self.pg7.sw_if_index,
2484 static_mappings[0].external_sw_if_index)
2485 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2487 # configure interface address again and check static mappings
2488 self.pg7.config_ip4()
2489 static_mappings = self.vapi.nat44_static_mapping_dump()
2490 self.assertEqual(2, len(static_mappings))
2492 for sm in static_mappings:
2493 if sm.external_sw_if_index == 0xFFFFFFFF:
2494 self.assertEqual(sm.external_ip_address[0:4],
2495 self.pg7.local_ip4n)
2496 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2498 self.assertTrue(resolved)
2500 # remove static mapping
2501 self.nat44_add_static_mapping(
2503 external_sw_if_index=self.pg7.sw_if_index,
2506 static_mappings = self.vapi.nat44_static_mapping_dump()
2507 self.assertEqual(0, len(static_mappings))
2509 def test_interface_addr_identity_nat(self):
2510 """ Identity NAT with addresses from interface """
2513 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2514 self.vapi.nat44_add_del_identity_mapping(
2515 sw_if_index=self.pg7.sw_if_index,
2517 protocol=IP_PROTOS.tcp,
2520 # identity mappings with external interface
2521 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2522 self.assertEqual(1, len(identity_mappings))
2523 self.assertEqual(self.pg7.sw_if_index,
2524 identity_mappings[0].sw_if_index)
2526 # configure interface address and check identity mappings
2527 self.pg7.config_ip4()
2528 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2530 self.assertEqual(2, len(identity_mappings))
2531 for sm in identity_mappings:
2532 if sm.sw_if_index == 0xFFFFFFFF:
2533 self.assertEqual(identity_mappings[0].ip_address,
2534 self.pg7.local_ip4n)
2535 self.assertEqual(port, identity_mappings[0].port)
2536 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2538 self.assertTrue(resolved)
2540 # remove interface address and check identity mappings
2541 self.pg7.unconfig_ip4()
2542 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2543 self.assertEqual(1, len(identity_mappings))
2544 self.assertEqual(self.pg7.sw_if_index,
2545 identity_mappings[0].sw_if_index)
2547 def test_ipfix_nat44_sess(self):
2548 """ IPFIX logging NAT44 session created/delted """
2549 self.ipfix_domain_id = 10
2550 self.ipfix_src_port = 20202
2551 colector_port = 30303
2552 bind_layers(UDP, IPFIX, dport=30303)
2553 self.nat44_add_address(self.nat_addr)
2554 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2555 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2557 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2558 src_address=self.pg3.local_ip4n,
2560 template_interval=10,
2561 collector_port=colector_port)
2562 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2563 src_port=self.ipfix_src_port)
2565 pkts = self.create_stream_in(self.pg0, self.pg1)
2566 self.pg0.add_stream(pkts)
2567 self.pg_enable_capture(self.pg_interfaces)
2569 capture = self.pg1.get_capture(len(pkts))
2570 self.verify_capture_out(capture)
2571 self.nat44_add_address(self.nat_addr, is_add=0)
2572 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2573 capture = self.pg3.get_capture(9)
2574 ipfix = IPFIXDecoder()
2575 # first load template
2577 self.assertTrue(p.haslayer(IPFIX))
2578 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2579 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2580 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2581 self.assertEqual(p[UDP].dport, colector_port)
2582 self.assertEqual(p[IPFIX].observationDomainID,
2583 self.ipfix_domain_id)
2584 if p.haslayer(Template):
2585 ipfix.add_template(p.getlayer(Template))
2586 # verify events in data set
2588 if p.haslayer(Data):
2589 data = ipfix.decode_data_set(p.getlayer(Set))
2590 self.verify_ipfix_nat44_ses(data)
2592 def test_ipfix_addr_exhausted(self):
2593 """ IPFIX logging NAT addresses exhausted """
2594 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2595 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2597 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2598 src_address=self.pg3.local_ip4n,
2600 template_interval=10)
2601 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2602 src_port=self.ipfix_src_port)
2604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2605 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2607 self.pg0.add_stream(p)
2608 self.pg_enable_capture(self.pg_interfaces)
2610 self.pg1.assert_nothing_captured()
2612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2613 capture = self.pg3.get_capture(9)
2614 ipfix = IPFIXDecoder()
2615 # first load template
2617 self.assertTrue(p.haslayer(IPFIX))
2618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2621 self.assertEqual(p[UDP].dport, 4739)
2622 self.assertEqual(p[IPFIX].observationDomainID,
2623 self.ipfix_domain_id)
2624 if p.haslayer(Template):
2625 ipfix.add_template(p.getlayer(Template))
2626 # verify events in data set
2628 if p.haslayer(Data):
2629 data = ipfix.decode_data_set(p.getlayer(Set))
2630 self.verify_ipfix_addr_exhausted(data)
2632 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2633 def test_ipfix_max_sessions(self):
2634 """ IPFIX logging maximum session entries exceeded """
2635 self.nat44_add_address(self.nat_addr)
2636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2640 nat44_config = self.vapi.nat_show_config()
2641 max_sessions = 10 * nat44_config.translation_buckets
2644 for i in range(0, max_sessions):
2645 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2647 IP(src=src, dst=self.pg1.remote_ip4) /
2650 self.pg0.add_stream(pkts)
2651 self.pg_enable_capture(self.pg_interfaces)
2654 self.pg1.get_capture(max_sessions)
2655 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2656 src_address=self.pg3.local_ip4n,
2658 template_interval=10)
2659 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2660 src_port=self.ipfix_src_port)
2662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2663 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2665 self.pg0.add_stream(p)
2666 self.pg_enable_capture(self.pg_interfaces)
2668 self.pg1.assert_nothing_captured()
2670 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2671 capture = self.pg3.get_capture(9)
2672 ipfix = IPFIXDecoder()
2673 # first load template
2675 self.assertTrue(p.haslayer(IPFIX))
2676 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2677 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2678 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2679 self.assertEqual(p[UDP].dport, 4739)
2680 self.assertEqual(p[IPFIX].observationDomainID,
2681 self.ipfix_domain_id)
2682 if p.haslayer(Template):
2683 ipfix.add_template(p.getlayer(Template))
2684 # verify events in data set
2686 if p.haslayer(Data):
2687 data = ipfix.decode_data_set(p.getlayer(Set))
2688 self.verify_ipfix_max_sessions(data, max_sessions)
2690 def test_pool_addr_fib(self):
2691 """ NAT44 add pool addresses to FIB """
2692 static_addr = '10.0.0.10'
2693 self.nat44_add_address(self.nat_addr)
2694 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2695 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2697 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2700 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2701 ARP(op=ARP.who_has, pdst=self.nat_addr,
2702 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2703 self.pg1.add_stream(p)
2704 self.pg_enable_capture(self.pg_interfaces)
2706 capture = self.pg1.get_capture(1)
2707 self.assertTrue(capture[0].haslayer(ARP))
2708 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2711 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2712 ARP(op=ARP.who_has, pdst=static_addr,
2713 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2714 self.pg1.add_stream(p)
2715 self.pg_enable_capture(self.pg_interfaces)
2717 capture = self.pg1.get_capture(1)
2718 self.assertTrue(capture[0].haslayer(ARP))
2719 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2721 # send ARP to non-NAT44 interface
2722 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2723 ARP(op=ARP.who_has, pdst=self.nat_addr,
2724 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2725 self.pg2.add_stream(p)
2726 self.pg_enable_capture(self.pg_interfaces)
2728 self.pg1.assert_nothing_captured()
2730 # remove addresses and verify
2731 self.nat44_add_address(self.nat_addr, is_add=0)
2732 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2735 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2736 ARP(op=ARP.who_has, pdst=self.nat_addr,
2737 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2738 self.pg1.add_stream(p)
2739 self.pg_enable_capture(self.pg_interfaces)
2741 self.pg1.assert_nothing_captured()
2743 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2744 ARP(op=ARP.who_has, pdst=static_addr,
2745 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2746 self.pg1.add_stream(p)
2747 self.pg_enable_capture(self.pg_interfaces)
2749 self.pg1.assert_nothing_captured()
2751 def test_vrf_mode(self):
2752 """ NAT44 tenant VRF aware address pool mode """
2756 nat_ip1 = "10.0.0.10"
2757 nat_ip2 = "10.0.0.11"
2759 self.pg0.unconfig_ip4()
2760 self.pg1.unconfig_ip4()
2761 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2762 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2763 self.pg0.set_table_ip4(vrf_id1)
2764 self.pg1.set_table_ip4(vrf_id2)
2765 self.pg0.config_ip4()
2766 self.pg1.config_ip4()
2767 self.pg0.resolve_arp()
2768 self.pg1.resolve_arp()
2770 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2771 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2772 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2773 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2774 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2779 pkts = self.create_stream_in(self.pg0, self.pg2)
2780 self.pg0.add_stream(pkts)
2781 self.pg_enable_capture(self.pg_interfaces)
2783 capture = self.pg2.get_capture(len(pkts))
2784 self.verify_capture_out(capture, nat_ip1)
2787 pkts = self.create_stream_in(self.pg1, self.pg2)
2788 self.pg1.add_stream(pkts)
2789 self.pg_enable_capture(self.pg_interfaces)
2791 capture = self.pg2.get_capture(len(pkts))
2792 self.verify_capture_out(capture, nat_ip2)
2795 self.pg0.unconfig_ip4()
2796 self.pg1.unconfig_ip4()
2797 self.pg0.set_table_ip4(0)
2798 self.pg1.set_table_ip4(0)
2799 self.pg0.config_ip4()
2800 self.pg1.config_ip4()
2801 self.pg0.resolve_arp()
2802 self.pg1.resolve_arp()
2803 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2804 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2806 def test_vrf_feature_independent(self):
2807 """ NAT44 tenant VRF independent address pool mode """
2809 nat_ip1 = "10.0.0.10"
2810 nat_ip2 = "10.0.0.11"
2812 self.nat44_add_address(nat_ip1)
2813 self.nat44_add_address(nat_ip2, vrf_id=99)
2814 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2815 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2816 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2820 pkts = self.create_stream_in(self.pg0, self.pg2)
2821 self.pg0.add_stream(pkts)
2822 self.pg_enable_capture(self.pg_interfaces)
2824 capture = self.pg2.get_capture(len(pkts))
2825 self.verify_capture_out(capture, nat_ip1)
2828 pkts = self.create_stream_in(self.pg1, self.pg2)
2829 self.pg1.add_stream(pkts)
2830 self.pg_enable_capture(self.pg_interfaces)
2832 capture = self.pg2.get_capture(len(pkts))
2833 self.verify_capture_out(capture, nat_ip1)
2835 def test_dynamic_ipless_interfaces(self):
2836 """ NAT44 interfaces without configured IP address """
2838 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2839 mactobinary(self.pg7.remote_mac),
2840 self.pg7.remote_ip4n,
2842 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2843 mactobinary(self.pg8.remote_mac),
2844 self.pg8.remote_ip4n,
2847 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2848 dst_address_length=32,
2849 next_hop_address=self.pg7.remote_ip4n,
2850 next_hop_sw_if_index=self.pg7.sw_if_index)
2851 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2852 dst_address_length=32,
2853 next_hop_address=self.pg8.remote_ip4n,
2854 next_hop_sw_if_index=self.pg8.sw_if_index)
2856 self.nat44_add_address(self.nat_addr)
2857 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2858 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2862 pkts = self.create_stream_in(self.pg7, self.pg8)
2863 self.pg7.add_stream(pkts)
2864 self.pg_enable_capture(self.pg_interfaces)
2866 capture = self.pg8.get_capture(len(pkts))
2867 self.verify_capture_out(capture)
2870 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2871 self.pg8.add_stream(pkts)
2872 self.pg_enable_capture(self.pg_interfaces)
2874 capture = self.pg7.get_capture(len(pkts))
2875 self.verify_capture_in(capture, self.pg7)
2877 def test_static_ipless_interfaces(self):
2878 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2880 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2881 mactobinary(self.pg7.remote_mac),
2882 self.pg7.remote_ip4n,
2884 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2885 mactobinary(self.pg8.remote_mac),
2886 self.pg8.remote_ip4n,
2889 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2890 dst_address_length=32,
2891 next_hop_address=self.pg7.remote_ip4n,
2892 next_hop_sw_if_index=self.pg7.sw_if_index)
2893 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2894 dst_address_length=32,
2895 next_hop_address=self.pg8.remote_ip4n,
2896 next_hop_sw_if_index=self.pg8.sw_if_index)
2898 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2899 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2900 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2904 pkts = self.create_stream_out(self.pg8)
2905 self.pg8.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2908 capture = self.pg7.get_capture(len(pkts))
2909 self.verify_capture_in(capture, self.pg7)
2912 pkts = self.create_stream_in(self.pg7, self.pg8)
2913 self.pg7.add_stream(pkts)
2914 self.pg_enable_capture(self.pg_interfaces)
2916 capture = self.pg8.get_capture(len(pkts))
2917 self.verify_capture_out(capture, self.nat_addr, True)
2919 def test_static_with_port_ipless_interfaces(self):
2920 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2922 self.tcp_port_out = 30606
2923 self.udp_port_out = 30607
2924 self.icmp_id_out = 30608
2926 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2927 mactobinary(self.pg7.remote_mac),
2928 self.pg7.remote_ip4n,
2930 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2931 mactobinary(self.pg8.remote_mac),
2932 self.pg8.remote_ip4n,
2935 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2936 dst_address_length=32,
2937 next_hop_address=self.pg7.remote_ip4n,
2938 next_hop_sw_if_index=self.pg7.sw_if_index)
2939 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2940 dst_address_length=32,
2941 next_hop_address=self.pg8.remote_ip4n,
2942 next_hop_sw_if_index=self.pg8.sw_if_index)
2944 self.nat44_add_address(self.nat_addr)
2945 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2946 self.tcp_port_in, self.tcp_port_out,
2947 proto=IP_PROTOS.tcp)
2948 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2949 self.udp_port_in, self.udp_port_out,
2950 proto=IP_PROTOS.udp)
2951 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2952 self.icmp_id_in, self.icmp_id_out,
2953 proto=IP_PROTOS.icmp)
2954 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2955 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2959 pkts = self.create_stream_out(self.pg8)
2960 self.pg8.add_stream(pkts)
2961 self.pg_enable_capture(self.pg_interfaces)
2963 capture = self.pg7.get_capture(len(pkts))
2964 self.verify_capture_in(capture, self.pg7)
2967 pkts = self.create_stream_in(self.pg7, self.pg8)
2968 self.pg7.add_stream(pkts)
2969 self.pg_enable_capture(self.pg_interfaces)
2971 capture = self.pg8.get_capture(len(pkts))
2972 self.verify_capture_out(capture)
2974 def test_static_unknown_proto(self):
2975 """ 1:1 NAT translate packet with unknown protocol """
2976 nat_ip = "10.0.0.10"
2977 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2979 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2983 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2986 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2987 TCP(sport=1234, dport=1234))
2988 self.pg0.add_stream(p)
2989 self.pg_enable_capture(self.pg_interfaces)
2991 p = self.pg1.get_capture(1)
2994 self.assertEqual(packet[IP].src, nat_ip)
2995 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2996 self.assertTrue(packet.haslayer(GRE))
2997 self.assert_packet_checksums_valid(packet)
2999 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3003 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3004 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3006 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3007 TCP(sport=1234, dport=1234))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 p = self.pg0.get_capture(1)
3014 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3015 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3016 self.assertTrue(packet.haslayer(GRE))
3017 self.assert_packet_checksums_valid(packet)
3019 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3022 def test_hairpinning_static_unknown_proto(self):
3023 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3025 host = self.pg0.remote_hosts[0]
3026 server = self.pg0.remote_hosts[1]
3028 host_nat_ip = "10.0.0.10"
3029 server_nat_ip = "10.0.0.11"
3031 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3032 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3033 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3034 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3038 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3039 IP(src=host.ip4, dst=server_nat_ip) /
3041 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3042 TCP(sport=1234, dport=1234))
3043 self.pg0.add_stream(p)
3044 self.pg_enable_capture(self.pg_interfaces)
3046 p = self.pg0.get_capture(1)
3049 self.assertEqual(packet[IP].src, host_nat_ip)
3050 self.assertEqual(packet[IP].dst, server.ip4)
3051 self.assertTrue(packet.haslayer(GRE))
3052 self.assert_packet_checksums_valid(packet)
3054 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3058 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3059 IP(src=server.ip4, dst=host_nat_ip) /
3061 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3062 TCP(sport=1234, dport=1234))
3063 self.pg0.add_stream(p)
3064 self.pg_enable_capture(self.pg_interfaces)
3066 p = self.pg0.get_capture(1)
3069 self.assertEqual(packet[IP].src, server_nat_ip)
3070 self.assertEqual(packet[IP].dst, host.ip4)
3071 self.assertTrue(packet.haslayer(GRE))
3072 self.assert_packet_checksums_valid(packet)
3074 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3077 def test_output_feature(self):
3078 """ NAT44 interface output feature (in2out postrouting) """
3079 self.nat44_add_address(self.nat_addr)
3080 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3081 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3082 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3086 pkts = self.create_stream_in(self.pg0, self.pg3)
3087 self.pg0.add_stream(pkts)
3088 self.pg_enable_capture(self.pg_interfaces)
3090 capture = self.pg3.get_capture(len(pkts))
3091 self.verify_capture_out(capture)
3094 pkts = self.create_stream_out(self.pg3)
3095 self.pg3.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg0.get_capture(len(pkts))
3099 self.verify_capture_in(capture, self.pg0)
3101 # from non-NAT interface to NAT inside interface
3102 pkts = self.create_stream_in(self.pg2, self.pg0)
3103 self.pg2.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg0.get_capture(len(pkts))
3107 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3109 def test_output_feature_vrf_aware(self):
3110 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3111 nat_ip_vrf10 = "10.0.0.10"
3112 nat_ip_vrf20 = "10.0.0.20"
3114 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3115 dst_address_length=32,
3116 next_hop_address=self.pg3.remote_ip4n,
3117 next_hop_sw_if_index=self.pg3.sw_if_index,
3119 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3120 dst_address_length=32,
3121 next_hop_address=self.pg3.remote_ip4n,
3122 next_hop_sw_if_index=self.pg3.sw_if_index,
3125 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3126 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3127 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3128 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3129 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3133 pkts = self.create_stream_in(self.pg4, self.pg3)
3134 self.pg4.add_stream(pkts)
3135 self.pg_enable_capture(self.pg_interfaces)
3137 capture = self.pg3.get_capture(len(pkts))
3138 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3141 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3142 self.pg3.add_stream(pkts)
3143 self.pg_enable_capture(self.pg_interfaces)
3145 capture = self.pg4.get_capture(len(pkts))
3146 self.verify_capture_in(capture, self.pg4)
3149 pkts = self.create_stream_in(self.pg6, self.pg3)
3150 self.pg6.add_stream(pkts)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 capture = self.pg3.get_capture(len(pkts))
3154 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3157 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3158 self.pg3.add_stream(pkts)
3159 self.pg_enable_capture(self.pg_interfaces)
3161 capture = self.pg6.get_capture(len(pkts))
3162 self.verify_capture_in(capture, self.pg6)
3164 def test_output_feature_hairpinning(self):
3165 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3166 host = self.pg0.remote_hosts[0]
3167 server = self.pg0.remote_hosts[1]
3170 server_in_port = 5678
3171 server_out_port = 8765
3173 self.nat44_add_address(self.nat_addr)
3174 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3175 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3178 # add static mapping for server
3179 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3180 server_in_port, server_out_port,
3181 proto=IP_PROTOS.tcp)
3183 # send packet from host to server
3184 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3185 IP(src=host.ip4, dst=self.nat_addr) /
3186 TCP(sport=host_in_port, dport=server_out_port))
3187 self.pg0.add_stream(p)
3188 self.pg_enable_capture(self.pg_interfaces)
3190 capture = self.pg0.get_capture(1)
3195 self.assertEqual(ip.src, self.nat_addr)
3196 self.assertEqual(ip.dst, server.ip4)
3197 self.assertNotEqual(tcp.sport, host_in_port)
3198 self.assertEqual(tcp.dport, server_in_port)
3199 self.assert_packet_checksums_valid(p)
3200 host_out_port = tcp.sport
3202 self.logger.error(ppp("Unexpected or invalid packet:", p))
3205 # send reply from server to host
3206 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3207 IP(src=server.ip4, dst=self.nat_addr) /
3208 TCP(sport=server_in_port, dport=host_out_port))
3209 self.pg0.add_stream(p)
3210 self.pg_enable_capture(self.pg_interfaces)
3212 capture = self.pg0.get_capture(1)
3217 self.assertEqual(ip.src, self.nat_addr)
3218 self.assertEqual(ip.dst, host.ip4)
3219 self.assertEqual(tcp.sport, server_out_port)
3220 self.assertEqual(tcp.dport, host_in_port)
3221 self.assert_packet_checksums_valid(p)
3223 self.logger.error(ppp("Unexpected or invalid packet:", p))
3226 def test_one_armed_nat44(self):
3227 """ One armed NAT44 """
3228 remote_host = self.pg9.remote_hosts[0]
3229 local_host = self.pg9.remote_hosts[1]
3232 self.nat44_add_address(self.nat_addr)
3233 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3234 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3238 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3239 IP(src=local_host.ip4, dst=remote_host.ip4) /
3240 TCP(sport=12345, dport=80))
3241 self.pg9.add_stream(p)
3242 self.pg_enable_capture(self.pg_interfaces)
3244 capture = self.pg9.get_capture(1)
3249 self.assertEqual(ip.src, self.nat_addr)
3250 self.assertEqual(ip.dst, remote_host.ip4)
3251 self.assertNotEqual(tcp.sport, 12345)
3252 external_port = tcp.sport
3253 self.assertEqual(tcp.dport, 80)
3254 self.assert_packet_checksums_valid(p)
3256 self.logger.error(ppp("Unexpected or invalid packet:", p))
3260 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3261 IP(src=remote_host.ip4, dst=self.nat_addr) /
3262 TCP(sport=80, dport=external_port))
3263 self.pg9.add_stream(p)
3264 self.pg_enable_capture(self.pg_interfaces)
3266 capture = self.pg9.get_capture(1)
3271 self.assertEqual(ip.src, remote_host.ip4)
3272 self.assertEqual(ip.dst, local_host.ip4)
3273 self.assertEqual(tcp.sport, 80)
3274 self.assertEqual(tcp.dport, 12345)
3275 self.assert_packet_checksums_valid(p)
3277 self.logger.error(ppp("Unexpected or invalid packet:", p))
3280 def test_del_session(self):
3281 """ Delete NAT44 session """
3282 self.nat44_add_address(self.nat_addr)
3283 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3284 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3287 pkts = self.create_stream_in(self.pg0, self.pg1)
3288 self.pg0.add_stream(pkts)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 self.pg1.get_capture(len(pkts))
3293 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3294 nsessions = len(sessions)
3296 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3297 sessions[0].inside_port,
3298 sessions[0].protocol)
3299 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3300 sessions[1].outside_port,
3301 sessions[1].protocol,
3304 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3305 self.assertEqual(nsessions - len(sessions), 2)
3307 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3308 sessions[0].inside_port,
3309 sessions[0].protocol)
3311 self.verify_no_nat44_user()
3313 def test_set_get_reass(self):
3314 """ NAT44 set/get virtual fragmentation reassembly """
3315 reas_cfg1 = self.vapi.nat_get_reass()
3317 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3318 max_reass=reas_cfg1.ip4_max_reass * 2,
3319 max_frag=reas_cfg1.ip4_max_frag * 2)
3321 reas_cfg2 = self.vapi.nat_get_reass()
3323 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3324 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3325 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3327 self.vapi.nat_set_reass(drop_frag=1)
3328 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3330 def test_frag_in_order(self):
3331 """ NAT44 translate fragments arriving in order """
3333 self.nat44_add_address(self.nat_addr)
3334 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3335 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3338 self.frag_in_order(proto=IP_PROTOS.tcp)
3339 self.frag_in_order(proto=IP_PROTOS.udp)
3340 self.frag_in_order(proto=IP_PROTOS.icmp)
3342 def test_reass_hairpinning(self):
3343 """ NAT44 fragments hairpinning """
3345 self.server = self.pg0.remote_hosts[1]
3346 self.host_in_port = random.randint(1025, 65535)
3347 self.server_in_port = random.randint(1025, 65535)
3348 self.server_out_port = random.randint(1025, 65535)
3350 self.nat44_add_address(self.nat_addr)
3351 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3352 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3354 # add static mapping for server
3355 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3356 self.server_in_port,
3357 self.server_out_port,
3358 proto=IP_PROTOS.tcp)
3359 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3360 self.server_in_port,
3361 self.server_out_port,
3362 proto=IP_PROTOS.udp)
3363 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3365 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3366 self.reass_hairpinning(proto=IP_PROTOS.udp)
3367 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3369 def test_frag_out_of_order(self):
3370 """ NAT44 translate fragments arriving out of order """
3372 self.nat44_add_address(self.nat_addr)
3373 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3374 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3377 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3378 self.frag_out_of_order(proto=IP_PROTOS.udp)
3379 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3381 def test_port_restricted(self):
3382 """ Port restricted NAT44 (MAP-E CE) """
3383 self.nat44_add_address(self.nat_addr)
3384 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3385 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3387 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3392 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3393 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3394 TCP(sport=4567, dport=22))
3395 self.pg0.add_stream(p)
3396 self.pg_enable_capture(self.pg_interfaces)
3398 capture = self.pg1.get_capture(1)
3403 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3404 self.assertEqual(ip.src, self.nat_addr)
3405 self.assertEqual(tcp.dport, 22)
3406 self.assertNotEqual(tcp.sport, 4567)
3407 self.assertEqual((tcp.sport >> 6) & 63, 10)
3408 self.assert_packet_checksums_valid(p)
3410 self.logger.error(ppp("Unexpected or invalid packet:", p))
3413 def test_port_range(self):
3414 """ External address port range """
3415 self.nat44_add_address(self.nat_addr)
3416 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3417 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3419 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3424 for port in range(0, 5):
3425 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3426 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3427 TCP(sport=1125 + port))
3429 self.pg0.add_stream(pkts)
3430 self.pg_enable_capture(self.pg_interfaces)
3432 capture = self.pg1.get_capture(3)
3435 self.assertGreaterEqual(tcp.sport, 1025)
3436 self.assertLessEqual(tcp.sport, 1027)
3438 def test_ipfix_max_frags(self):
3439 """ IPFIX logging maximum fragments pending reassembly exceeded """
3440 self.nat44_add_address(self.nat_addr)
3441 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3442 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3444 self.vapi.nat_set_reass(max_frag=1)
3445 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3446 src_address=self.pg3.local_ip4n,
3448 template_interval=10)
3449 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3450 src_port=self.ipfix_src_port)
3452 data = "A" * 4 + "B" * 16 + "C" * 3
3453 self.tcp_port_in = random.randint(1025, 65535)
3454 pkts = self.create_stream_frag(self.pg0,
3455 self.pg1.remote_ip4,
3460 self.pg0.add_stream(pkts)
3461 self.pg_enable_capture(self.pg_interfaces)
3463 self.pg1.assert_nothing_captured()
3465 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3466 capture = self.pg3.get_capture(9)
3467 ipfix = IPFIXDecoder()
3468 # first load template
3470 self.assertTrue(p.haslayer(IPFIX))
3471 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3472 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3473 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3474 self.assertEqual(p[UDP].dport, 4739)
3475 self.assertEqual(p[IPFIX].observationDomainID,
3476 self.ipfix_domain_id)
3477 if p.haslayer(Template):
3478 ipfix.add_template(p.getlayer(Template))
3479 # verify events in data set
3481 if p.haslayer(Data):
3482 data = ipfix.decode_data_set(p.getlayer(Set))
3483 self.verify_ipfix_max_fragments_ip4(data, 1,
3484 self.pg0.remote_ip4n)
3486 def test_multiple_outside_vrf(self):
3487 """ Multiple outside VRF """
3491 self.pg1.unconfig_ip4()
3492 self.pg2.unconfig_ip4()
3493 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3494 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3495 self.pg1.set_table_ip4(vrf_id1)
3496 self.pg2.set_table_ip4(vrf_id2)
3497 self.pg1.config_ip4()
3498 self.pg2.config_ip4()
3499 self.pg1.resolve_arp()
3500 self.pg2.resolve_arp()
3502 self.nat44_add_address(self.nat_addr)
3503 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3504 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3506 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3511 pkts = self.create_stream_in(self.pg0, self.pg1)
3512 self.pg0.add_stream(pkts)
3513 self.pg_enable_capture(self.pg_interfaces)
3515 capture = self.pg1.get_capture(len(pkts))
3516 self.verify_capture_out(capture, self.nat_addr)
3518 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3519 self.pg1.add_stream(pkts)
3520 self.pg_enable_capture(self.pg_interfaces)
3522 capture = self.pg0.get_capture(len(pkts))
3523 self.verify_capture_in(capture, self.pg0)
3525 self.tcp_port_in = 60303
3526 self.udp_port_in = 60304
3527 self.icmp_id_in = 60305
3530 pkts = self.create_stream_in(self.pg0, self.pg2)
3531 self.pg0.add_stream(pkts)
3532 self.pg_enable_capture(self.pg_interfaces)
3534 capture = self.pg2.get_capture(len(pkts))
3535 self.verify_capture_out(capture, self.nat_addr)
3537 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3538 self.pg2.add_stream(pkts)
3539 self.pg_enable_capture(self.pg_interfaces)
3541 capture = self.pg0.get_capture(len(pkts))
3542 self.verify_capture_in(capture, self.pg0)
3545 self.pg1.unconfig_ip4()
3546 self.pg2.unconfig_ip4()
3547 self.pg1.set_table_ip4(0)
3548 self.pg2.set_table_ip4(0)
3549 self.pg1.config_ip4()
3550 self.pg2.config_ip4()
3551 self.pg1.resolve_arp()
3552 self.pg2.resolve_arp()
3554 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3555 def test_session_timeout(self):
3556 """ NAT44 session timeouts """
3557 self.nat44_add_address(self.nat_addr)
3558 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3559 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3561 self.vapi.nat_set_timeouts(udp=5)
3565 for i in range(0, max_sessions):
3566 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3567 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3568 IP(src=src, dst=self.pg1.remote_ip4) /
3569 UDP(sport=1025, dport=53))
3571 self.pg0.add_stream(pkts)
3572 self.pg_enable_capture(self.pg_interfaces)
3574 self.pg1.get_capture(max_sessions)
3579 for i in range(0, max_sessions):
3580 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3581 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3582 IP(src=src, dst=self.pg1.remote_ip4) /
3583 UDP(sport=1026, dport=53))
3585 self.pg0.add_stream(pkts)
3586 self.pg_enable_capture(self.pg_interfaces)
3588 self.pg1.get_capture(max_sessions)
3591 users = self.vapi.nat44_user_dump()
3593 nsessions = nsessions + user.nsessions
3594 self.assertLess(nsessions, 2 * max_sessions)
3596 def test_mss_clamping(self):
3597 """ TCP MSS clamping """
3598 self.nat44_add_address(self.nat_addr)
3599 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3600 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3603 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3604 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3605 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3606 flags="S", options=[('MSS', 1400)]))
3608 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3609 self.pg0.add_stream(p)
3610 self.pg_enable_capture(self.pg_interfaces)
3612 capture = self.pg1.get_capture(1)
3613 # Negotiated MSS value greater than configured - changed
3614 self.verify_mss_value(capture[0], 1000)
3616 self.vapi.nat_set_mss_clamping(enable=0)
3617 self.pg0.add_stream(p)
3618 self.pg_enable_capture(self.pg_interfaces)
3620 capture = self.pg1.get_capture(1)
3621 # MSS clamping disabled - negotiated MSS unchanged
3622 self.verify_mss_value(capture[0], 1400)
3624 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3625 self.pg0.add_stream(p)
3626 self.pg_enable_capture(self.pg_interfaces)
3628 capture = self.pg1.get_capture(1)
3629 # Negotiated MSS value smaller than configured - unchanged
3630 self.verify_mss_value(capture[0], 1400)
3633 super(TestNAT44, self).tearDown()
3634 if not self.vpp_dead:
3635 self.logger.info(self.vapi.cli("show nat44 addresses"))
3636 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3637 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3638 self.logger.info(self.vapi.cli("show nat44 interface address"))
3639 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3640 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3641 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3642 self.logger.info(self.vapi.cli("show nat timeouts"))
3644 self.vapi.cli("show nat addr-port-assignment-alg"))
3646 self.vapi.cli("clear logging")
3649 class TestNAT44EndpointDependent(MethodHolder):
3650 """ Endpoint-Dependent mapping and filtering test cases """
3653 def setUpConstants(cls):
3654 super(TestNAT44EndpointDependent, cls).setUpConstants()
3655 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3658 def setUpClass(cls):
3659 super(TestNAT44EndpointDependent, cls).setUpClass()
3660 cls.vapi.cli("set log class nat level debug")
3662 cls.tcp_port_in = 6303
3663 cls.tcp_port_out = 6303
3664 cls.udp_port_in = 6304
3665 cls.udp_port_out = 6304
3666 cls.icmp_id_in = 6305
3667 cls.icmp_id_out = 6305
3668 cls.nat_addr = '10.0.0.3'
3669 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3670 cls.ipfix_src_port = 4739
3671 cls.ipfix_domain_id = 1
3672 cls.tcp_external_port = 80
3674 cls.create_pg_interfaces(range(7))
3675 cls.interfaces = list(cls.pg_interfaces[0:3])
3677 for i in cls.interfaces:
3682 cls.pg0.generate_remote_hosts(3)
3683 cls.pg0.configure_ipv4_neighbors()
3687 cls.pg4.generate_remote_hosts(2)
3688 cls.pg4.config_ip4()
3689 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3690 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3694 cls.pg4.resolve_arp()
3695 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3696 cls.pg4.resolve_arp()
3698 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3699 cls.vapi.ip_table_add_del(1, is_add=1)
3701 cls.pg5._local_ip4 = "10.1.1.1"
3702 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3704 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3705 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3706 socket.AF_INET, cls.pg5.remote_ip4)
3707 cls.pg5.set_table_ip4(1)
3708 cls.pg5.config_ip4()
3710 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3711 dst_address_length=32,
3713 next_hop_sw_if_index=cls.pg5.sw_if_index,
3714 next_hop_address=zero_ip4n)
3716 cls.pg6._local_ip4 = "10.1.2.1"
3717 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3719 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3720 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3721 socket.AF_INET, cls.pg6.remote_ip4)
3722 cls.pg6.set_table_ip4(1)
3723 cls.pg6.config_ip4()
3725 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3726 dst_address_length=32,
3728 next_hop_sw_if_index=cls.pg6.sw_if_index,
3729 next_hop_address=zero_ip4n)
3731 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3732 dst_address_length=16,
3733 next_hop_address=zero_ip4n,
3735 next_hop_table_id=1)
3736 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3737 dst_address_length=0,
3738 next_hop_address=zero_ip4n,
3740 next_hop_table_id=0)
3741 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3742 dst_address_length=0,
3744 next_hop_sw_if_index=cls.pg1.sw_if_index,
3745 next_hop_address=cls.pg1.local_ip4n)
3747 cls.pg5.resolve_arp()
3748 cls.pg6.resolve_arp()
3751 super(TestNAT44EndpointDependent, cls).tearDownClass()
3754 def test_frag_in_order(self):
3755 """ NAT44 translate fragments arriving in order """
3756 self.nat44_add_address(self.nat_addr)
3757 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3758 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3760 self.frag_in_order(proto=IP_PROTOS.tcp)
3761 self.frag_in_order(proto=IP_PROTOS.udp)
3762 self.frag_in_order(proto=IP_PROTOS.icmp)
3764 def test_frag_in_order_dont_translate(self):
3765 """ NAT44 don't translate fragments arriving in order """
3766 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3767 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3769 self.vapi.nat44_forwarding_enable_disable(enable=True)
3770 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3772 def test_frag_out_of_order(self):
3773 """ NAT44 translate fragments arriving out of order """
3774 self.nat44_add_address(self.nat_addr)
3775 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3776 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3778 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3779 self.frag_out_of_order(proto=IP_PROTOS.udp)
3780 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3782 def test_frag_out_of_order_dont_translate(self):
3783 """ NAT44 don't translate fragments arriving out of order """
3784 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3785 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3787 self.vapi.nat44_forwarding_enable_disable(enable=True)
3788 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3790 def test_frag_in_order_in_plus_out(self):
3791 """ in+out interface fragments in order """
3792 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3793 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3795 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3796 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3799 self.server = self.pg1.remote_hosts[0]
3801 self.server_in_addr = self.server.ip4
3802 self.server_out_addr = '11.11.11.11'
3803 self.server_in_port = random.randint(1025, 65535)
3804 self.server_out_port = random.randint(1025, 65535)
3806 self.nat44_add_address(self.server_out_addr)
3808 # add static mappings for server
3809 self.nat44_add_static_mapping(self.server_in_addr,
3810 self.server_out_addr,
3811 self.server_in_port,
3812 self.server_out_port,
3813 proto=IP_PROTOS.tcp)
3814 self.nat44_add_static_mapping(self.server_in_addr,
3815 self.server_out_addr,
3816 self.server_in_port,
3817 self.server_out_port,
3818 proto=IP_PROTOS.udp)
3819 self.nat44_add_static_mapping(self.server_in_addr,
3820 self.server_out_addr,
3821 proto=IP_PROTOS.icmp)
3823 self.vapi.nat_set_reass(timeout=10)
3825 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3826 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3827 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3829 def test_frag_out_of_order_in_plus_out(self):
3830 """ in+out interface fragments out of order """
3831 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3832 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3834 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3835 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3838 self.server = self.pg1.remote_hosts[0]
3840 self.server_in_addr = self.server.ip4
3841 self.server_out_addr = '11.11.11.11'
3842 self.server_in_port = random.randint(1025, 65535)
3843 self.server_out_port = random.randint(1025, 65535)
3845 self.nat44_add_address(self.server_out_addr)
3847 # add static mappings for server
3848 self.nat44_add_static_mapping(self.server_in_addr,
3849 self.server_out_addr,
3850 self.server_in_port,
3851 self.server_out_port,
3852 proto=IP_PROTOS.tcp)
3853 self.nat44_add_static_mapping(self.server_in_addr,
3854 self.server_out_addr,
3855 self.server_in_port,
3856 self.server_out_port,
3857 proto=IP_PROTOS.udp)
3858 self.nat44_add_static_mapping(self.server_in_addr,
3859 self.server_out_addr,
3860 proto=IP_PROTOS.icmp)
3862 self.vapi.nat_set_reass(timeout=10)
3864 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3865 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3866 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3868 def test_reass_hairpinning(self):
3869 """ NAT44 fragments hairpinning """
3870 self.server = self.pg0.remote_hosts[1]
3871 self.host_in_port = random.randint(1025, 65535)
3872 self.server_in_port = random.randint(1025, 65535)
3873 self.server_out_port = random.randint(1025, 65535)
3875 self.nat44_add_address(self.nat_addr)
3876 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3877 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3879 # add static mapping for server
3880 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3881 self.server_in_port,
3882 self.server_out_port,
3883 proto=IP_PROTOS.tcp)
3884 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3885 self.server_in_port,
3886 self.server_out_port,
3887 proto=IP_PROTOS.udp)
3888 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3890 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3891 self.reass_hairpinning(proto=IP_PROTOS.udp)
3892 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3894 def test_dynamic(self):
3895 """ NAT44 dynamic translation test """
3897 self.nat44_add_address(self.nat_addr)
3898 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3899 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3902 nat_config = self.vapi.nat_show_config()
3903 self.assertEqual(1, nat_config.endpoint_dependent)
3906 pkts = self.create_stream_in(self.pg0, self.pg1)
3907 self.pg0.add_stream(pkts)
3908 self.pg_enable_capture(self.pg_interfaces)
3910 capture = self.pg1.get_capture(len(pkts))
3911 self.verify_capture_out(capture)
3914 pkts = self.create_stream_out(self.pg1)
3915 self.pg1.add_stream(pkts)
3916 self.pg_enable_capture(self.pg_interfaces)
3918 capture = self.pg0.get_capture(len(pkts))
3919 self.verify_capture_in(capture, self.pg0)
3921 def test_forwarding(self):
3922 """ NAT44 forwarding test """
3924 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3925 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3927 self.vapi.nat44_forwarding_enable_disable(1)
3929 real_ip = self.pg0.remote_ip4n
3930 alias_ip = self.nat_addr_n
3931 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3932 external_ip=alias_ip)
3935 # in2out - static mapping match
3937 pkts = self.create_stream_out(self.pg1)
3938 self.pg1.add_stream(pkts)
3939 self.pg_enable_capture(self.pg_interfaces)
3941 capture = self.pg0.get_capture(len(pkts))
3942 self.verify_capture_in(capture, self.pg0)
3944 pkts = self.create_stream_in(self.pg0, self.pg1)
3945 self.pg0.add_stream(pkts)
3946 self.pg_enable_capture(self.pg_interfaces)
3948 capture = self.pg1.get_capture(len(pkts))
3949 self.verify_capture_out(capture, same_port=True)
3951 # in2out - no static mapping match
3953 host0 = self.pg0.remote_hosts[0]
3954 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3956 pkts = self.create_stream_out(self.pg1,
3957 dst_ip=self.pg0.remote_ip4,
3958 use_inside_ports=True)
3959 self.pg1.add_stream(pkts)
3960 self.pg_enable_capture(self.pg_interfaces)
3962 capture = self.pg0.get_capture(len(pkts))
3963 self.verify_capture_in(capture, self.pg0)
3965 pkts = self.create_stream_in(self.pg0, self.pg1)
3966 self.pg0.add_stream(pkts)
3967 self.pg_enable_capture(self.pg_interfaces)
3969 capture = self.pg1.get_capture(len(pkts))
3970 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3973 self.pg0.remote_hosts[0] = host0
3975 user = self.pg0.remote_hosts[1]
3976 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3977 self.assertEqual(len(sessions), 3)
3978 self.assertTrue(sessions[0].ext_host_valid)
3979 self.vapi.nat44_del_session(
3980 sessions[0].inside_ip_address,
3981 sessions[0].inside_port,
3982 sessions[0].protocol,
3983 ext_host_address=sessions[0].ext_host_address,
3984 ext_host_port=sessions[0].ext_host_port)
3985 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3986 self.assertEqual(len(sessions), 2)
3989 self.vapi.nat44_forwarding_enable_disable(0)
3990 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3991 external_ip=alias_ip,
3994 def test_static_lb(self):
3995 """ NAT44 local service load balancing """
3996 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3999 server1 = self.pg0.remote_hosts[0]
4000 server2 = self.pg0.remote_hosts[1]
4002 locals = [{'addr': server1.ip4n,
4006 {'addr': server2.ip4n,
4011 self.nat44_add_address(self.nat_addr)
4012 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4015 local_num=len(locals),
4017 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4018 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4021 # from client to service
4022 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4023 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4024 TCP(sport=12345, dport=external_port))
4025 self.pg1.add_stream(p)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 capture = self.pg0.get_capture(1)
4034 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4035 if ip.dst == server1.ip4:
4039 self.assertEqual(tcp.dport, local_port)
4040 self.assert_packet_checksums_valid(p)
4042 self.logger.error(ppp("Unexpected or invalid packet:", p))
4045 # from service back to client
4046 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4047 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4048 TCP(sport=local_port, dport=12345))
4049 self.pg0.add_stream(p)
4050 self.pg_enable_capture(self.pg_interfaces)
4052 capture = self.pg1.get_capture(1)
4057 self.assertEqual(ip.src, self.nat_addr)
4058 self.assertEqual(tcp.sport, external_port)
4059 self.assert_packet_checksums_valid(p)
4061 self.logger.error(ppp("Unexpected or invalid packet:", p))
4064 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4065 self.assertEqual(len(sessions), 1)
4066 self.assertTrue(sessions[0].ext_host_valid)
4067 self.vapi.nat44_del_session(
4068 sessions[0].inside_ip_address,
4069 sessions[0].inside_port,
4070 sessions[0].protocol,
4071 ext_host_address=sessions[0].ext_host_address,
4072 ext_host_port=sessions[0].ext_host_port)
4073 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4074 self.assertEqual(len(sessions), 0)
4076 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4077 def test_static_lb_multi_clients(self):
4078 """ NAT44 local service load balancing - multiple clients"""
4080 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4083 server1 = self.pg0.remote_hosts[0]
4084 server2 = self.pg0.remote_hosts[1]
4086 locals = [{'addr': server1.ip4n,
4090 {'addr': server2.ip4n,
4095 self.nat44_add_address(self.nat_addr)
4096 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4099 local_num=len(locals),
4101 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4102 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4107 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4109 for client in clients:
4110 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4111 IP(src=client, dst=self.nat_addr) /
4112 TCP(sport=12345, dport=external_port))
4114 self.pg1.add_stream(pkts)
4115 self.pg_enable_capture(self.pg_interfaces)
4117 capture = self.pg0.get_capture(len(pkts))
4119 if p[IP].dst == server1.ip4:
4123 self.assertTrue(server1_n > server2_n)
4125 def test_static_lb_2(self):
4126 """ NAT44 local service load balancing (asymmetrical rule) """
4127 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4130 server1 = self.pg0.remote_hosts[0]
4131 server2 = self.pg0.remote_hosts[1]
4133 locals = [{'addr': server1.ip4n,
4137 {'addr': server2.ip4n,
4142 self.vapi.nat44_forwarding_enable_disable(1)
4143 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4147 local_num=len(locals),
4149 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4150 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4153 # from client to service
4154 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4156 TCP(sport=12345, dport=external_port))
4157 self.pg1.add_stream(p)
4158 self.pg_enable_capture(self.pg_interfaces)
4160 capture = self.pg0.get_capture(1)
4166 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4167 if ip.dst == server1.ip4:
4171 self.assertEqual(tcp.dport, local_port)
4172 self.assert_packet_checksums_valid(p)
4174 self.logger.error(ppp("Unexpected or invalid packet:", p))
4177 # from service back to client
4178 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4179 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4180 TCP(sport=local_port, dport=12345))
4181 self.pg0.add_stream(p)
4182 self.pg_enable_capture(self.pg_interfaces)
4184 capture = self.pg1.get_capture(1)
4189 self.assertEqual(ip.src, self.nat_addr)
4190 self.assertEqual(tcp.sport, external_port)
4191 self.assert_packet_checksums_valid(p)
4193 self.logger.error(ppp("Unexpected or invalid packet:", p))
4196 # from client to server (no translation)
4197 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4198 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4199 TCP(sport=12346, dport=local_port))
4200 self.pg1.add_stream(p)
4201 self.pg_enable_capture(self.pg_interfaces)
4203 capture = self.pg0.get_capture(1)
4209 self.assertEqual(ip.dst, server1.ip4)
4210 self.assertEqual(tcp.dport, local_port)
4211 self.assert_packet_checksums_valid(p)
4213 self.logger.error(ppp("Unexpected or invalid packet:", p))
4216 # from service back to client (no translation)
4217 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4218 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4219 TCP(sport=local_port, dport=12346))
4220 self.pg0.add_stream(p)
4221 self.pg_enable_capture(self.pg_interfaces)
4223 capture = self.pg1.get_capture(1)
4228 self.assertEqual(ip.src, server1.ip4)
4229 self.assertEqual(tcp.sport, local_port)
4230 self.assert_packet_checksums_valid(p)
4232 self.logger.error(ppp("Unexpected or invalid packet:", p))
4235 def test_lb_affinity(self):
4236 """ NAT44 local service load balancing affinity """
4237 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4240 server1 = self.pg0.remote_hosts[0]
4241 server2 = self.pg0.remote_hosts[1]
4243 locals = [{'addr': server1.ip4n,
4247 {'addr': server2.ip4n,
4252 self.nat44_add_address(self.nat_addr)
4253 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4257 local_num=len(locals),
4259 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4260 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4263 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4264 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4265 TCP(sport=1025, dport=external_port))
4266 self.pg1.add_stream(p)
4267 self.pg_enable_capture(self.pg_interfaces)
4269 capture = self.pg0.get_capture(1)
4270 backend = capture[0][IP].dst
4272 sessions = self.vapi.nat44_user_session_dump(
4273 socket.inet_pton(socket.AF_INET, backend), 0)
4274 self.assertEqual(len(sessions), 1)
4275 self.assertTrue(sessions[0].ext_host_valid)
4276 self.vapi.nat44_del_session(
4277 sessions[0].inside_ip_address,
4278 sessions[0].inside_port,
4279 sessions[0].protocol,
4280 ext_host_address=sessions[0].ext_host_address,
4281 ext_host_port=sessions[0].ext_host_port)
4284 for port in range(1030, 1100):
4285 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4286 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4287 TCP(sport=port, dport=external_port))
4289 self.pg1.add_stream(pkts)
4290 self.pg_enable_capture(self.pg_interfaces)
4292 capture = self.pg0.get_capture(len(pkts))
4294 self.assertEqual(p[IP].dst, backend)
4296 def test_unknown_proto(self):
4297 """ NAT44 translate packet with unknown protocol """
4298 self.nat44_add_address(self.nat_addr)
4299 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4300 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4304 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4305 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4306 TCP(sport=self.tcp_port_in, dport=20))
4307 self.pg0.add_stream(p)
4308 self.pg_enable_capture(self.pg_interfaces)
4310 p = self.pg1.get_capture(1)
4312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4313 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4315 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4316 TCP(sport=1234, dport=1234))
4317 self.pg0.add_stream(p)
4318 self.pg_enable_capture(self.pg_interfaces)
4320 p = self.pg1.get_capture(1)
4323 self.assertEqual(packet[IP].src, self.nat_addr)
4324 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4325 self.assertTrue(packet.haslayer(GRE))
4326 self.assert_packet_checksums_valid(packet)
4328 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4332 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4333 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4335 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4336 TCP(sport=1234, dport=1234))
4337 self.pg1.add_stream(p)
4338 self.pg_enable_capture(self.pg_interfaces)
4340 p = self.pg0.get_capture(1)
4343 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4344 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4345 self.assertTrue(packet.haslayer(GRE))
4346 self.assert_packet_checksums_valid(packet)
4348 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4351 def test_hairpinning_unknown_proto(self):
4352 """ NAT44 translate packet with unknown protocol - hairpinning """
4353 host = self.pg0.remote_hosts[0]
4354 server = self.pg0.remote_hosts[1]
4356 server_out_port = 8765
4357 server_nat_ip = "10.0.0.11"
4359 self.nat44_add_address(self.nat_addr)
4360 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4361 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4364 # add static mapping for server
4365 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4368 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4369 IP(src=host.ip4, dst=server_nat_ip) /
4370 TCP(sport=host_in_port, dport=server_out_port))
4371 self.pg0.add_stream(p)
4372 self.pg_enable_capture(self.pg_interfaces)
4374 self.pg0.get_capture(1)
4376 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4377 IP(src=host.ip4, dst=server_nat_ip) /
4379 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4380 TCP(sport=1234, dport=1234))
4381 self.pg0.add_stream(p)
4382 self.pg_enable_capture(self.pg_interfaces)
4384 p = self.pg0.get_capture(1)
4387 self.assertEqual(packet[IP].src, self.nat_addr)
4388 self.assertEqual(packet[IP].dst, server.ip4)
4389 self.assertTrue(packet.haslayer(GRE))
4390 self.assert_packet_checksums_valid(packet)
4392 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4396 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4397 IP(src=server.ip4, dst=self.nat_addr) /
4399 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4400 TCP(sport=1234, dport=1234))
4401 self.pg0.add_stream(p)
4402 self.pg_enable_capture(self.pg_interfaces)
4404 p = self.pg0.get_capture(1)
4407 self.assertEqual(packet[IP].src, server_nat_ip)
4408 self.assertEqual(packet[IP].dst, host.ip4)
4409 self.assertTrue(packet.haslayer(GRE))
4410 self.assert_packet_checksums_valid(packet)
4412 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4415 def test_output_feature_and_service(self):
4416 """ NAT44 interface output feature and services """
4417 external_addr = '1.2.3.4'
4421 self.vapi.nat44_forwarding_enable_disable(1)
4422 self.nat44_add_address(self.nat_addr)
4423 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4424 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4425 local_port, external_port,
4426 proto=IP_PROTOS.tcp, out2in_only=1)
4427 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4428 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4430 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4433 # from client to service
4434 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4435 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4436 TCP(sport=12345, dport=external_port))
4437 self.pg1.add_stream(p)
4438 self.pg_enable_capture(self.pg_interfaces)
4440 capture = self.pg0.get_capture(1)
4445 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4446 self.assertEqual(tcp.dport, local_port)
4447 self.assert_packet_checksums_valid(p)
4449 self.logger.error(ppp("Unexpected or invalid packet:", p))
4452 # from service back to client
4453 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4454 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4455 TCP(sport=local_port, dport=12345))
4456 self.pg0.add_stream(p)
4457 self.pg_enable_capture(self.pg_interfaces)
4459 capture = self.pg1.get_capture(1)
4464 self.assertEqual(ip.src, external_addr)
4465 self.assertEqual(tcp.sport, external_port)
4466 self.assert_packet_checksums_valid(p)
4468 self.logger.error(ppp("Unexpected or invalid packet:", p))
4471 # from local network host to external network
4472 pkts = self.create_stream_in(self.pg0, self.pg1)
4473 self.pg0.add_stream(pkts)
4474 self.pg_enable_capture(self.pg_interfaces)
4476 capture = self.pg1.get_capture(len(pkts))
4477 self.verify_capture_out(capture)
4478 pkts = self.create_stream_in(self.pg0, self.pg1)
4479 self.pg0.add_stream(pkts)
4480 self.pg_enable_capture(self.pg_interfaces)
4482 capture = self.pg1.get_capture(len(pkts))
4483 self.verify_capture_out(capture)
4485 # from external network back to local network host
4486 pkts = self.create_stream_out(self.pg1)
4487 self.pg1.add_stream(pkts)
4488 self.pg_enable_capture(self.pg_interfaces)
4490 capture = self.pg0.get_capture(len(pkts))
4491 self.verify_capture_in(capture, self.pg0)
4493 def test_output_feature_and_service2(self):
4494 """ NAT44 interface output feature and service host direct access """
4495 self.vapi.nat44_forwarding_enable_disable(1)
4496 self.nat44_add_address(self.nat_addr)
4497 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4500 # session initiaded from service host - translate
4501 pkts = self.create_stream_in(self.pg0, self.pg1)
4502 self.pg0.add_stream(pkts)
4503 self.pg_enable_capture(self.pg_interfaces)
4505 capture = self.pg1.get_capture(len(pkts))
4506 self.verify_capture_out(capture)
4508 pkts = self.create_stream_out(self.pg1)
4509 self.pg1.add_stream(pkts)
4510 self.pg_enable_capture(self.pg_interfaces)
4512 capture = self.pg0.get_capture(len(pkts))
4513 self.verify_capture_in(capture, self.pg0)
4515 # session initiaded from remote host - do not translate
4516 self.tcp_port_in = 60303
4517 self.udp_port_in = 60304
4518 self.icmp_id_in = 60305
4519 pkts = self.create_stream_out(self.pg1,
4520 self.pg0.remote_ip4,
4521 use_inside_ports=True)
4522 self.pg1.add_stream(pkts)
4523 self.pg_enable_capture(self.pg_interfaces)
4525 capture = self.pg0.get_capture(len(pkts))
4526 self.verify_capture_in(capture, self.pg0)
4528 pkts = self.create_stream_in(self.pg0, self.pg1)
4529 self.pg0.add_stream(pkts)
4530 self.pg_enable_capture(self.pg_interfaces)
4532 capture = self.pg1.get_capture(len(pkts))
4533 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4536 def test_output_feature_and_service3(self):
4537 """ NAT44 interface output feature and DST NAT """
4538 external_addr = '1.2.3.4'
4542 self.vapi.nat44_forwarding_enable_disable(1)
4543 self.nat44_add_address(self.nat_addr)
4544 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4545 local_port, external_port,
4546 proto=IP_PROTOS.tcp, out2in_only=1)
4547 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4548 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4550 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4553 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4554 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4555 TCP(sport=12345, dport=external_port))
4556 self.pg0.add_stream(p)
4557 self.pg_enable_capture(self.pg_interfaces)
4559 capture = self.pg1.get_capture(1)
4564 self.assertEqual(ip.src, self.pg0.remote_ip4)
4565 self.assertEqual(tcp.sport, 12345)
4566 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4567 self.assertEqual(tcp.dport, local_port)
4568 self.assert_packet_checksums_valid(p)
4570 self.logger.error(ppp("Unexpected or invalid packet:", p))
4573 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4574 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4575 TCP(sport=local_port, dport=12345))
4576 self.pg1.add_stream(p)
4577 self.pg_enable_capture(self.pg_interfaces)
4579 capture = self.pg0.get_capture(1)
4584 self.assertEqual(ip.src, external_addr)
4585 self.assertEqual(tcp.sport, external_port)
4586 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4587 self.assertEqual(tcp.dport, 12345)
4588 self.assert_packet_checksums_valid(p)
4590 self.logger.error(ppp("Unexpected or invalid packet:", p))
4593 def test_next_src_nat(self):
4594 """ On way back forward packet to nat44-in2out node. """
4595 twice_nat_addr = '10.0.1.3'
4598 post_twice_nat_port = 0
4600 self.vapi.nat44_forwarding_enable_disable(1)
4601 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4602 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4603 local_port, external_port,
4604 proto=IP_PROTOS.tcp, out2in_only=1,
4605 self_twice_nat=1, vrf_id=1)
4606 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4609 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4610 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4611 TCP(sport=12345, dport=external_port))
4612 self.pg6.add_stream(p)
4613 self.pg_enable_capture(self.pg_interfaces)
4615 capture = self.pg6.get_capture(1)
4620 self.assertEqual(ip.src, twice_nat_addr)
4621 self.assertNotEqual(tcp.sport, 12345)
4622 post_twice_nat_port = tcp.sport
4623 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4624 self.assertEqual(tcp.dport, local_port)
4625 self.assert_packet_checksums_valid(p)
4627 self.logger.error(ppp("Unexpected or invalid packet:", p))
4630 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4631 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4632 TCP(sport=local_port, dport=post_twice_nat_port))
4633 self.pg6.add_stream(p)
4634 self.pg_enable_capture(self.pg_interfaces)
4636 capture = self.pg6.get_capture(1)
4641 self.assertEqual(ip.src, self.pg1.remote_ip4)
4642 self.assertEqual(tcp.sport, external_port)
4643 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4644 self.assertEqual(tcp.dport, 12345)
4645 self.assert_packet_checksums_valid(p)
4647 self.logger.error(ppp("Unexpected or invalid packet:", p))
4650 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4652 twice_nat_addr = '10.0.1.3'
4660 port_in1 = port_in+1
4661 port_in2 = port_in+2
4666 server1 = self.pg0.remote_hosts[0]
4667 server2 = self.pg0.remote_hosts[1]
4679 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4682 self.nat44_add_address(self.nat_addr)
4683 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4685 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4687 proto=IP_PROTOS.tcp,
4688 twice_nat=int(not self_twice_nat),
4689 self_twice_nat=int(self_twice_nat))
4691 locals = [{'addr': server1.ip4n,
4695 {'addr': server2.ip4n,
4699 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4700 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4704 not self_twice_nat),
4707 local_num=len(locals),
4709 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4710 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4717 assert client_id is not None
4719 client = self.pg0.remote_hosts[0]
4720 elif client_id == 2:
4721 client = self.pg0.remote_hosts[1]
4723 client = pg1.remote_hosts[0]
4724 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4725 IP(src=client.ip4, dst=self.nat_addr) /
4726 TCP(sport=eh_port_out, dport=port_out))
4728 self.pg_enable_capture(self.pg_interfaces)
4730 capture = pg0.get_capture(1)
4736 if ip.dst == server1.ip4:
4742 self.assertEqual(ip.dst, server.ip4)
4744 self.assertIn(tcp.dport, [port_in1, port_in2])
4746 self.assertEqual(tcp.dport, port_in)
4748 self.assertEqual(ip.src, twice_nat_addr)
4749 self.assertNotEqual(tcp.sport, eh_port_out)
4751 self.assertEqual(ip.src, client.ip4)
4752 self.assertEqual(tcp.sport, eh_port_out)
4754 eh_port_in = tcp.sport
4755 saved_port_in = tcp.dport
4756 self.assert_packet_checksums_valid(p)
4758 self.logger.error(ppp("Unexpected or invalid packet:", p))
4761 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4762 IP(src=server.ip4, dst=eh_addr_in) /
4763 TCP(sport=saved_port_in, dport=eh_port_in))
4765 self.pg_enable_capture(self.pg_interfaces)
4767 capture = pg1.get_capture(1)
4772 self.assertEqual(ip.dst, client.ip4)
4773 self.assertEqual(ip.src, self.nat_addr)
4774 self.assertEqual(tcp.dport, eh_port_out)
4775 self.assertEqual(tcp.sport, port_out)
4776 self.assert_packet_checksums_valid(p)
4778 self.logger.error(ppp("Unexpected or invalid packet:", p))
4782 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4783 self.assertEqual(len(sessions), 1)
4784 self.assertTrue(sessions[0].ext_host_valid)
4785 self.assertTrue(sessions[0].is_twicenat)
4786 self.vapi.nat44_del_session(
4787 sessions[0].inside_ip_address,
4788 sessions[0].inside_port,
4789 sessions[0].protocol,
4790 ext_host_address=sessions[0].ext_host_nat_address,
4791 ext_host_port=sessions[0].ext_host_nat_port)
4792 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4793 self.assertEqual(len(sessions), 0)
4795 def test_twice_nat(self):
4797 self.twice_nat_common()
4799 def test_self_twice_nat_positive(self):
4800 """ Self Twice NAT44 (positive test) """
4801 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4803 def test_self_twice_nat_negative(self):
4804 """ Self Twice NAT44 (negative test) """
4805 self.twice_nat_common(self_twice_nat=True)
4807 def test_twice_nat_lb(self):
4808 """ Twice NAT44 local service load balancing """
4809 self.twice_nat_common(lb=True)
4811 def test_self_twice_nat_lb_positive(self):
4812 """ Self Twice NAT44 local service load balancing (positive test) """
4813 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4816 def test_self_twice_nat_lb_negative(self):
4817 """ Self Twice NAT44 local service load balancing (negative test) """
4818 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4821 def test_twice_nat_interface_addr(self):
4822 """ Acquire twice NAT44 addresses from interface """
4823 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4825 # no address in NAT pool
4826 adresses = self.vapi.nat44_address_dump()
4827 self.assertEqual(0, len(adresses))
4829 # configure interface address and check NAT address pool
4830 self.pg3.config_ip4()
4831 adresses = self.vapi.nat44_address_dump()
4832 self.assertEqual(1, len(adresses))
4833 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4834 self.assertEqual(adresses[0].twice_nat, 1)
4836 # remove interface address and check NAT address pool
4837 self.pg3.unconfig_ip4()
4838 adresses = self.vapi.nat44_address_dump()
4839 self.assertEqual(0, len(adresses))
4841 def test_tcp_session_close_in(self):
4842 """ Close TCP session from inside network """
4843 self.tcp_port_out = 10505
4844 self.nat44_add_address(self.nat_addr)
4845 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4849 proto=IP_PROTOS.tcp,
4851 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4852 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4855 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4856 start_sessnum = len(sessions)
4858 self.initiate_tcp_session(self.pg0, self.pg1)
4860 # FIN packet in -> out
4861 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4862 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4863 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4864 flags="FA", seq=100, ack=300))
4865 self.pg0.add_stream(p)
4866 self.pg_enable_capture(self.pg_interfaces)
4868 self.pg1.get_capture(1)
4872 # ACK packet out -> in
4873 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4874 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4875 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4876 flags="A", seq=300, ack=101))
4879 # FIN packet out -> in
4880 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4881 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4882 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4883 flags="FA", seq=300, ack=101))
4886 self.pg1.add_stream(pkts)
4887 self.pg_enable_capture(self.pg_interfaces)
4889 self.pg0.get_capture(2)
4891 # ACK packet in -> out
4892 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4893 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4894 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4895 flags="A", seq=101, ack=301))
4896 self.pg0.add_stream(p)
4897 self.pg_enable_capture(self.pg_interfaces)
4899 self.pg1.get_capture(1)
4901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4903 self.assertEqual(len(sessions) - start_sessnum, 0)
4905 def test_tcp_session_close_out(self):
4906 """ Close TCP session from outside network """
4907 self.tcp_port_out = 10505
4908 self.nat44_add_address(self.nat_addr)
4909 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4913 proto=IP_PROTOS.tcp,
4915 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4916 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4919 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4920 start_sessnum = len(sessions)
4922 self.initiate_tcp_session(self.pg0, self.pg1)
4924 # FIN packet out -> in
4925 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4926 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4927 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4928 flags="FA", seq=100, ack=300))
4929 self.pg1.add_stream(p)
4930 self.pg_enable_capture(self.pg_interfaces)
4932 self.pg0.get_capture(1)
4934 # FIN+ACK packet in -> out
4935 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4936 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4937 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4938 flags="FA", seq=300, ack=101))
4940 self.pg0.add_stream(p)
4941 self.pg_enable_capture(self.pg_interfaces)
4943 self.pg1.get_capture(1)
4945 # ACK packet out -> in
4946 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4947 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4948 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4949 flags="A", seq=101, ack=301))
4950 self.pg1.add_stream(p)
4951 self.pg_enable_capture(self.pg_interfaces)
4953 self.pg0.get_capture(1)
4955 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4957 self.assertEqual(len(sessions) - start_sessnum, 0)
4959 def test_tcp_session_close_simultaneous(self):
4960 """ Close TCP session from inside network """
4961 self.tcp_port_out = 10505
4962 self.nat44_add_address(self.nat_addr)
4963 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4967 proto=IP_PROTOS.tcp,
4969 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4970 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4973 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4974 start_sessnum = len(sessions)
4976 self.initiate_tcp_session(self.pg0, self.pg1)
4978 # FIN 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="FA", seq=100, ack=300))
4983 self.pg0.add_stream(p)
4984 self.pg_enable_capture(self.pg_interfaces)
4986 self.pg1.get_capture(1)
4988 # FIN packet out -> in
4989 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4990 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4991 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4992 flags="FA", seq=300, ack=100))
4993 self.pg1.add_stream(p)
4994 self.pg_enable_capture(self.pg_interfaces)
4996 self.pg0.get_capture(1)
4998 # ACK packet in -> out
4999 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5000 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5001 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5002 flags="A", seq=101, ack=301))
5003 self.pg0.add_stream(p)
5004 self.pg_enable_capture(self.pg_interfaces)
5006 self.pg1.get_capture(1)
5008 # ACK packet out -> in
5009 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5010 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5011 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5012 flags="A", seq=301, ack=101))
5013 self.pg1.add_stream(p)
5014 self.pg_enable_capture(self.pg_interfaces)
5016 self.pg0.get_capture(1)
5018 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5020 self.assertEqual(len(sessions) - start_sessnum, 0)
5022 def test_one_armed_nat44_static(self):
5023 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5024 remote_host = self.pg4.remote_hosts[0]
5025 local_host = self.pg4.remote_hosts[1]
5030 self.vapi.nat44_forwarding_enable_disable(1)
5031 self.nat44_add_address(self.nat_addr, twice_nat=1)
5032 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5033 local_port, external_port,
5034 proto=IP_PROTOS.tcp, out2in_only=1,
5036 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5037 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5040 # from client to service
5041 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5042 IP(src=remote_host.ip4, dst=self.nat_addr) /
5043 TCP(sport=12345, dport=external_port))
5044 self.pg4.add_stream(p)
5045 self.pg_enable_capture(self.pg_interfaces)
5047 capture = self.pg4.get_capture(1)
5052 self.assertEqual(ip.dst, local_host.ip4)
5053 self.assertEqual(ip.src, self.nat_addr)
5054 self.assertEqual(tcp.dport, local_port)
5055 self.assertNotEqual(tcp.sport, 12345)
5056 eh_port_in = tcp.sport
5057 self.assert_packet_checksums_valid(p)
5059 self.logger.error(ppp("Unexpected or invalid packet:", p))
5062 # from service back to client
5063 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5064 IP(src=local_host.ip4, dst=self.nat_addr) /
5065 TCP(sport=local_port, dport=eh_port_in))
5066 self.pg4.add_stream(p)
5067 self.pg_enable_capture(self.pg_interfaces)
5069 capture = self.pg4.get_capture(1)
5074 self.assertEqual(ip.src, self.nat_addr)
5075 self.assertEqual(ip.dst, remote_host.ip4)
5076 self.assertEqual(tcp.sport, external_port)
5077 self.assertEqual(tcp.dport, 12345)
5078 self.assert_packet_checksums_valid(p)
5080 self.logger.error(ppp("Unexpected or invalid packet:", p))
5083 def test_static_with_port_out2(self):
5084 """ 1:1 NAPT asymmetrical rule """
5089 self.vapi.nat44_forwarding_enable_disable(1)
5090 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5091 local_port, external_port,
5092 proto=IP_PROTOS.tcp, out2in_only=1)
5093 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5094 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5097 # from client to service
5098 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5099 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5100 TCP(sport=12345, dport=external_port))
5101 self.pg1.add_stream(p)
5102 self.pg_enable_capture(self.pg_interfaces)
5104 capture = self.pg0.get_capture(1)
5109 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5110 self.assertEqual(tcp.dport, local_port)
5111 self.assert_packet_checksums_valid(p)
5113 self.logger.error(ppp("Unexpected or invalid packet:", p))
5117 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5118 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5119 ICMP(type=11) / capture[0][IP])
5120 self.pg0.add_stream(p)
5121 self.pg_enable_capture(self.pg_interfaces)
5123 capture = self.pg1.get_capture(1)
5126 self.assertEqual(p[IP].src, self.nat_addr)
5128 self.assertEqual(inner.dst, self.nat_addr)
5129 self.assertEqual(inner[TCPerror].dport, external_port)
5131 self.logger.error(ppp("Unexpected or invalid packet:", p))
5134 # from service back to client
5135 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5136 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5137 TCP(sport=local_port, dport=12345))
5138 self.pg0.add_stream(p)
5139 self.pg_enable_capture(self.pg_interfaces)
5141 capture = self.pg1.get_capture(1)
5146 self.assertEqual(ip.src, self.nat_addr)
5147 self.assertEqual(tcp.sport, external_port)
5148 self.assert_packet_checksums_valid(p)
5150 self.logger.error(ppp("Unexpected or invalid packet:", p))
5154 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5156 ICMP(type=11) / capture[0][IP])
5157 self.pg1.add_stream(p)
5158 self.pg_enable_capture(self.pg_interfaces)
5160 capture = self.pg0.get_capture(1)
5163 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5165 self.assertEqual(inner.src, self.pg0.remote_ip4)
5166 self.assertEqual(inner[TCPerror].sport, local_port)
5168 self.logger.error(ppp("Unexpected or invalid packet:", p))
5171 # from client to server (no translation)
5172 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5173 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5174 TCP(sport=12346, dport=local_port))
5175 self.pg1.add_stream(p)
5176 self.pg_enable_capture(self.pg_interfaces)
5178 capture = self.pg0.get_capture(1)
5183 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5184 self.assertEqual(tcp.dport, local_port)
5185 self.assert_packet_checksums_valid(p)
5187 self.logger.error(ppp("Unexpected or invalid packet:", p))
5190 # from service back to client (no translation)
5191 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5192 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5193 TCP(sport=local_port, dport=12346))
5194 self.pg0.add_stream(p)
5195 self.pg_enable_capture(self.pg_interfaces)
5197 capture = self.pg1.get_capture(1)
5202 self.assertEqual(ip.src, self.pg0.remote_ip4)
5203 self.assertEqual(tcp.sport, local_port)
5204 self.assert_packet_checksums_valid(p)
5206 self.logger.error(ppp("Unexpected or invalid packet:", p))
5209 def test_output_feature(self):
5210 """ NAT44 interface output feature (in2out postrouting) """
5211 self.vapi.nat44_forwarding_enable_disable(1)
5212 self.nat44_add_address(self.nat_addr)
5213 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5215 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5219 pkts = self.create_stream_in(self.pg0, self.pg1)
5220 self.pg0.add_stream(pkts)
5221 self.pg_enable_capture(self.pg_interfaces)
5223 capture = self.pg1.get_capture(len(pkts))
5224 self.verify_capture_out(capture)
5227 pkts = self.create_stream_out(self.pg1)
5228 self.pg1.add_stream(pkts)
5229 self.pg_enable_capture(self.pg_interfaces)
5231 capture = self.pg0.get_capture(len(pkts))
5232 self.verify_capture_in(capture, self.pg0)
5234 def test_multiple_vrf(self):
5235 """ Multiple VRF setup """
5236 external_addr = '1.2.3.4'
5241 self.vapi.nat44_forwarding_enable_disable(1)
5242 self.nat44_add_address(self.nat_addr)
5243 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5244 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5246 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5248 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5249 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5251 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5253 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5254 local_port, external_port, vrf_id=1,
5255 proto=IP_PROTOS.tcp, out2in_only=1)
5256 self.nat44_add_static_mapping(
5257 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5258 local_port=local_port, vrf_id=0, external_port=external_port,
5259 proto=IP_PROTOS.tcp, out2in_only=1)
5261 # from client to service (both VRF1)
5262 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5263 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5264 TCP(sport=12345, dport=external_port))
5265 self.pg6.add_stream(p)
5266 self.pg_enable_capture(self.pg_interfaces)
5268 capture = self.pg5.get_capture(1)
5273 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5274 self.assertEqual(tcp.dport, local_port)
5275 self.assert_packet_checksums_valid(p)
5277 self.logger.error(ppp("Unexpected or invalid packet:", p))
5280 # from service back to client (both VRF1)
5281 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5282 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5283 TCP(sport=local_port, dport=12345))
5284 self.pg5.add_stream(p)
5285 self.pg_enable_capture(self.pg_interfaces)
5287 capture = self.pg6.get_capture(1)
5292 self.assertEqual(ip.src, external_addr)
5293 self.assertEqual(tcp.sport, external_port)
5294 self.assert_packet_checksums_valid(p)
5296 self.logger.error(ppp("Unexpected or invalid packet:", p))
5299 # dynamic NAT from VRF1 to VRF0 (output-feature)
5300 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5301 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5302 TCP(sport=2345, dport=22))
5303 self.pg5.add_stream(p)
5304 self.pg_enable_capture(self.pg_interfaces)
5306 capture = self.pg1.get_capture(1)
5311 self.assertEqual(ip.src, self.nat_addr)
5312 self.assertNotEqual(tcp.sport, 2345)
5313 self.assert_packet_checksums_valid(p)
5316 self.logger.error(ppp("Unexpected or invalid packet:", p))
5319 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5320 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5321 TCP(sport=22, dport=port))
5322 self.pg1.add_stream(p)
5323 self.pg_enable_capture(self.pg_interfaces)
5325 capture = self.pg5.get_capture(1)
5330 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5331 self.assertEqual(tcp.dport, 2345)
5332 self.assert_packet_checksums_valid(p)
5334 self.logger.error(ppp("Unexpected or invalid packet:", p))
5337 # from client VRF1 to service VRF0
5338 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5339 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5340 TCP(sport=12346, dport=external_port))
5341 self.pg6.add_stream(p)
5342 self.pg_enable_capture(self.pg_interfaces)
5344 capture = self.pg0.get_capture(1)
5349 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5350 self.assertEqual(tcp.dport, local_port)
5351 self.assert_packet_checksums_valid(p)
5353 self.logger.error(ppp("Unexpected or invalid packet:", p))
5356 # from service VRF0 back to client VRF1
5357 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5358 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5359 TCP(sport=local_port, dport=12346))
5360 self.pg0.add_stream(p)
5361 self.pg_enable_capture(self.pg_interfaces)
5363 capture = self.pg6.get_capture(1)
5368 self.assertEqual(ip.src, self.pg0.local_ip4)
5369 self.assertEqual(tcp.sport, external_port)
5370 self.assert_packet_checksums_valid(p)
5372 self.logger.error(ppp("Unexpected or invalid packet:", p))
5375 # from client VRF0 to service VRF1
5376 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5377 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5378 TCP(sport=12347, dport=external_port))
5379 self.pg0.add_stream(p)
5380 self.pg_enable_capture(self.pg_interfaces)
5382 capture = self.pg5.get_capture(1)
5387 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5388 self.assertEqual(tcp.dport, local_port)
5389 self.assert_packet_checksums_valid(p)
5391 self.logger.error(ppp("Unexpected or invalid packet:", p))
5394 # from service VRF1 back to client VRF0
5395 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5396 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5397 TCP(sport=local_port, dport=12347))
5398 self.pg5.add_stream(p)
5399 self.pg_enable_capture(self.pg_interfaces)
5401 capture = self.pg0.get_capture(1)
5406 self.assertEqual(ip.src, external_addr)
5407 self.assertEqual(tcp.sport, external_port)
5408 self.assert_packet_checksums_valid(p)
5410 self.logger.error(ppp("Unexpected or invalid packet:", p))
5413 # from client to server (both VRF1, no translation)
5414 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5415 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5416 TCP(sport=12348, dport=local_port))
5417 self.pg6.add_stream(p)
5418 self.pg_enable_capture(self.pg_interfaces)
5420 capture = self.pg5.get_capture(1)
5425 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5426 self.assertEqual(tcp.dport, local_port)
5427 self.assert_packet_checksums_valid(p)
5429 self.logger.error(ppp("Unexpected or invalid packet:", p))
5432 # from server back to client (both VRF1, no translation)
5433 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5434 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5435 TCP(sport=local_port, dport=12348))
5436 self.pg5.add_stream(p)
5437 self.pg_enable_capture(self.pg_interfaces)
5439 capture = self.pg6.get_capture(1)
5444 self.assertEqual(ip.src, self.pg5.remote_ip4)
5445 self.assertEqual(tcp.sport, local_port)
5446 self.assert_packet_checksums_valid(p)
5448 self.logger.error(ppp("Unexpected or invalid packet:", p))
5451 # from client VRF1 to server VRF0 (no translation)
5452 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5453 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5454 TCP(sport=local_port, dport=12349))
5455 self.pg0.add_stream(p)
5456 self.pg_enable_capture(self.pg_interfaces)
5458 capture = self.pg6.get_capture(1)
5463 self.assertEqual(ip.src, self.pg0.remote_ip4)
5464 self.assertEqual(tcp.sport, local_port)
5465 self.assert_packet_checksums_valid(p)
5467 self.logger.error(ppp("Unexpected or invalid packet:", p))
5470 # from server VRF0 back to client VRF1 (no translation)
5471 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5472 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5473 TCP(sport=local_port, dport=12349))
5474 self.pg0.add_stream(p)
5475 self.pg_enable_capture(self.pg_interfaces)
5477 capture = self.pg6.get_capture(1)
5482 self.assertEqual(ip.src, self.pg0.remote_ip4)
5483 self.assertEqual(tcp.sport, local_port)
5484 self.assert_packet_checksums_valid(p)
5486 self.logger.error(ppp("Unexpected or invalid packet:", p))
5489 # from client VRF0 to server VRF1 (no translation)
5490 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5491 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5492 TCP(sport=12344, dport=local_port))
5493 self.pg0.add_stream(p)
5494 self.pg_enable_capture(self.pg_interfaces)
5496 capture = self.pg5.get_capture(1)
5501 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5502 self.assertEqual(tcp.dport, local_port)
5503 self.assert_packet_checksums_valid(p)
5505 self.logger.error(ppp("Unexpected or invalid packet:", p))
5508 # from server VRF1 back to client VRF0 (no translation)
5509 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5510 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5511 TCP(sport=local_port, dport=12344))
5512 self.pg5.add_stream(p)
5513 self.pg_enable_capture(self.pg_interfaces)
5515 capture = self.pg0.get_capture(1)
5520 self.assertEqual(ip.src, self.pg5.remote_ip4)
5521 self.assertEqual(tcp.sport, local_port)
5522 self.assert_packet_checksums_valid(p)
5524 self.logger.error(ppp("Unexpected or invalid packet:", p))
5527 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5528 def test_session_timeout(self):
5529 """ NAT44 session timeouts """
5530 self.nat44_add_address(self.nat_addr)
5531 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5532 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5534 self.vapi.nat_set_timeouts(icmp=5)
5538 for i in range(0, max_sessions):
5539 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5540 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5541 IP(src=src, dst=self.pg1.remote_ip4) /
5542 ICMP(id=1025, type='echo-request'))
5544 self.pg0.add_stream(pkts)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 self.pg1.get_capture(max_sessions)
5552 for i in range(0, max_sessions):
5553 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5554 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5555 IP(src=src, dst=self.pg1.remote_ip4) /
5556 ICMP(id=1026, type='echo-request'))
5558 self.pg0.add_stream(pkts)
5559 self.pg_enable_capture(self.pg_interfaces)
5561 self.pg1.get_capture(max_sessions)
5564 users = self.vapi.nat44_user_dump()
5566 nsessions = nsessions + user.nsessions
5567 self.assertLess(nsessions, 2 * max_sessions)
5569 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5570 def test_session_limit_per_user(self):
5571 """ Maximum sessions per user limit """
5572 self.nat44_add_address(self.nat_addr)
5573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5576 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5577 src_address=self.pg2.local_ip4n,
5579 template_interval=10)
5580 self.vapi.nat_set_timeouts(udp=5)
5582 # get maximum number of translations per user
5583 nat44_config = self.vapi.nat_show_config()
5586 for port in range(0, nat44_config.max_translations_per_user):
5587 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5588 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5589 UDP(sport=1025 + port, dport=1025 + port))
5592 self.pg0.add_stream(pkts)
5593 self.pg_enable_capture(self.pg_interfaces)
5595 capture = self.pg1.get_capture(len(pkts))
5597 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5598 src_port=self.ipfix_src_port)
5600 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5601 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5602 UDP(sport=3001, dport=3002))
5603 self.pg0.add_stream(p)
5604 self.pg_enable_capture(self.pg_interfaces)
5606 capture = self.pg1.assert_nothing_captured()
5608 # verify IPFIX logging
5609 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5611 capture = self.pg2.get_capture(10)
5612 ipfix = IPFIXDecoder()
5613 # first load template
5615 self.assertTrue(p.haslayer(IPFIX))
5616 if p.haslayer(Template):
5617 ipfix.add_template(p.getlayer(Template))
5618 # verify events in data set
5620 if p.haslayer(Data):
5621 data = ipfix.decode_data_set(p.getlayer(Set))
5622 self.verify_ipfix_max_entries_per_user(
5624 nat44_config.max_translations_per_user,
5625 self.pg0.remote_ip4n)
5628 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5629 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5630 UDP(sport=3001, dport=3002))
5631 self.pg0.add_stream(p)
5632 self.pg_enable_capture(self.pg_interfaces)
5634 self.pg1.get_capture(1)
5637 super(TestNAT44EndpointDependent, self).tearDown()
5638 if not self.vpp_dead:
5639 self.logger.info(self.vapi.cli("show nat44 addresses"))
5640 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5641 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5642 self.logger.info(self.vapi.cli("show nat44 interface address"))
5643 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5644 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5645 self.logger.info(self.vapi.cli("show nat timeouts"))
5647 self.vapi.cli("clear logging")
5650 class TestNAT44Out2InDPO(MethodHolder):
5651 """ NAT44 Test Cases using out2in DPO """
5654 def setUpConstants(cls):
5655 super(TestNAT44Out2InDPO, cls).setUpConstants()
5656 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5659 def setUpClass(cls):
5660 super(TestNAT44Out2InDPO, cls).setUpClass()
5661 cls.vapi.cli("set log class nat level debug")
5664 cls.tcp_port_in = 6303
5665 cls.tcp_port_out = 6303
5666 cls.udp_port_in = 6304
5667 cls.udp_port_out = 6304
5668 cls.icmp_id_in = 6305
5669 cls.icmp_id_out = 6305
5670 cls.nat_addr = '10.0.0.3'
5671 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5672 cls.dst_ip4 = '192.168.70.1'
5674 cls.create_pg_interfaces(range(2))
5677 cls.pg0.config_ip4()
5678 cls.pg0.resolve_arp()
5681 cls.pg1.config_ip6()
5682 cls.pg1.resolve_ndp()
5684 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5685 dst_address_length=0,
5686 next_hop_address=cls.pg1.remote_ip6n,
5687 next_hop_sw_if_index=cls.pg1.sw_if_index)
5690 super(TestNAT44Out2InDPO, cls).tearDownClass()
5693 def configure_xlat(self):
5694 self.dst_ip6_pfx = '1:2:3::'
5695 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5697 self.dst_ip6_pfx_len = 96
5698 self.src_ip6_pfx = '4:5:6::'
5699 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5701 self.src_ip6_pfx_len = 96
5702 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5703 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5704 '\x00\x00\x00\x00', 0, is_translation=1,
5707 def test_464xlat_ce(self):
5708 """ Test 464XLAT CE with NAT44 """
5710 nat_config = self.vapi.nat_show_config()
5711 self.assertEqual(1, nat_config.out2in_dpo)
5713 self.configure_xlat()
5715 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5716 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5718 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5719 self.dst_ip6_pfx_len)
5720 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5721 self.src_ip6_pfx_len)
5724 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5725 self.pg0.add_stream(pkts)
5726 self.pg_enable_capture(self.pg_interfaces)
5728 capture = self.pg1.get_capture(len(pkts))
5729 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5732 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5734 self.pg1.add_stream(pkts)
5735 self.pg_enable_capture(self.pg_interfaces)
5737 capture = self.pg0.get_capture(len(pkts))
5738 self.verify_capture_in(capture, self.pg0)
5740 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5742 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5743 self.nat_addr_n, is_add=0)
5745 def test_464xlat_ce_no_nat(self):
5746 """ Test 464XLAT CE without NAT44 """
5748 self.configure_xlat()
5750 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5751 self.dst_ip6_pfx_len)
5752 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5753 self.src_ip6_pfx_len)
5755 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5756 self.pg0.add_stream(pkts)
5757 self.pg_enable_capture(self.pg_interfaces)
5759 capture = self.pg1.get_capture(len(pkts))
5760 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5761 nat_ip=out_dst_ip6, same_port=True)
5763 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5764 self.pg1.add_stream(pkts)
5765 self.pg_enable_capture(self.pg_interfaces)
5767 capture = self.pg0.get_capture(len(pkts))
5768 self.verify_capture_in(capture, self.pg0)
5771 class TestDeterministicNAT(MethodHolder):
5772 """ Deterministic NAT Test Cases """
5775 def setUpConstants(cls):
5776 super(TestDeterministicNAT, cls).setUpConstants()
5777 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5780 def setUpClass(cls):
5781 super(TestDeterministicNAT, cls).setUpClass()
5782 cls.vapi.cli("set log class nat level debug")
5785 cls.tcp_port_in = 6303
5786 cls.tcp_external_port = 6303
5787 cls.udp_port_in = 6304
5788 cls.udp_external_port = 6304
5789 cls.icmp_id_in = 6305
5790 cls.nat_addr = '10.0.0.3'
5792 cls.create_pg_interfaces(range(3))
5793 cls.interfaces = list(cls.pg_interfaces)
5795 for i in cls.interfaces:
5800 cls.pg0.generate_remote_hosts(2)
5801 cls.pg0.configure_ipv4_neighbors()
5804 super(TestDeterministicNAT, cls).tearDownClass()
5807 def create_stream_in(self, in_if, out_if, ttl=64):
5809 Create packet stream for inside network
5811 :param in_if: Inside interface
5812 :param out_if: Outside interface
5813 :param ttl: TTL of generated packets
5817 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5818 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5819 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5823 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5824 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5825 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5829 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5831 ICMP(id=self.icmp_id_in, type='echo-request'))
5836 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5838 Create packet stream for outside network
5840 :param out_if: Outside interface
5841 :param dst_ip: Destination IP address (Default use global NAT address)
5842 :param ttl: TTL of generated packets
5845 dst_ip = self.nat_addr
5848 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5849 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5850 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
5854 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5855 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5856 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
5860 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5861 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5862 ICMP(id=self.icmp_external_id, type='echo-reply'))
5867 def verify_capture_out(self, capture, nat_ip=None):
5869 Verify captured packets on outside network
5871 :param capture: Captured packets
5872 :param nat_ip: Translated IP address (Default use global NAT address)
5873 :param same_port: Sorce port number is not translated (Default False)
5876 nat_ip = self.nat_addr
5877 for packet in capture:
5879 self.assertEqual(packet[IP].src, nat_ip)
5880 if packet.haslayer(TCP):
5881 self.tcp_port_out = packet[TCP].sport
5882 elif packet.haslayer(UDP):
5883 self.udp_port_out = packet[UDP].sport
5885 self.icmp_external_id = packet[ICMP].id
5887 self.logger.error(ppp("Unexpected or invalid packet "
5888 "(outside network):", packet))
5891 def test_deterministic_mode(self):
5892 """ NAT plugin run deterministic mode """
5893 in_addr = '172.16.255.0'
5894 out_addr = '172.17.255.50'
5895 in_addr_t = '172.16.255.20'
5896 in_addr_n = socket.inet_aton(in_addr)
5897 out_addr_n = socket.inet_aton(out_addr)
5898 in_addr_t_n = socket.inet_aton(in_addr_t)
5902 nat_config = self.vapi.nat_show_config()
5903 self.assertEqual(1, nat_config.deterministic)
5905 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
5907 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
5908 self.assertEqual(rep1.out_addr[:4], out_addr_n)
5909 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
5910 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5912 deterministic_mappings = self.vapi.nat_det_map_dump()
5913 self.assertEqual(len(deterministic_mappings), 1)
5914 dsm = deterministic_mappings[0]
5915 self.assertEqual(in_addr_n, dsm.in_addr[:4])
5916 self.assertEqual(in_plen, dsm.in_plen)
5917 self.assertEqual(out_addr_n, dsm.out_addr[:4])
5918 self.assertEqual(out_plen, dsm.out_plen)
5920 self.clear_nat_det()
5921 deterministic_mappings = self.vapi.nat_det_map_dump()
5922 self.assertEqual(len(deterministic_mappings), 0)
5924 def test_set_timeouts(self):
5925 """ Set deterministic NAT timeouts """
5926 timeouts_before = self.vapi.nat_get_timeouts()
5928 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
5929 timeouts_before.tcp_established + 10,
5930 timeouts_before.tcp_transitory + 10,
5931 timeouts_before.icmp + 10)
5933 timeouts_after = self.vapi.nat_get_timeouts()
5935 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
5936 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
5937 self.assertNotEqual(timeouts_before.tcp_established,
5938 timeouts_after.tcp_established)
5939 self.assertNotEqual(timeouts_before.tcp_transitory,
5940 timeouts_after.tcp_transitory)
5942 def test_det_in(self):
5943 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
5945 nat_ip = "10.0.0.10"
5947 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5949 socket.inet_aton(nat_ip),
5951 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5952 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5956 pkts = self.create_stream_in(self.pg0, self.pg1)
5957 self.pg0.add_stream(pkts)
5958 self.pg_enable_capture(self.pg_interfaces)
5960 capture = self.pg1.get_capture(len(pkts))
5961 self.verify_capture_out(capture, nat_ip)
5964 pkts = self.create_stream_out(self.pg1, nat_ip)
5965 self.pg1.add_stream(pkts)
5966 self.pg_enable_capture(self.pg_interfaces)
5968 capture = self.pg0.get_capture(len(pkts))
5969 self.verify_capture_in(capture, self.pg0)
5972 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
5973 self.assertEqual(len(sessions), 3)
5977 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5978 self.assertEqual(s.in_port, self.tcp_port_in)
5979 self.assertEqual(s.out_port, self.tcp_port_out)
5980 self.assertEqual(s.ext_port, self.tcp_external_port)
5984 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5985 self.assertEqual(s.in_port, self.udp_port_in)
5986 self.assertEqual(s.out_port, self.udp_port_out)
5987 self.assertEqual(s.ext_port, self.udp_external_port)
5991 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5992 self.assertEqual(s.in_port, self.icmp_id_in)
5993 self.assertEqual(s.out_port, self.icmp_external_id)
5995 def test_multiple_users(self):
5996 """ Deterministic NAT multiple users """
5998 nat_ip = "10.0.0.10"
6000 external_port = 6303
6002 host0 = self.pg0.remote_hosts[0]
6003 host1 = self.pg0.remote_hosts[1]
6005 self.vapi.nat_det_add_del_map(host0.ip4n,
6007 socket.inet_aton(nat_ip),
6009 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6010 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6014 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6015 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6016 TCP(sport=port_in, dport=external_port))
6017 self.pg0.add_stream(p)
6018 self.pg_enable_capture(self.pg_interfaces)
6020 capture = self.pg1.get_capture(1)
6025 self.assertEqual(ip.src, nat_ip)
6026 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6027 self.assertEqual(tcp.dport, external_port)
6028 port_out0 = tcp.sport
6030 self.logger.error(ppp("Unexpected or invalid packet:", p))
6034 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6035 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6036 TCP(sport=port_in, dport=external_port))
6037 self.pg0.add_stream(p)
6038 self.pg_enable_capture(self.pg_interfaces)
6040 capture = self.pg1.get_capture(1)
6045 self.assertEqual(ip.src, nat_ip)
6046 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6047 self.assertEqual(tcp.dport, external_port)
6048 port_out1 = tcp.sport
6050 self.logger.error(ppp("Unexpected or invalid packet:", p))
6053 dms = self.vapi.nat_det_map_dump()
6054 self.assertEqual(1, len(dms))
6055 self.assertEqual(2, dms[0].ses_num)
6058 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6059 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6060 TCP(sport=external_port, dport=port_out0))
6061 self.pg1.add_stream(p)
6062 self.pg_enable_capture(self.pg_interfaces)
6064 capture = self.pg0.get_capture(1)
6069 self.assertEqual(ip.src, self.pg1.remote_ip4)
6070 self.assertEqual(ip.dst, host0.ip4)
6071 self.assertEqual(tcp.dport, port_in)
6072 self.assertEqual(tcp.sport, external_port)
6074 self.logger.error(ppp("Unexpected or invalid packet:", p))
6078 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6079 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6080 TCP(sport=external_port, dport=port_out1))
6081 self.pg1.add_stream(p)
6082 self.pg_enable_capture(self.pg_interfaces)
6084 capture = self.pg0.get_capture(1)
6089 self.assertEqual(ip.src, self.pg1.remote_ip4)
6090 self.assertEqual(ip.dst, host1.ip4)
6091 self.assertEqual(tcp.dport, port_in)
6092 self.assertEqual(tcp.sport, external_port)
6094 self.logger.error(ppp("Unexpected or invalid packet", p))
6097 # session close api test
6098 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6100 self.pg1.remote_ip4n,
6102 dms = self.vapi.nat_det_map_dump()
6103 self.assertEqual(dms[0].ses_num, 1)
6105 self.vapi.nat_det_close_session_in(host0.ip4n,
6107 self.pg1.remote_ip4n,
6109 dms = self.vapi.nat_det_map_dump()
6110 self.assertEqual(dms[0].ses_num, 0)
6112 def test_tcp_session_close_detection_in(self):
6113 """ Deterministic NAT TCP session close from inside network """
6114 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6116 socket.inet_aton(self.nat_addr),
6118 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6119 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6122 self.initiate_tcp_session(self.pg0, self.pg1)
6124 # close the session from inside
6126 # FIN packet in -> out
6127 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6128 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6129 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6131 self.pg0.add_stream(p)
6132 self.pg_enable_capture(self.pg_interfaces)
6134 self.pg1.get_capture(1)
6138 # ACK packet out -> in
6139 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6140 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6141 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6145 # FIN packet out -> in
6146 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6147 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6148 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6152 self.pg1.add_stream(pkts)
6153 self.pg_enable_capture(self.pg_interfaces)
6155 self.pg0.get_capture(2)
6157 # ACK packet in -> out
6158 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6159 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6160 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6162 self.pg0.add_stream(p)
6163 self.pg_enable_capture(self.pg_interfaces)
6165 self.pg1.get_capture(1)
6167 # Check if deterministic NAT44 closed the session
6168 dms = self.vapi.nat_det_map_dump()
6169 self.assertEqual(0, dms[0].ses_num)
6171 self.logger.error("TCP session termination failed")
6174 def test_tcp_session_close_detection_out(self):
6175 """ Deterministic NAT TCP session close from outside network """
6176 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6178 socket.inet_aton(self.nat_addr),
6180 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6181 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6184 self.initiate_tcp_session(self.pg0, self.pg1)
6186 # close the session from outside
6188 # FIN packet out -> in
6189 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6190 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6191 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6193 self.pg1.add_stream(p)
6194 self.pg_enable_capture(self.pg_interfaces)
6196 self.pg0.get_capture(1)
6200 # ACK packet in -> out
6201 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6202 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6203 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6207 # ACK packet in -> out
6208 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6209 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6210 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6214 self.pg0.add_stream(pkts)
6215 self.pg_enable_capture(self.pg_interfaces)
6217 self.pg1.get_capture(2)
6219 # ACK packet out -> in
6220 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6221 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6222 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6224 self.pg1.add_stream(p)
6225 self.pg_enable_capture(self.pg_interfaces)
6227 self.pg0.get_capture(1)
6229 # Check if deterministic NAT44 closed the session
6230 dms = self.vapi.nat_det_map_dump()
6231 self.assertEqual(0, dms[0].ses_num)
6233 self.logger.error("TCP session termination failed")
6236 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6237 def test_session_timeout(self):
6238 """ Deterministic NAT session timeouts """
6239 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6241 socket.inet_aton(self.nat_addr),
6243 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6244 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6247 self.initiate_tcp_session(self.pg0, self.pg1)
6248 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6249 pkts = self.create_stream_in(self.pg0, self.pg1)
6250 self.pg0.add_stream(pkts)
6251 self.pg_enable_capture(self.pg_interfaces)
6253 capture = self.pg1.get_capture(len(pkts))
6256 dms = self.vapi.nat_det_map_dump()
6257 self.assertEqual(0, dms[0].ses_num)
6259 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6260 def test_session_limit_per_user(self):
6261 """ Deterministic NAT maximum sessions per user limit """
6262 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6264 socket.inet_aton(self.nat_addr),
6266 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6267 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6269 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6270 src_address=self.pg2.local_ip4n,
6272 template_interval=10)
6273 self.vapi.nat_ipfix()
6276 for port in range(1025, 2025):
6277 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6278 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6279 UDP(sport=port, dport=port))
6282 self.pg0.add_stream(pkts)
6283 self.pg_enable_capture(self.pg_interfaces)
6285 capture = self.pg1.get_capture(len(pkts))
6287 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6288 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6289 UDP(sport=3001, dport=3002))
6290 self.pg0.add_stream(p)
6291 self.pg_enable_capture(self.pg_interfaces)
6293 capture = self.pg1.assert_nothing_captured()
6295 # verify ICMP error packet
6296 capture = self.pg0.get_capture(1)
6298 self.assertTrue(p.haslayer(ICMP))
6300 self.assertEqual(icmp.type, 3)
6301 self.assertEqual(icmp.code, 1)
6302 self.assertTrue(icmp.haslayer(IPerror))
6303 inner_ip = icmp[IPerror]
6304 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6305 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6307 dms = self.vapi.nat_det_map_dump()
6309 self.assertEqual(1000, dms[0].ses_num)
6311 # verify IPFIX logging
6312 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6314 capture = self.pg2.get_capture(2)
6315 ipfix = IPFIXDecoder()
6316 # first load template
6318 self.assertTrue(p.haslayer(IPFIX))
6319 if p.haslayer(Template):
6320 ipfix.add_template(p.getlayer(Template))
6321 # verify events in data set
6323 if p.haslayer(Data):
6324 data = ipfix.decode_data_set(p.getlayer(Set))
6325 self.verify_ipfix_max_entries_per_user(data,
6327 self.pg0.remote_ip4n)
6329 def clear_nat_det(self):
6331 Clear deterministic NAT configuration.
6333 self.vapi.nat_ipfix(enable=0)
6334 self.vapi.nat_set_timeouts()
6335 deterministic_mappings = self.vapi.nat_det_map_dump()
6336 for dsm in deterministic_mappings:
6337 self.vapi.nat_det_add_del_map(dsm.in_addr,
6343 interfaces = self.vapi.nat44_interface_dump()
6344 for intf in interfaces:
6345 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6350 super(TestDeterministicNAT, self).tearDown()
6351 if not self.vpp_dead:
6352 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6353 self.logger.info(self.vapi.cli("show nat timeouts"))
6355 self.vapi.cli("show nat44 deterministic mappings"))
6357 self.vapi.cli("show nat44 deterministic sessions"))
6358 self.clear_nat_det()
6361 class TestNAT64(MethodHolder):
6362 """ NAT64 Test Cases """
6365 def setUpConstants(cls):
6366 super(TestNAT64, cls).setUpConstants()
6367 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6368 "nat64 st hash buckets 256", "}"])
6371 def setUpClass(cls):
6372 super(TestNAT64, cls).setUpClass()
6375 cls.tcp_port_in = 6303
6376 cls.tcp_port_out = 6303
6377 cls.udp_port_in = 6304
6378 cls.udp_port_out = 6304
6379 cls.icmp_id_in = 6305
6380 cls.icmp_id_out = 6305
6381 cls.nat_addr = '10.0.0.3'
6382 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6384 cls.vrf1_nat_addr = '10.0.10.3'
6385 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6387 cls.ipfix_src_port = 4739
6388 cls.ipfix_domain_id = 1
6390 cls.create_pg_interfaces(range(6))
6391 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6392 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6393 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6395 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6397 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6399 cls.pg0.generate_remote_hosts(2)
6401 for i in cls.ip6_interfaces:
6404 i.configure_ipv6_neighbors()
6406 for i in cls.ip4_interfaces:
6412 cls.pg3.config_ip4()
6413 cls.pg3.resolve_arp()
6414 cls.pg3.config_ip6()
6415 cls.pg3.configure_ipv6_neighbors()
6418 cls.pg5.config_ip6()
6421 super(TestNAT64, cls).tearDownClass()
6424 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6425 """ NAT64 inside interface handles Neighbor Advertisement """
6427 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6430 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6431 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6432 ICMPv6EchoRequest())
6434 self.pg5.add_stream(pkts)
6435 self.pg_enable_capture(self.pg_interfaces)
6438 # Wait for Neighbor Solicitation
6439 capture = self.pg5.get_capture(len(pkts))
6442 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6443 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6444 tgt = packet[ICMPv6ND_NS].tgt
6446 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6449 # Send Neighbor Advertisement
6450 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6451 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6452 ICMPv6ND_NA(tgt=tgt) /
6453 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6455 self.pg5.add_stream(pkts)
6456 self.pg_enable_capture(self.pg_interfaces)
6459 # Try to send ping again
6461 self.pg5.add_stream(pkts)
6462 self.pg_enable_capture(self.pg_interfaces)
6465 # Wait for ping reply
6466 capture = self.pg5.get_capture(len(pkts))
6469 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6470 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6471 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6473 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6476 def test_pool(self):
6477 """ Add/delete address to NAT64 pool """
6478 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6480 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6482 addresses = self.vapi.nat64_pool_addr_dump()
6483 self.assertEqual(len(addresses), 1)
6484 self.assertEqual(addresses[0].address, nat_addr)
6486 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6488 addresses = self.vapi.nat64_pool_addr_dump()
6489 self.assertEqual(len(addresses), 0)
6491 def test_interface(self):
6492 """ Enable/disable NAT64 feature on the interface """
6493 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6494 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6496 interfaces = self.vapi.nat64_interface_dump()
6497 self.assertEqual(len(interfaces), 2)
6500 for intf in interfaces:
6501 if intf.sw_if_index == self.pg0.sw_if_index:
6502 self.assertEqual(intf.is_inside, 1)
6504 elif intf.sw_if_index == self.pg1.sw_if_index:
6505 self.assertEqual(intf.is_inside, 0)
6507 self.assertTrue(pg0_found)
6508 self.assertTrue(pg1_found)
6510 features = self.vapi.cli("show interface features pg0")
6511 self.assertNotEqual(features.find('nat64-in2out'), -1)
6512 features = self.vapi.cli("show interface features pg1")
6513 self.assertNotEqual(features.find('nat64-out2in'), -1)
6515 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6516 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6518 interfaces = self.vapi.nat64_interface_dump()
6519 self.assertEqual(len(interfaces), 0)
6521 def test_static_bib(self):
6522 """ Add/delete static BIB entry """
6523 in_addr = socket.inet_pton(socket.AF_INET6,
6524 '2001:db8:85a3::8a2e:370:7334')
6525 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6528 proto = IP_PROTOS.tcp
6530 self.vapi.nat64_add_del_static_bib(in_addr,
6535 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6540 self.assertEqual(bibe.i_addr, in_addr)
6541 self.assertEqual(bibe.o_addr, out_addr)
6542 self.assertEqual(bibe.i_port, in_port)
6543 self.assertEqual(bibe.o_port, out_port)
6544 self.assertEqual(static_bib_num, 1)
6546 self.vapi.nat64_add_del_static_bib(in_addr,
6552 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6557 self.assertEqual(static_bib_num, 0)
6559 def test_set_timeouts(self):
6560 """ Set NAT64 timeouts """
6561 # verify default values
6562 timeouts = self.vapi.nat_get_timeouts()
6563 self.assertEqual(timeouts.udp, 300)
6564 self.assertEqual(timeouts.icmp, 60)
6565 self.assertEqual(timeouts.tcp_transitory, 240)
6566 self.assertEqual(timeouts.tcp_established, 7440)
6568 # set and verify custom values
6569 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6570 tcp_established=7450)
6571 timeouts = self.vapi.nat_get_timeouts()
6572 self.assertEqual(timeouts.udp, 200)
6573 self.assertEqual(timeouts.icmp, 30)
6574 self.assertEqual(timeouts.tcp_transitory, 250)
6575 self.assertEqual(timeouts.tcp_established, 7450)
6577 def test_dynamic(self):
6578 """ NAT64 dynamic translation test """
6579 self.tcp_port_in = 6303
6580 self.udp_port_in = 6304
6581 self.icmp_id_in = 6305
6583 ses_num_start = self.nat64_get_ses_num()
6585 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6587 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6588 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6591 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6592 self.pg0.add_stream(pkts)
6593 self.pg_enable_capture(self.pg_interfaces)
6595 capture = self.pg1.get_capture(len(pkts))
6596 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6597 dst_ip=self.pg1.remote_ip4)
6600 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6601 self.pg1.add_stream(pkts)
6602 self.pg_enable_capture(self.pg_interfaces)
6604 capture = self.pg0.get_capture(len(pkts))
6605 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6606 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6609 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6610 self.pg0.add_stream(pkts)
6611 self.pg_enable_capture(self.pg_interfaces)
6613 capture = self.pg1.get_capture(len(pkts))
6614 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6615 dst_ip=self.pg1.remote_ip4)
6618 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6619 self.pg1.add_stream(pkts)
6620 self.pg_enable_capture(self.pg_interfaces)
6622 capture = self.pg0.get_capture(len(pkts))
6623 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6625 ses_num_end = self.nat64_get_ses_num()
6627 self.assertEqual(ses_num_end - ses_num_start, 3)
6629 # tenant with specific VRF
6630 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6631 self.vrf1_nat_addr_n,
6632 vrf_id=self.vrf1_id)
6633 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6635 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6636 self.pg2.add_stream(pkts)
6637 self.pg_enable_capture(self.pg_interfaces)
6639 capture = self.pg1.get_capture(len(pkts))
6640 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6641 dst_ip=self.pg1.remote_ip4)
6643 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6644 self.pg1.add_stream(pkts)
6645 self.pg_enable_capture(self.pg_interfaces)
6647 capture = self.pg2.get_capture(len(pkts))
6648 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6650 def test_static(self):
6651 """ NAT64 static translation test """
6652 self.tcp_port_in = 60303
6653 self.udp_port_in = 60304
6654 self.icmp_id_in = 60305
6655 self.tcp_port_out = 60303
6656 self.udp_port_out = 60304
6657 self.icmp_id_out = 60305
6659 ses_num_start = self.nat64_get_ses_num()
6661 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6663 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6664 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6666 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6671 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6676 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6683 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6684 self.pg0.add_stream(pkts)
6685 self.pg_enable_capture(self.pg_interfaces)
6687 capture = self.pg1.get_capture(len(pkts))
6688 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6689 dst_ip=self.pg1.remote_ip4, same_port=True)
6692 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6693 self.pg1.add_stream(pkts)
6694 self.pg_enable_capture(self.pg_interfaces)
6696 capture = self.pg0.get_capture(len(pkts))
6697 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6698 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6700 ses_num_end = self.nat64_get_ses_num()
6702 self.assertEqual(ses_num_end - ses_num_start, 3)
6704 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6705 def test_session_timeout(self):
6706 """ NAT64 session timeout """
6707 self.icmp_id_in = 1234
6708 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6710 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6711 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6712 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6714 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6715 self.pg0.add_stream(pkts)
6716 self.pg_enable_capture(self.pg_interfaces)
6718 capture = self.pg1.get_capture(len(pkts))
6720 ses_num_before_timeout = self.nat64_get_ses_num()
6724 # ICMP and TCP session after timeout
6725 ses_num_after_timeout = self.nat64_get_ses_num()
6726 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6728 def test_icmp_error(self):
6729 """ NAT64 ICMP Error message translation """
6730 self.tcp_port_in = 6303
6731 self.udp_port_in = 6304
6732 self.icmp_id_in = 6305
6734 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6736 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6737 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6739 # send some packets to create sessions
6740 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6741 self.pg0.add_stream(pkts)
6742 self.pg_enable_capture(self.pg_interfaces)
6744 capture_ip4 = self.pg1.get_capture(len(pkts))
6745 self.verify_capture_out(capture_ip4,
6746 nat_ip=self.nat_addr,
6747 dst_ip=self.pg1.remote_ip4)
6749 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6750 self.pg1.add_stream(pkts)
6751 self.pg_enable_capture(self.pg_interfaces)
6753 capture_ip6 = self.pg0.get_capture(len(pkts))
6754 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6755 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6756 self.pg0.remote_ip6)
6759 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6760 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6761 ICMPv6DestUnreach(code=1) /
6762 packet[IPv6] for packet in capture_ip6]
6763 self.pg0.add_stream(pkts)
6764 self.pg_enable_capture(self.pg_interfaces)
6766 capture = self.pg1.get_capture(len(pkts))
6767 for packet in capture:
6769 self.assertEqual(packet[IP].src, self.nat_addr)
6770 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6771 self.assertEqual(packet[ICMP].type, 3)
6772 self.assertEqual(packet[ICMP].code, 13)
6773 inner = packet[IPerror]
6774 self.assertEqual(inner.src, self.pg1.remote_ip4)
6775 self.assertEqual(inner.dst, self.nat_addr)
6776 self.assert_packet_checksums_valid(packet)
6777 if inner.haslayer(TCPerror):
6778 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6779 elif inner.haslayer(UDPerror):
6780 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6782 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6784 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6788 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6789 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6790 ICMP(type=3, code=13) /
6791 packet[IP] for packet in capture_ip4]
6792 self.pg1.add_stream(pkts)
6793 self.pg_enable_capture(self.pg_interfaces)
6795 capture = self.pg0.get_capture(len(pkts))
6796 for packet in capture:
6798 self.assertEqual(packet[IPv6].src, ip.src)
6799 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6800 icmp = packet[ICMPv6DestUnreach]
6801 self.assertEqual(icmp.code, 1)
6802 inner = icmp[IPerror6]
6803 self.assertEqual(inner.src, self.pg0.remote_ip6)
6804 self.assertEqual(inner.dst, ip.src)
6805 self.assert_icmpv6_checksum_valid(packet)
6806 if inner.haslayer(TCPerror):
6807 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6808 elif inner.haslayer(UDPerror):
6809 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6811 self.assertEqual(inner[ICMPv6EchoRequest].id,
6814 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6817 def test_hairpinning(self):
6818 """ NAT64 hairpinning """
6820 client = self.pg0.remote_hosts[0]
6821 server = self.pg0.remote_hosts[1]
6822 server_tcp_in_port = 22
6823 server_tcp_out_port = 4022
6824 server_udp_in_port = 23
6825 server_udp_out_port = 4023
6826 client_tcp_in_port = 1234
6827 client_udp_in_port = 1235
6828 client_tcp_out_port = 0
6829 client_udp_out_port = 0
6830 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6831 nat_addr_ip6 = ip.src
6833 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6835 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6836 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6838 self.vapi.nat64_add_del_static_bib(server.ip6n,
6841 server_tcp_out_port,
6843 self.vapi.nat64_add_del_static_bib(server.ip6n,
6846 server_udp_out_port,
6851 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6852 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6853 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6855 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6856 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6857 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6859 self.pg0.add_stream(pkts)
6860 self.pg_enable_capture(self.pg_interfaces)
6862 capture = self.pg0.get_capture(len(pkts))
6863 for packet in capture:
6865 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6866 self.assertEqual(packet[IPv6].dst, server.ip6)
6867 self.assert_packet_checksums_valid(packet)
6868 if packet.haslayer(TCP):
6869 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6870 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
6871 client_tcp_out_port = packet[TCP].sport
6873 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6874 self.assertEqual(packet[UDP].dport, server_udp_in_port)
6875 client_udp_out_port = packet[UDP].sport
6877 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6882 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6883 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6884 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6886 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6887 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6888 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6890 self.pg0.add_stream(pkts)
6891 self.pg_enable_capture(self.pg_interfaces)
6893 capture = self.pg0.get_capture(len(pkts))
6894 for packet in capture:
6896 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6897 self.assertEqual(packet[IPv6].dst, client.ip6)
6898 self.assert_packet_checksums_valid(packet)
6899 if packet.haslayer(TCP):
6900 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6901 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
6903 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6904 self.assertEqual(packet[UDP].dport, client_udp_in_port)
6906 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6911 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6912 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6913 ICMPv6DestUnreach(code=1) /
6914 packet[IPv6] for packet in capture]
6915 self.pg0.add_stream(pkts)
6916 self.pg_enable_capture(self.pg_interfaces)
6918 capture = self.pg0.get_capture(len(pkts))
6919 for packet in capture:
6921 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6922 self.assertEqual(packet[IPv6].dst, server.ip6)
6923 icmp = packet[ICMPv6DestUnreach]
6924 self.assertEqual(icmp.code, 1)
6925 inner = icmp[IPerror6]
6926 self.assertEqual(inner.src, server.ip6)
6927 self.assertEqual(inner.dst, nat_addr_ip6)
6928 self.assert_packet_checksums_valid(packet)
6929 if inner.haslayer(TCPerror):
6930 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
6931 self.assertEqual(inner[TCPerror].dport,
6932 client_tcp_out_port)
6934 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
6935 self.assertEqual(inner[UDPerror].dport,
6936 client_udp_out_port)
6938 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6941 def test_prefix(self):
6942 """ NAT64 Network-Specific Prefix """
6944 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6946 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6947 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6948 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6949 self.vrf1_nat_addr_n,
6950 vrf_id=self.vrf1_id)
6951 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6954 global_pref64 = "2001:db8::"
6955 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
6956 global_pref64_len = 32
6957 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
6959 prefix = self.vapi.nat64_prefix_dump()
6960 self.assertEqual(len(prefix), 1)
6961 self.assertEqual(prefix[0].prefix, global_pref64_n)
6962 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
6963 self.assertEqual(prefix[0].vrf_id, 0)
6965 # Add tenant specific prefix
6966 vrf1_pref64 = "2001:db8:122:300::"
6967 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
6968 vrf1_pref64_len = 56
6969 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
6971 vrf_id=self.vrf1_id)
6972 prefix = self.vapi.nat64_prefix_dump()
6973 self.assertEqual(len(prefix), 2)
6976 pkts = self.create_stream_in_ip6(self.pg0,
6979 plen=global_pref64_len)
6980 self.pg0.add_stream(pkts)
6981 self.pg_enable_capture(self.pg_interfaces)
6983 capture = self.pg1.get_capture(len(pkts))
6984 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6985 dst_ip=self.pg1.remote_ip4)
6987 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6988 self.pg1.add_stream(pkts)
6989 self.pg_enable_capture(self.pg_interfaces)
6991 capture = self.pg0.get_capture(len(pkts))
6992 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
6995 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
6997 # Tenant specific prefix
6998 pkts = self.create_stream_in_ip6(self.pg2,
7001 plen=vrf1_pref64_len)
7002 self.pg2.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 capture = self.pg1.get_capture(len(pkts))
7006 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7007 dst_ip=self.pg1.remote_ip4)
7009 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7010 self.pg1.add_stream(pkts)
7011 self.pg_enable_capture(self.pg_interfaces)
7013 capture = self.pg2.get_capture(len(pkts))
7014 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7017 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7019 def test_unknown_proto(self):
7020 """ NAT64 translate packet with unknown protocol """
7022 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7024 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7025 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7026 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7029 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7030 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7031 TCP(sport=self.tcp_port_in, dport=20))
7032 self.pg0.add_stream(p)
7033 self.pg_enable_capture(self.pg_interfaces)
7035 p = self.pg1.get_capture(1)
7037 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7038 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7040 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7041 TCP(sport=1234, dport=1234))
7042 self.pg0.add_stream(p)
7043 self.pg_enable_capture(self.pg_interfaces)
7045 p = self.pg1.get_capture(1)
7048 self.assertEqual(packet[IP].src, self.nat_addr)
7049 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7050 self.assertTrue(packet.haslayer(GRE))
7051 self.assert_packet_checksums_valid(packet)
7053 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7057 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7058 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7060 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7061 TCP(sport=1234, dport=1234))
7062 self.pg1.add_stream(p)
7063 self.pg_enable_capture(self.pg_interfaces)
7065 p = self.pg0.get_capture(1)
7068 self.assertEqual(packet[IPv6].src, remote_ip6)
7069 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7070 self.assertEqual(packet[IPv6].nh, 47)
7072 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7075 def test_hairpinning_unknown_proto(self):
7076 """ NAT64 translate packet with unknown protocol - hairpinning """
7078 client = self.pg0.remote_hosts[0]
7079 server = self.pg0.remote_hosts[1]
7080 server_tcp_in_port = 22
7081 server_tcp_out_port = 4022
7082 client_tcp_in_port = 1234
7083 client_tcp_out_port = 1235
7084 server_nat_ip = "10.0.0.100"
7085 client_nat_ip = "10.0.0.110"
7086 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7087 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7088 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7089 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7091 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7093 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7094 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7096 self.vapi.nat64_add_del_static_bib(server.ip6n,
7099 server_tcp_out_port,
7102 self.vapi.nat64_add_del_static_bib(server.ip6n,
7108 self.vapi.nat64_add_del_static_bib(client.ip6n,
7111 client_tcp_out_port,
7115 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7116 IPv6(src=client.ip6, dst=server_nat_ip6) /
7117 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7118 self.pg0.add_stream(p)
7119 self.pg_enable_capture(self.pg_interfaces)
7121 p = self.pg0.get_capture(1)
7123 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7124 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7126 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7127 TCP(sport=1234, dport=1234))
7128 self.pg0.add_stream(p)
7129 self.pg_enable_capture(self.pg_interfaces)
7131 p = self.pg0.get_capture(1)
7134 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7135 self.assertEqual(packet[IPv6].dst, server.ip6)
7136 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7138 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7142 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7143 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7145 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7146 TCP(sport=1234, dport=1234))
7147 self.pg0.add_stream(p)
7148 self.pg_enable_capture(self.pg_interfaces)
7150 p = self.pg0.get_capture(1)
7153 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7154 self.assertEqual(packet[IPv6].dst, client.ip6)
7155 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7157 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7160 def test_one_armed_nat64(self):
7161 """ One armed NAT64 """
7163 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7167 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7169 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7170 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7173 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7174 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7175 TCP(sport=12345, dport=80))
7176 self.pg3.add_stream(p)
7177 self.pg_enable_capture(self.pg_interfaces)
7179 capture = self.pg3.get_capture(1)
7184 self.assertEqual(ip.src, self.nat_addr)
7185 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7186 self.assertNotEqual(tcp.sport, 12345)
7187 external_port = tcp.sport
7188 self.assertEqual(tcp.dport, 80)
7189 self.assert_packet_checksums_valid(p)
7191 self.logger.error(ppp("Unexpected or invalid packet:", p))
7195 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7196 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7197 TCP(sport=80, dport=external_port))
7198 self.pg3.add_stream(p)
7199 self.pg_enable_capture(self.pg_interfaces)
7201 capture = self.pg3.get_capture(1)
7206 self.assertEqual(ip.src, remote_host_ip6)
7207 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7208 self.assertEqual(tcp.sport, 80)
7209 self.assertEqual(tcp.dport, 12345)
7210 self.assert_packet_checksums_valid(p)
7212 self.logger.error(ppp("Unexpected or invalid packet:", p))
7215 def test_frag_in_order(self):
7216 """ NAT64 translate fragments arriving in order """
7217 self.tcp_port_in = random.randint(1025, 65535)
7219 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7221 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7222 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7224 reass = self.vapi.nat_reass_dump()
7225 reass_n_start = len(reass)
7229 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7230 self.tcp_port_in, 20, data)
7231 self.pg0.add_stream(pkts)
7232 self.pg_enable_capture(self.pg_interfaces)
7234 frags = self.pg1.get_capture(len(pkts))
7235 p = self.reass_frags_and_verify(frags,
7237 self.pg1.remote_ip4)
7238 self.assertEqual(p[TCP].dport, 20)
7239 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7240 self.tcp_port_out = p[TCP].sport
7241 self.assertEqual(data, p[Raw].load)
7244 data = "A" * 4 + "b" * 16 + "C" * 3
7245 pkts = self.create_stream_frag(self.pg1,
7250 self.pg1.add_stream(pkts)
7251 self.pg_enable_capture(self.pg_interfaces)
7253 frags = self.pg0.get_capture(len(pkts))
7254 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7255 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7256 self.assertEqual(p[TCP].sport, 20)
7257 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7258 self.assertEqual(data, p[Raw].load)
7260 reass = self.vapi.nat_reass_dump()
7261 reass_n_end = len(reass)
7263 self.assertEqual(reass_n_end - reass_n_start, 2)
7265 def test_reass_hairpinning(self):
7266 """ NAT64 fragments hairpinning """
7268 server = self.pg0.remote_hosts[1]
7269 server_in_port = random.randint(1025, 65535)
7270 server_out_port = random.randint(1025, 65535)
7271 client_in_port = random.randint(1025, 65535)
7272 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7273 nat_addr_ip6 = ip.src
7275 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7277 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7278 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7280 # add static BIB entry for server
7281 self.vapi.nat64_add_del_static_bib(server.ip6n,
7287 # send packet from host to server
7288 pkts = self.create_stream_frag_ip6(self.pg0,
7293 self.pg0.add_stream(pkts)
7294 self.pg_enable_capture(self.pg_interfaces)
7296 frags = self.pg0.get_capture(len(pkts))
7297 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7298 self.assertNotEqual(p[TCP].sport, client_in_port)
7299 self.assertEqual(p[TCP].dport, server_in_port)
7300 self.assertEqual(data, p[Raw].load)
7302 def test_frag_out_of_order(self):
7303 """ NAT64 translate fragments arriving out of 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)
7313 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7314 self.tcp_port_in, 20, data)
7316 self.pg0.add_stream(pkts)
7317 self.pg_enable_capture(self.pg_interfaces)
7319 frags = self.pg1.get_capture(len(pkts))
7320 p = self.reass_frags_and_verify(frags,
7322 self.pg1.remote_ip4)
7323 self.assertEqual(p[TCP].dport, 20)
7324 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7325 self.tcp_port_out = p[TCP].sport
7326 self.assertEqual(data, p[Raw].load)
7329 data = "A" * 4 + "B" * 16 + "C" * 3
7330 pkts = self.create_stream_frag(self.pg1,
7336 self.pg1.add_stream(pkts)
7337 self.pg_enable_capture(self.pg_interfaces)
7339 frags = self.pg0.get_capture(len(pkts))
7340 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7341 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7342 self.assertEqual(p[TCP].sport, 20)
7343 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7344 self.assertEqual(data, p[Raw].load)
7346 def test_interface_addr(self):
7347 """ Acquire NAT64 pool addresses from interface """
7348 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7350 # no address in NAT64 pool
7351 adresses = self.vapi.nat44_address_dump()
7352 self.assertEqual(0, len(adresses))
7354 # configure interface address and check NAT64 address pool
7355 self.pg4.config_ip4()
7356 addresses = self.vapi.nat64_pool_addr_dump()
7357 self.assertEqual(len(addresses), 1)
7358 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7360 # remove interface address and check NAT64 address pool
7361 self.pg4.unconfig_ip4()
7362 addresses = self.vapi.nat64_pool_addr_dump()
7363 self.assertEqual(0, len(adresses))
7365 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7366 def test_ipfix_max_bibs_sessions(self):
7367 """ IPFIX logging maximum session and BIB entries exceeded """
7370 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7374 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7376 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7377 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7381 for i in range(0, max_bibs):
7382 src = "fd01:aa::%x" % (i)
7383 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7384 IPv6(src=src, dst=remote_host_ip6) /
7385 TCP(sport=12345, dport=80))
7387 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7388 IPv6(src=src, dst=remote_host_ip6) /
7389 TCP(sport=12345, dport=22))
7391 self.pg0.add_stream(pkts)
7392 self.pg_enable_capture(self.pg_interfaces)
7394 self.pg1.get_capture(max_sessions)
7396 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7397 src_address=self.pg3.local_ip4n,
7399 template_interval=10)
7400 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7401 src_port=self.ipfix_src_port)
7403 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7404 IPv6(src=src, dst=remote_host_ip6) /
7405 TCP(sport=12345, dport=25))
7406 self.pg0.add_stream(p)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 self.pg1.assert_nothing_captured()
7411 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7412 capture = self.pg3.get_capture(9)
7413 ipfix = IPFIXDecoder()
7414 # first load template
7416 self.assertTrue(p.haslayer(IPFIX))
7417 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7418 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7419 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7420 self.assertEqual(p[UDP].dport, 4739)
7421 self.assertEqual(p[IPFIX].observationDomainID,
7422 self.ipfix_domain_id)
7423 if p.haslayer(Template):
7424 ipfix.add_template(p.getlayer(Template))
7425 # verify events in data set
7427 if p.haslayer(Data):
7428 data = ipfix.decode_data_set(p.getlayer(Set))
7429 self.verify_ipfix_max_sessions(data, max_sessions)
7431 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7432 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7433 TCP(sport=12345, dport=80))
7434 self.pg0.add_stream(p)
7435 self.pg_enable_capture(self.pg_interfaces)
7437 self.pg1.assert_nothing_captured()
7439 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7440 capture = self.pg3.get_capture(1)
7441 # verify events in data set
7443 self.assertTrue(p.haslayer(IPFIX))
7444 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7445 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7446 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7447 self.assertEqual(p[UDP].dport, 4739)
7448 self.assertEqual(p[IPFIX].observationDomainID,
7449 self.ipfix_domain_id)
7450 if p.haslayer(Data):
7451 data = ipfix.decode_data_set(p.getlayer(Set))
7452 self.verify_ipfix_max_bibs(data, max_bibs)
7454 def test_ipfix_max_frags(self):
7455 """ IPFIX logging maximum fragments pending reassembly exceeded """
7456 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7458 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7459 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7460 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7461 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7462 src_address=self.pg3.local_ip4n,
7464 template_interval=10)
7465 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7466 src_port=self.ipfix_src_port)
7469 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7470 self.tcp_port_in, 20, data)
7472 self.pg0.add_stream(pkts)
7473 self.pg_enable_capture(self.pg_interfaces)
7475 self.pg1.assert_nothing_captured()
7477 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7478 capture = self.pg3.get_capture(9)
7479 ipfix = IPFIXDecoder()
7480 # first load template
7482 self.assertTrue(p.haslayer(IPFIX))
7483 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7484 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7485 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7486 self.assertEqual(p[UDP].dport, 4739)
7487 self.assertEqual(p[IPFIX].observationDomainID,
7488 self.ipfix_domain_id)
7489 if p.haslayer(Template):
7490 ipfix.add_template(p.getlayer(Template))
7491 # verify events in data set
7493 if p.haslayer(Data):
7494 data = ipfix.decode_data_set(p.getlayer(Set))
7495 self.verify_ipfix_max_fragments_ip6(data, 1,
7496 self.pg0.remote_ip6n)
7498 def test_ipfix_bib_ses(self):
7499 """ IPFIX logging NAT64 BIB/session create and delete events """
7500 self.tcp_port_in = random.randint(1025, 65535)
7501 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7505 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7507 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7508 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7509 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7510 src_address=self.pg3.local_ip4n,
7512 template_interval=10)
7513 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7514 src_port=self.ipfix_src_port)
7517 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7518 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7519 TCP(sport=self.tcp_port_in, dport=25))
7520 self.pg0.add_stream(p)
7521 self.pg_enable_capture(self.pg_interfaces)
7523 p = self.pg1.get_capture(1)
7524 self.tcp_port_out = p[0][TCP].sport
7525 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7526 capture = self.pg3.get_capture(10)
7527 ipfix = IPFIXDecoder()
7528 # first load template
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(Template):
7538 ipfix.add_template(p.getlayer(Template))
7539 # verify events in data set
7541 if p.haslayer(Data):
7542 data = ipfix.decode_data_set(p.getlayer(Set))
7543 if ord(data[0][230]) == 10:
7544 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7545 elif ord(data[0][230]) == 6:
7546 self.verify_ipfix_nat64_ses(data,
7548 self.pg0.remote_ip6n,
7549 self.pg1.remote_ip4,
7552 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7555 self.pg_enable_capture(self.pg_interfaces)
7556 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7559 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7560 capture = self.pg3.get_capture(2)
7561 # verify events in data set
7563 self.assertTrue(p.haslayer(IPFIX))
7564 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7565 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7566 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7567 self.assertEqual(p[UDP].dport, 4739)
7568 self.assertEqual(p[IPFIX].observationDomainID,
7569 self.ipfix_domain_id)
7570 if p.haslayer(Data):
7571 data = ipfix.decode_data_set(p.getlayer(Set))
7572 if ord(data[0][230]) == 11:
7573 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7574 elif ord(data[0][230]) == 7:
7575 self.verify_ipfix_nat64_ses(data,
7577 self.pg0.remote_ip6n,
7578 self.pg1.remote_ip4,
7581 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7583 def nat64_get_ses_num(self):
7585 Return number of active NAT64 sessions.
7587 st = self.vapi.nat64_st_dump()
7590 def clear_nat64(self):
7592 Clear NAT64 configuration.
7594 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7595 domain_id=self.ipfix_domain_id)
7596 self.ipfix_src_port = 4739
7597 self.ipfix_domain_id = 1
7599 self.vapi.nat_set_timeouts()
7601 interfaces = self.vapi.nat64_interface_dump()
7602 for intf in interfaces:
7603 if intf.is_inside > 1:
7604 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7607 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7611 bib = self.vapi.nat64_bib_dump(255)
7614 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7622 adresses = self.vapi.nat64_pool_addr_dump()
7623 for addr in adresses:
7624 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7629 prefixes = self.vapi.nat64_prefix_dump()
7630 for prefix in prefixes:
7631 self.vapi.nat64_add_del_prefix(prefix.prefix,
7633 vrf_id=prefix.vrf_id,
7637 super(TestNAT64, self).tearDown()
7638 if not self.vpp_dead:
7639 self.logger.info(self.vapi.cli("show nat64 pool"))
7640 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7641 self.logger.info(self.vapi.cli("show nat64 prefix"))
7642 self.logger.info(self.vapi.cli("show nat64 bib all"))
7643 self.logger.info(self.vapi.cli("show nat64 session table all"))
7644 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7648 class TestDSlite(MethodHolder):
7649 """ DS-Lite Test Cases """
7652 def setUpClass(cls):
7653 super(TestDSlite, cls).setUpClass()
7656 cls.nat_addr = '10.0.0.3'
7657 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7659 cls.create_pg_interfaces(range(2))
7661 cls.pg0.config_ip4()
7662 cls.pg0.resolve_arp()
7664 cls.pg1.config_ip6()
7665 cls.pg1.generate_remote_hosts(2)
7666 cls.pg1.configure_ipv6_neighbors()
7669 super(TestDSlite, cls).tearDownClass()
7672 def test_dslite(self):
7673 """ Test DS-Lite """
7674 nat_config = self.vapi.nat_show_config()
7675 self.assertEqual(0, nat_config.dslite_ce)
7677 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7679 aftr_ip4 = '192.0.0.1'
7680 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7681 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7682 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7683 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7686 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7687 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7688 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7689 UDP(sport=20000, dport=10000))
7690 self.pg1.add_stream(p)
7691 self.pg_enable_capture(self.pg_interfaces)
7693 capture = self.pg0.get_capture(1)
7694 capture = capture[0]
7695 self.assertFalse(capture.haslayer(IPv6))
7696 self.assertEqual(capture[IP].src, self.nat_addr)
7697 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7698 self.assertNotEqual(capture[UDP].sport, 20000)
7699 self.assertEqual(capture[UDP].dport, 10000)
7700 self.assert_packet_checksums_valid(capture)
7701 out_port = capture[UDP].sport
7703 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7704 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7705 UDP(sport=10000, dport=out_port))
7706 self.pg0.add_stream(p)
7707 self.pg_enable_capture(self.pg_interfaces)
7709 capture = self.pg1.get_capture(1)
7710 capture = capture[0]
7711 self.assertEqual(capture[IPv6].src, aftr_ip6)
7712 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7713 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7714 self.assertEqual(capture[IP].dst, '192.168.1.1')
7715 self.assertEqual(capture[UDP].sport, 10000)
7716 self.assertEqual(capture[UDP].dport, 20000)
7717 self.assert_packet_checksums_valid(capture)
7720 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7721 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7722 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7723 TCP(sport=20001, dport=10001))
7724 self.pg1.add_stream(p)
7725 self.pg_enable_capture(self.pg_interfaces)
7727 capture = self.pg0.get_capture(1)
7728 capture = capture[0]
7729 self.assertFalse(capture.haslayer(IPv6))
7730 self.assertEqual(capture[IP].src, self.nat_addr)
7731 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7732 self.assertNotEqual(capture[TCP].sport, 20001)
7733 self.assertEqual(capture[TCP].dport, 10001)
7734 self.assert_packet_checksums_valid(capture)
7735 out_port = capture[TCP].sport
7737 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7738 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7739 TCP(sport=10001, dport=out_port))
7740 self.pg0.add_stream(p)
7741 self.pg_enable_capture(self.pg_interfaces)
7743 capture = self.pg1.get_capture(1)
7744 capture = capture[0]
7745 self.assertEqual(capture[IPv6].src, aftr_ip6)
7746 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7747 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7748 self.assertEqual(capture[IP].dst, '192.168.1.1')
7749 self.assertEqual(capture[TCP].sport, 10001)
7750 self.assertEqual(capture[TCP].dport, 20001)
7751 self.assert_packet_checksums_valid(capture)
7754 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7755 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7756 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7757 ICMP(id=4000, type='echo-request'))
7758 self.pg1.add_stream(p)
7759 self.pg_enable_capture(self.pg_interfaces)
7761 capture = self.pg0.get_capture(1)
7762 capture = capture[0]
7763 self.assertFalse(capture.haslayer(IPv6))
7764 self.assertEqual(capture[IP].src, self.nat_addr)
7765 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7766 self.assertNotEqual(capture[ICMP].id, 4000)
7767 self.assert_packet_checksums_valid(capture)
7768 out_id = capture[ICMP].id
7770 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7771 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7772 ICMP(id=out_id, type='echo-reply'))
7773 self.pg0.add_stream(p)
7774 self.pg_enable_capture(self.pg_interfaces)
7776 capture = self.pg1.get_capture(1)
7777 capture = capture[0]
7778 self.assertEqual(capture[IPv6].src, aftr_ip6)
7779 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7780 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7781 self.assertEqual(capture[IP].dst, '192.168.1.1')
7782 self.assertEqual(capture[ICMP].id, 4000)
7783 self.assert_packet_checksums_valid(capture)
7785 # ping DS-Lite AFTR tunnel endpoint address
7786 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7787 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7788 ICMPv6EchoRequest())
7789 self.pg1.add_stream(p)
7790 self.pg_enable_capture(self.pg_interfaces)
7792 capture = self.pg1.get_capture(1)
7793 capture = capture[0]
7794 self.assertEqual(capture[IPv6].src, aftr_ip6)
7795 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7796 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7799 super(TestDSlite, self).tearDown()
7800 if not self.vpp_dead:
7801 self.logger.info(self.vapi.cli("show dslite pool"))
7803 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7804 self.logger.info(self.vapi.cli("show dslite sessions"))
7807 class TestDSliteCE(MethodHolder):
7808 """ DS-Lite CE Test Cases """
7811 def setUpConstants(cls):
7812 super(TestDSliteCE, cls).setUpConstants()
7813 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7816 def setUpClass(cls):
7817 super(TestDSliteCE, cls).setUpClass()
7820 cls.create_pg_interfaces(range(2))
7822 cls.pg0.config_ip4()
7823 cls.pg0.resolve_arp()
7825 cls.pg1.config_ip6()
7826 cls.pg1.generate_remote_hosts(1)
7827 cls.pg1.configure_ipv6_neighbors()
7830 super(TestDSliteCE, cls).tearDownClass()
7833 def test_dslite_ce(self):
7834 """ Test DS-Lite CE """
7836 nat_config = self.vapi.nat_show_config()
7837 self.assertEqual(1, nat_config.dslite_ce)
7839 b4_ip4 = '192.0.0.2'
7840 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7841 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7842 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7843 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7845 aftr_ip4 = '192.0.0.1'
7846 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7847 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7848 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7849 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7851 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7852 dst_address_length=128,
7853 next_hop_address=self.pg1.remote_ip6n,
7854 next_hop_sw_if_index=self.pg1.sw_if_index,
7858 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7859 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7860 UDP(sport=10000, dport=20000))
7861 self.pg0.add_stream(p)
7862 self.pg_enable_capture(self.pg_interfaces)
7864 capture = self.pg1.get_capture(1)
7865 capture = capture[0]
7866 self.assertEqual(capture[IPv6].src, b4_ip6)
7867 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7868 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7869 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7870 self.assertEqual(capture[UDP].sport, 10000)
7871 self.assertEqual(capture[UDP].dport, 20000)
7872 self.assert_packet_checksums_valid(capture)
7875 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7876 IPv6(dst=b4_ip6, src=aftr_ip6) /
7877 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7878 UDP(sport=20000, dport=10000))
7879 self.pg1.add_stream(p)
7880 self.pg_enable_capture(self.pg_interfaces)
7882 capture = self.pg0.get_capture(1)
7883 capture = capture[0]
7884 self.assertFalse(capture.haslayer(IPv6))
7885 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7886 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7887 self.assertEqual(capture[UDP].sport, 20000)
7888 self.assertEqual(capture[UDP].dport, 10000)
7889 self.assert_packet_checksums_valid(capture)
7891 # ping DS-Lite B4 tunnel endpoint address
7892 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7893 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7894 ICMPv6EchoRequest())
7895 self.pg1.add_stream(p)
7896 self.pg_enable_capture(self.pg_interfaces)
7898 capture = self.pg1.get_capture(1)
7899 capture = capture[0]
7900 self.assertEqual(capture[IPv6].src, b4_ip6)
7901 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7902 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7905 super(TestDSliteCE, self).tearDown()
7906 if not self.vpp_dead:
7908 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7910 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
7913 class TestNAT66(MethodHolder):
7914 """ NAT66 Test Cases """
7917 def setUpClass(cls):
7918 super(TestNAT66, cls).setUpClass()
7921 cls.nat_addr = 'fd01:ff::2'
7922 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
7924 cls.create_pg_interfaces(range(2))
7925 cls.interfaces = list(cls.pg_interfaces)
7927 for i in cls.interfaces:
7930 i.configure_ipv6_neighbors()
7933 super(TestNAT66, cls).tearDownClass()
7936 def test_static(self):
7937 """ 1:1 NAT66 test """
7938 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
7939 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7940 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
7945 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7946 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7949 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7950 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7953 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7954 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7955 ICMPv6EchoRequest())
7957 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7958 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7959 GRE() / IP() / TCP())
7961 self.pg0.add_stream(pkts)
7962 self.pg_enable_capture(self.pg_interfaces)
7964 capture = self.pg1.get_capture(len(pkts))
7965 for packet in capture:
7967 self.assertEqual(packet[IPv6].src, self.nat_addr)
7968 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
7969 self.assert_packet_checksums_valid(packet)
7971 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7976 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7977 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7980 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7981 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7984 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7985 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7988 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7989 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7990 GRE() / IP() / TCP())
7992 self.pg1.add_stream(pkts)
7993 self.pg_enable_capture(self.pg_interfaces)
7995 capture = self.pg0.get_capture(len(pkts))
7996 for packet in capture:
7998 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
7999 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8000 self.assert_packet_checksums_valid(packet)
8002 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8005 sm = self.vapi.nat66_static_mapping_dump()
8006 self.assertEqual(len(sm), 1)
8007 self.assertEqual(sm[0].total_pkts, 8)
8009 def test_check_no_translate(self):
8010 """ NAT66 translate only when egress interface is outside interface """
8011 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8012 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8013 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8017 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8018 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8020 self.pg0.add_stream([p])
8021 self.pg_enable_capture(self.pg_interfaces)
8023 capture = self.pg1.get_capture(1)
8026 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8027 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8029 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8032 def clear_nat66(self):
8034 Clear NAT66 configuration.
8036 interfaces = self.vapi.nat66_interface_dump()
8037 for intf in interfaces:
8038 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8042 static_mappings = self.vapi.nat66_static_mapping_dump()
8043 for sm in static_mappings:
8044 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8045 sm.external_ip_address,
8050 super(TestNAT66, self).tearDown()
8051 if not self.vpp_dead:
8052 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8053 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8057 if __name__ == '__main__':
8058 unittest.main(testRunner=VppTestRunner)