9 from framework import VppTestCase, VppTestRunner, running_extended_tests
10 from scapy.layers.inet import IP, TCP, UDP, ICMP
11 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
12 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
13 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr
14 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
15 from scapy.layers.l2 import Ether, ARP, GRE
16 from scapy.data import IP_PROTOS
17 from scapy.packet import bind_layers, Raw
18 from scapy.all import fragment6
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from util import mactobinary
26 class MethodHolder(VppTestCase):
27 """ NAT create capture and verify method holder """
29 def clear_nat44(self):
31 Clear NAT44 configuration.
33 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
34 # I found no elegant way to do this
35 self.vapi.ip_add_del_route(
36 dst_address=self.pg7.remote_ip4n,
37 dst_address_length=32,
38 next_hop_address=self.pg7.remote_ip4n,
39 next_hop_sw_if_index=self.pg7.sw_if_index,
41 self.vapi.ip_add_del_route(
42 dst_address=self.pg8.remote_ip4n,
43 dst_address_length=32,
44 next_hop_address=self.pg8.remote_ip4n,
45 next_hop_sw_if_index=self.pg8.sw_if_index,
48 for intf in [self.pg7, self.pg8]:
49 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
51 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
56 if self.pg7.has_ip4_config:
57 self.pg7.unconfig_ip4()
59 self.vapi.nat44_forwarding_enable_disable(0)
61 interfaces = self.vapi.nat44_interface_addr_dump()
62 for intf in interfaces:
63 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
64 twice_nat=intf.twice_nat,
67 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
68 domain_id=self.ipfix_domain_id)
69 self.ipfix_src_port = 4739
70 self.ipfix_domain_id = 1
72 interfaces = self.vapi.nat44_interface_dump()
73 for intf in interfaces:
74 if intf.is_inside > 1:
75 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
78 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
82 interfaces = self.vapi.nat44_interface_output_feature_dump()
83 for intf in interfaces:
84 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
88 static_mappings = self.vapi.nat44_static_mapping_dump()
89 for sm in static_mappings:
90 self.vapi.nat44_add_del_static_mapping(
92 sm.external_ip_address,
93 local_port=sm.local_port,
94 external_port=sm.external_port,
95 addr_only=sm.addr_only,
98 twice_nat=sm.twice_nat,
99 self_twice_nat=sm.self_twice_nat,
100 out2in_only=sm.out2in_only,
102 external_sw_if_index=sm.external_sw_if_index,
105 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
106 for lb_sm in lb_static_mappings:
107 self.vapi.nat44_add_del_lb_static_mapping(
111 twice_nat=lb_sm.twice_nat,
112 self_twice_nat=lb_sm.self_twice_nat,
113 out2in_only=lb_sm.out2in_only,
119 identity_mappings = self.vapi.nat44_identity_mapping_dump()
120 for id_m in identity_mappings:
121 self.vapi.nat44_add_del_identity_mapping(
122 addr_only=id_m.addr_only,
125 sw_if_index=id_m.sw_if_index,
127 protocol=id_m.protocol,
130 adresses = self.vapi.nat44_address_dump()
131 for addr in adresses:
132 self.vapi.nat44_add_del_address_range(addr.ip_address,
134 twice_nat=addr.twice_nat,
137 self.vapi.nat_set_reass()
138 self.vapi.nat_set_reass(is_ip6=1)
139 self.verify_no_nat44_user()
140 self.vapi.nat_set_timeouts()
141 self.vapi.nat_set_addr_and_port_alloc_alg()
142 self.vapi.nat_set_mss_clamping()
144 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
145 local_port=0, external_port=0, vrf_id=0,
146 is_add=1, external_sw_if_index=0xFFFFFFFF,
147 proto=0, twice_nat=0, self_twice_nat=0,
148 out2in_only=0, tag=""):
150 Add/delete NAT44 static mapping
152 :param local_ip: Local IP address
153 :param external_ip: External IP address
154 :param local_port: Local port number (Optional)
155 :param external_port: External port number (Optional)
156 :param vrf_id: VRF ID (Default 0)
157 :param is_add: 1 if add, 0 if delete (Default add)
158 :param external_sw_if_index: External interface instead of IP address
159 :param proto: IP protocol (Mandatory if port specified)
160 :param twice_nat: 1 if translate external host address and port
161 :param self_twice_nat: 1 if translate external host address and port
162 whenever external host address equals
163 local address of internal host
164 :param out2in_only: if 1 rule is matching only out2in direction
165 :param tag: Opaque string tag
168 if local_port and external_port:
170 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
171 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
172 self.vapi.nat44_add_del_static_mapping(
175 external_sw_if_index,
187 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
189 Add/delete NAT44 address
191 :param ip: IP address
192 :param is_add: 1 if add, 0 if delete (Default add)
193 :param twice_nat: twice NAT address for extenal hosts
195 nat_addr = socket.inet_pton(socket.AF_INET, ip)
196 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
200 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
202 Create packet stream for inside network
204 :param in_if: Inside interface
205 :param out_if: Outside interface
206 :param dst_ip: Destination address
207 :param ttl: TTL of generated packets
210 dst_ip = out_if.remote_ip4
214 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
215 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
216 TCP(sport=self.tcp_port_in, dport=20))
220 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
221 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
222 UDP(sport=self.udp_port_in, dport=20))
226 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
227 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
228 ICMP(id=self.icmp_id_in, type='echo-request'))
233 def compose_ip6(self, ip4, pref, plen):
235 Compose IPv4-embedded IPv6 addresses
237 :param ip4: IPv4 address
238 :param pref: IPv6 prefix
239 :param plen: IPv6 prefix length
240 :returns: IPv4-embedded IPv6 addresses
242 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
243 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
258 pref_n[10] = ip4_n[3]
262 pref_n[10] = ip4_n[2]
263 pref_n[11] = ip4_n[3]
266 pref_n[10] = ip4_n[1]
267 pref_n[11] = ip4_n[2]
268 pref_n[12] = ip4_n[3]
270 pref_n[12] = ip4_n[0]
271 pref_n[13] = ip4_n[1]
272 pref_n[14] = ip4_n[2]
273 pref_n[15] = ip4_n[3]
274 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
276 def extract_ip4(self, ip6, plen):
278 Extract IPv4 address embedded in IPv6 addresses
280 :param ip6: IPv6 address
281 :param plen: IPv6 prefix length
282 :returns: extracted IPv4 address
284 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
316 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
318 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
320 Create IPv6 packet stream for inside network
322 :param in_if: Inside interface
323 :param out_if: Outside interface
324 :param ttl: Hop Limit of generated packets
325 :param pref: NAT64 prefix
326 :param plen: NAT64 prefix length
330 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
332 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
335 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
336 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
337 TCP(sport=self.tcp_port_in, dport=20))
341 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
342 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
343 UDP(sport=self.udp_port_in, dport=20))
347 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
348 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
349 ICMPv6EchoRequest(id=self.icmp_id_in))
354 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
355 use_inside_ports=False):
357 Create packet stream for outside network
359 :param out_if: Outside interface
360 :param dst_ip: Destination IP address (Default use global NAT address)
361 :param ttl: TTL of generated packets
362 :param use_inside_ports: Use inside NAT ports as destination ports
363 instead of outside ports
366 dst_ip = self.nat_addr
367 if not use_inside_ports:
368 tcp_port = self.tcp_port_out
369 udp_port = self.udp_port_out
370 icmp_id = self.icmp_id_out
372 tcp_port = self.tcp_port_in
373 udp_port = self.udp_port_in
374 icmp_id = self.icmp_id_in
377 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
378 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
379 TCP(dport=tcp_port, sport=20))
383 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
384 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
385 UDP(dport=udp_port, sport=20))
389 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
390 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
391 ICMP(id=icmp_id, type='echo-reply'))
396 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
398 Create packet stream for outside network
400 :param out_if: Outside interface
401 :param dst_ip: Destination IP address (Default use global NAT address)
402 :param hl: HL of generated packets
406 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
407 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
408 TCP(dport=self.tcp_port_out, sport=20))
412 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
413 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
414 UDP(dport=self.udp_port_out, sport=20))
418 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
419 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
420 ICMPv6EchoReply(id=self.icmp_id_out))
425 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
426 dst_ip=None, is_ip6=False):
428 Verify captured packets on outside network
430 :param capture: Captured packets
431 :param nat_ip: Translated IP address (Default use global NAT address)
432 :param same_port: Sorce port number is not translated (Default False)
433 :param dst_ip: Destination IP address (Default do not verify)
434 :param is_ip6: If L3 protocol is IPv6 (Default False)
438 ICMP46 = ICMPv6EchoRequest
443 nat_ip = self.nat_addr
444 for packet in capture:
447 self.assert_packet_checksums_valid(packet)
448 self.assertEqual(packet[IP46].src, nat_ip)
449 if dst_ip is not None:
450 self.assertEqual(packet[IP46].dst, dst_ip)
451 if packet.haslayer(TCP):
453 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
456 packet[TCP].sport, self.tcp_port_in)
457 self.tcp_port_out = packet[TCP].sport
458 self.assert_packet_checksums_valid(packet)
459 elif packet.haslayer(UDP):
461 self.assertEqual(packet[UDP].sport, self.udp_port_in)
464 packet[UDP].sport, self.udp_port_in)
465 self.udp_port_out = packet[UDP].sport
468 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
470 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
471 self.icmp_id_out = packet[ICMP46].id
472 self.assert_packet_checksums_valid(packet)
474 self.logger.error(ppp("Unexpected or invalid packet "
475 "(outside network):", packet))
478 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
481 Verify captured packets on outside network
483 :param capture: Captured packets
484 :param nat_ip: Translated IP address
485 :param same_port: Sorce port number is not translated (Default False)
486 :param dst_ip: Destination IP address (Default do not verify)
488 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
491 def verify_capture_in(self, capture, in_if):
493 Verify captured packets on inside network
495 :param capture: Captured packets
496 :param in_if: Inside interface
498 for packet in capture:
500 self.assert_packet_checksums_valid(packet)
501 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
502 if packet.haslayer(TCP):
503 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
504 elif packet.haslayer(UDP):
505 self.assertEqual(packet[UDP].dport, self.udp_port_in)
507 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
509 self.logger.error(ppp("Unexpected or invalid packet "
510 "(inside network):", packet))
513 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
515 Verify captured IPv6 packets on inside network
517 :param capture: Captured packets
518 :param src_ip: Source IP
519 :param dst_ip: Destination IP address
521 for packet in capture:
523 self.assertEqual(packet[IPv6].src, src_ip)
524 self.assertEqual(packet[IPv6].dst, dst_ip)
525 self.assert_packet_checksums_valid(packet)
526 if packet.haslayer(TCP):
527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
528 elif packet.haslayer(UDP):
529 self.assertEqual(packet[UDP].dport, self.udp_port_in)
531 self.assertEqual(packet[ICMPv6EchoReply].id,
534 self.logger.error(ppp("Unexpected or invalid packet "
535 "(inside network):", packet))
538 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
540 Verify captured packet that don't have to be translated
542 :param capture: Captured packets
543 :param ingress_if: Ingress interface
544 :param egress_if: Egress interface
546 for packet in capture:
548 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
549 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
550 if packet.haslayer(TCP):
551 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
552 elif packet.haslayer(UDP):
553 self.assertEqual(packet[UDP].sport, self.udp_port_in)
555 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
557 self.logger.error(ppp("Unexpected or invalid packet "
558 "(inside network):", packet))
561 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
564 Verify captured packets with ICMP errors on outside network
566 :param capture: Captured packets
567 :param src_ip: Translated IP address or IP address of VPP
568 (Default use global NAT address)
569 :param icmp_type: Type of error ICMP packet
570 we are expecting (Default 11)
573 src_ip = self.nat_addr
574 for packet in capture:
576 self.assertEqual(packet[IP].src, src_ip)
577 self.assertTrue(packet.haslayer(ICMP))
579 self.assertEqual(icmp.type, icmp_type)
580 self.assertTrue(icmp.haslayer(IPerror))
581 inner_ip = icmp[IPerror]
582 if inner_ip.haslayer(TCPerror):
583 self.assertEqual(inner_ip[TCPerror].dport,
585 elif inner_ip.haslayer(UDPerror):
586 self.assertEqual(inner_ip[UDPerror].dport,
589 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
591 self.logger.error(ppp("Unexpected or invalid packet "
592 "(outside network):", packet))
595 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
597 Verify captured packets with ICMP errors on inside network
599 :param capture: Captured packets
600 :param in_if: Inside interface
601 :param icmp_type: Type of error ICMP packet
602 we are expecting (Default 11)
604 for packet in capture:
606 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
607 self.assertTrue(packet.haslayer(ICMP))
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].sport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].sport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(inside network):", packet))
625 def create_stream_frag(self, src_if, dst, sport, dport, data,
626 proto=IP_PROTOS.tcp, echo_reply=False):
628 Create fragmented packet stream
630 :param src_if: Source interface
631 :param dst: Destination IPv4 address
632 :param sport: Source port
633 :param dport: Destination port
634 :param data: Payload data
635 :param proto: protocol (TCP, UDP, ICMP)
636 :param echo_reply: use echo_reply if protocol is ICMP
639 if proto == IP_PROTOS.tcp:
640 p = (IP(src=src_if.remote_ip4, dst=dst) /
641 TCP(sport=sport, dport=dport) /
643 p = p.__class__(str(p))
644 chksum = p['TCP'].chksum
645 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
646 elif proto == IP_PROTOS.udp:
647 proto_header = UDP(sport=sport, dport=dport)
648 elif proto == IP_PROTOS.icmp:
650 proto_header = ICMP(id=sport, type='echo-request')
652 proto_header = ICMP(id=sport, type='echo-reply')
654 raise Exception("Unsupported protocol")
655 id = random.randint(0, 65535)
657 if proto == IP_PROTOS.tcp:
660 raw = Raw(data[0:16])
661 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
662 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
666 if proto == IP_PROTOS.tcp:
667 raw = Raw(data[4:20])
669 raw = Raw(data[16:32])
670 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
671 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
675 if proto == IP_PROTOS.tcp:
679 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
680 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
686 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
687 pref=None, plen=0, frag_size=128):
689 Create fragmented packet stream
691 :param src_if: Source interface
692 :param dst: Destination IPv4 address
693 :param sport: Source TCP port
694 :param dport: Destination TCP port
695 :param data: Payload data
696 :param pref: NAT64 prefix
697 :param plen: NAT64 prefix length
698 :param fragsize: size of fragments
702 dst_ip6 = ''.join(['64:ff9b::', dst])
704 dst_ip6 = self.compose_ip6(dst, pref, plen)
706 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
707 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
708 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
709 TCP(sport=sport, dport=dport) /
712 return fragment6(p, frag_size)
714 def reass_frags_and_verify(self, frags, src, dst):
716 Reassemble and verify fragmented packet
718 :param frags: Captured fragments
719 :param src: Source IPv4 address to verify
720 :param dst: Destination IPv4 address to verify
722 :returns: Reassembled IPv4 packet
724 buffer = StringIO.StringIO()
726 self.assertEqual(p[IP].src, src)
727 self.assertEqual(p[IP].dst, dst)
728 self.assert_ip_checksum_valid(p)
729 buffer.seek(p[IP].frag * 8)
730 buffer.write(p[IP].payload)
731 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
732 proto=frags[0][IP].proto)
733 if ip.proto == IP_PROTOS.tcp:
734 p = (ip / TCP(buffer.getvalue()))
735 self.assert_tcp_checksum_valid(p)
736 elif ip.proto == IP_PROTOS.udp:
737 p = (ip / UDP(buffer.getvalue()[:8]) /
738 Raw(buffer.getvalue()[8:]))
739 elif ip.proto == IP_PROTOS.icmp:
740 p = (ip / ICMP(buffer.getvalue()))
743 def reass_frags_and_verify_ip6(self, frags, src, dst):
745 Reassemble and verify fragmented packet
747 :param frags: Captured fragments
748 :param src: Source IPv6 address to verify
749 :param dst: Destination IPv6 address to verify
751 :returns: Reassembled IPv6 packet
753 buffer = StringIO.StringIO()
755 self.assertEqual(p[IPv6].src, src)
756 self.assertEqual(p[IPv6].dst, dst)
757 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
758 buffer.write(p[IPv6ExtHdrFragment].payload)
759 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
760 nh=frags[0][IPv6ExtHdrFragment].nh)
761 if ip.nh == IP_PROTOS.tcp:
762 p = (ip / TCP(buffer.getvalue()))
763 elif ip.nh == IP_PROTOS.udp:
764 p = (ip / UDP(buffer.getvalue()))
765 self.assert_packet_checksums_valid(p)
768 def initiate_tcp_session(self, in_if, out_if):
770 Initiates TCP session
772 :param in_if: Inside interface
773 :param out_if: Outside interface
777 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
778 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
779 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
782 self.pg_enable_capture(self.pg_interfaces)
784 capture = out_if.get_capture(1)
786 self.tcp_port_out = p[TCP].sport
788 # SYN + ACK packet out->in
789 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
790 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
791 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
794 self.pg_enable_capture(self.pg_interfaces)
799 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
800 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
801 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
804 self.pg_enable_capture(self.pg_interfaces)
806 out_if.get_capture(1)
809 self.logger.error("TCP 3 way handshake failed")
812 def verify_ipfix_nat44_ses(self, data):
814 Verify IPFIX NAT44 session create/delete event
816 :param data: Decoded IPFIX data records
818 nat44_ses_create_num = 0
819 nat44_ses_delete_num = 0
820 self.assertEqual(6, len(data))
823 self.assertIn(ord(record[230]), [4, 5])
824 if ord(record[230]) == 4:
825 nat44_ses_create_num += 1
827 nat44_ses_delete_num += 1
829 self.assertEqual(self.pg0.remote_ip4n, record[8])
830 # postNATSourceIPv4Address
831 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
834 self.assertEqual(struct.pack("!I", 0), record[234])
835 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
836 if IP_PROTOS.icmp == ord(record[4]):
837 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
838 self.assertEqual(struct.pack("!H", self.icmp_id_out),
840 elif IP_PROTOS.tcp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.tcp_port_in),
843 self.assertEqual(struct.pack("!H", self.tcp_port_out),
845 elif IP_PROTOS.udp == ord(record[4]):
846 self.assertEqual(struct.pack("!H", self.udp_port_in),
848 self.assertEqual(struct.pack("!H", self.udp_port_out),
851 self.fail("Invalid protocol")
852 self.assertEqual(3, nat44_ses_create_num)
853 self.assertEqual(3, nat44_ses_delete_num)
855 def verify_ipfix_addr_exhausted(self, data):
857 Verify IPFIX NAT addresses event
859 :param data: Decoded IPFIX data records
861 self.assertEqual(1, len(data))
864 self.assertEqual(ord(record[230]), 3)
866 self.assertEqual(struct.pack("!I", 0), record[283])
868 def verify_ipfix_max_sessions(self, data, limit):
870 Verify IPFIX maximum session entries exceeded event
872 :param data: Decoded IPFIX data records
873 :param limit: Number of maximum session entries that can be created.
875 self.assertEqual(1, len(data))
878 self.assertEqual(ord(record[230]), 13)
879 # natQuotaExceededEvent
880 self.assertEqual(struct.pack("I", 1), record[466])
882 self.assertEqual(struct.pack("I", limit), record[471])
884 def verify_ipfix_max_bibs(self, data, limit):
886 Verify IPFIX maximum BIB entries exceeded event
888 :param data: Decoded IPFIX data records
889 :param limit: Number of maximum BIB entries that can be created.
891 self.assertEqual(1, len(data))
894 self.assertEqual(ord(record[230]), 13)
895 # natQuotaExceededEvent
896 self.assertEqual(struct.pack("I", 2), record[466])
898 self.assertEqual(struct.pack("I", limit), record[472])
900 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
902 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum fragments pending reassembly
906 :param src_addr: IPv6 source address
908 self.assertEqual(1, len(data))
911 self.assertEqual(ord(record[230]), 13)
912 # natQuotaExceededEvent
913 self.assertEqual(struct.pack("I", 5), record[466])
914 # maxFragmentsPendingReassembly
915 self.assertEqual(struct.pack("I", limit), record[475])
917 self.assertEqual(src_addr, record[27])
919 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
921 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
923 :param data: Decoded IPFIX data records
924 :param limit: Number of maximum fragments pending reassembly
925 :param src_addr: IPv4 source address
927 self.assertEqual(1, len(data))
930 self.assertEqual(ord(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 5), record[466])
933 # maxFragmentsPendingReassembly
934 self.assertEqual(struct.pack("I", limit), record[475])
936 self.assertEqual(src_addr, record[8])
938 def verify_ipfix_bib(self, data, is_create, src_addr):
940 Verify IPFIX NAT64 BIB create and delete events
942 :param data: Decoded IPFIX data records
943 :param is_create: Create event if nonzero value otherwise delete event
944 :param src_addr: IPv6 source address
946 self.assertEqual(1, len(data))
950 self.assertEqual(ord(record[230]), 10)
952 self.assertEqual(ord(record[230]), 11)
954 self.assertEqual(src_addr, record[27])
955 # postNATSourceIPv4Address
956 self.assertEqual(self.nat_addr_n, record[225])
958 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
960 self.assertEqual(struct.pack("!I", 0), record[234])
961 # sourceTransportPort
962 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
963 # postNAPTSourceTransportPort
964 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
966 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
969 Verify IPFIX NAT64 session create and delete events
971 :param data: Decoded IPFIX data records
972 :param is_create: Create event if nonzero value otherwise delete event
973 :param src_addr: IPv6 source address
974 :param dst_addr: IPv4 destination address
975 :param dst_port: destination TCP port
977 self.assertEqual(1, len(data))
981 self.assertEqual(ord(record[230]), 6)
983 self.assertEqual(ord(record[230]), 7)
985 self.assertEqual(src_addr, record[27])
986 # destinationIPv6Address
987 self.assertEqual(socket.inet_pton(socket.AF_INET6,
988 self.compose_ip6(dst_addr,
992 # postNATSourceIPv4Address
993 self.assertEqual(self.nat_addr_n, record[225])
994 # postNATDestinationIPv4Address
995 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
998 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1000 self.assertEqual(struct.pack("!I", 0), record[234])
1001 # sourceTransportPort
1002 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1003 # postNAPTSourceTransportPort
1004 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1005 # destinationTransportPort
1006 self.assertEqual(struct.pack("!H", dst_port), record[11])
1007 # postNAPTDestinationTransportPort
1008 self.assertEqual(struct.pack("!H", dst_port), record[228])
1010 def verify_no_nat44_user(self):
1011 """ Verify that there is no NAT44 user """
1012 users = self.vapi.nat44_user_dump()
1013 self.assertEqual(len(users), 0)
1015 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1017 Verify IPFIX maximum entries per user exceeded event
1019 :param data: Decoded IPFIX data records
1020 :param limit: Number of maximum entries per user
1021 :param src_addr: IPv4 source address
1023 self.assertEqual(1, len(data))
1026 self.assertEqual(ord(record[230]), 13)
1027 # natQuotaExceededEvent
1028 self.assertEqual(struct.pack("I", 3), record[466])
1030 self.assertEqual(struct.pack("I", limit), record[473])
1032 self.assertEqual(src_addr, record[8])
1034 def verify_mss_value(self, pkt, mss):
1036 Verify TCP MSS value
1041 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1042 raise TypeError("Not a TCP/IP packet")
1044 for option in pkt[TCP].options:
1045 if option[0] == 'MSS':
1046 self.assertEqual(option[1], mss)
1047 self.assert_tcp_checksum_valid(pkt)
1050 def proto2layer(proto):
1051 if proto == IP_PROTOS.tcp:
1053 elif proto == IP_PROTOS.udp:
1055 elif proto == IP_PROTOS.icmp:
1058 raise Exception("Unsupported protocol")
1060 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1061 layer = self.proto2layer(proto)
1063 if proto == IP_PROTOS.tcp:
1064 data = "A" * 4 + "B" * 16 + "C" * 3
1066 data = "A" * 16 + "B" * 16 + "C" * 3
1067 self.port_in = random.randint(1025, 65535)
1069 reass = self.vapi.nat_reass_dump()
1070 reass_n_start = len(reass)
1073 pkts = self.create_stream_frag(self.pg0,
1074 self.pg1.remote_ip4,
1079 self.pg0.add_stream(pkts)
1080 self.pg_enable_capture(self.pg_interfaces)
1082 frags = self.pg1.get_capture(len(pkts))
1083 if not dont_translate:
1084 p = self.reass_frags_and_verify(frags,
1086 self.pg1.remote_ip4)
1088 p = self.reass_frags_and_verify(frags,
1089 self.pg0.remote_ip4,
1090 self.pg1.remote_ip4)
1091 if proto != IP_PROTOS.icmp:
1092 if not dont_translate:
1093 self.assertEqual(p[layer].dport, 20)
1094 self.assertNotEqual(p[layer].sport, self.port_in)
1096 self.assertEqual(p[layer].sport, self.port_in)
1098 if not dont_translate:
1099 self.assertNotEqual(p[layer].id, self.port_in)
1101 self.assertEqual(p[layer].id, self.port_in)
1102 self.assertEqual(data, p[Raw].load)
1105 if not dont_translate:
1106 dst_addr = self.nat_addr
1108 dst_addr = self.pg0.remote_ip4
1109 if proto != IP_PROTOS.icmp:
1111 dport = p[layer].sport
1115 pkts = self.create_stream_frag(self.pg1,
1122 self.pg1.add_stream(pkts)
1123 self.pg_enable_capture(self.pg_interfaces)
1125 frags = self.pg0.get_capture(len(pkts))
1126 p = self.reass_frags_and_verify(frags,
1127 self.pg1.remote_ip4,
1128 self.pg0.remote_ip4)
1129 if proto != IP_PROTOS.icmp:
1130 self.assertEqual(p[layer].sport, 20)
1131 self.assertEqual(p[layer].dport, self.port_in)
1133 self.assertEqual(p[layer].id, self.port_in)
1134 self.assertEqual(data, p[Raw].load)
1136 reass = self.vapi.nat_reass_dump()
1137 reass_n_end = len(reass)
1139 self.assertEqual(reass_n_end - reass_n_start, 2)
1141 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1142 layer = self.proto2layer(proto)
1144 if proto == IP_PROTOS.tcp:
1145 data = "A" * 4 + "B" * 16 + "C" * 3
1147 data = "A" * 16 + "B" * 16 + "C" * 3
1148 self.port_in = random.randint(1025, 65535)
1151 reass = self.vapi.nat_reass_dump()
1152 reass_n_start = len(reass)
1155 pkts = self.create_stream_frag(self.pg0,
1156 self.server_out_addr,
1158 self.server_out_port,
1161 self.pg0.add_stream(pkts)
1162 self.pg_enable_capture(self.pg_interfaces)
1164 frags = self.pg1.get_capture(len(pkts))
1165 p = self.reass_frags_and_verify(frags,
1166 self.pg0.remote_ip4,
1167 self.server_in_addr)
1168 if proto != IP_PROTOS.icmp:
1169 self.assertEqual(p[layer].sport, self.port_in)
1170 self.assertEqual(p[layer].dport, self.server_in_port)
1172 self.assertEqual(p[layer].id, self.port_in)
1173 self.assertEqual(data, p[Raw].load)
1176 if proto != IP_PROTOS.icmp:
1177 pkts = self.create_stream_frag(self.pg1,
1178 self.pg0.remote_ip4,
1179 self.server_in_port,
1184 pkts = self.create_stream_frag(self.pg1,
1185 self.pg0.remote_ip4,
1191 self.pg1.add_stream(pkts)
1192 self.pg_enable_capture(self.pg_interfaces)
1194 frags = self.pg0.get_capture(len(pkts))
1195 p = self.reass_frags_and_verify(frags,
1196 self.server_out_addr,
1197 self.pg0.remote_ip4)
1198 if proto != IP_PROTOS.icmp:
1199 self.assertEqual(p[layer].sport, self.server_out_port)
1200 self.assertEqual(p[layer].dport, self.port_in)
1202 self.assertEqual(p[layer].id, self.port_in)
1203 self.assertEqual(data, p[Raw].load)
1205 reass = self.vapi.nat_reass_dump()
1206 reass_n_end = len(reass)
1208 self.assertEqual(reass_n_end - reass_n_start, 2)
1210 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1211 layer = self.proto2layer(proto)
1213 if proto == IP_PROTOS.tcp:
1214 data = "A" * 4 + "B" * 16 + "C" * 3
1216 data = "A" * 16 + "B" * 16 + "C" * 3
1218 # send packet from host to server
1219 pkts = self.create_stream_frag(self.pg0,
1222 self.server_out_port,
1225 self.pg0.add_stream(pkts)
1226 self.pg_enable_capture(self.pg_interfaces)
1228 frags = self.pg0.get_capture(len(pkts))
1229 p = self.reass_frags_and_verify(frags,
1232 if proto != IP_PROTOS.icmp:
1233 self.assertNotEqual(p[layer].sport, self.host_in_port)
1234 self.assertEqual(p[layer].dport, self.server_in_port)
1236 self.assertNotEqual(p[layer].id, self.host_in_port)
1237 self.assertEqual(data, p[Raw].load)
1239 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1240 layer = self.proto2layer(proto)
1242 if proto == IP_PROTOS.tcp:
1243 data = "A" * 4 + "B" * 16 + "C" * 3
1245 data = "A" * 16 + "B" * 16 + "C" * 3
1246 self.port_in = random.randint(1025, 65535)
1250 pkts = self.create_stream_frag(self.pg0,
1251 self.pg1.remote_ip4,
1257 self.pg0.add_stream(pkts)
1258 self.pg_enable_capture(self.pg_interfaces)
1260 frags = self.pg1.get_capture(len(pkts))
1261 if not dont_translate:
1262 p = self.reass_frags_and_verify(frags,
1264 self.pg1.remote_ip4)
1266 p = self.reass_frags_and_verify(frags,
1267 self.pg0.remote_ip4,
1268 self.pg1.remote_ip4)
1269 if proto != IP_PROTOS.icmp:
1270 if not dont_translate:
1271 self.assertEqual(p[layer].dport, 20)
1272 self.assertNotEqual(p[layer].sport, self.port_in)
1274 self.assertEqual(p[layer].sport, self.port_in)
1276 if not dont_translate:
1277 self.assertNotEqual(p[layer].id, self.port_in)
1279 self.assertEqual(p[layer].id, self.port_in)
1280 self.assertEqual(data, p[Raw].load)
1283 if not dont_translate:
1284 dst_addr = self.nat_addr
1286 dst_addr = self.pg0.remote_ip4
1287 if proto != IP_PROTOS.icmp:
1289 dport = p[layer].sport
1293 pkts = self.create_stream_frag(self.pg1,
1301 self.pg1.add_stream(pkts)
1302 self.pg_enable_capture(self.pg_interfaces)
1304 frags = self.pg0.get_capture(len(pkts))
1305 p = self.reass_frags_and_verify(frags,
1306 self.pg1.remote_ip4,
1307 self.pg0.remote_ip4)
1308 if proto != IP_PROTOS.icmp:
1309 self.assertEqual(p[layer].sport, 20)
1310 self.assertEqual(p[layer].dport, self.port_in)
1312 self.assertEqual(p[layer].id, self.port_in)
1313 self.assertEqual(data, p[Raw].load)
1315 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1316 layer = self.proto2layer(proto)
1318 if proto == IP_PROTOS.tcp:
1319 data = "A" * 4 + "B" * 16 + "C" * 3
1321 data = "A" * 16 + "B" * 16 + "C" * 3
1322 self.port_in = random.randint(1025, 65535)
1326 pkts = self.create_stream_frag(self.pg0,
1327 self.server_out_addr,
1329 self.server_out_port,
1333 self.pg0.add_stream(pkts)
1334 self.pg_enable_capture(self.pg_interfaces)
1336 frags = self.pg1.get_capture(len(pkts))
1337 p = self.reass_frags_and_verify(frags,
1338 self.pg0.remote_ip4,
1339 self.server_in_addr)
1340 if proto != IP_PROTOS.icmp:
1341 self.assertEqual(p[layer].dport, self.server_in_port)
1342 self.assertEqual(p[layer].sport, self.port_in)
1343 self.assertEqual(p[layer].dport, self.server_in_port)
1345 self.assertEqual(p[layer].id, self.port_in)
1346 self.assertEqual(data, p[Raw].load)
1349 if proto != IP_PROTOS.icmp:
1350 pkts = self.create_stream_frag(self.pg1,
1351 self.pg0.remote_ip4,
1352 self.server_in_port,
1357 pkts = self.create_stream_frag(self.pg1,
1358 self.pg0.remote_ip4,
1365 self.pg1.add_stream(pkts)
1366 self.pg_enable_capture(self.pg_interfaces)
1368 frags = self.pg0.get_capture(len(pkts))
1369 p = self.reass_frags_and_verify(frags,
1370 self.server_out_addr,
1371 self.pg0.remote_ip4)
1372 if proto != IP_PROTOS.icmp:
1373 self.assertEqual(p[layer].sport, self.server_out_port)
1374 self.assertEqual(p[layer].dport, self.port_in)
1376 self.assertEqual(p[layer].id, self.port_in)
1377 self.assertEqual(data, p[Raw].load)
1380 class TestNAT44(MethodHolder):
1381 """ NAT44 Test Cases """
1384 def setUpClass(cls):
1385 super(TestNAT44, cls).setUpClass()
1386 cls.vapi.cli("set log class nat level debug")
1389 cls.tcp_port_in = 6303
1390 cls.tcp_port_out = 6303
1391 cls.udp_port_in = 6304
1392 cls.udp_port_out = 6304
1393 cls.icmp_id_in = 6305
1394 cls.icmp_id_out = 6305
1395 cls.nat_addr = '10.0.0.3'
1396 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1397 cls.ipfix_src_port = 4739
1398 cls.ipfix_domain_id = 1
1399 cls.tcp_external_port = 80
1401 cls.create_pg_interfaces(range(10))
1402 cls.interfaces = list(cls.pg_interfaces[0:4])
1404 for i in cls.interfaces:
1409 cls.pg0.generate_remote_hosts(3)
1410 cls.pg0.configure_ipv4_neighbors()
1412 cls.pg1.generate_remote_hosts(1)
1413 cls.pg1.configure_ipv4_neighbors()
1415 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1416 cls.vapi.ip_table_add_del(10, is_add=1)
1417 cls.vapi.ip_table_add_del(20, is_add=1)
1419 cls.pg4._local_ip4 = "172.16.255.1"
1420 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1421 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1422 cls.pg4.set_table_ip4(10)
1423 cls.pg5._local_ip4 = "172.17.255.3"
1424 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1425 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1426 cls.pg5.set_table_ip4(10)
1427 cls.pg6._local_ip4 = "172.16.255.1"
1428 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1429 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1430 cls.pg6.set_table_ip4(20)
1431 for i in cls.overlapping_interfaces:
1439 cls.pg9.generate_remote_hosts(2)
1440 cls.pg9.config_ip4()
1441 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1442 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1446 cls.pg9.resolve_arp()
1447 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1448 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1449 cls.pg9.resolve_arp()
1452 super(TestNAT44, cls).tearDownClass()
1455 def test_dynamic(self):
1456 """ NAT44 dynamic translation test """
1458 self.nat44_add_address(self.nat_addr)
1459 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1460 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1464 pkts = self.create_stream_in(self.pg0, self.pg1)
1465 self.pg0.add_stream(pkts)
1466 self.pg_enable_capture(self.pg_interfaces)
1468 capture = self.pg1.get_capture(len(pkts))
1469 self.verify_capture_out(capture)
1472 pkts = self.create_stream_out(self.pg1)
1473 self.pg1.add_stream(pkts)
1474 self.pg_enable_capture(self.pg_interfaces)
1476 capture = self.pg0.get_capture(len(pkts))
1477 self.verify_capture_in(capture, self.pg0)
1479 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1480 """ NAT44 handling of client packets with TTL=1 """
1482 self.nat44_add_address(self.nat_addr)
1483 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1484 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1487 # Client side - generate traffic
1488 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1489 self.pg0.add_stream(pkts)
1490 self.pg_enable_capture(self.pg_interfaces)
1493 # Client side - verify ICMP type 11 packets
1494 capture = self.pg0.get_capture(len(pkts))
1495 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1497 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1498 """ NAT44 handling of server packets with TTL=1 """
1500 self.nat44_add_address(self.nat_addr)
1501 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1502 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1505 # Client side - create sessions
1506 pkts = self.create_stream_in(self.pg0, self.pg1)
1507 self.pg0.add_stream(pkts)
1508 self.pg_enable_capture(self.pg_interfaces)
1511 # Server side - generate traffic
1512 capture = self.pg1.get_capture(len(pkts))
1513 self.verify_capture_out(capture)
1514 pkts = self.create_stream_out(self.pg1, ttl=1)
1515 self.pg1.add_stream(pkts)
1516 self.pg_enable_capture(self.pg_interfaces)
1519 # Server side - verify ICMP type 11 packets
1520 capture = self.pg1.get_capture(len(pkts))
1521 self.verify_capture_out_with_icmp_errors(capture,
1522 src_ip=self.pg1.local_ip4)
1524 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1525 """ NAT44 handling of error responses to client packets with TTL=2 """
1527 self.nat44_add_address(self.nat_addr)
1528 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1529 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1532 # Client side - generate traffic
1533 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1534 self.pg0.add_stream(pkts)
1535 self.pg_enable_capture(self.pg_interfaces)
1538 # Server side - simulate ICMP type 11 response
1539 capture = self.pg1.get_capture(len(pkts))
1540 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1541 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1542 ICMP(type=11) / packet[IP] for packet in capture]
1543 self.pg1.add_stream(pkts)
1544 self.pg_enable_capture(self.pg_interfaces)
1547 # Client side - verify ICMP type 11 packets
1548 capture = self.pg0.get_capture(len(pkts))
1549 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1551 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1552 """ NAT44 handling of error responses to server packets with TTL=2 """
1554 self.nat44_add_address(self.nat_addr)
1555 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1556 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1559 # Client side - create sessions
1560 pkts = self.create_stream_in(self.pg0, self.pg1)
1561 self.pg0.add_stream(pkts)
1562 self.pg_enable_capture(self.pg_interfaces)
1565 # Server side - generate traffic
1566 capture = self.pg1.get_capture(len(pkts))
1567 self.verify_capture_out(capture)
1568 pkts = self.create_stream_out(self.pg1, ttl=2)
1569 self.pg1.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1573 # Client side - simulate ICMP type 11 response
1574 capture = self.pg0.get_capture(len(pkts))
1575 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1576 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1577 ICMP(type=11) / packet[IP] for packet in capture]
1578 self.pg0.add_stream(pkts)
1579 self.pg_enable_capture(self.pg_interfaces)
1582 # Server side - verify ICMP type 11 packets
1583 capture = self.pg1.get_capture(len(pkts))
1584 self.verify_capture_out_with_icmp_errors(capture)
1586 def test_ping_out_interface_from_outside(self):
1587 """ Ping NAT44 out interface from outside network """
1589 self.nat44_add_address(self.nat_addr)
1590 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1591 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1594 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1595 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1596 ICMP(id=self.icmp_id_out, type='echo-request'))
1598 self.pg1.add_stream(pkts)
1599 self.pg_enable_capture(self.pg_interfaces)
1601 capture = self.pg1.get_capture(len(pkts))
1604 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1605 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1606 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1607 self.assertEqual(packet[ICMP].type, 0) # echo reply
1609 self.logger.error(ppp("Unexpected or invalid packet "
1610 "(outside network):", packet))
1613 def test_ping_internal_host_from_outside(self):
1614 """ Ping internal host from outside network """
1616 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1617 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1618 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1622 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1623 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1624 ICMP(id=self.icmp_id_out, type='echo-request'))
1625 self.pg1.add_stream(pkt)
1626 self.pg_enable_capture(self.pg_interfaces)
1628 capture = self.pg0.get_capture(1)
1629 self.verify_capture_in(capture, self.pg0)
1630 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1633 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1634 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1635 ICMP(id=self.icmp_id_in, type='echo-reply'))
1636 self.pg0.add_stream(pkt)
1637 self.pg_enable_capture(self.pg_interfaces)
1639 capture = self.pg1.get_capture(1)
1640 self.verify_capture_out(capture, same_port=True)
1641 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1643 def test_forwarding(self):
1644 """ NAT44 forwarding test """
1646 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1647 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1649 self.vapi.nat44_forwarding_enable_disable(1)
1651 real_ip = self.pg0.remote_ip4n
1652 alias_ip = self.nat_addr_n
1653 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1654 external_ip=alias_ip)
1657 # static mapping match
1659 pkts = self.create_stream_out(self.pg1)
1660 self.pg1.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1663 capture = self.pg0.get_capture(len(pkts))
1664 self.verify_capture_in(capture, self.pg0)
1666 pkts = self.create_stream_in(self.pg0, self.pg1)
1667 self.pg0.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1670 capture = self.pg1.get_capture(len(pkts))
1671 self.verify_capture_out(capture, same_port=True)
1673 # no static mapping match
1675 host0 = self.pg0.remote_hosts[0]
1676 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1678 pkts = self.create_stream_out(self.pg1,
1679 dst_ip=self.pg0.remote_ip4,
1680 use_inside_ports=True)
1681 self.pg1.add_stream(pkts)
1682 self.pg_enable_capture(self.pg_interfaces)
1684 capture = self.pg0.get_capture(len(pkts))
1685 self.verify_capture_in(capture, self.pg0)
1687 pkts = self.create_stream_in(self.pg0, self.pg1)
1688 self.pg0.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1691 capture = self.pg1.get_capture(len(pkts))
1692 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1695 self.pg0.remote_hosts[0] = host0
1698 self.vapi.nat44_forwarding_enable_disable(0)
1699 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1700 external_ip=alias_ip,
1703 def test_static_in(self):
1704 """ 1:1 NAT initialized from inside network """
1706 nat_ip = "10.0.0.10"
1707 self.tcp_port_out = 6303
1708 self.udp_port_out = 6304
1709 self.icmp_id_out = 6305
1711 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1712 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1713 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1715 sm = self.vapi.nat44_static_mapping_dump()
1716 self.assertEqual(len(sm), 1)
1717 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1718 self.assertEqual(sm[0].protocol, 0)
1719 self.assertEqual(sm[0].local_port, 0)
1720 self.assertEqual(sm[0].external_port, 0)
1723 pkts = self.create_stream_in(self.pg0, self.pg1)
1724 self.pg0.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1727 capture = self.pg1.get_capture(len(pkts))
1728 self.verify_capture_out(capture, nat_ip, True)
1731 pkts = self.create_stream_out(self.pg1, nat_ip)
1732 self.pg1.add_stream(pkts)
1733 self.pg_enable_capture(self.pg_interfaces)
1735 capture = self.pg0.get_capture(len(pkts))
1736 self.verify_capture_in(capture, self.pg0)
1738 def test_static_out(self):
1739 """ 1:1 NAT initialized from outside network """
1741 nat_ip = "10.0.0.20"
1742 self.tcp_port_out = 6303
1743 self.udp_port_out = 6304
1744 self.icmp_id_out = 6305
1747 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1748 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1749 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1751 sm = self.vapi.nat44_static_mapping_dump()
1752 self.assertEqual(len(sm), 1)
1753 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1756 pkts = self.create_stream_out(self.pg1, nat_ip)
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg0.get_capture(len(pkts))
1761 self.verify_capture_in(capture, self.pg0)
1764 pkts = self.create_stream_in(self.pg0, self.pg1)
1765 self.pg0.add_stream(pkts)
1766 self.pg_enable_capture(self.pg_interfaces)
1768 capture = self.pg1.get_capture(len(pkts))
1769 self.verify_capture_out(capture, nat_ip, True)
1771 def test_static_with_port_in(self):
1772 """ 1:1 NAPT initialized from inside network """
1774 self.tcp_port_out = 3606
1775 self.udp_port_out = 3607
1776 self.icmp_id_out = 3608
1778 self.nat44_add_address(self.nat_addr)
1779 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1780 self.tcp_port_in, self.tcp_port_out,
1781 proto=IP_PROTOS.tcp)
1782 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1783 self.udp_port_in, self.udp_port_out,
1784 proto=IP_PROTOS.udp)
1785 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1786 self.icmp_id_in, self.icmp_id_out,
1787 proto=IP_PROTOS.icmp)
1788 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1789 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1793 pkts = self.create_stream_in(self.pg0, self.pg1)
1794 self.pg0.add_stream(pkts)
1795 self.pg_enable_capture(self.pg_interfaces)
1797 capture = self.pg1.get_capture(len(pkts))
1798 self.verify_capture_out(capture)
1801 pkts = self.create_stream_out(self.pg1)
1802 self.pg1.add_stream(pkts)
1803 self.pg_enable_capture(self.pg_interfaces)
1805 capture = self.pg0.get_capture(len(pkts))
1806 self.verify_capture_in(capture, self.pg0)
1808 def test_static_with_port_out(self):
1809 """ 1:1 NAPT initialized from outside network """
1811 self.tcp_port_out = 30606
1812 self.udp_port_out = 30607
1813 self.icmp_id_out = 30608
1815 self.nat44_add_address(self.nat_addr)
1816 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1817 self.tcp_port_in, self.tcp_port_out,
1818 proto=IP_PROTOS.tcp)
1819 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1820 self.udp_port_in, self.udp_port_out,
1821 proto=IP_PROTOS.udp)
1822 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1823 self.icmp_id_in, self.icmp_id_out,
1824 proto=IP_PROTOS.icmp)
1825 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1826 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1838 pkts = self.create_stream_in(self.pg0, self.pg1)
1839 self.pg0.add_stream(pkts)
1840 self.pg_enable_capture(self.pg_interfaces)
1842 capture = self.pg1.get_capture(len(pkts))
1843 self.verify_capture_out(capture)
1845 def test_static_vrf_aware(self):
1846 """ 1:1 NAT VRF awareness """
1848 nat_ip1 = "10.0.0.30"
1849 nat_ip2 = "10.0.0.40"
1850 self.tcp_port_out = 6303
1851 self.udp_port_out = 6304
1852 self.icmp_id_out = 6305
1854 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1856 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1858 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1861 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1863 # inside interface VRF match NAT44 static mapping VRF
1864 pkts = self.create_stream_in(self.pg4, self.pg3)
1865 self.pg4.add_stream(pkts)
1866 self.pg_enable_capture(self.pg_interfaces)
1868 capture = self.pg3.get_capture(len(pkts))
1869 self.verify_capture_out(capture, nat_ip1, True)
1871 # inside interface VRF don't match NAT44 static mapping VRF (packets
1873 pkts = self.create_stream_in(self.pg0, self.pg3)
1874 self.pg0.add_stream(pkts)
1875 self.pg_enable_capture(self.pg_interfaces)
1877 self.pg3.assert_nothing_captured()
1879 def test_dynamic_to_static(self):
1880 """ Switch from dynamic translation to 1:1NAT """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_address(self.nat_addr)
1887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg1.get_capture(len(pkts))
1897 self.verify_capture_out(capture)
1900 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1901 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1902 self.assertEqual(len(sessions), 0)
1903 pkts = self.create_stream_in(self.pg0, self.pg1)
1904 self.pg0.add_stream(pkts)
1905 self.pg_enable_capture(self.pg_interfaces)
1907 capture = self.pg1.get_capture(len(pkts))
1908 self.verify_capture_out(capture, nat_ip, True)
1910 def test_identity_nat(self):
1911 """ Identity NAT """
1913 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1915 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1918 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1919 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1920 TCP(sport=12345, dport=56789))
1921 self.pg1.add_stream(p)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg0.get_capture(1)
1929 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1930 self.assertEqual(ip.src, self.pg1.remote_ip4)
1931 self.assertEqual(tcp.dport, 56789)
1932 self.assertEqual(tcp.sport, 12345)
1933 self.assert_packet_checksums_valid(p)
1935 self.logger.error(ppp("Unexpected or invalid packet:", p))
1938 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1939 self.assertEqual(len(sessions), 0)
1940 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
1942 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1943 self.assertEqual(len(identity_mappings), 2)
1945 def test_multiple_inside_interfaces(self):
1946 """ NAT44 multiple non-overlapping address space inside interfaces """
1948 self.nat44_add_address(self.nat_addr)
1949 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1950 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1951 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1954 # between two NAT44 inside interfaces (no translation)
1955 pkts = self.create_stream_in(self.pg0, self.pg1)
1956 self.pg0.add_stream(pkts)
1957 self.pg_enable_capture(self.pg_interfaces)
1959 capture = self.pg1.get_capture(len(pkts))
1960 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1962 # from NAT44 inside to interface without NAT44 feature (no translation)
1963 pkts = self.create_stream_in(self.pg0, self.pg2)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1967 capture = self.pg2.get_capture(len(pkts))
1968 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1970 # in2out 1st interface
1971 pkts = self.create_stream_in(self.pg0, self.pg3)
1972 self.pg0.add_stream(pkts)
1973 self.pg_enable_capture(self.pg_interfaces)
1975 capture = self.pg3.get_capture(len(pkts))
1976 self.verify_capture_out(capture)
1978 # out2in 1st interface
1979 pkts = self.create_stream_out(self.pg3)
1980 self.pg3.add_stream(pkts)
1981 self.pg_enable_capture(self.pg_interfaces)
1983 capture = self.pg0.get_capture(len(pkts))
1984 self.verify_capture_in(capture, self.pg0)
1986 # in2out 2nd interface
1987 pkts = self.create_stream_in(self.pg1, self.pg3)
1988 self.pg1.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1991 capture = self.pg3.get_capture(len(pkts))
1992 self.verify_capture_out(capture)
1994 # out2in 2nd interface
1995 pkts = self.create_stream_out(self.pg3)
1996 self.pg3.add_stream(pkts)
1997 self.pg_enable_capture(self.pg_interfaces)
1999 capture = self.pg1.get_capture(len(pkts))
2000 self.verify_capture_in(capture, self.pg1)
2002 def test_inside_overlapping_interfaces(self):
2003 """ NAT44 multiple inside interfaces with overlapping address space """
2005 static_nat_ip = "10.0.0.10"
2006 self.nat44_add_address(self.nat_addr)
2007 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2009 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2010 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2011 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2012 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2015 # between NAT44 inside interfaces with same VRF (no translation)
2016 pkts = self.create_stream_in(self.pg4, self.pg5)
2017 self.pg4.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2020 capture = self.pg5.get_capture(len(pkts))
2021 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2023 # between NAT44 inside interfaces with different VRF (hairpinning)
2024 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2025 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2026 TCP(sport=1234, dport=5678))
2027 self.pg4.add_stream(p)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg6.get_capture(1)
2035 self.assertEqual(ip.src, self.nat_addr)
2036 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2037 self.assertNotEqual(tcp.sport, 1234)
2038 self.assertEqual(tcp.dport, 5678)
2040 self.logger.error(ppp("Unexpected or invalid packet:", p))
2043 # in2out 1st interface
2044 pkts = self.create_stream_in(self.pg4, self.pg3)
2045 self.pg4.add_stream(pkts)
2046 self.pg_enable_capture(self.pg_interfaces)
2048 capture = self.pg3.get_capture(len(pkts))
2049 self.verify_capture_out(capture)
2051 # out2in 1st interface
2052 pkts = self.create_stream_out(self.pg3)
2053 self.pg3.add_stream(pkts)
2054 self.pg_enable_capture(self.pg_interfaces)
2056 capture = self.pg4.get_capture(len(pkts))
2057 self.verify_capture_in(capture, self.pg4)
2059 # in2out 2nd interface
2060 pkts = self.create_stream_in(self.pg5, self.pg3)
2061 self.pg5.add_stream(pkts)
2062 self.pg_enable_capture(self.pg_interfaces)
2064 capture = self.pg3.get_capture(len(pkts))
2065 self.verify_capture_out(capture)
2067 # out2in 2nd interface
2068 pkts = self.create_stream_out(self.pg3)
2069 self.pg3.add_stream(pkts)
2070 self.pg_enable_capture(self.pg_interfaces)
2072 capture = self.pg5.get_capture(len(pkts))
2073 self.verify_capture_in(capture, self.pg5)
2076 addresses = self.vapi.nat44_address_dump()
2077 self.assertEqual(len(addresses), 1)
2078 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2079 self.assertEqual(len(sessions), 3)
2080 for session in sessions:
2081 self.assertFalse(session.is_static)
2082 self.assertEqual(session.inside_ip_address[0:4],
2083 self.pg5.remote_ip4n)
2084 self.assertEqual(session.outside_ip_address,
2085 addresses[0].ip_address)
2086 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2087 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2088 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2089 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2090 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2091 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2092 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2093 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2094 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2096 # in2out 3rd interface
2097 pkts = self.create_stream_in(self.pg6, self.pg3)
2098 self.pg6.add_stream(pkts)
2099 self.pg_enable_capture(self.pg_interfaces)
2101 capture = self.pg3.get_capture(len(pkts))
2102 self.verify_capture_out(capture, static_nat_ip, True)
2104 # out2in 3rd interface
2105 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2106 self.pg3.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg6.get_capture(len(pkts))
2110 self.verify_capture_in(capture, self.pg6)
2112 # general user and session dump verifications
2113 users = self.vapi.nat44_user_dump()
2114 self.assertTrue(len(users) >= 3)
2115 addresses = self.vapi.nat44_address_dump()
2116 self.assertEqual(len(addresses), 1)
2118 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2120 for session in sessions:
2121 self.assertEqual(user.ip_address, session.inside_ip_address)
2122 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2123 self.assertTrue(session.protocol in
2124 [IP_PROTOS.tcp, IP_PROTOS.udp,
2126 self.assertFalse(session.ext_host_valid)
2129 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2130 self.assertTrue(len(sessions) >= 4)
2131 for session in sessions:
2132 self.assertFalse(session.is_static)
2133 self.assertEqual(session.inside_ip_address[0:4],
2134 self.pg4.remote_ip4n)
2135 self.assertEqual(session.outside_ip_address,
2136 addresses[0].ip_address)
2139 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2140 self.assertTrue(len(sessions) >= 3)
2141 for session in sessions:
2142 self.assertTrue(session.is_static)
2143 self.assertEqual(session.inside_ip_address[0:4],
2144 self.pg6.remote_ip4n)
2145 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2146 map(int, static_nat_ip.split('.')))
2147 self.assertTrue(session.inside_port in
2148 [self.tcp_port_in, self.udp_port_in,
2151 def test_hairpinning(self):
2152 """ NAT44 hairpinning - 1:1 NAPT """
2154 host = self.pg0.remote_hosts[0]
2155 server = self.pg0.remote_hosts[1]
2158 server_in_port = 5678
2159 server_out_port = 8765
2161 self.nat44_add_address(self.nat_addr)
2162 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2163 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2165 # add static mapping for server
2166 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2167 server_in_port, server_out_port,
2168 proto=IP_PROTOS.tcp)
2170 # send packet from host to server
2171 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2172 IP(src=host.ip4, dst=self.nat_addr) /
2173 TCP(sport=host_in_port, dport=server_out_port))
2174 self.pg0.add_stream(p)
2175 self.pg_enable_capture(self.pg_interfaces)
2177 capture = self.pg0.get_capture(1)
2182 self.assertEqual(ip.src, self.nat_addr)
2183 self.assertEqual(ip.dst, server.ip4)
2184 self.assertNotEqual(tcp.sport, host_in_port)
2185 self.assertEqual(tcp.dport, server_in_port)
2186 self.assert_packet_checksums_valid(p)
2187 host_out_port = tcp.sport
2189 self.logger.error(ppp("Unexpected or invalid packet:", p))
2192 # send reply from server to host
2193 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2194 IP(src=server.ip4, dst=self.nat_addr) /
2195 TCP(sport=server_in_port, dport=host_out_port))
2196 self.pg0.add_stream(p)
2197 self.pg_enable_capture(self.pg_interfaces)
2199 capture = self.pg0.get_capture(1)
2204 self.assertEqual(ip.src, self.nat_addr)
2205 self.assertEqual(ip.dst, host.ip4)
2206 self.assertEqual(tcp.sport, server_out_port)
2207 self.assertEqual(tcp.dport, host_in_port)
2208 self.assert_packet_checksums_valid(p)
2210 self.logger.error(ppp("Unexpected or invalid packet:", p))
2213 def test_hairpinning2(self):
2214 """ NAT44 hairpinning - 1:1 NAT"""
2216 server1_nat_ip = "10.0.0.10"
2217 server2_nat_ip = "10.0.0.11"
2218 host = self.pg0.remote_hosts[0]
2219 server1 = self.pg0.remote_hosts[1]
2220 server2 = self.pg0.remote_hosts[2]
2221 server_tcp_port = 22
2222 server_udp_port = 20
2224 self.nat44_add_address(self.nat_addr)
2225 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2226 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2229 # add static mapping for servers
2230 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2231 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2235 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2236 IP(src=host.ip4, dst=server1_nat_ip) /
2237 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2240 IP(src=host.ip4, dst=server1_nat_ip) /
2241 UDP(sport=self.udp_port_in, dport=server_udp_port))
2243 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2244 IP(src=host.ip4, dst=server1_nat_ip) /
2245 ICMP(id=self.icmp_id_in, type='echo-request'))
2247 self.pg0.add_stream(pkts)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg0.get_capture(len(pkts))
2251 for packet in capture:
2253 self.assertEqual(packet[IP].src, self.nat_addr)
2254 self.assertEqual(packet[IP].dst, server1.ip4)
2255 if packet.haslayer(TCP):
2256 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2257 self.assertEqual(packet[TCP].dport, server_tcp_port)
2258 self.tcp_port_out = packet[TCP].sport
2259 self.assert_packet_checksums_valid(packet)
2260 elif packet.haslayer(UDP):
2261 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2262 self.assertEqual(packet[UDP].dport, server_udp_port)
2263 self.udp_port_out = packet[UDP].sport
2265 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2266 self.icmp_id_out = packet[ICMP].id
2268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2274 IP(src=server1.ip4, dst=self.nat_addr) /
2275 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2278 IP(src=server1.ip4, dst=self.nat_addr) /
2279 UDP(sport=server_udp_port, dport=self.udp_port_out))
2281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2282 IP(src=server1.ip4, dst=self.nat_addr) /
2283 ICMP(id=self.icmp_id_out, type='echo-reply'))
2285 self.pg0.add_stream(pkts)
2286 self.pg_enable_capture(self.pg_interfaces)
2288 capture = self.pg0.get_capture(len(pkts))
2289 for packet in capture:
2291 self.assertEqual(packet[IP].src, server1_nat_ip)
2292 self.assertEqual(packet[IP].dst, host.ip4)
2293 if packet.haslayer(TCP):
2294 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2295 self.assertEqual(packet[TCP].sport, server_tcp_port)
2296 self.assert_packet_checksums_valid(packet)
2297 elif packet.haslayer(UDP):
2298 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2299 self.assertEqual(packet[UDP].sport, server_udp_port)
2301 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2306 # server2 to server1
2308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2309 IP(src=server2.ip4, dst=server1_nat_ip) /
2310 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2313 IP(src=server2.ip4, dst=server1_nat_ip) /
2314 UDP(sport=self.udp_port_in, dport=server_udp_port))
2316 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2317 IP(src=server2.ip4, dst=server1_nat_ip) /
2318 ICMP(id=self.icmp_id_in, type='echo-request'))
2320 self.pg0.add_stream(pkts)
2321 self.pg_enable_capture(self.pg_interfaces)
2323 capture = self.pg0.get_capture(len(pkts))
2324 for packet in capture:
2326 self.assertEqual(packet[IP].src, server2_nat_ip)
2327 self.assertEqual(packet[IP].dst, server1.ip4)
2328 if packet.haslayer(TCP):
2329 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2330 self.assertEqual(packet[TCP].dport, server_tcp_port)
2331 self.tcp_port_out = packet[TCP].sport
2332 self.assert_packet_checksums_valid(packet)
2333 elif packet.haslayer(UDP):
2334 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2335 self.assertEqual(packet[UDP].dport, server_udp_port)
2336 self.udp_port_out = packet[UDP].sport
2338 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2339 self.icmp_id_out = packet[ICMP].id
2341 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2344 # server1 to server2
2346 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2347 IP(src=server1.ip4, dst=server2_nat_ip) /
2348 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2350 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2351 IP(src=server1.ip4, dst=server2_nat_ip) /
2352 UDP(sport=server_udp_port, dport=self.udp_port_out))
2354 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2355 IP(src=server1.ip4, dst=server2_nat_ip) /
2356 ICMP(id=self.icmp_id_out, type='echo-reply'))
2358 self.pg0.add_stream(pkts)
2359 self.pg_enable_capture(self.pg_interfaces)
2361 capture = self.pg0.get_capture(len(pkts))
2362 for packet in capture:
2364 self.assertEqual(packet[IP].src, server1_nat_ip)
2365 self.assertEqual(packet[IP].dst, server2.ip4)
2366 if packet.haslayer(TCP):
2367 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2368 self.assertEqual(packet[TCP].sport, server_tcp_port)
2369 self.assert_packet_checksums_valid(packet)
2370 elif packet.haslayer(UDP):
2371 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2372 self.assertEqual(packet[UDP].sport, server_udp_port)
2374 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2376 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2379 def test_max_translations_per_user(self):
2380 """ MAX translations per user - recycle the least recently used """
2382 self.nat44_add_address(self.nat_addr)
2383 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2384 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2387 # get maximum number of translations per user
2388 nat44_config = self.vapi.nat_show_config()
2390 # send more than maximum number of translations per user packets
2391 pkts_num = nat44_config.max_translations_per_user + 5
2393 for port in range(0, pkts_num):
2394 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2395 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2396 TCP(sport=1025 + port))
2398 self.pg0.add_stream(pkts)
2399 self.pg_enable_capture(self.pg_interfaces)
2402 # verify number of translated packet
2403 self.pg1.get_capture(pkts_num)
2405 users = self.vapi.nat44_user_dump()
2407 if user.ip_address == self.pg0.remote_ip4n:
2408 self.assertEqual(user.nsessions,
2409 nat44_config.max_translations_per_user)
2410 self.assertEqual(user.nstaticsessions, 0)
2413 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2415 proto=IP_PROTOS.tcp)
2416 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2417 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2418 TCP(sport=tcp_port))
2419 self.pg0.add_stream(p)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 self.pg1.get_capture(1)
2423 users = self.vapi.nat44_user_dump()
2425 if user.ip_address == self.pg0.remote_ip4n:
2426 self.assertEqual(user.nsessions,
2427 nat44_config.max_translations_per_user - 1)
2428 self.assertEqual(user.nstaticsessions, 1)
2430 def test_interface_addr(self):
2431 """ Acquire NAT44 addresses from interface """
2432 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2434 # no address in NAT pool
2435 adresses = self.vapi.nat44_address_dump()
2436 self.assertEqual(0, len(adresses))
2438 # configure interface address and check NAT address pool
2439 self.pg7.config_ip4()
2440 adresses = self.vapi.nat44_address_dump()
2441 self.assertEqual(1, len(adresses))
2442 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2444 # remove interface address and check NAT address pool
2445 self.pg7.unconfig_ip4()
2446 adresses = self.vapi.nat44_address_dump()
2447 self.assertEqual(0, len(adresses))
2449 def test_interface_addr_static_mapping(self):
2450 """ Static mapping with addresses from interface """
2453 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2454 self.nat44_add_static_mapping(
2456 external_sw_if_index=self.pg7.sw_if_index,
2459 # static mappings with external interface
2460 static_mappings = self.vapi.nat44_static_mapping_dump()
2461 self.assertEqual(1, len(static_mappings))
2462 self.assertEqual(self.pg7.sw_if_index,
2463 static_mappings[0].external_sw_if_index)
2464 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2466 # configure interface address and check static mappings
2467 self.pg7.config_ip4()
2468 static_mappings = self.vapi.nat44_static_mapping_dump()
2469 self.assertEqual(2, len(static_mappings))
2471 for sm in static_mappings:
2472 if sm.external_sw_if_index == 0xFFFFFFFF:
2473 self.assertEqual(sm.external_ip_address[0:4],
2474 self.pg7.local_ip4n)
2475 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2477 self.assertTrue(resolved)
2479 # remove interface address and check static mappings
2480 self.pg7.unconfig_ip4()
2481 static_mappings = self.vapi.nat44_static_mapping_dump()
2482 self.assertEqual(1, len(static_mappings))
2483 self.assertEqual(self.pg7.sw_if_index,
2484 static_mappings[0].external_sw_if_index)
2485 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2487 # configure interface address again and check static mappings
2488 self.pg7.config_ip4()
2489 static_mappings = self.vapi.nat44_static_mapping_dump()
2490 self.assertEqual(2, len(static_mappings))
2492 for sm in static_mappings:
2493 if sm.external_sw_if_index == 0xFFFFFFFF:
2494 self.assertEqual(sm.external_ip_address[0:4],
2495 self.pg7.local_ip4n)
2496 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2498 self.assertTrue(resolved)
2500 # remove static mapping
2501 self.nat44_add_static_mapping(
2503 external_sw_if_index=self.pg7.sw_if_index,
2506 static_mappings = self.vapi.nat44_static_mapping_dump()
2507 self.assertEqual(0, len(static_mappings))
2509 def test_interface_addr_identity_nat(self):
2510 """ Identity NAT with addresses from interface """
2513 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2514 self.vapi.nat44_add_del_identity_mapping(
2515 sw_if_index=self.pg7.sw_if_index,
2517 protocol=IP_PROTOS.tcp,
2520 # identity mappings with external interface
2521 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2522 self.assertEqual(1, len(identity_mappings))
2523 self.assertEqual(self.pg7.sw_if_index,
2524 identity_mappings[0].sw_if_index)
2526 # configure interface address and check identity mappings
2527 self.pg7.config_ip4()
2528 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2530 self.assertEqual(2, len(identity_mappings))
2531 for sm in identity_mappings:
2532 if sm.sw_if_index == 0xFFFFFFFF:
2533 self.assertEqual(identity_mappings[0].ip_address,
2534 self.pg7.local_ip4n)
2535 self.assertEqual(port, identity_mappings[0].port)
2536 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2538 self.assertTrue(resolved)
2540 # remove interface address and check identity mappings
2541 self.pg7.unconfig_ip4()
2542 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2543 self.assertEqual(1, len(identity_mappings))
2544 self.assertEqual(self.pg7.sw_if_index,
2545 identity_mappings[0].sw_if_index)
2547 def test_ipfix_nat44_sess(self):
2548 """ IPFIX logging NAT44 session created/delted """
2549 self.ipfix_domain_id = 10
2550 self.ipfix_src_port = 20202
2551 colector_port = 30303
2552 bind_layers(UDP, IPFIX, dport=30303)
2553 self.nat44_add_address(self.nat_addr)
2554 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2555 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2557 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2558 src_address=self.pg3.local_ip4n,
2560 template_interval=10,
2561 collector_port=colector_port)
2562 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2563 src_port=self.ipfix_src_port)
2565 pkts = self.create_stream_in(self.pg0, self.pg1)
2566 self.pg0.add_stream(pkts)
2567 self.pg_enable_capture(self.pg_interfaces)
2569 capture = self.pg1.get_capture(len(pkts))
2570 self.verify_capture_out(capture)
2571 self.nat44_add_address(self.nat_addr, is_add=0)
2572 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2573 capture = self.pg3.get_capture(9)
2574 ipfix = IPFIXDecoder()
2575 # first load template
2577 self.assertTrue(p.haslayer(IPFIX))
2578 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2579 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2580 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2581 self.assertEqual(p[UDP].dport, colector_port)
2582 self.assertEqual(p[IPFIX].observationDomainID,
2583 self.ipfix_domain_id)
2584 if p.haslayer(Template):
2585 ipfix.add_template(p.getlayer(Template))
2586 # verify events in data set
2588 if p.haslayer(Data):
2589 data = ipfix.decode_data_set(p.getlayer(Set))
2590 self.verify_ipfix_nat44_ses(data)
2592 def test_ipfix_addr_exhausted(self):
2593 """ IPFIX logging NAT addresses exhausted """
2594 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2595 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2597 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2598 src_address=self.pg3.local_ip4n,
2600 template_interval=10)
2601 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2602 src_port=self.ipfix_src_port)
2604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2605 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2607 self.pg0.add_stream(p)
2608 self.pg_enable_capture(self.pg_interfaces)
2610 self.pg1.assert_nothing_captured()
2612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2613 capture = self.pg3.get_capture(9)
2614 ipfix = IPFIXDecoder()
2615 # first load template
2617 self.assertTrue(p.haslayer(IPFIX))
2618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2621 self.assertEqual(p[UDP].dport, 4739)
2622 self.assertEqual(p[IPFIX].observationDomainID,
2623 self.ipfix_domain_id)
2624 if p.haslayer(Template):
2625 ipfix.add_template(p.getlayer(Template))
2626 # verify events in data set
2628 if p.haslayer(Data):
2629 data = ipfix.decode_data_set(p.getlayer(Set))
2630 self.verify_ipfix_addr_exhausted(data)
2632 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2633 def test_ipfix_max_sessions(self):
2634 """ IPFIX logging maximum session entries exceeded """
2635 self.nat44_add_address(self.nat_addr)
2636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2640 nat44_config = self.vapi.nat_show_config()
2641 max_sessions = 10 * nat44_config.translation_buckets
2644 for i in range(0, max_sessions):
2645 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2646 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2647 IP(src=src, dst=self.pg1.remote_ip4) /
2650 self.pg0.add_stream(pkts)
2651 self.pg_enable_capture(self.pg_interfaces)
2654 self.pg1.get_capture(max_sessions)
2655 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2656 src_address=self.pg3.local_ip4n,
2658 template_interval=10)
2659 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2660 src_port=self.ipfix_src_port)
2662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2663 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2665 self.pg0.add_stream(p)
2666 self.pg_enable_capture(self.pg_interfaces)
2668 self.pg1.assert_nothing_captured()
2670 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2671 capture = self.pg3.get_capture(9)
2672 ipfix = IPFIXDecoder()
2673 # first load template
2675 self.assertTrue(p.haslayer(IPFIX))
2676 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2677 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2678 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2679 self.assertEqual(p[UDP].dport, 4739)
2680 self.assertEqual(p[IPFIX].observationDomainID,
2681 self.ipfix_domain_id)
2682 if p.haslayer(Template):
2683 ipfix.add_template(p.getlayer(Template))
2684 # verify events in data set
2686 if p.haslayer(Data):
2687 data = ipfix.decode_data_set(p.getlayer(Set))
2688 self.verify_ipfix_max_sessions(data, max_sessions)
2690 def test_pool_addr_fib(self):
2691 """ NAT44 add pool addresses to FIB """
2692 static_addr = '10.0.0.10'
2693 self.nat44_add_address(self.nat_addr)
2694 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2695 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2697 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2700 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2701 ARP(op=ARP.who_has, pdst=self.nat_addr,
2702 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2703 self.pg1.add_stream(p)
2704 self.pg_enable_capture(self.pg_interfaces)
2706 capture = self.pg1.get_capture(1)
2707 self.assertTrue(capture[0].haslayer(ARP))
2708 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2711 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2712 ARP(op=ARP.who_has, pdst=static_addr,
2713 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2714 self.pg1.add_stream(p)
2715 self.pg_enable_capture(self.pg_interfaces)
2717 capture = self.pg1.get_capture(1)
2718 self.assertTrue(capture[0].haslayer(ARP))
2719 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2721 # send ARP to non-NAT44 interface
2722 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2723 ARP(op=ARP.who_has, pdst=self.nat_addr,
2724 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2725 self.pg2.add_stream(p)
2726 self.pg_enable_capture(self.pg_interfaces)
2728 self.pg1.assert_nothing_captured()
2730 # remove addresses and verify
2731 self.nat44_add_address(self.nat_addr, is_add=0)
2732 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2735 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2736 ARP(op=ARP.who_has, pdst=self.nat_addr,
2737 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2738 self.pg1.add_stream(p)
2739 self.pg_enable_capture(self.pg_interfaces)
2741 self.pg1.assert_nothing_captured()
2743 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2744 ARP(op=ARP.who_has, pdst=static_addr,
2745 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2746 self.pg1.add_stream(p)
2747 self.pg_enable_capture(self.pg_interfaces)
2749 self.pg1.assert_nothing_captured()
2751 def test_vrf_mode(self):
2752 """ NAT44 tenant VRF aware address pool mode """
2756 nat_ip1 = "10.0.0.10"
2757 nat_ip2 = "10.0.0.11"
2759 self.pg0.unconfig_ip4()
2760 self.pg1.unconfig_ip4()
2761 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2762 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2763 self.pg0.set_table_ip4(vrf_id1)
2764 self.pg1.set_table_ip4(vrf_id2)
2765 self.pg0.config_ip4()
2766 self.pg1.config_ip4()
2767 self.pg0.resolve_arp()
2768 self.pg1.resolve_arp()
2770 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2771 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2772 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2773 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2774 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2779 pkts = self.create_stream_in(self.pg0, self.pg2)
2780 self.pg0.add_stream(pkts)
2781 self.pg_enable_capture(self.pg_interfaces)
2783 capture = self.pg2.get_capture(len(pkts))
2784 self.verify_capture_out(capture, nat_ip1)
2787 pkts = self.create_stream_in(self.pg1, self.pg2)
2788 self.pg1.add_stream(pkts)
2789 self.pg_enable_capture(self.pg_interfaces)
2791 capture = self.pg2.get_capture(len(pkts))
2792 self.verify_capture_out(capture, nat_ip2)
2795 self.pg0.unconfig_ip4()
2796 self.pg1.unconfig_ip4()
2797 self.pg0.set_table_ip4(0)
2798 self.pg1.set_table_ip4(0)
2799 self.pg0.config_ip4()
2800 self.pg1.config_ip4()
2801 self.pg0.resolve_arp()
2802 self.pg1.resolve_arp()
2803 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2804 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2806 def test_vrf_feature_independent(self):
2807 """ NAT44 tenant VRF independent address pool mode """
2809 nat_ip1 = "10.0.0.10"
2810 nat_ip2 = "10.0.0.11"
2812 self.nat44_add_address(nat_ip1)
2813 self.nat44_add_address(nat_ip2, vrf_id=99)
2814 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2815 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2816 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2820 pkts = self.create_stream_in(self.pg0, self.pg2)
2821 self.pg0.add_stream(pkts)
2822 self.pg_enable_capture(self.pg_interfaces)
2824 capture = self.pg2.get_capture(len(pkts))
2825 self.verify_capture_out(capture, nat_ip1)
2828 pkts = self.create_stream_in(self.pg1, self.pg2)
2829 self.pg1.add_stream(pkts)
2830 self.pg_enable_capture(self.pg_interfaces)
2832 capture = self.pg2.get_capture(len(pkts))
2833 self.verify_capture_out(capture, nat_ip1)
2835 def test_dynamic_ipless_interfaces(self):
2836 """ NAT44 interfaces without configured IP address """
2838 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2839 mactobinary(self.pg7.remote_mac),
2840 self.pg7.remote_ip4n,
2842 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2843 mactobinary(self.pg8.remote_mac),
2844 self.pg8.remote_ip4n,
2847 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2848 dst_address_length=32,
2849 next_hop_address=self.pg7.remote_ip4n,
2850 next_hop_sw_if_index=self.pg7.sw_if_index)
2851 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2852 dst_address_length=32,
2853 next_hop_address=self.pg8.remote_ip4n,
2854 next_hop_sw_if_index=self.pg8.sw_if_index)
2856 self.nat44_add_address(self.nat_addr)
2857 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2858 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2862 pkts = self.create_stream_in(self.pg7, self.pg8)
2863 self.pg7.add_stream(pkts)
2864 self.pg_enable_capture(self.pg_interfaces)
2866 capture = self.pg8.get_capture(len(pkts))
2867 self.verify_capture_out(capture)
2870 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2871 self.pg8.add_stream(pkts)
2872 self.pg_enable_capture(self.pg_interfaces)
2874 capture = self.pg7.get_capture(len(pkts))
2875 self.verify_capture_in(capture, self.pg7)
2877 def test_static_ipless_interfaces(self):
2878 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2880 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2881 mactobinary(self.pg7.remote_mac),
2882 self.pg7.remote_ip4n,
2884 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2885 mactobinary(self.pg8.remote_mac),
2886 self.pg8.remote_ip4n,
2889 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2890 dst_address_length=32,
2891 next_hop_address=self.pg7.remote_ip4n,
2892 next_hop_sw_if_index=self.pg7.sw_if_index)
2893 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2894 dst_address_length=32,
2895 next_hop_address=self.pg8.remote_ip4n,
2896 next_hop_sw_if_index=self.pg8.sw_if_index)
2898 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2899 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2900 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2904 pkts = self.create_stream_out(self.pg8)
2905 self.pg8.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2908 capture = self.pg7.get_capture(len(pkts))
2909 self.verify_capture_in(capture, self.pg7)
2912 pkts = self.create_stream_in(self.pg7, self.pg8)
2913 self.pg7.add_stream(pkts)
2914 self.pg_enable_capture(self.pg_interfaces)
2916 capture = self.pg8.get_capture(len(pkts))
2917 self.verify_capture_out(capture, self.nat_addr, True)
2919 def test_static_with_port_ipless_interfaces(self):
2920 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
2922 self.tcp_port_out = 30606
2923 self.udp_port_out = 30607
2924 self.icmp_id_out = 30608
2926 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2927 mactobinary(self.pg7.remote_mac),
2928 self.pg7.remote_ip4n,
2930 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2931 mactobinary(self.pg8.remote_mac),
2932 self.pg8.remote_ip4n,
2935 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2936 dst_address_length=32,
2937 next_hop_address=self.pg7.remote_ip4n,
2938 next_hop_sw_if_index=self.pg7.sw_if_index)
2939 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2940 dst_address_length=32,
2941 next_hop_address=self.pg8.remote_ip4n,
2942 next_hop_sw_if_index=self.pg8.sw_if_index)
2944 self.nat44_add_address(self.nat_addr)
2945 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2946 self.tcp_port_in, self.tcp_port_out,
2947 proto=IP_PROTOS.tcp)
2948 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2949 self.udp_port_in, self.udp_port_out,
2950 proto=IP_PROTOS.udp)
2951 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2952 self.icmp_id_in, self.icmp_id_out,
2953 proto=IP_PROTOS.icmp)
2954 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2955 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2959 pkts = self.create_stream_out(self.pg8)
2960 self.pg8.add_stream(pkts)
2961 self.pg_enable_capture(self.pg_interfaces)
2963 capture = self.pg7.get_capture(len(pkts))
2964 self.verify_capture_in(capture, self.pg7)
2967 pkts = self.create_stream_in(self.pg7, self.pg8)
2968 self.pg7.add_stream(pkts)
2969 self.pg_enable_capture(self.pg_interfaces)
2971 capture = self.pg8.get_capture(len(pkts))
2972 self.verify_capture_out(capture)
2974 def test_static_unknown_proto(self):
2975 """ 1:1 NAT translate packet with unknown protocol """
2976 nat_ip = "10.0.0.10"
2977 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2979 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2983 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2984 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2986 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2987 TCP(sport=1234, dport=1234))
2988 self.pg0.add_stream(p)
2989 self.pg_enable_capture(self.pg_interfaces)
2991 p = self.pg1.get_capture(1)
2994 self.assertEqual(packet[IP].src, nat_ip)
2995 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2996 self.assertTrue(packet.haslayer(GRE))
2997 self.assert_packet_checksums_valid(packet)
2999 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3003 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3004 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3006 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3007 TCP(sport=1234, dport=1234))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 p = self.pg0.get_capture(1)
3014 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3015 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3016 self.assertTrue(packet.haslayer(GRE))
3017 self.assert_packet_checksums_valid(packet)
3019 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3022 def test_hairpinning_static_unknown_proto(self):
3023 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3025 host = self.pg0.remote_hosts[0]
3026 server = self.pg0.remote_hosts[1]
3028 host_nat_ip = "10.0.0.10"
3029 server_nat_ip = "10.0.0.11"
3031 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3032 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3033 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3034 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3038 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3039 IP(src=host.ip4, dst=server_nat_ip) /
3041 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3042 TCP(sport=1234, dport=1234))
3043 self.pg0.add_stream(p)
3044 self.pg_enable_capture(self.pg_interfaces)
3046 p = self.pg0.get_capture(1)
3049 self.assertEqual(packet[IP].src, host_nat_ip)
3050 self.assertEqual(packet[IP].dst, server.ip4)
3051 self.assertTrue(packet.haslayer(GRE))
3052 self.assert_packet_checksums_valid(packet)
3054 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3058 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3059 IP(src=server.ip4, dst=host_nat_ip) /
3061 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3062 TCP(sport=1234, dport=1234))
3063 self.pg0.add_stream(p)
3064 self.pg_enable_capture(self.pg_interfaces)
3066 p = self.pg0.get_capture(1)
3069 self.assertEqual(packet[IP].src, server_nat_ip)
3070 self.assertEqual(packet[IP].dst, host.ip4)
3071 self.assertTrue(packet.haslayer(GRE))
3072 self.assert_packet_checksums_valid(packet)
3074 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3077 def test_output_feature(self):
3078 """ NAT44 interface output feature (in2out postrouting) """
3079 self.nat44_add_address(self.nat_addr)
3080 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3081 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3082 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3086 pkts = self.create_stream_in(self.pg0, self.pg3)
3087 self.pg0.add_stream(pkts)
3088 self.pg_enable_capture(self.pg_interfaces)
3090 capture = self.pg3.get_capture(len(pkts))
3091 self.verify_capture_out(capture)
3094 pkts = self.create_stream_out(self.pg3)
3095 self.pg3.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg0.get_capture(len(pkts))
3099 self.verify_capture_in(capture, self.pg0)
3101 # from non-NAT interface to NAT inside interface
3102 pkts = self.create_stream_in(self.pg2, self.pg0)
3103 self.pg2.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg0.get_capture(len(pkts))
3107 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3109 def test_output_feature_vrf_aware(self):
3110 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3111 nat_ip_vrf10 = "10.0.0.10"
3112 nat_ip_vrf20 = "10.0.0.20"
3114 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3115 dst_address_length=32,
3116 next_hop_address=self.pg3.remote_ip4n,
3117 next_hop_sw_if_index=self.pg3.sw_if_index,
3119 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3120 dst_address_length=32,
3121 next_hop_address=self.pg3.remote_ip4n,
3122 next_hop_sw_if_index=self.pg3.sw_if_index,
3125 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3126 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3127 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3128 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3129 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3133 pkts = self.create_stream_in(self.pg4, self.pg3)
3134 self.pg4.add_stream(pkts)
3135 self.pg_enable_capture(self.pg_interfaces)
3137 capture = self.pg3.get_capture(len(pkts))
3138 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3141 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3142 self.pg3.add_stream(pkts)
3143 self.pg_enable_capture(self.pg_interfaces)
3145 capture = self.pg4.get_capture(len(pkts))
3146 self.verify_capture_in(capture, self.pg4)
3149 pkts = self.create_stream_in(self.pg6, self.pg3)
3150 self.pg6.add_stream(pkts)
3151 self.pg_enable_capture(self.pg_interfaces)
3153 capture = self.pg3.get_capture(len(pkts))
3154 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3157 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3158 self.pg3.add_stream(pkts)
3159 self.pg_enable_capture(self.pg_interfaces)
3161 capture = self.pg6.get_capture(len(pkts))
3162 self.verify_capture_in(capture, self.pg6)
3164 def test_output_feature_hairpinning(self):
3165 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3166 host = self.pg0.remote_hosts[0]
3167 server = self.pg0.remote_hosts[1]
3170 server_in_port = 5678
3171 server_out_port = 8765
3173 self.nat44_add_address(self.nat_addr)
3174 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3175 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3178 # add static mapping for server
3179 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3180 server_in_port, server_out_port,
3181 proto=IP_PROTOS.tcp)
3183 # send packet from host to server
3184 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3185 IP(src=host.ip4, dst=self.nat_addr) /
3186 TCP(sport=host_in_port, dport=server_out_port))
3187 self.pg0.add_stream(p)
3188 self.pg_enable_capture(self.pg_interfaces)
3190 capture = self.pg0.get_capture(1)
3195 self.assertEqual(ip.src, self.nat_addr)
3196 self.assertEqual(ip.dst, server.ip4)
3197 self.assertNotEqual(tcp.sport, host_in_port)
3198 self.assertEqual(tcp.dport, server_in_port)
3199 self.assert_packet_checksums_valid(p)
3200 host_out_port = tcp.sport
3202 self.logger.error(ppp("Unexpected or invalid packet:", p))
3205 # send reply from server to host
3206 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3207 IP(src=server.ip4, dst=self.nat_addr) /
3208 TCP(sport=server_in_port, dport=host_out_port))
3209 self.pg0.add_stream(p)
3210 self.pg_enable_capture(self.pg_interfaces)
3212 capture = self.pg0.get_capture(1)
3217 self.assertEqual(ip.src, self.nat_addr)
3218 self.assertEqual(ip.dst, host.ip4)
3219 self.assertEqual(tcp.sport, server_out_port)
3220 self.assertEqual(tcp.dport, host_in_port)
3221 self.assert_packet_checksums_valid(p)
3223 self.logger.error(ppp("Unexpected or invalid packet:", p))
3226 def test_one_armed_nat44(self):
3227 """ One armed NAT44 """
3228 remote_host = self.pg9.remote_hosts[0]
3229 local_host = self.pg9.remote_hosts[1]
3232 self.nat44_add_address(self.nat_addr)
3233 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3234 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3238 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3239 IP(src=local_host.ip4, dst=remote_host.ip4) /
3240 TCP(sport=12345, dport=80))
3241 self.pg9.add_stream(p)
3242 self.pg_enable_capture(self.pg_interfaces)
3244 capture = self.pg9.get_capture(1)
3249 self.assertEqual(ip.src, self.nat_addr)
3250 self.assertEqual(ip.dst, remote_host.ip4)
3251 self.assertNotEqual(tcp.sport, 12345)
3252 external_port = tcp.sport
3253 self.assertEqual(tcp.dport, 80)
3254 self.assert_packet_checksums_valid(p)
3256 self.logger.error(ppp("Unexpected or invalid packet:", p))
3260 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3261 IP(src=remote_host.ip4, dst=self.nat_addr) /
3262 TCP(sport=80, dport=external_port))
3263 self.pg9.add_stream(p)
3264 self.pg_enable_capture(self.pg_interfaces)
3266 capture = self.pg9.get_capture(1)
3271 self.assertEqual(ip.src, remote_host.ip4)
3272 self.assertEqual(ip.dst, local_host.ip4)
3273 self.assertEqual(tcp.sport, 80)
3274 self.assertEqual(tcp.dport, 12345)
3275 self.assert_packet_checksums_valid(p)
3277 self.logger.error(ppp("Unexpected or invalid packet:", p))
3280 def test_del_session(self):
3281 """ Delete NAT44 session """
3282 self.nat44_add_address(self.nat_addr)
3283 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3284 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3287 pkts = self.create_stream_in(self.pg0, self.pg1)
3288 self.pg0.add_stream(pkts)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 self.pg1.get_capture(len(pkts))
3293 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3294 nsessions = len(sessions)
3296 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3297 sessions[0].inside_port,
3298 sessions[0].protocol)
3299 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3300 sessions[1].outside_port,
3301 sessions[1].protocol,
3304 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3305 self.assertEqual(nsessions - len(sessions), 2)
3307 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3308 sessions[0].inside_port,
3309 sessions[0].protocol)
3311 self.verify_no_nat44_user()
3313 def test_set_get_reass(self):
3314 """ NAT44 set/get virtual fragmentation reassembly """
3315 reas_cfg1 = self.vapi.nat_get_reass()
3317 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3318 max_reass=reas_cfg1.ip4_max_reass * 2,
3319 max_frag=reas_cfg1.ip4_max_frag * 2)
3321 reas_cfg2 = self.vapi.nat_get_reass()
3323 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3324 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3325 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3327 self.vapi.nat_set_reass(drop_frag=1)
3328 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3330 def test_frag_in_order(self):
3331 """ NAT44 translate fragments arriving in order """
3333 self.nat44_add_address(self.nat_addr)
3334 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3335 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3338 self.frag_in_order(proto=IP_PROTOS.tcp)
3339 self.frag_in_order(proto=IP_PROTOS.udp)
3340 self.frag_in_order(proto=IP_PROTOS.icmp)
3342 def test_frag_forwarding(self):
3343 """ NAT44 forwarding fragment test """
3344 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3345 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3346 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3348 self.vapi.nat44_forwarding_enable_disable(1)
3350 data = "A" * 16 + "B" * 16 + "C" * 3
3351 pkts = self.create_stream_frag(self.pg1,
3352 self.pg0.remote_ip4,
3356 proto=IP_PROTOS.udp)
3357 self.pg1.add_stream(pkts)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 frags = self.pg0.get_capture(len(pkts))
3361 p = self.reass_frags_and_verify(frags,
3362 self.pg1.remote_ip4,
3363 self.pg0.remote_ip4)
3364 self.assertEqual(p[UDP].sport, 4789)
3365 self.assertEqual(p[UDP].dport, 4789)
3366 self.assertEqual(data, p[Raw].load)
3368 def test_reass_hairpinning(self):
3369 """ NAT44 fragments hairpinning """
3371 self.server = self.pg0.remote_hosts[1]
3372 self.host_in_port = random.randint(1025, 65535)
3373 self.server_in_port = random.randint(1025, 65535)
3374 self.server_out_port = random.randint(1025, 65535)
3376 self.nat44_add_address(self.nat_addr)
3377 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3378 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3380 # add static mapping for server
3381 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3382 self.server_in_port,
3383 self.server_out_port,
3384 proto=IP_PROTOS.tcp)
3385 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3386 self.server_in_port,
3387 self.server_out_port,
3388 proto=IP_PROTOS.udp)
3389 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3391 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3392 self.reass_hairpinning(proto=IP_PROTOS.udp)
3393 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3395 def test_frag_out_of_order(self):
3396 """ NAT44 translate fragments arriving out of order """
3398 self.nat44_add_address(self.nat_addr)
3399 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3400 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3403 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3404 self.frag_out_of_order(proto=IP_PROTOS.udp)
3405 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3407 def test_port_restricted(self):
3408 """ Port restricted NAT44 (MAP-E CE) """
3409 self.nat44_add_address(self.nat_addr)
3410 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3411 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3413 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3418 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3419 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3420 TCP(sport=4567, dport=22))
3421 self.pg0.add_stream(p)
3422 self.pg_enable_capture(self.pg_interfaces)
3424 capture = self.pg1.get_capture(1)
3429 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3430 self.assertEqual(ip.src, self.nat_addr)
3431 self.assertEqual(tcp.dport, 22)
3432 self.assertNotEqual(tcp.sport, 4567)
3433 self.assertEqual((tcp.sport >> 6) & 63, 10)
3434 self.assert_packet_checksums_valid(p)
3436 self.logger.error(ppp("Unexpected or invalid packet:", p))
3439 def test_port_range(self):
3440 """ External address port range """
3441 self.nat44_add_address(self.nat_addr)
3442 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3443 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3445 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3450 for port in range(0, 5):
3451 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3452 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3453 TCP(sport=1125 + port))
3455 self.pg0.add_stream(pkts)
3456 self.pg_enable_capture(self.pg_interfaces)
3458 capture = self.pg1.get_capture(3)
3461 self.assertGreaterEqual(tcp.sport, 1025)
3462 self.assertLessEqual(tcp.sport, 1027)
3464 def test_ipfix_max_frags(self):
3465 """ IPFIX logging maximum fragments pending reassembly exceeded """
3466 self.nat44_add_address(self.nat_addr)
3467 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3468 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3470 self.vapi.nat_set_reass(max_frag=1)
3471 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3472 src_address=self.pg3.local_ip4n,
3474 template_interval=10)
3475 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3476 src_port=self.ipfix_src_port)
3478 data = "A" * 4 + "B" * 16 + "C" * 3
3479 self.tcp_port_in = random.randint(1025, 65535)
3480 pkts = self.create_stream_frag(self.pg0,
3481 self.pg1.remote_ip4,
3486 self.pg0.add_stream(pkts)
3487 self.pg_enable_capture(self.pg_interfaces)
3489 self.pg1.assert_nothing_captured()
3491 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3492 capture = self.pg3.get_capture(9)
3493 ipfix = IPFIXDecoder()
3494 # first load template
3496 self.assertTrue(p.haslayer(IPFIX))
3497 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3498 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3499 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3500 self.assertEqual(p[UDP].dport, 4739)
3501 self.assertEqual(p[IPFIX].observationDomainID,
3502 self.ipfix_domain_id)
3503 if p.haslayer(Template):
3504 ipfix.add_template(p.getlayer(Template))
3505 # verify events in data set
3507 if p.haslayer(Data):
3508 data = ipfix.decode_data_set(p.getlayer(Set))
3509 self.verify_ipfix_max_fragments_ip4(data, 1,
3510 self.pg0.remote_ip4n)
3512 def test_multiple_outside_vrf(self):
3513 """ Multiple outside VRF """
3517 self.pg1.unconfig_ip4()
3518 self.pg2.unconfig_ip4()
3519 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3520 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3521 self.pg1.set_table_ip4(vrf_id1)
3522 self.pg2.set_table_ip4(vrf_id2)
3523 self.pg1.config_ip4()
3524 self.pg2.config_ip4()
3525 self.pg1.resolve_arp()
3526 self.pg2.resolve_arp()
3528 self.nat44_add_address(self.nat_addr)
3529 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3530 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3532 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3537 pkts = self.create_stream_in(self.pg0, self.pg1)
3538 self.pg0.add_stream(pkts)
3539 self.pg_enable_capture(self.pg_interfaces)
3541 capture = self.pg1.get_capture(len(pkts))
3542 self.verify_capture_out(capture, self.nat_addr)
3544 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3545 self.pg1.add_stream(pkts)
3546 self.pg_enable_capture(self.pg_interfaces)
3548 capture = self.pg0.get_capture(len(pkts))
3549 self.verify_capture_in(capture, self.pg0)
3551 self.tcp_port_in = 60303
3552 self.udp_port_in = 60304
3553 self.icmp_id_in = 60305
3556 pkts = self.create_stream_in(self.pg0, self.pg2)
3557 self.pg0.add_stream(pkts)
3558 self.pg_enable_capture(self.pg_interfaces)
3560 capture = self.pg2.get_capture(len(pkts))
3561 self.verify_capture_out(capture, self.nat_addr)
3563 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3564 self.pg2.add_stream(pkts)
3565 self.pg_enable_capture(self.pg_interfaces)
3567 capture = self.pg0.get_capture(len(pkts))
3568 self.verify_capture_in(capture, self.pg0)
3571 self.pg1.unconfig_ip4()
3572 self.pg2.unconfig_ip4()
3573 self.pg1.set_table_ip4(0)
3574 self.pg2.set_table_ip4(0)
3575 self.pg1.config_ip4()
3576 self.pg2.config_ip4()
3577 self.pg1.resolve_arp()
3578 self.pg2.resolve_arp()
3580 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3581 def test_session_timeout(self):
3582 """ NAT44 session timeouts """
3583 self.nat44_add_address(self.nat_addr)
3584 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3585 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3587 self.vapi.nat_set_timeouts(udp=5)
3591 for i in range(0, max_sessions):
3592 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3593 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3594 IP(src=src, dst=self.pg1.remote_ip4) /
3595 UDP(sport=1025, dport=53))
3597 self.pg0.add_stream(pkts)
3598 self.pg_enable_capture(self.pg_interfaces)
3600 self.pg1.get_capture(max_sessions)
3605 for i in range(0, max_sessions):
3606 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3607 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3608 IP(src=src, dst=self.pg1.remote_ip4) /
3609 UDP(sport=1026, dport=53))
3611 self.pg0.add_stream(pkts)
3612 self.pg_enable_capture(self.pg_interfaces)
3614 self.pg1.get_capture(max_sessions)
3617 users = self.vapi.nat44_user_dump()
3619 nsessions = nsessions + user.nsessions
3620 self.assertLess(nsessions, 2 * max_sessions)
3622 def test_mss_clamping(self):
3623 """ TCP MSS clamping """
3624 self.nat44_add_address(self.nat_addr)
3625 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3626 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3629 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3630 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3631 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3632 flags="S", options=[('MSS', 1400)]))
3634 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3635 self.pg0.add_stream(p)
3636 self.pg_enable_capture(self.pg_interfaces)
3638 capture = self.pg1.get_capture(1)
3639 # Negotiated MSS value greater than configured - changed
3640 self.verify_mss_value(capture[0], 1000)
3642 self.vapi.nat_set_mss_clamping(enable=0)
3643 self.pg0.add_stream(p)
3644 self.pg_enable_capture(self.pg_interfaces)
3646 capture = self.pg1.get_capture(1)
3647 # MSS clamping disabled - negotiated MSS unchanged
3648 self.verify_mss_value(capture[0], 1400)
3650 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3651 self.pg0.add_stream(p)
3652 self.pg_enable_capture(self.pg_interfaces)
3654 capture = self.pg1.get_capture(1)
3655 # Negotiated MSS value smaller than configured - unchanged
3656 self.verify_mss_value(capture[0], 1400)
3659 super(TestNAT44, self).tearDown()
3660 if not self.vpp_dead:
3661 self.logger.info(self.vapi.cli("show nat44 addresses"))
3662 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3663 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3664 self.logger.info(self.vapi.cli("show nat44 interface address"))
3665 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3666 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3667 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3668 self.logger.info(self.vapi.cli("show nat timeouts"))
3670 self.vapi.cli("show nat addr-port-assignment-alg"))
3672 self.vapi.cli("clear logging")
3675 class TestNAT44EndpointDependent(MethodHolder):
3676 """ Endpoint-Dependent mapping and filtering test cases """
3679 def setUpConstants(cls):
3680 super(TestNAT44EndpointDependent, cls).setUpConstants()
3681 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3684 def setUpClass(cls):
3685 super(TestNAT44EndpointDependent, cls).setUpClass()
3686 cls.vapi.cli("set log class nat level debug")
3688 cls.tcp_port_in = 6303
3689 cls.tcp_port_out = 6303
3690 cls.udp_port_in = 6304
3691 cls.udp_port_out = 6304
3692 cls.icmp_id_in = 6305
3693 cls.icmp_id_out = 6305
3694 cls.nat_addr = '10.0.0.3'
3695 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3696 cls.ipfix_src_port = 4739
3697 cls.ipfix_domain_id = 1
3698 cls.tcp_external_port = 80
3700 cls.create_pg_interfaces(range(7))
3701 cls.interfaces = list(cls.pg_interfaces[0:3])
3703 for i in cls.interfaces:
3708 cls.pg0.generate_remote_hosts(3)
3709 cls.pg0.configure_ipv4_neighbors()
3713 cls.pg4.generate_remote_hosts(2)
3714 cls.pg4.config_ip4()
3715 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3716 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3720 cls.pg4.resolve_arp()
3721 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3722 cls.pg4.resolve_arp()
3724 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3725 cls.vapi.ip_table_add_del(1, is_add=1)
3727 cls.pg5._local_ip4 = "10.1.1.1"
3728 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3730 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3731 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3732 socket.AF_INET, cls.pg5.remote_ip4)
3733 cls.pg5.set_table_ip4(1)
3734 cls.pg5.config_ip4()
3736 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3737 dst_address_length=32,
3739 next_hop_sw_if_index=cls.pg5.sw_if_index,
3740 next_hop_address=zero_ip4n)
3742 cls.pg6._local_ip4 = "10.1.2.1"
3743 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3745 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3746 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3747 socket.AF_INET, cls.pg6.remote_ip4)
3748 cls.pg6.set_table_ip4(1)
3749 cls.pg6.config_ip4()
3751 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3752 dst_address_length=32,
3754 next_hop_sw_if_index=cls.pg6.sw_if_index,
3755 next_hop_address=zero_ip4n)
3757 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3758 dst_address_length=16,
3759 next_hop_address=zero_ip4n,
3761 next_hop_table_id=1)
3762 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3763 dst_address_length=0,
3764 next_hop_address=zero_ip4n,
3766 next_hop_table_id=0)
3767 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3768 dst_address_length=0,
3770 next_hop_sw_if_index=cls.pg1.sw_if_index,
3771 next_hop_address=cls.pg1.local_ip4n)
3773 cls.pg5.resolve_arp()
3774 cls.pg6.resolve_arp()
3777 super(TestNAT44EndpointDependent, cls).tearDownClass()
3780 def test_frag_in_order(self):
3781 """ NAT44 translate fragments arriving in order """
3782 self.nat44_add_address(self.nat_addr)
3783 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3784 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3786 self.frag_in_order(proto=IP_PROTOS.tcp)
3787 self.frag_in_order(proto=IP_PROTOS.udp)
3788 self.frag_in_order(proto=IP_PROTOS.icmp)
3790 def test_frag_in_order_dont_translate(self):
3791 """ NAT44 don't translate fragments arriving in order """
3792 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3793 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3795 self.vapi.nat44_forwarding_enable_disable(enable=True)
3796 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3798 def test_frag_out_of_order(self):
3799 """ NAT44 translate fragments arriving out of order """
3800 self.nat44_add_address(self.nat_addr)
3801 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3802 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3804 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3805 self.frag_out_of_order(proto=IP_PROTOS.udp)
3806 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3808 def test_frag_out_of_order_dont_translate(self):
3809 """ NAT44 don't translate fragments arriving out of order """
3810 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3811 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3813 self.vapi.nat44_forwarding_enable_disable(enable=True)
3814 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3816 def test_frag_in_order_in_plus_out(self):
3817 """ in+out interface fragments in order """
3818 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3819 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3821 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3822 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3825 self.server = self.pg1.remote_hosts[0]
3827 self.server_in_addr = self.server.ip4
3828 self.server_out_addr = '11.11.11.11'
3829 self.server_in_port = random.randint(1025, 65535)
3830 self.server_out_port = random.randint(1025, 65535)
3832 self.nat44_add_address(self.server_out_addr)
3834 # add static mappings for server
3835 self.nat44_add_static_mapping(self.server_in_addr,
3836 self.server_out_addr,
3837 self.server_in_port,
3838 self.server_out_port,
3839 proto=IP_PROTOS.tcp)
3840 self.nat44_add_static_mapping(self.server_in_addr,
3841 self.server_out_addr,
3842 self.server_in_port,
3843 self.server_out_port,
3844 proto=IP_PROTOS.udp)
3845 self.nat44_add_static_mapping(self.server_in_addr,
3846 self.server_out_addr,
3847 proto=IP_PROTOS.icmp)
3849 self.vapi.nat_set_reass(timeout=10)
3851 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3852 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3853 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3855 def test_frag_out_of_order_in_plus_out(self):
3856 """ in+out interface fragments out of order """
3857 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3858 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3860 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3861 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3864 self.server = self.pg1.remote_hosts[0]
3866 self.server_in_addr = self.server.ip4
3867 self.server_out_addr = '11.11.11.11'
3868 self.server_in_port = random.randint(1025, 65535)
3869 self.server_out_port = random.randint(1025, 65535)
3871 self.nat44_add_address(self.server_out_addr)
3873 # add static mappings for server
3874 self.nat44_add_static_mapping(self.server_in_addr,
3875 self.server_out_addr,
3876 self.server_in_port,
3877 self.server_out_port,
3878 proto=IP_PROTOS.tcp)
3879 self.nat44_add_static_mapping(self.server_in_addr,
3880 self.server_out_addr,
3881 self.server_in_port,
3882 self.server_out_port,
3883 proto=IP_PROTOS.udp)
3884 self.nat44_add_static_mapping(self.server_in_addr,
3885 self.server_out_addr,
3886 proto=IP_PROTOS.icmp)
3888 self.vapi.nat_set_reass(timeout=10)
3890 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3891 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3892 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3894 def test_reass_hairpinning(self):
3895 """ NAT44 fragments hairpinning """
3896 self.server = self.pg0.remote_hosts[1]
3897 self.host_in_port = random.randint(1025, 65535)
3898 self.server_in_port = random.randint(1025, 65535)
3899 self.server_out_port = random.randint(1025, 65535)
3901 self.nat44_add_address(self.nat_addr)
3902 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3903 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3905 # add static mapping for server
3906 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3907 self.server_in_port,
3908 self.server_out_port,
3909 proto=IP_PROTOS.tcp)
3910 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3911 self.server_in_port,
3912 self.server_out_port,
3913 proto=IP_PROTOS.udp)
3914 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3916 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3917 self.reass_hairpinning(proto=IP_PROTOS.udp)
3918 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3920 def test_dynamic(self):
3921 """ NAT44 dynamic translation test """
3923 self.nat44_add_address(self.nat_addr)
3924 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3925 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3928 nat_config = self.vapi.nat_show_config()
3929 self.assertEqual(1, nat_config.endpoint_dependent)
3932 pkts = self.create_stream_in(self.pg0, self.pg1)
3933 self.pg0.add_stream(pkts)
3934 self.pg_enable_capture(self.pg_interfaces)
3936 capture = self.pg1.get_capture(len(pkts))
3937 self.verify_capture_out(capture)
3940 pkts = self.create_stream_out(self.pg1)
3941 self.pg1.add_stream(pkts)
3942 self.pg_enable_capture(self.pg_interfaces)
3944 capture = self.pg0.get_capture(len(pkts))
3945 self.verify_capture_in(capture, self.pg0)
3947 def test_forwarding(self):
3948 """ NAT44 forwarding test """
3950 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3951 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3953 self.vapi.nat44_forwarding_enable_disable(1)
3955 real_ip = self.pg0.remote_ip4n
3956 alias_ip = self.nat_addr_n
3957 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3958 external_ip=alias_ip)
3961 # in2out - static mapping match
3963 pkts = self.create_stream_out(self.pg1)
3964 self.pg1.add_stream(pkts)
3965 self.pg_enable_capture(self.pg_interfaces)
3967 capture = self.pg0.get_capture(len(pkts))
3968 self.verify_capture_in(capture, self.pg0)
3970 pkts = self.create_stream_in(self.pg0, self.pg1)
3971 self.pg0.add_stream(pkts)
3972 self.pg_enable_capture(self.pg_interfaces)
3974 capture = self.pg1.get_capture(len(pkts))
3975 self.verify_capture_out(capture, same_port=True)
3977 # in2out - no static mapping match
3979 host0 = self.pg0.remote_hosts[0]
3980 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3982 pkts = self.create_stream_out(self.pg1,
3983 dst_ip=self.pg0.remote_ip4,
3984 use_inside_ports=True)
3985 self.pg1.add_stream(pkts)
3986 self.pg_enable_capture(self.pg_interfaces)
3988 capture = self.pg0.get_capture(len(pkts))
3989 self.verify_capture_in(capture, self.pg0)
3991 pkts = self.create_stream_in(self.pg0, self.pg1)
3992 self.pg0.add_stream(pkts)
3993 self.pg_enable_capture(self.pg_interfaces)
3995 capture = self.pg1.get_capture(len(pkts))
3996 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3999 self.pg0.remote_hosts[0] = host0
4001 user = self.pg0.remote_hosts[1]
4002 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4003 self.assertEqual(len(sessions), 3)
4004 self.assertTrue(sessions[0].ext_host_valid)
4005 self.vapi.nat44_del_session(
4006 sessions[0].inside_ip_address,
4007 sessions[0].inside_port,
4008 sessions[0].protocol,
4009 ext_host_address=sessions[0].ext_host_address,
4010 ext_host_port=sessions[0].ext_host_port)
4011 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4012 self.assertEqual(len(sessions), 2)
4015 self.vapi.nat44_forwarding_enable_disable(0)
4016 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4017 external_ip=alias_ip,
4020 def test_static_lb(self):
4021 """ NAT44 local service load balancing """
4022 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4025 server1 = self.pg0.remote_hosts[0]
4026 server2 = self.pg0.remote_hosts[1]
4028 locals = [{'addr': server1.ip4n,
4032 {'addr': server2.ip4n,
4037 self.nat44_add_address(self.nat_addr)
4038 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4041 local_num=len(locals),
4043 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4044 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4047 # from client to service
4048 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4049 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4050 TCP(sport=12345, dport=external_port))
4051 self.pg1.add_stream(p)
4052 self.pg_enable_capture(self.pg_interfaces)
4054 capture = self.pg0.get_capture(1)
4060 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4061 if ip.dst == server1.ip4:
4065 self.assertEqual(tcp.dport, local_port)
4066 self.assert_packet_checksums_valid(p)
4068 self.logger.error(ppp("Unexpected or invalid packet:", p))
4071 # from service back to client
4072 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4073 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4074 TCP(sport=local_port, dport=12345))
4075 self.pg0.add_stream(p)
4076 self.pg_enable_capture(self.pg_interfaces)
4078 capture = self.pg1.get_capture(1)
4083 self.assertEqual(ip.src, self.nat_addr)
4084 self.assertEqual(tcp.sport, external_port)
4085 self.assert_packet_checksums_valid(p)
4087 self.logger.error(ppp("Unexpected or invalid packet:", p))
4090 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4091 self.assertEqual(len(sessions), 1)
4092 self.assertTrue(sessions[0].ext_host_valid)
4093 self.vapi.nat44_del_session(
4094 sessions[0].inside_ip_address,
4095 sessions[0].inside_port,
4096 sessions[0].protocol,
4097 ext_host_address=sessions[0].ext_host_address,
4098 ext_host_port=sessions[0].ext_host_port)
4099 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4100 self.assertEqual(len(sessions), 0)
4102 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4103 def test_static_lb_multi_clients(self):
4104 """ NAT44 local service load balancing - multiple clients"""
4106 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4109 server1 = self.pg0.remote_hosts[0]
4110 server2 = self.pg0.remote_hosts[1]
4112 locals = [{'addr': server1.ip4n,
4116 {'addr': server2.ip4n,
4121 self.nat44_add_address(self.nat_addr)
4122 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4125 local_num=len(locals),
4127 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4128 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4133 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4135 for client in clients:
4136 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4137 IP(src=client, dst=self.nat_addr) /
4138 TCP(sport=12345, dport=external_port))
4140 self.pg1.add_stream(pkts)
4141 self.pg_enable_capture(self.pg_interfaces)
4143 capture = self.pg0.get_capture(len(pkts))
4145 if p[IP].dst == server1.ip4:
4149 self.assertTrue(server1_n > server2_n)
4151 def test_static_lb_2(self):
4152 """ NAT44 local service load balancing (asymmetrical rule) """
4153 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4156 server1 = self.pg0.remote_hosts[0]
4157 server2 = self.pg0.remote_hosts[1]
4159 locals = [{'addr': server1.ip4n,
4163 {'addr': server2.ip4n,
4168 self.vapi.nat44_forwarding_enable_disable(1)
4169 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4173 local_num=len(locals),
4175 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4176 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4179 # from client to service
4180 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4181 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4182 TCP(sport=12345, dport=external_port))
4183 self.pg1.add_stream(p)
4184 self.pg_enable_capture(self.pg_interfaces)
4186 capture = self.pg0.get_capture(1)
4192 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4193 if ip.dst == server1.ip4:
4197 self.assertEqual(tcp.dport, local_port)
4198 self.assert_packet_checksums_valid(p)
4200 self.logger.error(ppp("Unexpected or invalid packet:", p))
4203 # from service back to client
4204 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4205 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4206 TCP(sport=local_port, dport=12345))
4207 self.pg0.add_stream(p)
4208 self.pg_enable_capture(self.pg_interfaces)
4210 capture = self.pg1.get_capture(1)
4215 self.assertEqual(ip.src, self.nat_addr)
4216 self.assertEqual(tcp.sport, external_port)
4217 self.assert_packet_checksums_valid(p)
4219 self.logger.error(ppp("Unexpected or invalid packet:", p))
4222 # from client to server (no translation)
4223 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4224 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4225 TCP(sport=12346, dport=local_port))
4226 self.pg1.add_stream(p)
4227 self.pg_enable_capture(self.pg_interfaces)
4229 capture = self.pg0.get_capture(1)
4235 self.assertEqual(ip.dst, server1.ip4)
4236 self.assertEqual(tcp.dport, local_port)
4237 self.assert_packet_checksums_valid(p)
4239 self.logger.error(ppp("Unexpected or invalid packet:", p))
4242 # from service back to client (no translation)
4243 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4244 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4245 TCP(sport=local_port, dport=12346))
4246 self.pg0.add_stream(p)
4247 self.pg_enable_capture(self.pg_interfaces)
4249 capture = self.pg1.get_capture(1)
4254 self.assertEqual(ip.src, server1.ip4)
4255 self.assertEqual(tcp.sport, local_port)
4256 self.assert_packet_checksums_valid(p)
4258 self.logger.error(ppp("Unexpected or invalid packet:", p))
4261 def test_lb_affinity(self):
4262 """ NAT44 local service load balancing affinity """
4263 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4266 server1 = self.pg0.remote_hosts[0]
4267 server2 = self.pg0.remote_hosts[1]
4269 locals = [{'addr': server1.ip4n,
4273 {'addr': server2.ip4n,
4278 self.nat44_add_address(self.nat_addr)
4279 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4283 local_num=len(locals),
4285 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4286 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4289 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4290 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4291 TCP(sport=1025, dport=external_port))
4292 self.pg1.add_stream(p)
4293 self.pg_enable_capture(self.pg_interfaces)
4295 capture = self.pg0.get_capture(1)
4296 backend = capture[0][IP].dst
4298 sessions = self.vapi.nat44_user_session_dump(
4299 socket.inet_pton(socket.AF_INET, backend), 0)
4300 self.assertEqual(len(sessions), 1)
4301 self.assertTrue(sessions[0].ext_host_valid)
4302 self.vapi.nat44_del_session(
4303 sessions[0].inside_ip_address,
4304 sessions[0].inside_port,
4305 sessions[0].protocol,
4306 ext_host_address=sessions[0].ext_host_address,
4307 ext_host_port=sessions[0].ext_host_port)
4310 for port in range(1030, 1100):
4311 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4312 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4313 TCP(sport=port, dport=external_port))
4315 self.pg1.add_stream(pkts)
4316 self.pg_enable_capture(self.pg_interfaces)
4318 capture = self.pg0.get_capture(len(pkts))
4320 self.assertEqual(p[IP].dst, backend)
4322 def test_unknown_proto(self):
4323 """ NAT44 translate packet with unknown protocol """
4324 self.nat44_add_address(self.nat_addr)
4325 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4326 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4331 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4332 TCP(sport=self.tcp_port_in, dport=20))
4333 self.pg0.add_stream(p)
4334 self.pg_enable_capture(self.pg_interfaces)
4336 p = self.pg1.get_capture(1)
4338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4339 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4341 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4342 TCP(sport=1234, dport=1234))
4343 self.pg0.add_stream(p)
4344 self.pg_enable_capture(self.pg_interfaces)
4346 p = self.pg1.get_capture(1)
4349 self.assertEqual(packet[IP].src, self.nat_addr)
4350 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4351 self.assertTrue(packet.haslayer(GRE))
4352 self.assert_packet_checksums_valid(packet)
4354 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4358 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4359 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4361 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4362 TCP(sport=1234, dport=1234))
4363 self.pg1.add_stream(p)
4364 self.pg_enable_capture(self.pg_interfaces)
4366 p = self.pg0.get_capture(1)
4369 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4370 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4371 self.assertTrue(packet.haslayer(GRE))
4372 self.assert_packet_checksums_valid(packet)
4374 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4377 def test_hairpinning_unknown_proto(self):
4378 """ NAT44 translate packet with unknown protocol - hairpinning """
4379 host = self.pg0.remote_hosts[0]
4380 server = self.pg0.remote_hosts[1]
4382 server_out_port = 8765
4383 server_nat_ip = "10.0.0.11"
4385 self.nat44_add_address(self.nat_addr)
4386 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4387 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4390 # add static mapping for server
4391 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4394 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4395 IP(src=host.ip4, dst=server_nat_ip) /
4396 TCP(sport=host_in_port, dport=server_out_port))
4397 self.pg0.add_stream(p)
4398 self.pg_enable_capture(self.pg_interfaces)
4400 self.pg0.get_capture(1)
4402 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4403 IP(src=host.ip4, dst=server_nat_ip) /
4405 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4406 TCP(sport=1234, dport=1234))
4407 self.pg0.add_stream(p)
4408 self.pg_enable_capture(self.pg_interfaces)
4410 p = self.pg0.get_capture(1)
4413 self.assertEqual(packet[IP].src, self.nat_addr)
4414 self.assertEqual(packet[IP].dst, server.ip4)
4415 self.assertTrue(packet.haslayer(GRE))
4416 self.assert_packet_checksums_valid(packet)
4418 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4422 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4423 IP(src=server.ip4, dst=self.nat_addr) /
4425 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4426 TCP(sport=1234, dport=1234))
4427 self.pg0.add_stream(p)
4428 self.pg_enable_capture(self.pg_interfaces)
4430 p = self.pg0.get_capture(1)
4433 self.assertEqual(packet[IP].src, server_nat_ip)
4434 self.assertEqual(packet[IP].dst, host.ip4)
4435 self.assertTrue(packet.haslayer(GRE))
4436 self.assert_packet_checksums_valid(packet)
4438 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4441 def test_output_feature_and_service(self):
4442 """ NAT44 interface output feature and services """
4443 external_addr = '1.2.3.4'
4447 self.vapi.nat44_forwarding_enable_disable(1)
4448 self.nat44_add_address(self.nat_addr)
4449 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4450 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4451 local_port, external_port,
4452 proto=IP_PROTOS.tcp, out2in_only=1)
4453 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4454 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4456 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4459 # from client to service
4460 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4461 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4462 TCP(sport=12345, dport=external_port))
4463 self.pg1.add_stream(p)
4464 self.pg_enable_capture(self.pg_interfaces)
4466 capture = self.pg0.get_capture(1)
4471 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4472 self.assertEqual(tcp.dport, local_port)
4473 self.assert_packet_checksums_valid(p)
4475 self.logger.error(ppp("Unexpected or invalid packet:", p))
4478 # from service back to client
4479 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4480 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4481 TCP(sport=local_port, dport=12345))
4482 self.pg0.add_stream(p)
4483 self.pg_enable_capture(self.pg_interfaces)
4485 capture = self.pg1.get_capture(1)
4490 self.assertEqual(ip.src, external_addr)
4491 self.assertEqual(tcp.sport, external_port)
4492 self.assert_packet_checksums_valid(p)
4494 self.logger.error(ppp("Unexpected or invalid packet:", p))
4497 # from local network host to external network
4498 pkts = self.create_stream_in(self.pg0, self.pg1)
4499 self.pg0.add_stream(pkts)
4500 self.pg_enable_capture(self.pg_interfaces)
4502 capture = self.pg1.get_capture(len(pkts))
4503 self.verify_capture_out(capture)
4504 pkts = self.create_stream_in(self.pg0, self.pg1)
4505 self.pg0.add_stream(pkts)
4506 self.pg_enable_capture(self.pg_interfaces)
4508 capture = self.pg1.get_capture(len(pkts))
4509 self.verify_capture_out(capture)
4511 # from external network back to local network host
4512 pkts = self.create_stream_out(self.pg1)
4513 self.pg1.add_stream(pkts)
4514 self.pg_enable_capture(self.pg_interfaces)
4516 capture = self.pg0.get_capture(len(pkts))
4517 self.verify_capture_in(capture, self.pg0)
4519 def test_output_feature_and_service2(self):
4520 """ NAT44 interface output feature and service host direct access """
4521 self.vapi.nat44_forwarding_enable_disable(1)
4522 self.nat44_add_address(self.nat_addr)
4523 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4526 # session initiaded from service host - translate
4527 pkts = self.create_stream_in(self.pg0, self.pg1)
4528 self.pg0.add_stream(pkts)
4529 self.pg_enable_capture(self.pg_interfaces)
4531 capture = self.pg1.get_capture(len(pkts))
4532 self.verify_capture_out(capture)
4534 pkts = self.create_stream_out(self.pg1)
4535 self.pg1.add_stream(pkts)
4536 self.pg_enable_capture(self.pg_interfaces)
4538 capture = self.pg0.get_capture(len(pkts))
4539 self.verify_capture_in(capture, self.pg0)
4541 # session initiaded from remote host - do not translate
4542 self.tcp_port_in = 60303
4543 self.udp_port_in = 60304
4544 self.icmp_id_in = 60305
4545 pkts = self.create_stream_out(self.pg1,
4546 self.pg0.remote_ip4,
4547 use_inside_ports=True)
4548 self.pg1.add_stream(pkts)
4549 self.pg_enable_capture(self.pg_interfaces)
4551 capture = self.pg0.get_capture(len(pkts))
4552 self.verify_capture_in(capture, self.pg0)
4554 pkts = self.create_stream_in(self.pg0, self.pg1)
4555 self.pg0.add_stream(pkts)
4556 self.pg_enable_capture(self.pg_interfaces)
4558 capture = self.pg1.get_capture(len(pkts))
4559 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4562 def test_output_feature_and_service3(self):
4563 """ NAT44 interface output feature and DST NAT """
4564 external_addr = '1.2.3.4'
4568 self.vapi.nat44_forwarding_enable_disable(1)
4569 self.nat44_add_address(self.nat_addr)
4570 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4571 local_port, external_port,
4572 proto=IP_PROTOS.tcp, out2in_only=1)
4573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4574 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4576 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4579 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4580 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4581 TCP(sport=12345, dport=external_port))
4582 self.pg0.add_stream(p)
4583 self.pg_enable_capture(self.pg_interfaces)
4585 capture = self.pg1.get_capture(1)
4590 self.assertEqual(ip.src, self.pg0.remote_ip4)
4591 self.assertEqual(tcp.sport, 12345)
4592 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4593 self.assertEqual(tcp.dport, local_port)
4594 self.assert_packet_checksums_valid(p)
4596 self.logger.error(ppp("Unexpected or invalid packet:", p))
4599 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4600 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4601 TCP(sport=local_port, dport=12345))
4602 self.pg1.add_stream(p)
4603 self.pg_enable_capture(self.pg_interfaces)
4605 capture = self.pg0.get_capture(1)
4610 self.assertEqual(ip.src, external_addr)
4611 self.assertEqual(tcp.sport, external_port)
4612 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4613 self.assertEqual(tcp.dport, 12345)
4614 self.assert_packet_checksums_valid(p)
4616 self.logger.error(ppp("Unexpected or invalid packet:", p))
4619 def test_next_src_nat(self):
4620 """ On way back forward packet to nat44-in2out node. """
4621 twice_nat_addr = '10.0.1.3'
4624 post_twice_nat_port = 0
4626 self.vapi.nat44_forwarding_enable_disable(1)
4627 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4628 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4629 local_port, external_port,
4630 proto=IP_PROTOS.tcp, out2in_only=1,
4631 self_twice_nat=1, vrf_id=1)
4632 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4635 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4636 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4637 TCP(sport=12345, dport=external_port))
4638 self.pg6.add_stream(p)
4639 self.pg_enable_capture(self.pg_interfaces)
4641 capture = self.pg6.get_capture(1)
4646 self.assertEqual(ip.src, twice_nat_addr)
4647 self.assertNotEqual(tcp.sport, 12345)
4648 post_twice_nat_port = tcp.sport
4649 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4650 self.assertEqual(tcp.dport, local_port)
4651 self.assert_packet_checksums_valid(p)
4653 self.logger.error(ppp("Unexpected or invalid packet:", p))
4656 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4657 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4658 TCP(sport=local_port, dport=post_twice_nat_port))
4659 self.pg6.add_stream(p)
4660 self.pg_enable_capture(self.pg_interfaces)
4662 capture = self.pg6.get_capture(1)
4667 self.assertEqual(ip.src, self.pg1.remote_ip4)
4668 self.assertEqual(tcp.sport, external_port)
4669 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4670 self.assertEqual(tcp.dport, 12345)
4671 self.assert_packet_checksums_valid(p)
4673 self.logger.error(ppp("Unexpected or invalid packet:", p))
4676 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4678 twice_nat_addr = '10.0.1.3'
4686 port_in1 = port_in+1
4687 port_in2 = port_in+2
4692 server1 = self.pg0.remote_hosts[0]
4693 server2 = self.pg0.remote_hosts[1]
4705 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4708 self.nat44_add_address(self.nat_addr)
4709 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4711 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4713 proto=IP_PROTOS.tcp,
4714 twice_nat=int(not self_twice_nat),
4715 self_twice_nat=int(self_twice_nat))
4717 locals = [{'addr': server1.ip4n,
4721 {'addr': server2.ip4n,
4725 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4726 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4730 not self_twice_nat),
4733 local_num=len(locals),
4735 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4736 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4743 assert client_id is not None
4745 client = self.pg0.remote_hosts[0]
4746 elif client_id == 2:
4747 client = self.pg0.remote_hosts[1]
4749 client = pg1.remote_hosts[0]
4750 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4751 IP(src=client.ip4, dst=self.nat_addr) /
4752 TCP(sport=eh_port_out, dport=port_out))
4754 self.pg_enable_capture(self.pg_interfaces)
4756 capture = pg0.get_capture(1)
4762 if ip.dst == server1.ip4:
4768 self.assertEqual(ip.dst, server.ip4)
4770 self.assertIn(tcp.dport, [port_in1, port_in2])
4772 self.assertEqual(tcp.dport, port_in)
4774 self.assertEqual(ip.src, twice_nat_addr)
4775 self.assertNotEqual(tcp.sport, eh_port_out)
4777 self.assertEqual(ip.src, client.ip4)
4778 self.assertEqual(tcp.sport, eh_port_out)
4780 eh_port_in = tcp.sport
4781 saved_port_in = tcp.dport
4782 self.assert_packet_checksums_valid(p)
4784 self.logger.error(ppp("Unexpected or invalid packet:", p))
4787 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4788 IP(src=server.ip4, dst=eh_addr_in) /
4789 TCP(sport=saved_port_in, dport=eh_port_in))
4791 self.pg_enable_capture(self.pg_interfaces)
4793 capture = pg1.get_capture(1)
4798 self.assertEqual(ip.dst, client.ip4)
4799 self.assertEqual(ip.src, self.nat_addr)
4800 self.assertEqual(tcp.dport, eh_port_out)
4801 self.assertEqual(tcp.sport, port_out)
4802 self.assert_packet_checksums_valid(p)
4804 self.logger.error(ppp("Unexpected or invalid packet:", p))
4808 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4809 self.assertEqual(len(sessions), 1)
4810 self.assertTrue(sessions[0].ext_host_valid)
4811 self.assertTrue(sessions[0].is_twicenat)
4812 self.vapi.nat44_del_session(
4813 sessions[0].inside_ip_address,
4814 sessions[0].inside_port,
4815 sessions[0].protocol,
4816 ext_host_address=sessions[0].ext_host_nat_address,
4817 ext_host_port=sessions[0].ext_host_nat_port)
4818 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4819 self.assertEqual(len(sessions), 0)
4821 def test_twice_nat(self):
4823 self.twice_nat_common()
4825 def test_self_twice_nat_positive(self):
4826 """ Self Twice NAT44 (positive test) """
4827 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4829 def test_self_twice_nat_negative(self):
4830 """ Self Twice NAT44 (negative test) """
4831 self.twice_nat_common(self_twice_nat=True)
4833 def test_twice_nat_lb(self):
4834 """ Twice NAT44 local service load balancing """
4835 self.twice_nat_common(lb=True)
4837 def test_self_twice_nat_lb_positive(self):
4838 """ Self Twice NAT44 local service load balancing (positive test) """
4839 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4842 def test_self_twice_nat_lb_negative(self):
4843 """ Self Twice NAT44 local service load balancing (negative test) """
4844 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4847 def test_twice_nat_interface_addr(self):
4848 """ Acquire twice NAT44 addresses from interface """
4849 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4851 # no address in NAT pool
4852 adresses = self.vapi.nat44_address_dump()
4853 self.assertEqual(0, len(adresses))
4855 # configure interface address and check NAT address pool
4856 self.pg3.config_ip4()
4857 adresses = self.vapi.nat44_address_dump()
4858 self.assertEqual(1, len(adresses))
4859 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4860 self.assertEqual(adresses[0].twice_nat, 1)
4862 # remove interface address and check NAT address pool
4863 self.pg3.unconfig_ip4()
4864 adresses = self.vapi.nat44_address_dump()
4865 self.assertEqual(0, len(adresses))
4867 def test_tcp_close(self):
4868 """ Close TCP session from inside network - output feature """
4869 self.vapi.nat44_forwarding_enable_disable(1)
4870 self.nat44_add_address(self.pg1.local_ip4)
4871 twice_nat_addr = '10.0.1.3'
4872 service_ip = '192.168.16.150'
4873 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4874 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4875 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4877 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4879 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4883 proto=IP_PROTOS.tcp,
4886 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4887 start_sessnum = len(sessions)
4889 # SYN packet out->in
4890 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4891 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4892 TCP(sport=33898, dport=80, flags="S"))
4893 self.pg1.add_stream(p)
4894 self.pg_enable_capture(self.pg_interfaces)
4896 capture = self.pg0.get_capture(1)
4898 tcp_port = p[TCP].sport
4900 # SYN + ACK packet in->out
4901 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4902 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4903 TCP(sport=80, dport=tcp_port, flags="SA"))
4904 self.pg0.add_stream(p)
4905 self.pg_enable_capture(self.pg_interfaces)
4907 self.pg1.get_capture(1)
4909 # ACK packet out->in
4910 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4911 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4912 TCP(sport=33898, dport=80, flags="A"))
4913 self.pg1.add_stream(p)
4914 self.pg_enable_capture(self.pg_interfaces)
4916 self.pg0.get_capture(1)
4918 # FIN packet in -> out
4919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4920 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4921 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
4922 self.pg0.add_stream(p)
4923 self.pg_enable_capture(self.pg_interfaces)
4925 self.pg1.get_capture(1)
4927 # FIN+ACK packet out -> in
4928 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4929 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4930 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
4931 self.pg1.add_stream(p)
4932 self.pg_enable_capture(self.pg_interfaces)
4934 self.pg0.get_capture(1)
4936 # ACK packet in -> out
4937 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4938 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4939 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
4940 self.pg0.add_stream(p)
4941 self.pg_enable_capture(self.pg_interfaces)
4943 self.pg1.get_capture(1)
4945 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4947 self.assertEqual(len(sessions) - start_sessnum, 0)
4949 def test_tcp_session_close_in(self):
4950 """ Close TCP session from inside network """
4951 self.tcp_port_out = 10505
4952 self.nat44_add_address(self.nat_addr)
4953 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4957 proto=IP_PROTOS.tcp,
4959 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4960 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4963 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4964 start_sessnum = len(sessions)
4966 self.initiate_tcp_session(self.pg0, self.pg1)
4968 # FIN packet in -> out
4969 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4970 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4971 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4972 flags="FA", seq=100, ack=300))
4973 self.pg0.add_stream(p)
4974 self.pg_enable_capture(self.pg_interfaces)
4976 self.pg1.get_capture(1)
4980 # ACK packet out -> in
4981 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4982 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4983 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4984 flags="A", seq=300, ack=101))
4987 # FIN packet out -> in
4988 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4989 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4990 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4991 flags="FA", seq=300, ack=101))
4994 self.pg1.add_stream(pkts)
4995 self.pg_enable_capture(self.pg_interfaces)
4997 self.pg0.get_capture(2)
4999 # ACK packet in -> out
5000 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5001 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5002 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5003 flags="A", seq=101, ack=301))
5004 self.pg0.add_stream(p)
5005 self.pg_enable_capture(self.pg_interfaces)
5007 self.pg1.get_capture(1)
5009 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5011 self.assertEqual(len(sessions) - start_sessnum, 0)
5013 def test_tcp_session_close_out(self):
5014 """ Close TCP session from outside network """
5015 self.tcp_port_out = 10505
5016 self.nat44_add_address(self.nat_addr)
5017 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5021 proto=IP_PROTOS.tcp,
5023 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5024 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5027 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5028 start_sessnum = len(sessions)
5030 self.initiate_tcp_session(self.pg0, self.pg1)
5032 # FIN packet out -> in
5033 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5034 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5035 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5036 flags="FA", seq=100, ack=300))
5037 self.pg1.add_stream(p)
5038 self.pg_enable_capture(self.pg_interfaces)
5040 self.pg0.get_capture(1)
5042 # FIN+ACK packet in -> out
5043 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5044 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5045 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5046 flags="FA", seq=300, ack=101))
5048 self.pg0.add_stream(p)
5049 self.pg_enable_capture(self.pg_interfaces)
5051 self.pg1.get_capture(1)
5053 # ACK packet out -> in
5054 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5055 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5056 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5057 flags="A", seq=101, ack=301))
5058 self.pg1.add_stream(p)
5059 self.pg_enable_capture(self.pg_interfaces)
5061 self.pg0.get_capture(1)
5063 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5065 self.assertEqual(len(sessions) - start_sessnum, 0)
5067 def test_tcp_session_close_simultaneous(self):
5068 """ Close TCP session from inside network """
5069 self.tcp_port_out = 10505
5070 self.nat44_add_address(self.nat_addr)
5071 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5075 proto=IP_PROTOS.tcp,
5077 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5078 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5081 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5082 start_sessnum = len(sessions)
5084 self.initiate_tcp_session(self.pg0, self.pg1)
5086 # FIN packet in -> out
5087 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5088 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5089 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5090 flags="FA", seq=100, ack=300))
5091 self.pg0.add_stream(p)
5092 self.pg_enable_capture(self.pg_interfaces)
5094 self.pg1.get_capture(1)
5096 # FIN packet out -> in
5097 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5098 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5099 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5100 flags="FA", seq=300, ack=100))
5101 self.pg1.add_stream(p)
5102 self.pg_enable_capture(self.pg_interfaces)
5104 self.pg0.get_capture(1)
5106 # ACK packet in -> out
5107 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5108 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5109 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5110 flags="A", seq=101, ack=301))
5111 self.pg0.add_stream(p)
5112 self.pg_enable_capture(self.pg_interfaces)
5114 self.pg1.get_capture(1)
5116 # ACK packet out -> in
5117 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5118 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5119 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5120 flags="A", seq=301, ack=101))
5121 self.pg1.add_stream(p)
5122 self.pg_enable_capture(self.pg_interfaces)
5124 self.pg0.get_capture(1)
5126 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5128 self.assertEqual(len(sessions) - start_sessnum, 0)
5130 def test_one_armed_nat44_static(self):
5131 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5132 remote_host = self.pg4.remote_hosts[0]
5133 local_host = self.pg4.remote_hosts[1]
5138 self.vapi.nat44_forwarding_enable_disable(1)
5139 self.nat44_add_address(self.nat_addr, twice_nat=1)
5140 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5141 local_port, external_port,
5142 proto=IP_PROTOS.tcp, out2in_only=1,
5144 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5145 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5148 # from client to service
5149 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5150 IP(src=remote_host.ip4, dst=self.nat_addr) /
5151 TCP(sport=12345, dport=external_port))
5152 self.pg4.add_stream(p)
5153 self.pg_enable_capture(self.pg_interfaces)
5155 capture = self.pg4.get_capture(1)
5160 self.assertEqual(ip.dst, local_host.ip4)
5161 self.assertEqual(ip.src, self.nat_addr)
5162 self.assertEqual(tcp.dport, local_port)
5163 self.assertNotEqual(tcp.sport, 12345)
5164 eh_port_in = tcp.sport
5165 self.assert_packet_checksums_valid(p)
5167 self.logger.error(ppp("Unexpected or invalid packet:", p))
5170 # from service back to client
5171 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5172 IP(src=local_host.ip4, dst=self.nat_addr) /
5173 TCP(sport=local_port, dport=eh_port_in))
5174 self.pg4.add_stream(p)
5175 self.pg_enable_capture(self.pg_interfaces)
5177 capture = self.pg4.get_capture(1)
5182 self.assertEqual(ip.src, self.nat_addr)
5183 self.assertEqual(ip.dst, remote_host.ip4)
5184 self.assertEqual(tcp.sport, external_port)
5185 self.assertEqual(tcp.dport, 12345)
5186 self.assert_packet_checksums_valid(p)
5188 self.logger.error(ppp("Unexpected or invalid packet:", p))
5191 def test_static_with_port_out2(self):
5192 """ 1:1 NAPT asymmetrical rule """
5197 self.vapi.nat44_forwarding_enable_disable(1)
5198 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5199 local_port, external_port,
5200 proto=IP_PROTOS.tcp, out2in_only=1)
5201 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5202 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5205 # from client to service
5206 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5207 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5208 TCP(sport=12345, dport=external_port))
5209 self.pg1.add_stream(p)
5210 self.pg_enable_capture(self.pg_interfaces)
5212 capture = self.pg0.get_capture(1)
5217 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5218 self.assertEqual(tcp.dport, local_port)
5219 self.assert_packet_checksums_valid(p)
5221 self.logger.error(ppp("Unexpected or invalid packet:", p))
5225 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5226 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5227 ICMP(type=11) / capture[0][IP])
5228 self.pg0.add_stream(p)
5229 self.pg_enable_capture(self.pg_interfaces)
5231 capture = self.pg1.get_capture(1)
5234 self.assertEqual(p[IP].src, self.nat_addr)
5236 self.assertEqual(inner.dst, self.nat_addr)
5237 self.assertEqual(inner[TCPerror].dport, external_port)
5239 self.logger.error(ppp("Unexpected or invalid packet:", p))
5242 # from service back to client
5243 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5244 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5245 TCP(sport=local_port, dport=12345))
5246 self.pg0.add_stream(p)
5247 self.pg_enable_capture(self.pg_interfaces)
5249 capture = self.pg1.get_capture(1)
5254 self.assertEqual(ip.src, self.nat_addr)
5255 self.assertEqual(tcp.sport, external_port)
5256 self.assert_packet_checksums_valid(p)
5258 self.logger.error(ppp("Unexpected or invalid packet:", p))
5262 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5263 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5264 ICMP(type=11) / capture[0][IP])
5265 self.pg1.add_stream(p)
5266 self.pg_enable_capture(self.pg_interfaces)
5268 capture = self.pg0.get_capture(1)
5271 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5273 self.assertEqual(inner.src, self.pg0.remote_ip4)
5274 self.assertEqual(inner[TCPerror].sport, local_port)
5276 self.logger.error(ppp("Unexpected or invalid packet:", p))
5279 # from client to server (no translation)
5280 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5281 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5282 TCP(sport=12346, dport=local_port))
5283 self.pg1.add_stream(p)
5284 self.pg_enable_capture(self.pg_interfaces)
5286 capture = self.pg0.get_capture(1)
5291 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5292 self.assertEqual(tcp.dport, local_port)
5293 self.assert_packet_checksums_valid(p)
5295 self.logger.error(ppp("Unexpected or invalid packet:", p))
5298 # from service back to client (no translation)
5299 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5300 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5301 TCP(sport=local_port, dport=12346))
5302 self.pg0.add_stream(p)
5303 self.pg_enable_capture(self.pg_interfaces)
5305 capture = self.pg1.get_capture(1)
5310 self.assertEqual(ip.src, self.pg0.remote_ip4)
5311 self.assertEqual(tcp.sport, local_port)
5312 self.assert_packet_checksums_valid(p)
5314 self.logger.error(ppp("Unexpected or invalid packet:", p))
5317 def test_output_feature(self):
5318 """ NAT44 interface output feature (in2out postrouting) """
5319 self.vapi.nat44_forwarding_enable_disable(1)
5320 self.nat44_add_address(self.nat_addr)
5321 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5323 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5327 pkts = self.create_stream_in(self.pg0, self.pg1)
5328 self.pg0.add_stream(pkts)
5329 self.pg_enable_capture(self.pg_interfaces)
5331 capture = self.pg1.get_capture(len(pkts))
5332 self.verify_capture_out(capture)
5335 pkts = self.create_stream_out(self.pg1)
5336 self.pg1.add_stream(pkts)
5337 self.pg_enable_capture(self.pg_interfaces)
5339 capture = self.pg0.get_capture(len(pkts))
5340 self.verify_capture_in(capture, self.pg0)
5342 def test_multiple_vrf(self):
5343 """ Multiple VRF setup """
5344 external_addr = '1.2.3.4'
5349 self.vapi.nat44_forwarding_enable_disable(1)
5350 self.nat44_add_address(self.nat_addr)
5351 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5352 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5354 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5356 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5357 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5359 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5361 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5362 local_port, external_port, vrf_id=1,
5363 proto=IP_PROTOS.tcp, out2in_only=1)
5364 self.nat44_add_static_mapping(
5365 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5366 local_port=local_port, vrf_id=0, external_port=external_port,
5367 proto=IP_PROTOS.tcp, out2in_only=1)
5369 # from client to service (both VRF1)
5370 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5371 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5372 TCP(sport=12345, dport=external_port))
5373 self.pg6.add_stream(p)
5374 self.pg_enable_capture(self.pg_interfaces)
5376 capture = self.pg5.get_capture(1)
5381 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5382 self.assertEqual(tcp.dport, local_port)
5383 self.assert_packet_checksums_valid(p)
5385 self.logger.error(ppp("Unexpected or invalid packet:", p))
5388 # from service back to client (both VRF1)
5389 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5390 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5391 TCP(sport=local_port, dport=12345))
5392 self.pg5.add_stream(p)
5393 self.pg_enable_capture(self.pg_interfaces)
5395 capture = self.pg6.get_capture(1)
5400 self.assertEqual(ip.src, external_addr)
5401 self.assertEqual(tcp.sport, external_port)
5402 self.assert_packet_checksums_valid(p)
5404 self.logger.error(ppp("Unexpected or invalid packet:", p))
5407 # dynamic NAT from VRF1 to VRF0 (output-feature)
5408 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5409 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5410 TCP(sport=2345, dport=22))
5411 self.pg5.add_stream(p)
5412 self.pg_enable_capture(self.pg_interfaces)
5414 capture = self.pg1.get_capture(1)
5419 self.assertEqual(ip.src, self.nat_addr)
5420 self.assertNotEqual(tcp.sport, 2345)
5421 self.assert_packet_checksums_valid(p)
5424 self.logger.error(ppp("Unexpected or invalid packet:", p))
5427 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5429 TCP(sport=22, dport=port))
5430 self.pg1.add_stream(p)
5431 self.pg_enable_capture(self.pg_interfaces)
5433 capture = self.pg5.get_capture(1)
5438 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5439 self.assertEqual(tcp.dport, 2345)
5440 self.assert_packet_checksums_valid(p)
5442 self.logger.error(ppp("Unexpected or invalid packet:", p))
5445 # from client VRF1 to service VRF0
5446 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5447 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5448 TCP(sport=12346, dport=external_port))
5449 self.pg6.add_stream(p)
5450 self.pg_enable_capture(self.pg_interfaces)
5452 capture = self.pg0.get_capture(1)
5457 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5458 self.assertEqual(tcp.dport, local_port)
5459 self.assert_packet_checksums_valid(p)
5461 self.logger.error(ppp("Unexpected or invalid packet:", p))
5464 # from service VRF0 back to client VRF1
5465 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5466 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5467 TCP(sport=local_port, dport=12346))
5468 self.pg0.add_stream(p)
5469 self.pg_enable_capture(self.pg_interfaces)
5471 capture = self.pg6.get_capture(1)
5476 self.assertEqual(ip.src, self.pg0.local_ip4)
5477 self.assertEqual(tcp.sport, external_port)
5478 self.assert_packet_checksums_valid(p)
5480 self.logger.error(ppp("Unexpected or invalid packet:", p))
5483 # from client VRF0 to service VRF1
5484 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5485 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5486 TCP(sport=12347, dport=external_port))
5487 self.pg0.add_stream(p)
5488 self.pg_enable_capture(self.pg_interfaces)
5490 capture = self.pg5.get_capture(1)
5495 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5496 self.assertEqual(tcp.dport, local_port)
5497 self.assert_packet_checksums_valid(p)
5499 self.logger.error(ppp("Unexpected or invalid packet:", p))
5502 # from service VRF1 back to client VRF0
5503 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5504 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5505 TCP(sport=local_port, dport=12347))
5506 self.pg5.add_stream(p)
5507 self.pg_enable_capture(self.pg_interfaces)
5509 capture = self.pg0.get_capture(1)
5514 self.assertEqual(ip.src, external_addr)
5515 self.assertEqual(tcp.sport, external_port)
5516 self.assert_packet_checksums_valid(p)
5518 self.logger.error(ppp("Unexpected or invalid packet:", p))
5521 # from client to server (both VRF1, no translation)
5522 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5523 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5524 TCP(sport=12348, dport=local_port))
5525 self.pg6.add_stream(p)
5526 self.pg_enable_capture(self.pg_interfaces)
5528 capture = self.pg5.get_capture(1)
5533 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5534 self.assertEqual(tcp.dport, local_port)
5535 self.assert_packet_checksums_valid(p)
5537 self.logger.error(ppp("Unexpected or invalid packet:", p))
5540 # from server back to client (both VRF1, no translation)
5541 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5542 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5543 TCP(sport=local_port, dport=12348))
5544 self.pg5.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 capture = self.pg6.get_capture(1)
5552 self.assertEqual(ip.src, self.pg5.remote_ip4)
5553 self.assertEqual(tcp.sport, local_port)
5554 self.assert_packet_checksums_valid(p)
5556 self.logger.error(ppp("Unexpected or invalid packet:", p))
5559 # from client VRF1 to server VRF0 (no translation)
5560 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5561 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5562 TCP(sport=local_port, dport=12349))
5563 self.pg0.add_stream(p)
5564 self.pg_enable_capture(self.pg_interfaces)
5566 capture = self.pg6.get_capture(1)
5571 self.assertEqual(ip.src, self.pg0.remote_ip4)
5572 self.assertEqual(tcp.sport, local_port)
5573 self.assert_packet_checksums_valid(p)
5575 self.logger.error(ppp("Unexpected or invalid packet:", p))
5578 # from server VRF0 back to client VRF1 (no translation)
5579 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5580 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5581 TCP(sport=local_port, dport=12349))
5582 self.pg0.add_stream(p)
5583 self.pg_enable_capture(self.pg_interfaces)
5585 capture = self.pg6.get_capture(1)
5590 self.assertEqual(ip.src, self.pg0.remote_ip4)
5591 self.assertEqual(tcp.sport, local_port)
5592 self.assert_packet_checksums_valid(p)
5594 self.logger.error(ppp("Unexpected or invalid packet:", p))
5597 # from client VRF0 to server VRF1 (no translation)
5598 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5599 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5600 TCP(sport=12344, dport=local_port))
5601 self.pg0.add_stream(p)
5602 self.pg_enable_capture(self.pg_interfaces)
5604 capture = self.pg5.get_capture(1)
5609 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5610 self.assertEqual(tcp.dport, local_port)
5611 self.assert_packet_checksums_valid(p)
5613 self.logger.error(ppp("Unexpected or invalid packet:", p))
5616 # from server VRF1 back to client VRF0 (no translation)
5617 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5618 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5619 TCP(sport=local_port, dport=12344))
5620 self.pg5.add_stream(p)
5621 self.pg_enable_capture(self.pg_interfaces)
5623 capture = self.pg0.get_capture(1)
5628 self.assertEqual(ip.src, self.pg5.remote_ip4)
5629 self.assertEqual(tcp.sport, local_port)
5630 self.assert_packet_checksums_valid(p)
5632 self.logger.error(ppp("Unexpected or invalid packet:", p))
5635 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5636 def test_session_timeout(self):
5637 """ NAT44 session timeouts """
5638 self.nat44_add_address(self.nat_addr)
5639 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5640 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5642 self.vapi.nat_set_timeouts(icmp=5)
5646 for i in range(0, max_sessions):
5647 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5648 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5649 IP(src=src, dst=self.pg1.remote_ip4) /
5650 ICMP(id=1025, type='echo-request'))
5652 self.pg0.add_stream(pkts)
5653 self.pg_enable_capture(self.pg_interfaces)
5655 self.pg1.get_capture(max_sessions)
5660 for i in range(0, max_sessions):
5661 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5663 IP(src=src, dst=self.pg1.remote_ip4) /
5664 ICMP(id=1026, type='echo-request'))
5666 self.pg0.add_stream(pkts)
5667 self.pg_enable_capture(self.pg_interfaces)
5669 self.pg1.get_capture(max_sessions)
5672 users = self.vapi.nat44_user_dump()
5674 nsessions = nsessions + user.nsessions
5675 self.assertLess(nsessions, 2 * max_sessions)
5677 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5678 def test_session_rst_timeout(self):
5679 """ NAT44 session RST timeouts """
5680 self.nat44_add_address(self.nat_addr)
5681 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5682 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5684 self.vapi.nat_set_timeouts(tcp_transitory=5)
5686 nat44_config = self.vapi.nat_show_config()
5688 self.initiate_tcp_session(self.pg0, self.pg1)
5689 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5690 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5691 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5693 self.pg0.add_stream(p)
5694 self.pg_enable_capture(self.pg_interfaces)
5696 self.pg1.get_capture(1)
5698 pkts_num = nat44_config.max_translations_per_user - 1
5700 for i in range(0, pkts_num):
5701 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5702 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5703 UDP(sport=1025 + i, dport=53))
5705 self.pg0.add_stream(pkts)
5706 self.pg_enable_capture(self.pg_interfaces)
5708 self.pg1.get_capture(pkts_num)
5712 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5713 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5714 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5716 self.pg0.add_stream(p)
5717 self.pg_enable_capture(self.pg_interfaces)
5719 self.pg1.get_capture(1)
5722 users = self.vapi.nat44_user_dump()
5723 self.assertEqual(len(users), 1)
5724 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5725 self.assertEqual(users[0].nsessions,
5726 nat44_config.max_translations_per_user)
5728 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5729 def test_session_limit_per_user(self):
5730 """ Maximum sessions per user limit """
5731 self.nat44_add_address(self.nat_addr)
5732 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5733 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5735 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5736 src_address=self.pg2.local_ip4n,
5738 template_interval=10)
5739 self.vapi.nat_set_timeouts(udp=5)
5741 # get maximum number of translations per user
5742 nat44_config = self.vapi.nat_show_config()
5745 for port in range(0, nat44_config.max_translations_per_user):
5746 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5747 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5748 UDP(sport=1025 + port, dport=1025 + port))
5751 self.pg0.add_stream(pkts)
5752 self.pg_enable_capture(self.pg_interfaces)
5754 capture = self.pg1.get_capture(len(pkts))
5756 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5757 src_port=self.ipfix_src_port)
5759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5760 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5761 UDP(sport=3001, dport=3002))
5762 self.pg0.add_stream(p)
5763 self.pg_enable_capture(self.pg_interfaces)
5765 capture = self.pg1.assert_nothing_captured()
5767 # verify IPFIX logging
5768 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5770 capture = self.pg2.get_capture(10)
5771 ipfix = IPFIXDecoder()
5772 # first load template
5774 self.assertTrue(p.haslayer(IPFIX))
5775 if p.haslayer(Template):
5776 ipfix.add_template(p.getlayer(Template))
5777 # verify events in data set
5779 if p.haslayer(Data):
5780 data = ipfix.decode_data_set(p.getlayer(Set))
5781 self.verify_ipfix_max_entries_per_user(
5783 nat44_config.max_translations_per_user,
5784 self.pg0.remote_ip4n)
5787 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5788 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5789 UDP(sport=3001, dport=3002))
5790 self.pg0.add_stream(p)
5791 self.pg_enable_capture(self.pg_interfaces)
5793 self.pg1.get_capture(1)
5796 super(TestNAT44EndpointDependent, self).tearDown()
5797 if not self.vpp_dead:
5798 self.logger.info(self.vapi.cli("show nat44 addresses"))
5799 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5800 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5801 self.logger.info(self.vapi.cli("show nat44 interface address"))
5802 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5803 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5804 self.logger.info(self.vapi.cli("show nat timeouts"))
5806 self.vapi.cli("clear logging")
5809 class TestNAT44Out2InDPO(MethodHolder):
5810 """ NAT44 Test Cases using out2in DPO """
5813 def setUpConstants(cls):
5814 super(TestNAT44Out2InDPO, cls).setUpConstants()
5815 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5818 def setUpClass(cls):
5819 super(TestNAT44Out2InDPO, cls).setUpClass()
5820 cls.vapi.cli("set log class nat level debug")
5823 cls.tcp_port_in = 6303
5824 cls.tcp_port_out = 6303
5825 cls.udp_port_in = 6304
5826 cls.udp_port_out = 6304
5827 cls.icmp_id_in = 6305
5828 cls.icmp_id_out = 6305
5829 cls.nat_addr = '10.0.0.3'
5830 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5831 cls.dst_ip4 = '192.168.70.1'
5833 cls.create_pg_interfaces(range(2))
5836 cls.pg0.config_ip4()
5837 cls.pg0.resolve_arp()
5840 cls.pg1.config_ip6()
5841 cls.pg1.resolve_ndp()
5843 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5844 dst_address_length=0,
5845 next_hop_address=cls.pg1.remote_ip6n,
5846 next_hop_sw_if_index=cls.pg1.sw_if_index)
5849 super(TestNAT44Out2InDPO, cls).tearDownClass()
5852 def configure_xlat(self):
5853 self.dst_ip6_pfx = '1:2:3::'
5854 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5856 self.dst_ip6_pfx_len = 96
5857 self.src_ip6_pfx = '4:5:6::'
5858 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5860 self.src_ip6_pfx_len = 96
5861 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5862 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5863 '\x00\x00\x00\x00', 0, is_translation=1,
5866 def test_464xlat_ce(self):
5867 """ Test 464XLAT CE with NAT44 """
5869 nat_config = self.vapi.nat_show_config()
5870 self.assertEqual(1, nat_config.out2in_dpo)
5872 self.configure_xlat()
5874 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5875 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5877 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5878 self.dst_ip6_pfx_len)
5879 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5880 self.src_ip6_pfx_len)
5883 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5884 self.pg0.add_stream(pkts)
5885 self.pg_enable_capture(self.pg_interfaces)
5887 capture = self.pg1.get_capture(len(pkts))
5888 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5891 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5893 self.pg1.add_stream(pkts)
5894 self.pg_enable_capture(self.pg_interfaces)
5896 capture = self.pg0.get_capture(len(pkts))
5897 self.verify_capture_in(capture, self.pg0)
5899 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5901 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5902 self.nat_addr_n, is_add=0)
5904 def test_464xlat_ce_no_nat(self):
5905 """ Test 464XLAT CE without NAT44 """
5907 self.configure_xlat()
5909 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5910 self.dst_ip6_pfx_len)
5911 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5912 self.src_ip6_pfx_len)
5914 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5915 self.pg0.add_stream(pkts)
5916 self.pg_enable_capture(self.pg_interfaces)
5918 capture = self.pg1.get_capture(len(pkts))
5919 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5920 nat_ip=out_dst_ip6, same_port=True)
5922 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5923 self.pg1.add_stream(pkts)
5924 self.pg_enable_capture(self.pg_interfaces)
5926 capture = self.pg0.get_capture(len(pkts))
5927 self.verify_capture_in(capture, self.pg0)
5930 class TestDeterministicNAT(MethodHolder):
5931 """ Deterministic NAT Test Cases """
5934 def setUpConstants(cls):
5935 super(TestDeterministicNAT, cls).setUpConstants()
5936 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5939 def setUpClass(cls):
5940 super(TestDeterministicNAT, cls).setUpClass()
5941 cls.vapi.cli("set log class nat level debug")
5944 cls.tcp_port_in = 6303
5945 cls.tcp_external_port = 6303
5946 cls.udp_port_in = 6304
5947 cls.udp_external_port = 6304
5948 cls.icmp_id_in = 6305
5949 cls.nat_addr = '10.0.0.3'
5951 cls.create_pg_interfaces(range(3))
5952 cls.interfaces = list(cls.pg_interfaces)
5954 for i in cls.interfaces:
5959 cls.pg0.generate_remote_hosts(2)
5960 cls.pg0.configure_ipv4_neighbors()
5963 super(TestDeterministicNAT, cls).tearDownClass()
5966 def create_stream_in(self, in_if, out_if, ttl=64):
5968 Create packet stream for inside network
5970 :param in_if: Inside interface
5971 :param out_if: Outside interface
5972 :param ttl: TTL of generated packets
5976 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5977 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5978 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5982 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5983 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5984 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5988 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5989 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5990 ICMP(id=self.icmp_id_in, type='echo-request'))
5995 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5997 Create packet stream for outside network
5999 :param out_if: Outside interface
6000 :param dst_ip: Destination IP address (Default use global NAT address)
6001 :param ttl: TTL of generated packets
6004 dst_ip = self.nat_addr
6007 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6008 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6009 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6013 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6014 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6015 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6019 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6020 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6021 ICMP(id=self.icmp_external_id, type='echo-reply'))
6026 def verify_capture_out(self, capture, nat_ip=None):
6028 Verify captured packets on outside network
6030 :param capture: Captured packets
6031 :param nat_ip: Translated IP address (Default use global NAT address)
6032 :param same_port: Sorce port number is not translated (Default False)
6035 nat_ip = self.nat_addr
6036 for packet in capture:
6038 self.assertEqual(packet[IP].src, nat_ip)
6039 if packet.haslayer(TCP):
6040 self.tcp_port_out = packet[TCP].sport
6041 elif packet.haslayer(UDP):
6042 self.udp_port_out = packet[UDP].sport
6044 self.icmp_external_id = packet[ICMP].id
6046 self.logger.error(ppp("Unexpected or invalid packet "
6047 "(outside network):", packet))
6050 def test_deterministic_mode(self):
6051 """ NAT plugin run deterministic mode """
6052 in_addr = '172.16.255.0'
6053 out_addr = '172.17.255.50'
6054 in_addr_t = '172.16.255.20'
6055 in_addr_n = socket.inet_aton(in_addr)
6056 out_addr_n = socket.inet_aton(out_addr)
6057 in_addr_t_n = socket.inet_aton(in_addr_t)
6061 nat_config = self.vapi.nat_show_config()
6062 self.assertEqual(1, nat_config.deterministic)
6064 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6066 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6067 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6068 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6069 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6071 deterministic_mappings = self.vapi.nat_det_map_dump()
6072 self.assertEqual(len(deterministic_mappings), 1)
6073 dsm = deterministic_mappings[0]
6074 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6075 self.assertEqual(in_plen, dsm.in_plen)
6076 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6077 self.assertEqual(out_plen, dsm.out_plen)
6079 self.clear_nat_det()
6080 deterministic_mappings = self.vapi.nat_det_map_dump()
6081 self.assertEqual(len(deterministic_mappings), 0)
6083 def test_set_timeouts(self):
6084 """ Set deterministic NAT timeouts """
6085 timeouts_before = self.vapi.nat_get_timeouts()
6087 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6088 timeouts_before.tcp_established + 10,
6089 timeouts_before.tcp_transitory + 10,
6090 timeouts_before.icmp + 10)
6092 timeouts_after = self.vapi.nat_get_timeouts()
6094 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6095 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6096 self.assertNotEqual(timeouts_before.tcp_established,
6097 timeouts_after.tcp_established)
6098 self.assertNotEqual(timeouts_before.tcp_transitory,
6099 timeouts_after.tcp_transitory)
6101 def test_det_in(self):
6102 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6104 nat_ip = "10.0.0.10"
6106 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6108 socket.inet_aton(nat_ip),
6110 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6111 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6115 pkts = self.create_stream_in(self.pg0, self.pg1)
6116 self.pg0.add_stream(pkts)
6117 self.pg_enable_capture(self.pg_interfaces)
6119 capture = self.pg1.get_capture(len(pkts))
6120 self.verify_capture_out(capture, nat_ip)
6123 pkts = self.create_stream_out(self.pg1, nat_ip)
6124 self.pg1.add_stream(pkts)
6125 self.pg_enable_capture(self.pg_interfaces)
6127 capture = self.pg0.get_capture(len(pkts))
6128 self.verify_capture_in(capture, self.pg0)
6131 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6132 self.assertEqual(len(sessions), 3)
6136 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6137 self.assertEqual(s.in_port, self.tcp_port_in)
6138 self.assertEqual(s.out_port, self.tcp_port_out)
6139 self.assertEqual(s.ext_port, self.tcp_external_port)
6143 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6144 self.assertEqual(s.in_port, self.udp_port_in)
6145 self.assertEqual(s.out_port, self.udp_port_out)
6146 self.assertEqual(s.ext_port, self.udp_external_port)
6150 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6151 self.assertEqual(s.in_port, self.icmp_id_in)
6152 self.assertEqual(s.out_port, self.icmp_external_id)
6154 def test_multiple_users(self):
6155 """ Deterministic NAT multiple users """
6157 nat_ip = "10.0.0.10"
6159 external_port = 6303
6161 host0 = self.pg0.remote_hosts[0]
6162 host1 = self.pg0.remote_hosts[1]
6164 self.vapi.nat_det_add_del_map(host0.ip4n,
6166 socket.inet_aton(nat_ip),
6168 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6169 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6173 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6174 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6175 TCP(sport=port_in, dport=external_port))
6176 self.pg0.add_stream(p)
6177 self.pg_enable_capture(self.pg_interfaces)
6179 capture = self.pg1.get_capture(1)
6184 self.assertEqual(ip.src, nat_ip)
6185 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6186 self.assertEqual(tcp.dport, external_port)
6187 port_out0 = tcp.sport
6189 self.logger.error(ppp("Unexpected or invalid packet:", p))
6193 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6194 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6195 TCP(sport=port_in, dport=external_port))
6196 self.pg0.add_stream(p)
6197 self.pg_enable_capture(self.pg_interfaces)
6199 capture = self.pg1.get_capture(1)
6204 self.assertEqual(ip.src, nat_ip)
6205 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6206 self.assertEqual(tcp.dport, external_port)
6207 port_out1 = tcp.sport
6209 self.logger.error(ppp("Unexpected or invalid packet:", p))
6212 dms = self.vapi.nat_det_map_dump()
6213 self.assertEqual(1, len(dms))
6214 self.assertEqual(2, dms[0].ses_num)
6217 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6218 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6219 TCP(sport=external_port, dport=port_out0))
6220 self.pg1.add_stream(p)
6221 self.pg_enable_capture(self.pg_interfaces)
6223 capture = self.pg0.get_capture(1)
6228 self.assertEqual(ip.src, self.pg1.remote_ip4)
6229 self.assertEqual(ip.dst, host0.ip4)
6230 self.assertEqual(tcp.dport, port_in)
6231 self.assertEqual(tcp.sport, external_port)
6233 self.logger.error(ppp("Unexpected or invalid packet:", p))
6237 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6238 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6239 TCP(sport=external_port, dport=port_out1))
6240 self.pg1.add_stream(p)
6241 self.pg_enable_capture(self.pg_interfaces)
6243 capture = self.pg0.get_capture(1)
6248 self.assertEqual(ip.src, self.pg1.remote_ip4)
6249 self.assertEqual(ip.dst, host1.ip4)
6250 self.assertEqual(tcp.dport, port_in)
6251 self.assertEqual(tcp.sport, external_port)
6253 self.logger.error(ppp("Unexpected or invalid packet", p))
6256 # session close api test
6257 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6259 self.pg1.remote_ip4n,
6261 dms = self.vapi.nat_det_map_dump()
6262 self.assertEqual(dms[0].ses_num, 1)
6264 self.vapi.nat_det_close_session_in(host0.ip4n,
6266 self.pg1.remote_ip4n,
6268 dms = self.vapi.nat_det_map_dump()
6269 self.assertEqual(dms[0].ses_num, 0)
6271 def test_tcp_session_close_detection_in(self):
6272 """ Deterministic NAT TCP session close from inside network """
6273 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6275 socket.inet_aton(self.nat_addr),
6277 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6278 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6281 self.initiate_tcp_session(self.pg0, self.pg1)
6283 # close the session from inside
6285 # FIN packet in -> out
6286 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6287 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6288 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6290 self.pg0.add_stream(p)
6291 self.pg_enable_capture(self.pg_interfaces)
6293 self.pg1.get_capture(1)
6297 # ACK packet out -> in
6298 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6299 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6300 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6304 # FIN packet out -> in
6305 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6306 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6307 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6311 self.pg1.add_stream(pkts)
6312 self.pg_enable_capture(self.pg_interfaces)
6314 self.pg0.get_capture(2)
6316 # ACK packet in -> out
6317 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6318 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6319 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6321 self.pg0.add_stream(p)
6322 self.pg_enable_capture(self.pg_interfaces)
6324 self.pg1.get_capture(1)
6326 # Check if deterministic NAT44 closed the session
6327 dms = self.vapi.nat_det_map_dump()
6328 self.assertEqual(0, dms[0].ses_num)
6330 self.logger.error("TCP session termination failed")
6333 def test_tcp_session_close_detection_out(self):
6334 """ Deterministic NAT TCP session close from outside network """
6335 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6337 socket.inet_aton(self.nat_addr),
6339 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6340 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6343 self.initiate_tcp_session(self.pg0, self.pg1)
6345 # close the session from outside
6347 # FIN packet out -> in
6348 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6349 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6350 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6352 self.pg1.add_stream(p)
6353 self.pg_enable_capture(self.pg_interfaces)
6355 self.pg0.get_capture(1)
6359 # ACK packet in -> out
6360 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6361 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6362 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6366 # ACK packet in -> out
6367 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6368 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6369 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6373 self.pg0.add_stream(pkts)
6374 self.pg_enable_capture(self.pg_interfaces)
6376 self.pg1.get_capture(2)
6378 # ACK packet out -> in
6379 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6380 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6381 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6383 self.pg1.add_stream(p)
6384 self.pg_enable_capture(self.pg_interfaces)
6386 self.pg0.get_capture(1)
6388 # Check if deterministic NAT44 closed the session
6389 dms = self.vapi.nat_det_map_dump()
6390 self.assertEqual(0, dms[0].ses_num)
6392 self.logger.error("TCP session termination failed")
6395 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6396 def test_session_timeout(self):
6397 """ Deterministic NAT session timeouts """
6398 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6400 socket.inet_aton(self.nat_addr),
6402 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6403 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6406 self.initiate_tcp_session(self.pg0, self.pg1)
6407 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6408 pkts = self.create_stream_in(self.pg0, self.pg1)
6409 self.pg0.add_stream(pkts)
6410 self.pg_enable_capture(self.pg_interfaces)
6412 capture = self.pg1.get_capture(len(pkts))
6415 dms = self.vapi.nat_det_map_dump()
6416 self.assertEqual(0, dms[0].ses_num)
6418 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6419 def test_session_limit_per_user(self):
6420 """ Deterministic NAT maximum sessions per user limit """
6421 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6423 socket.inet_aton(self.nat_addr),
6425 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6426 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6428 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6429 src_address=self.pg2.local_ip4n,
6431 template_interval=10)
6432 self.vapi.nat_ipfix()
6435 for port in range(1025, 2025):
6436 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6437 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6438 UDP(sport=port, dport=port))
6441 self.pg0.add_stream(pkts)
6442 self.pg_enable_capture(self.pg_interfaces)
6444 capture = self.pg1.get_capture(len(pkts))
6446 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6447 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6448 UDP(sport=3001, dport=3002))
6449 self.pg0.add_stream(p)
6450 self.pg_enable_capture(self.pg_interfaces)
6452 capture = self.pg1.assert_nothing_captured()
6454 # verify ICMP error packet
6455 capture = self.pg0.get_capture(1)
6457 self.assertTrue(p.haslayer(ICMP))
6459 self.assertEqual(icmp.type, 3)
6460 self.assertEqual(icmp.code, 1)
6461 self.assertTrue(icmp.haslayer(IPerror))
6462 inner_ip = icmp[IPerror]
6463 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6464 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6466 dms = self.vapi.nat_det_map_dump()
6468 self.assertEqual(1000, dms[0].ses_num)
6470 # verify IPFIX logging
6471 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6473 capture = self.pg2.get_capture(2)
6474 ipfix = IPFIXDecoder()
6475 # first load template
6477 self.assertTrue(p.haslayer(IPFIX))
6478 if p.haslayer(Template):
6479 ipfix.add_template(p.getlayer(Template))
6480 # verify events in data set
6482 if p.haslayer(Data):
6483 data = ipfix.decode_data_set(p.getlayer(Set))
6484 self.verify_ipfix_max_entries_per_user(data,
6486 self.pg0.remote_ip4n)
6488 def clear_nat_det(self):
6490 Clear deterministic NAT configuration.
6492 self.vapi.nat_ipfix(enable=0)
6493 self.vapi.nat_set_timeouts()
6494 deterministic_mappings = self.vapi.nat_det_map_dump()
6495 for dsm in deterministic_mappings:
6496 self.vapi.nat_det_add_del_map(dsm.in_addr,
6502 interfaces = self.vapi.nat44_interface_dump()
6503 for intf in interfaces:
6504 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6509 super(TestDeterministicNAT, self).tearDown()
6510 if not self.vpp_dead:
6511 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6512 self.logger.info(self.vapi.cli("show nat timeouts"))
6514 self.vapi.cli("show nat44 deterministic mappings"))
6516 self.vapi.cli("show nat44 deterministic sessions"))
6517 self.clear_nat_det()
6520 class TestNAT64(MethodHolder):
6521 """ NAT64 Test Cases """
6524 def setUpConstants(cls):
6525 super(TestNAT64, cls).setUpConstants()
6526 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6527 "nat64 st hash buckets 256", "}"])
6530 def setUpClass(cls):
6531 super(TestNAT64, cls).setUpClass()
6534 cls.tcp_port_in = 6303
6535 cls.tcp_port_out = 6303
6536 cls.udp_port_in = 6304
6537 cls.udp_port_out = 6304
6538 cls.icmp_id_in = 6305
6539 cls.icmp_id_out = 6305
6540 cls.nat_addr = '10.0.0.3'
6541 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6543 cls.vrf1_nat_addr = '10.0.10.3'
6544 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6546 cls.ipfix_src_port = 4739
6547 cls.ipfix_domain_id = 1
6549 cls.create_pg_interfaces(range(6))
6550 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6551 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6552 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6554 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6556 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6558 cls.pg0.generate_remote_hosts(2)
6560 for i in cls.ip6_interfaces:
6563 i.configure_ipv6_neighbors()
6565 for i in cls.ip4_interfaces:
6571 cls.pg3.config_ip4()
6572 cls.pg3.resolve_arp()
6573 cls.pg3.config_ip6()
6574 cls.pg3.configure_ipv6_neighbors()
6577 cls.pg5.config_ip6()
6580 super(TestNAT64, cls).tearDownClass()
6583 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6584 """ NAT64 inside interface handles Neighbor Advertisement """
6586 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6589 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6590 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6591 ICMPv6EchoRequest())
6593 self.pg5.add_stream(pkts)
6594 self.pg_enable_capture(self.pg_interfaces)
6597 # Wait for Neighbor Solicitation
6598 capture = self.pg5.get_capture(len(pkts))
6601 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6602 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6603 tgt = packet[ICMPv6ND_NS].tgt
6605 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6608 # Send Neighbor Advertisement
6609 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6610 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6611 ICMPv6ND_NA(tgt=tgt) /
6612 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6614 self.pg5.add_stream(pkts)
6615 self.pg_enable_capture(self.pg_interfaces)
6618 # Try to send ping again
6620 self.pg5.add_stream(pkts)
6621 self.pg_enable_capture(self.pg_interfaces)
6624 # Wait for ping reply
6625 capture = self.pg5.get_capture(len(pkts))
6628 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6629 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6630 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6632 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6635 def test_pool(self):
6636 """ Add/delete address to NAT64 pool """
6637 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6639 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6641 addresses = self.vapi.nat64_pool_addr_dump()
6642 self.assertEqual(len(addresses), 1)
6643 self.assertEqual(addresses[0].address, nat_addr)
6645 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6647 addresses = self.vapi.nat64_pool_addr_dump()
6648 self.assertEqual(len(addresses), 0)
6650 def test_interface(self):
6651 """ Enable/disable NAT64 feature on the interface """
6652 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6653 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6655 interfaces = self.vapi.nat64_interface_dump()
6656 self.assertEqual(len(interfaces), 2)
6659 for intf in interfaces:
6660 if intf.sw_if_index == self.pg0.sw_if_index:
6661 self.assertEqual(intf.is_inside, 1)
6663 elif intf.sw_if_index == self.pg1.sw_if_index:
6664 self.assertEqual(intf.is_inside, 0)
6666 self.assertTrue(pg0_found)
6667 self.assertTrue(pg1_found)
6669 features = self.vapi.cli("show interface features pg0")
6670 self.assertNotEqual(features.find('nat64-in2out'), -1)
6671 features = self.vapi.cli("show interface features pg1")
6672 self.assertNotEqual(features.find('nat64-out2in'), -1)
6674 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6675 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6677 interfaces = self.vapi.nat64_interface_dump()
6678 self.assertEqual(len(interfaces), 0)
6680 def test_static_bib(self):
6681 """ Add/delete static BIB entry """
6682 in_addr = socket.inet_pton(socket.AF_INET6,
6683 '2001:db8:85a3::8a2e:370:7334')
6684 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6687 proto = IP_PROTOS.tcp
6689 self.vapi.nat64_add_del_static_bib(in_addr,
6694 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6699 self.assertEqual(bibe.i_addr, in_addr)
6700 self.assertEqual(bibe.o_addr, out_addr)
6701 self.assertEqual(bibe.i_port, in_port)
6702 self.assertEqual(bibe.o_port, out_port)
6703 self.assertEqual(static_bib_num, 1)
6705 self.vapi.nat64_add_del_static_bib(in_addr,
6711 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6716 self.assertEqual(static_bib_num, 0)
6718 def test_set_timeouts(self):
6719 """ Set NAT64 timeouts """
6720 # verify default values
6721 timeouts = self.vapi.nat_get_timeouts()
6722 self.assertEqual(timeouts.udp, 300)
6723 self.assertEqual(timeouts.icmp, 60)
6724 self.assertEqual(timeouts.tcp_transitory, 240)
6725 self.assertEqual(timeouts.tcp_established, 7440)
6727 # set and verify custom values
6728 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6729 tcp_established=7450)
6730 timeouts = self.vapi.nat_get_timeouts()
6731 self.assertEqual(timeouts.udp, 200)
6732 self.assertEqual(timeouts.icmp, 30)
6733 self.assertEqual(timeouts.tcp_transitory, 250)
6734 self.assertEqual(timeouts.tcp_established, 7450)
6736 def test_dynamic(self):
6737 """ NAT64 dynamic translation test """
6738 self.tcp_port_in = 6303
6739 self.udp_port_in = 6304
6740 self.icmp_id_in = 6305
6742 ses_num_start = self.nat64_get_ses_num()
6744 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6746 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6747 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6750 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6751 self.pg0.add_stream(pkts)
6752 self.pg_enable_capture(self.pg_interfaces)
6754 capture = self.pg1.get_capture(len(pkts))
6755 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6756 dst_ip=self.pg1.remote_ip4)
6759 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6760 self.pg1.add_stream(pkts)
6761 self.pg_enable_capture(self.pg_interfaces)
6763 capture = self.pg0.get_capture(len(pkts))
6764 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6765 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6768 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6769 self.pg0.add_stream(pkts)
6770 self.pg_enable_capture(self.pg_interfaces)
6772 capture = self.pg1.get_capture(len(pkts))
6773 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6774 dst_ip=self.pg1.remote_ip4)
6777 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6778 self.pg1.add_stream(pkts)
6779 self.pg_enable_capture(self.pg_interfaces)
6781 capture = self.pg0.get_capture(len(pkts))
6782 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6784 ses_num_end = self.nat64_get_ses_num()
6786 self.assertEqual(ses_num_end - ses_num_start, 3)
6788 # tenant with specific VRF
6789 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6790 self.vrf1_nat_addr_n,
6791 vrf_id=self.vrf1_id)
6792 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6794 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6795 self.pg2.add_stream(pkts)
6796 self.pg_enable_capture(self.pg_interfaces)
6798 capture = self.pg1.get_capture(len(pkts))
6799 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6800 dst_ip=self.pg1.remote_ip4)
6802 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6803 self.pg1.add_stream(pkts)
6804 self.pg_enable_capture(self.pg_interfaces)
6806 capture = self.pg2.get_capture(len(pkts))
6807 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6809 def test_static(self):
6810 """ NAT64 static translation test """
6811 self.tcp_port_in = 60303
6812 self.udp_port_in = 60304
6813 self.icmp_id_in = 60305
6814 self.tcp_port_out = 60303
6815 self.udp_port_out = 60304
6816 self.icmp_id_out = 60305
6818 ses_num_start = self.nat64_get_ses_num()
6820 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6822 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6823 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6825 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6830 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6835 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6842 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6843 self.pg0.add_stream(pkts)
6844 self.pg_enable_capture(self.pg_interfaces)
6846 capture = self.pg1.get_capture(len(pkts))
6847 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6848 dst_ip=self.pg1.remote_ip4, same_port=True)
6851 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6852 self.pg1.add_stream(pkts)
6853 self.pg_enable_capture(self.pg_interfaces)
6855 capture = self.pg0.get_capture(len(pkts))
6856 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6857 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6859 ses_num_end = self.nat64_get_ses_num()
6861 self.assertEqual(ses_num_end - ses_num_start, 3)
6863 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6864 def test_session_timeout(self):
6865 """ NAT64 session timeout """
6866 self.icmp_id_in = 1234
6867 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6869 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6870 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6871 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6873 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6874 self.pg0.add_stream(pkts)
6875 self.pg_enable_capture(self.pg_interfaces)
6877 capture = self.pg1.get_capture(len(pkts))
6879 ses_num_before_timeout = self.nat64_get_ses_num()
6883 # ICMP and TCP session after timeout
6884 ses_num_after_timeout = self.nat64_get_ses_num()
6885 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6887 def test_icmp_error(self):
6888 """ NAT64 ICMP Error message translation """
6889 self.tcp_port_in = 6303
6890 self.udp_port_in = 6304
6891 self.icmp_id_in = 6305
6893 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6895 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6896 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6898 # send some packets to create sessions
6899 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6900 self.pg0.add_stream(pkts)
6901 self.pg_enable_capture(self.pg_interfaces)
6903 capture_ip4 = self.pg1.get_capture(len(pkts))
6904 self.verify_capture_out(capture_ip4,
6905 nat_ip=self.nat_addr,
6906 dst_ip=self.pg1.remote_ip4)
6908 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6909 self.pg1.add_stream(pkts)
6910 self.pg_enable_capture(self.pg_interfaces)
6912 capture_ip6 = self.pg0.get_capture(len(pkts))
6913 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6914 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6915 self.pg0.remote_ip6)
6918 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6919 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6920 ICMPv6DestUnreach(code=1) /
6921 packet[IPv6] for packet in capture_ip6]
6922 self.pg0.add_stream(pkts)
6923 self.pg_enable_capture(self.pg_interfaces)
6925 capture = self.pg1.get_capture(len(pkts))
6926 for packet in capture:
6928 self.assertEqual(packet[IP].src, self.nat_addr)
6929 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6930 self.assertEqual(packet[ICMP].type, 3)
6931 self.assertEqual(packet[ICMP].code, 13)
6932 inner = packet[IPerror]
6933 self.assertEqual(inner.src, self.pg1.remote_ip4)
6934 self.assertEqual(inner.dst, self.nat_addr)
6935 self.assert_packet_checksums_valid(packet)
6936 if inner.haslayer(TCPerror):
6937 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6938 elif inner.haslayer(UDPerror):
6939 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6941 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6943 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6947 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6948 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6949 ICMP(type=3, code=13) /
6950 packet[IP] for packet in capture_ip4]
6951 self.pg1.add_stream(pkts)
6952 self.pg_enable_capture(self.pg_interfaces)
6954 capture = self.pg0.get_capture(len(pkts))
6955 for packet in capture:
6957 self.assertEqual(packet[IPv6].src, ip.src)
6958 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6959 icmp = packet[ICMPv6DestUnreach]
6960 self.assertEqual(icmp.code, 1)
6961 inner = icmp[IPerror6]
6962 self.assertEqual(inner.src, self.pg0.remote_ip6)
6963 self.assertEqual(inner.dst, ip.src)
6964 self.assert_icmpv6_checksum_valid(packet)
6965 if inner.haslayer(TCPerror):
6966 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6967 elif inner.haslayer(UDPerror):
6968 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6970 self.assertEqual(inner[ICMPv6EchoRequest].id,
6973 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6976 def test_hairpinning(self):
6977 """ NAT64 hairpinning """
6979 client = self.pg0.remote_hosts[0]
6980 server = self.pg0.remote_hosts[1]
6981 server_tcp_in_port = 22
6982 server_tcp_out_port = 4022
6983 server_udp_in_port = 23
6984 server_udp_out_port = 4023
6985 client_tcp_in_port = 1234
6986 client_udp_in_port = 1235
6987 client_tcp_out_port = 0
6988 client_udp_out_port = 0
6989 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6990 nat_addr_ip6 = ip.src
6992 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6994 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6995 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6997 self.vapi.nat64_add_del_static_bib(server.ip6n,
7000 server_tcp_out_port,
7002 self.vapi.nat64_add_del_static_bib(server.ip6n,
7005 server_udp_out_port,
7010 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7011 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7012 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7014 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7015 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7016 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7018 self.pg0.add_stream(pkts)
7019 self.pg_enable_capture(self.pg_interfaces)
7021 capture = self.pg0.get_capture(len(pkts))
7022 for packet in capture:
7024 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7025 self.assertEqual(packet[IPv6].dst, server.ip6)
7026 self.assert_packet_checksums_valid(packet)
7027 if packet.haslayer(TCP):
7028 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7029 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7030 client_tcp_out_port = packet[TCP].sport
7032 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7033 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7034 client_udp_out_port = packet[UDP].sport
7036 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7041 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7042 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7043 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7045 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7046 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7047 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7049 self.pg0.add_stream(pkts)
7050 self.pg_enable_capture(self.pg_interfaces)
7052 capture = self.pg0.get_capture(len(pkts))
7053 for packet in capture:
7055 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7056 self.assertEqual(packet[IPv6].dst, client.ip6)
7057 self.assert_packet_checksums_valid(packet)
7058 if packet.haslayer(TCP):
7059 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7060 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7062 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7063 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7065 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7070 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7071 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7072 ICMPv6DestUnreach(code=1) /
7073 packet[IPv6] for packet in capture]
7074 self.pg0.add_stream(pkts)
7075 self.pg_enable_capture(self.pg_interfaces)
7077 capture = self.pg0.get_capture(len(pkts))
7078 for packet in capture:
7080 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7081 self.assertEqual(packet[IPv6].dst, server.ip6)
7082 icmp = packet[ICMPv6DestUnreach]
7083 self.assertEqual(icmp.code, 1)
7084 inner = icmp[IPerror6]
7085 self.assertEqual(inner.src, server.ip6)
7086 self.assertEqual(inner.dst, nat_addr_ip6)
7087 self.assert_packet_checksums_valid(packet)
7088 if inner.haslayer(TCPerror):
7089 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7090 self.assertEqual(inner[TCPerror].dport,
7091 client_tcp_out_port)
7093 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7094 self.assertEqual(inner[UDPerror].dport,
7095 client_udp_out_port)
7097 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7100 def test_prefix(self):
7101 """ NAT64 Network-Specific Prefix """
7103 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7105 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7106 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7107 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7108 self.vrf1_nat_addr_n,
7109 vrf_id=self.vrf1_id)
7110 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7113 global_pref64 = "2001:db8::"
7114 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7115 global_pref64_len = 32
7116 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7118 prefix = self.vapi.nat64_prefix_dump()
7119 self.assertEqual(len(prefix), 1)
7120 self.assertEqual(prefix[0].prefix, global_pref64_n)
7121 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7122 self.assertEqual(prefix[0].vrf_id, 0)
7124 # Add tenant specific prefix
7125 vrf1_pref64 = "2001:db8:122:300::"
7126 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7127 vrf1_pref64_len = 56
7128 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7130 vrf_id=self.vrf1_id)
7131 prefix = self.vapi.nat64_prefix_dump()
7132 self.assertEqual(len(prefix), 2)
7135 pkts = self.create_stream_in_ip6(self.pg0,
7138 plen=global_pref64_len)
7139 self.pg0.add_stream(pkts)
7140 self.pg_enable_capture(self.pg_interfaces)
7142 capture = self.pg1.get_capture(len(pkts))
7143 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7144 dst_ip=self.pg1.remote_ip4)
7146 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7147 self.pg1.add_stream(pkts)
7148 self.pg_enable_capture(self.pg_interfaces)
7150 capture = self.pg0.get_capture(len(pkts))
7151 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7154 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7156 # Tenant specific prefix
7157 pkts = self.create_stream_in_ip6(self.pg2,
7160 plen=vrf1_pref64_len)
7161 self.pg2.add_stream(pkts)
7162 self.pg_enable_capture(self.pg_interfaces)
7164 capture = self.pg1.get_capture(len(pkts))
7165 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7166 dst_ip=self.pg1.remote_ip4)
7168 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7169 self.pg1.add_stream(pkts)
7170 self.pg_enable_capture(self.pg_interfaces)
7172 capture = self.pg2.get_capture(len(pkts))
7173 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7176 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7178 def test_unknown_proto(self):
7179 """ NAT64 translate packet with unknown protocol """
7181 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7183 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7184 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7185 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7188 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7189 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7190 TCP(sport=self.tcp_port_in, dport=20))
7191 self.pg0.add_stream(p)
7192 self.pg_enable_capture(self.pg_interfaces)
7194 p = self.pg1.get_capture(1)
7196 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7197 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7199 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7200 TCP(sport=1234, dport=1234))
7201 self.pg0.add_stream(p)
7202 self.pg_enable_capture(self.pg_interfaces)
7204 p = self.pg1.get_capture(1)
7207 self.assertEqual(packet[IP].src, self.nat_addr)
7208 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7209 self.assertTrue(packet.haslayer(GRE))
7210 self.assert_packet_checksums_valid(packet)
7212 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7216 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7217 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7219 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7220 TCP(sport=1234, dport=1234))
7221 self.pg1.add_stream(p)
7222 self.pg_enable_capture(self.pg_interfaces)
7224 p = self.pg0.get_capture(1)
7227 self.assertEqual(packet[IPv6].src, remote_ip6)
7228 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7229 self.assertEqual(packet[IPv6].nh, 47)
7231 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7234 def test_hairpinning_unknown_proto(self):
7235 """ NAT64 translate packet with unknown protocol - hairpinning """
7237 client = self.pg0.remote_hosts[0]
7238 server = self.pg0.remote_hosts[1]
7239 server_tcp_in_port = 22
7240 server_tcp_out_port = 4022
7241 client_tcp_in_port = 1234
7242 client_tcp_out_port = 1235
7243 server_nat_ip = "10.0.0.100"
7244 client_nat_ip = "10.0.0.110"
7245 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7246 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7247 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7248 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7250 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7252 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7253 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7255 self.vapi.nat64_add_del_static_bib(server.ip6n,
7258 server_tcp_out_port,
7261 self.vapi.nat64_add_del_static_bib(server.ip6n,
7267 self.vapi.nat64_add_del_static_bib(client.ip6n,
7270 client_tcp_out_port,
7274 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7275 IPv6(src=client.ip6, dst=server_nat_ip6) /
7276 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7277 self.pg0.add_stream(p)
7278 self.pg_enable_capture(self.pg_interfaces)
7280 p = self.pg0.get_capture(1)
7282 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7283 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7285 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7286 TCP(sport=1234, dport=1234))
7287 self.pg0.add_stream(p)
7288 self.pg_enable_capture(self.pg_interfaces)
7290 p = self.pg0.get_capture(1)
7293 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7294 self.assertEqual(packet[IPv6].dst, server.ip6)
7295 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7297 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7301 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7302 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7304 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7305 TCP(sport=1234, dport=1234))
7306 self.pg0.add_stream(p)
7307 self.pg_enable_capture(self.pg_interfaces)
7309 p = self.pg0.get_capture(1)
7312 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7313 self.assertEqual(packet[IPv6].dst, client.ip6)
7314 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7316 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7319 def test_one_armed_nat64(self):
7320 """ One armed NAT64 """
7322 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7326 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7328 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7329 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7332 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7333 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7334 TCP(sport=12345, dport=80))
7335 self.pg3.add_stream(p)
7336 self.pg_enable_capture(self.pg_interfaces)
7338 capture = self.pg3.get_capture(1)
7343 self.assertEqual(ip.src, self.nat_addr)
7344 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7345 self.assertNotEqual(tcp.sport, 12345)
7346 external_port = tcp.sport
7347 self.assertEqual(tcp.dport, 80)
7348 self.assert_packet_checksums_valid(p)
7350 self.logger.error(ppp("Unexpected or invalid packet:", p))
7354 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7355 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7356 TCP(sport=80, dport=external_port))
7357 self.pg3.add_stream(p)
7358 self.pg_enable_capture(self.pg_interfaces)
7360 capture = self.pg3.get_capture(1)
7365 self.assertEqual(ip.src, remote_host_ip6)
7366 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7367 self.assertEqual(tcp.sport, 80)
7368 self.assertEqual(tcp.dport, 12345)
7369 self.assert_packet_checksums_valid(p)
7371 self.logger.error(ppp("Unexpected or invalid packet:", p))
7374 def test_frag_in_order(self):
7375 """ NAT64 translate fragments arriving in order """
7376 self.tcp_port_in = random.randint(1025, 65535)
7378 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7380 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7381 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7383 reass = self.vapi.nat_reass_dump()
7384 reass_n_start = len(reass)
7388 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7389 self.tcp_port_in, 20, data)
7390 self.pg0.add_stream(pkts)
7391 self.pg_enable_capture(self.pg_interfaces)
7393 frags = self.pg1.get_capture(len(pkts))
7394 p = self.reass_frags_and_verify(frags,
7396 self.pg1.remote_ip4)
7397 self.assertEqual(p[TCP].dport, 20)
7398 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7399 self.tcp_port_out = p[TCP].sport
7400 self.assertEqual(data, p[Raw].load)
7403 data = "A" * 4 + "b" * 16 + "C" * 3
7404 pkts = self.create_stream_frag(self.pg1,
7409 self.pg1.add_stream(pkts)
7410 self.pg_enable_capture(self.pg_interfaces)
7412 frags = self.pg0.get_capture(len(pkts))
7413 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7414 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7415 self.assertEqual(p[TCP].sport, 20)
7416 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7417 self.assertEqual(data, p[Raw].load)
7419 reass = self.vapi.nat_reass_dump()
7420 reass_n_end = len(reass)
7422 self.assertEqual(reass_n_end - reass_n_start, 2)
7424 def test_reass_hairpinning(self):
7425 """ NAT64 fragments hairpinning """
7427 server = self.pg0.remote_hosts[1]
7428 server_in_port = random.randint(1025, 65535)
7429 server_out_port = random.randint(1025, 65535)
7430 client_in_port = random.randint(1025, 65535)
7431 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7432 nat_addr_ip6 = ip.src
7434 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7436 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7437 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7439 # add static BIB entry for server
7440 self.vapi.nat64_add_del_static_bib(server.ip6n,
7446 # send packet from host to server
7447 pkts = self.create_stream_frag_ip6(self.pg0,
7452 self.pg0.add_stream(pkts)
7453 self.pg_enable_capture(self.pg_interfaces)
7455 frags = self.pg0.get_capture(len(pkts))
7456 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7457 self.assertNotEqual(p[TCP].sport, client_in_port)
7458 self.assertEqual(p[TCP].dport, server_in_port)
7459 self.assertEqual(data, p[Raw].load)
7461 def test_frag_out_of_order(self):
7462 """ NAT64 translate fragments arriving out of order """
7463 self.tcp_port_in = random.randint(1025, 65535)
7465 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7467 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7468 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7472 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7473 self.tcp_port_in, 20, data)
7475 self.pg0.add_stream(pkts)
7476 self.pg_enable_capture(self.pg_interfaces)
7478 frags = self.pg1.get_capture(len(pkts))
7479 p = self.reass_frags_and_verify(frags,
7481 self.pg1.remote_ip4)
7482 self.assertEqual(p[TCP].dport, 20)
7483 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7484 self.tcp_port_out = p[TCP].sport
7485 self.assertEqual(data, p[Raw].load)
7488 data = "A" * 4 + "B" * 16 + "C" * 3
7489 pkts = self.create_stream_frag(self.pg1,
7495 self.pg1.add_stream(pkts)
7496 self.pg_enable_capture(self.pg_interfaces)
7498 frags = self.pg0.get_capture(len(pkts))
7499 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7500 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7501 self.assertEqual(p[TCP].sport, 20)
7502 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7503 self.assertEqual(data, p[Raw].load)
7505 def test_interface_addr(self):
7506 """ Acquire NAT64 pool addresses from interface """
7507 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7509 # no address in NAT64 pool
7510 adresses = self.vapi.nat44_address_dump()
7511 self.assertEqual(0, len(adresses))
7513 # configure interface address and check NAT64 address pool
7514 self.pg4.config_ip4()
7515 addresses = self.vapi.nat64_pool_addr_dump()
7516 self.assertEqual(len(addresses), 1)
7517 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7519 # remove interface address and check NAT64 address pool
7520 self.pg4.unconfig_ip4()
7521 addresses = self.vapi.nat64_pool_addr_dump()
7522 self.assertEqual(0, len(adresses))
7524 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7525 def test_ipfix_max_bibs_sessions(self):
7526 """ IPFIX logging maximum session and BIB entries exceeded """
7529 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7533 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7535 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7536 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7540 for i in range(0, max_bibs):
7541 src = "fd01:aa::%x" % (i)
7542 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7543 IPv6(src=src, dst=remote_host_ip6) /
7544 TCP(sport=12345, dport=80))
7546 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7547 IPv6(src=src, dst=remote_host_ip6) /
7548 TCP(sport=12345, dport=22))
7550 self.pg0.add_stream(pkts)
7551 self.pg_enable_capture(self.pg_interfaces)
7553 self.pg1.get_capture(max_sessions)
7555 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7556 src_address=self.pg3.local_ip4n,
7558 template_interval=10)
7559 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7560 src_port=self.ipfix_src_port)
7562 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7563 IPv6(src=src, dst=remote_host_ip6) /
7564 TCP(sport=12345, dport=25))
7565 self.pg0.add_stream(p)
7566 self.pg_enable_capture(self.pg_interfaces)
7568 self.pg1.assert_nothing_captured()
7570 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7571 capture = self.pg3.get_capture(9)
7572 ipfix = IPFIXDecoder()
7573 # first load template
7575 self.assertTrue(p.haslayer(IPFIX))
7576 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7577 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7578 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7579 self.assertEqual(p[UDP].dport, 4739)
7580 self.assertEqual(p[IPFIX].observationDomainID,
7581 self.ipfix_domain_id)
7582 if p.haslayer(Template):
7583 ipfix.add_template(p.getlayer(Template))
7584 # verify events in data set
7586 if p.haslayer(Data):
7587 data = ipfix.decode_data_set(p.getlayer(Set))
7588 self.verify_ipfix_max_sessions(data, max_sessions)
7590 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7591 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7592 TCP(sport=12345, dport=80))
7593 self.pg0.add_stream(p)
7594 self.pg_enable_capture(self.pg_interfaces)
7596 self.pg1.assert_nothing_captured()
7598 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7599 capture = self.pg3.get_capture(1)
7600 # verify events in data set
7602 self.assertTrue(p.haslayer(IPFIX))
7603 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7604 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7605 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7606 self.assertEqual(p[UDP].dport, 4739)
7607 self.assertEqual(p[IPFIX].observationDomainID,
7608 self.ipfix_domain_id)
7609 if p.haslayer(Data):
7610 data = ipfix.decode_data_set(p.getlayer(Set))
7611 self.verify_ipfix_max_bibs(data, max_bibs)
7613 def test_ipfix_max_frags(self):
7614 """ IPFIX logging maximum fragments pending reassembly exceeded """
7615 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7617 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7618 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7619 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7620 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7621 src_address=self.pg3.local_ip4n,
7623 template_interval=10)
7624 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7625 src_port=self.ipfix_src_port)
7628 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7629 self.tcp_port_in, 20, data)
7631 self.pg0.add_stream(pkts)
7632 self.pg_enable_capture(self.pg_interfaces)
7634 self.pg1.assert_nothing_captured()
7636 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7637 capture = self.pg3.get_capture(9)
7638 ipfix = IPFIXDecoder()
7639 # first load template
7641 self.assertTrue(p.haslayer(IPFIX))
7642 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7643 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7644 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7645 self.assertEqual(p[UDP].dport, 4739)
7646 self.assertEqual(p[IPFIX].observationDomainID,
7647 self.ipfix_domain_id)
7648 if p.haslayer(Template):
7649 ipfix.add_template(p.getlayer(Template))
7650 # verify events in data set
7652 if p.haslayer(Data):
7653 data = ipfix.decode_data_set(p.getlayer(Set))
7654 self.verify_ipfix_max_fragments_ip6(data, 1,
7655 self.pg0.remote_ip6n)
7657 def test_ipfix_bib_ses(self):
7658 """ IPFIX logging NAT64 BIB/session create and delete events """
7659 self.tcp_port_in = random.randint(1025, 65535)
7660 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7664 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7666 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7667 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7668 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7669 src_address=self.pg3.local_ip4n,
7671 template_interval=10)
7672 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7673 src_port=self.ipfix_src_port)
7676 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7677 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7678 TCP(sport=self.tcp_port_in, dport=25))
7679 self.pg0.add_stream(p)
7680 self.pg_enable_capture(self.pg_interfaces)
7682 p = self.pg1.get_capture(1)
7683 self.tcp_port_out = p[0][TCP].sport
7684 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7685 capture = self.pg3.get_capture(10)
7686 ipfix = IPFIXDecoder()
7687 # first load template
7689 self.assertTrue(p.haslayer(IPFIX))
7690 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7691 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7692 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7693 self.assertEqual(p[UDP].dport, 4739)
7694 self.assertEqual(p[IPFIX].observationDomainID,
7695 self.ipfix_domain_id)
7696 if p.haslayer(Template):
7697 ipfix.add_template(p.getlayer(Template))
7698 # verify events in data set
7700 if p.haslayer(Data):
7701 data = ipfix.decode_data_set(p.getlayer(Set))
7702 if ord(data[0][230]) == 10:
7703 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7704 elif ord(data[0][230]) == 6:
7705 self.verify_ipfix_nat64_ses(data,
7707 self.pg0.remote_ip6n,
7708 self.pg1.remote_ip4,
7711 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7714 self.pg_enable_capture(self.pg_interfaces)
7715 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7718 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7719 capture = self.pg3.get_capture(2)
7720 # verify events in data set
7722 self.assertTrue(p.haslayer(IPFIX))
7723 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7724 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7725 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7726 self.assertEqual(p[UDP].dport, 4739)
7727 self.assertEqual(p[IPFIX].observationDomainID,
7728 self.ipfix_domain_id)
7729 if p.haslayer(Data):
7730 data = ipfix.decode_data_set(p.getlayer(Set))
7731 if ord(data[0][230]) == 11:
7732 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7733 elif ord(data[0][230]) == 7:
7734 self.verify_ipfix_nat64_ses(data,
7736 self.pg0.remote_ip6n,
7737 self.pg1.remote_ip4,
7740 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7742 def nat64_get_ses_num(self):
7744 Return number of active NAT64 sessions.
7746 st = self.vapi.nat64_st_dump()
7749 def clear_nat64(self):
7751 Clear NAT64 configuration.
7753 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7754 domain_id=self.ipfix_domain_id)
7755 self.ipfix_src_port = 4739
7756 self.ipfix_domain_id = 1
7758 self.vapi.nat_set_timeouts()
7760 interfaces = self.vapi.nat64_interface_dump()
7761 for intf in interfaces:
7762 if intf.is_inside > 1:
7763 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7766 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7770 bib = self.vapi.nat64_bib_dump(255)
7773 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7781 adresses = self.vapi.nat64_pool_addr_dump()
7782 for addr in adresses:
7783 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7788 prefixes = self.vapi.nat64_prefix_dump()
7789 for prefix in prefixes:
7790 self.vapi.nat64_add_del_prefix(prefix.prefix,
7792 vrf_id=prefix.vrf_id,
7796 super(TestNAT64, self).tearDown()
7797 if not self.vpp_dead:
7798 self.logger.info(self.vapi.cli("show nat64 pool"))
7799 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7800 self.logger.info(self.vapi.cli("show nat64 prefix"))
7801 self.logger.info(self.vapi.cli("show nat64 bib all"))
7802 self.logger.info(self.vapi.cli("show nat64 session table all"))
7803 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7807 class TestDSlite(MethodHolder):
7808 """ DS-Lite Test Cases """
7811 def setUpClass(cls):
7812 super(TestDSlite, cls).setUpClass()
7815 cls.nat_addr = '10.0.0.3'
7816 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7818 cls.create_pg_interfaces(range(2))
7820 cls.pg0.config_ip4()
7821 cls.pg0.resolve_arp()
7823 cls.pg1.config_ip6()
7824 cls.pg1.generate_remote_hosts(2)
7825 cls.pg1.configure_ipv6_neighbors()
7828 super(TestDSlite, cls).tearDownClass()
7831 def test_dslite(self):
7832 """ Test DS-Lite """
7833 nat_config = self.vapi.nat_show_config()
7834 self.assertEqual(0, nat_config.dslite_ce)
7836 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7838 aftr_ip4 = '192.0.0.1'
7839 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7840 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7841 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7842 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7845 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7846 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7847 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7848 UDP(sport=20000, dport=10000))
7849 self.pg1.add_stream(p)
7850 self.pg_enable_capture(self.pg_interfaces)
7852 capture = self.pg0.get_capture(1)
7853 capture = capture[0]
7854 self.assertFalse(capture.haslayer(IPv6))
7855 self.assertEqual(capture[IP].src, self.nat_addr)
7856 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7857 self.assertNotEqual(capture[UDP].sport, 20000)
7858 self.assertEqual(capture[UDP].dport, 10000)
7859 self.assert_packet_checksums_valid(capture)
7860 out_port = capture[UDP].sport
7862 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7863 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7864 UDP(sport=10000, dport=out_port))
7865 self.pg0.add_stream(p)
7866 self.pg_enable_capture(self.pg_interfaces)
7868 capture = self.pg1.get_capture(1)
7869 capture = capture[0]
7870 self.assertEqual(capture[IPv6].src, aftr_ip6)
7871 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7872 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7873 self.assertEqual(capture[IP].dst, '192.168.1.1')
7874 self.assertEqual(capture[UDP].sport, 10000)
7875 self.assertEqual(capture[UDP].dport, 20000)
7876 self.assert_packet_checksums_valid(capture)
7879 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7880 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7881 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7882 TCP(sport=20001, dport=10001))
7883 self.pg1.add_stream(p)
7884 self.pg_enable_capture(self.pg_interfaces)
7886 capture = self.pg0.get_capture(1)
7887 capture = capture[0]
7888 self.assertFalse(capture.haslayer(IPv6))
7889 self.assertEqual(capture[IP].src, self.nat_addr)
7890 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7891 self.assertNotEqual(capture[TCP].sport, 20001)
7892 self.assertEqual(capture[TCP].dport, 10001)
7893 self.assert_packet_checksums_valid(capture)
7894 out_port = capture[TCP].sport
7896 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7897 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7898 TCP(sport=10001, dport=out_port))
7899 self.pg0.add_stream(p)
7900 self.pg_enable_capture(self.pg_interfaces)
7902 capture = self.pg1.get_capture(1)
7903 capture = capture[0]
7904 self.assertEqual(capture[IPv6].src, aftr_ip6)
7905 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7906 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7907 self.assertEqual(capture[IP].dst, '192.168.1.1')
7908 self.assertEqual(capture[TCP].sport, 10001)
7909 self.assertEqual(capture[TCP].dport, 20001)
7910 self.assert_packet_checksums_valid(capture)
7913 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7914 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7915 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7916 ICMP(id=4000, type='echo-request'))
7917 self.pg1.add_stream(p)
7918 self.pg_enable_capture(self.pg_interfaces)
7920 capture = self.pg0.get_capture(1)
7921 capture = capture[0]
7922 self.assertFalse(capture.haslayer(IPv6))
7923 self.assertEqual(capture[IP].src, self.nat_addr)
7924 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7925 self.assertNotEqual(capture[ICMP].id, 4000)
7926 self.assert_packet_checksums_valid(capture)
7927 out_id = capture[ICMP].id
7929 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7930 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7931 ICMP(id=out_id, type='echo-reply'))
7932 self.pg0.add_stream(p)
7933 self.pg_enable_capture(self.pg_interfaces)
7935 capture = self.pg1.get_capture(1)
7936 capture = capture[0]
7937 self.assertEqual(capture[IPv6].src, aftr_ip6)
7938 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7939 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7940 self.assertEqual(capture[IP].dst, '192.168.1.1')
7941 self.assertEqual(capture[ICMP].id, 4000)
7942 self.assert_packet_checksums_valid(capture)
7944 # ping DS-Lite AFTR tunnel endpoint address
7945 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7946 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7947 ICMPv6EchoRequest())
7948 self.pg1.add_stream(p)
7949 self.pg_enable_capture(self.pg_interfaces)
7951 capture = self.pg1.get_capture(1)
7952 capture = capture[0]
7953 self.assertEqual(capture[IPv6].src, aftr_ip6)
7954 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7955 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7958 super(TestDSlite, self).tearDown()
7959 if not self.vpp_dead:
7960 self.logger.info(self.vapi.cli("show dslite pool"))
7962 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7963 self.logger.info(self.vapi.cli("show dslite sessions"))
7966 class TestDSliteCE(MethodHolder):
7967 """ DS-Lite CE Test Cases """
7970 def setUpConstants(cls):
7971 super(TestDSliteCE, cls).setUpConstants()
7972 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7975 def setUpClass(cls):
7976 super(TestDSliteCE, cls).setUpClass()
7979 cls.create_pg_interfaces(range(2))
7981 cls.pg0.config_ip4()
7982 cls.pg0.resolve_arp()
7984 cls.pg1.config_ip6()
7985 cls.pg1.generate_remote_hosts(1)
7986 cls.pg1.configure_ipv6_neighbors()
7989 super(TestDSliteCE, cls).tearDownClass()
7992 def test_dslite_ce(self):
7993 """ Test DS-Lite CE """
7995 nat_config = self.vapi.nat_show_config()
7996 self.assertEqual(1, nat_config.dslite_ce)
7998 b4_ip4 = '192.0.0.2'
7999 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8000 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8001 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8002 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8004 aftr_ip4 = '192.0.0.1'
8005 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8006 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8007 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8008 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8010 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8011 dst_address_length=128,
8012 next_hop_address=self.pg1.remote_ip6n,
8013 next_hop_sw_if_index=self.pg1.sw_if_index,
8017 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8018 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8019 UDP(sport=10000, dport=20000))
8020 self.pg0.add_stream(p)
8021 self.pg_enable_capture(self.pg_interfaces)
8023 capture = self.pg1.get_capture(1)
8024 capture = capture[0]
8025 self.assertEqual(capture[IPv6].src, b4_ip6)
8026 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8027 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8028 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8029 self.assertEqual(capture[UDP].sport, 10000)
8030 self.assertEqual(capture[UDP].dport, 20000)
8031 self.assert_packet_checksums_valid(capture)
8034 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8035 IPv6(dst=b4_ip6, src=aftr_ip6) /
8036 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8037 UDP(sport=20000, dport=10000))
8038 self.pg1.add_stream(p)
8039 self.pg_enable_capture(self.pg_interfaces)
8041 capture = self.pg0.get_capture(1)
8042 capture = capture[0]
8043 self.assertFalse(capture.haslayer(IPv6))
8044 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8045 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8046 self.assertEqual(capture[UDP].sport, 20000)
8047 self.assertEqual(capture[UDP].dport, 10000)
8048 self.assert_packet_checksums_valid(capture)
8050 # ping DS-Lite B4 tunnel endpoint address
8051 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8052 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8053 ICMPv6EchoRequest())
8054 self.pg1.add_stream(p)
8055 self.pg_enable_capture(self.pg_interfaces)
8057 capture = self.pg1.get_capture(1)
8058 capture = capture[0]
8059 self.assertEqual(capture[IPv6].src, b4_ip6)
8060 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8061 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8064 super(TestDSliteCE, self).tearDown()
8065 if not self.vpp_dead:
8067 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8069 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8072 class TestNAT66(MethodHolder):
8073 """ NAT66 Test Cases """
8076 def setUpClass(cls):
8077 super(TestNAT66, cls).setUpClass()
8080 cls.nat_addr = 'fd01:ff::2'
8081 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8083 cls.create_pg_interfaces(range(2))
8084 cls.interfaces = list(cls.pg_interfaces)
8086 for i in cls.interfaces:
8089 i.configure_ipv6_neighbors()
8092 super(TestNAT66, cls).tearDownClass()
8095 def test_static(self):
8096 """ 1:1 NAT66 test """
8097 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8098 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8099 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8104 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8105 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8108 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8109 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8112 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8113 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8114 ICMPv6EchoRequest())
8116 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8117 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8118 GRE() / IP() / TCP())
8120 self.pg0.add_stream(pkts)
8121 self.pg_enable_capture(self.pg_interfaces)
8123 capture = self.pg1.get_capture(len(pkts))
8124 for packet in capture:
8126 self.assertEqual(packet[IPv6].src, self.nat_addr)
8127 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8128 self.assert_packet_checksums_valid(packet)
8130 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8135 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8136 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8139 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8140 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8143 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8144 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8147 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8148 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8149 GRE() / IP() / TCP())
8151 self.pg1.add_stream(pkts)
8152 self.pg_enable_capture(self.pg_interfaces)
8154 capture = self.pg0.get_capture(len(pkts))
8155 for packet in capture:
8157 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8158 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8159 self.assert_packet_checksums_valid(packet)
8161 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8164 sm = self.vapi.nat66_static_mapping_dump()
8165 self.assertEqual(len(sm), 1)
8166 self.assertEqual(sm[0].total_pkts, 8)
8168 def test_check_no_translate(self):
8169 """ NAT66 translate only when egress interface is outside interface """
8170 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8171 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8172 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8176 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8177 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8179 self.pg0.add_stream([p])
8180 self.pg_enable_capture(self.pg_interfaces)
8182 capture = self.pg1.get_capture(1)
8185 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8186 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8188 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8191 def clear_nat66(self):
8193 Clear NAT66 configuration.
8195 interfaces = self.vapi.nat66_interface_dump()
8196 for intf in interfaces:
8197 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8201 static_mappings = self.vapi.nat66_static_mapping_dump()
8202 for sm in static_mappings:
8203 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8204 sm.external_ip_address,
8209 super(TestNAT66, self).tearDown()
8210 if not self.vpp_dead:
8211 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8212 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8216 if __name__ == '__main__':
8217 unittest.main(testRunner=VppTestRunner)