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.assertGreaterEqual(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.assertGreaterEqual(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.assertGreaterEqual(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.assertGreater(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.11.%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 self.initiate_tcp_session(self.pg0, self.pg1)
5687 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5688 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5689 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5691 self.pg0.add_stream(p)
5692 self.pg_enable_capture(self.pg_interfaces)
5694 self.pg1.get_capture(1)
5698 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5699 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5700 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5702 self.pg0.add_stream(p)
5703 self.pg_enable_capture(self.pg_interfaces)
5705 self.pg1.get_capture(1)
5708 users = self.vapi.nat44_user_dump()
5709 self.assertEqual(len(users), 1)
5710 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5711 self.assertEqual(users[0].nsessions, 1)
5713 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5714 def test_session_limit_per_user(self):
5715 """ Maximum sessions per user limit """
5716 self.nat44_add_address(self.nat_addr)
5717 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5718 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5720 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5721 src_address=self.pg2.local_ip4n,
5723 template_interval=10)
5724 self.vapi.nat_set_timeouts(udp=5)
5726 # get maximum number of translations per user
5727 nat44_config = self.vapi.nat_show_config()
5730 for port in range(0, nat44_config.max_translations_per_user):
5731 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5732 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5733 UDP(sport=1025 + port, dport=1025 + port))
5736 self.pg0.add_stream(pkts)
5737 self.pg_enable_capture(self.pg_interfaces)
5739 capture = self.pg1.get_capture(len(pkts))
5741 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5742 src_port=self.ipfix_src_port)
5744 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5745 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5746 UDP(sport=3001, dport=3002))
5747 self.pg0.add_stream(p)
5748 self.pg_enable_capture(self.pg_interfaces)
5750 capture = self.pg1.assert_nothing_captured()
5752 # verify IPFIX logging
5753 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5755 capture = self.pg2.get_capture(10)
5756 ipfix = IPFIXDecoder()
5757 # first load template
5759 self.assertTrue(p.haslayer(IPFIX))
5760 if p.haslayer(Template):
5761 ipfix.add_template(p.getlayer(Template))
5762 # verify events in data set
5764 if p.haslayer(Data):
5765 data = ipfix.decode_data_set(p.getlayer(Set))
5766 self.verify_ipfix_max_entries_per_user(
5768 nat44_config.max_translations_per_user,
5769 self.pg0.remote_ip4n)
5772 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5773 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5774 UDP(sport=3001, dport=3002))
5775 self.pg0.add_stream(p)
5776 self.pg_enable_capture(self.pg_interfaces)
5778 self.pg1.get_capture(1)
5781 super(TestNAT44EndpointDependent, self).tearDown()
5782 if not self.vpp_dead:
5783 self.logger.info(self.vapi.cli("show nat44 addresses"))
5784 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5785 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5786 self.logger.info(self.vapi.cli("show nat44 interface address"))
5787 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5788 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5789 self.logger.info(self.vapi.cli("show nat timeouts"))
5791 self.vapi.cli("clear logging")
5794 class TestNAT44Out2InDPO(MethodHolder):
5795 """ NAT44 Test Cases using out2in DPO """
5798 def setUpConstants(cls):
5799 super(TestNAT44Out2InDPO, cls).setUpConstants()
5800 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5803 def setUpClass(cls):
5804 super(TestNAT44Out2InDPO, cls).setUpClass()
5805 cls.vapi.cli("set log class nat level debug")
5808 cls.tcp_port_in = 6303
5809 cls.tcp_port_out = 6303
5810 cls.udp_port_in = 6304
5811 cls.udp_port_out = 6304
5812 cls.icmp_id_in = 6305
5813 cls.icmp_id_out = 6305
5814 cls.nat_addr = '10.0.0.3'
5815 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5816 cls.dst_ip4 = '192.168.70.1'
5818 cls.create_pg_interfaces(range(2))
5821 cls.pg0.config_ip4()
5822 cls.pg0.resolve_arp()
5825 cls.pg1.config_ip6()
5826 cls.pg1.resolve_ndp()
5828 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5829 dst_address_length=0,
5830 next_hop_address=cls.pg1.remote_ip6n,
5831 next_hop_sw_if_index=cls.pg1.sw_if_index)
5834 super(TestNAT44Out2InDPO, cls).tearDownClass()
5837 def configure_xlat(self):
5838 self.dst_ip6_pfx = '1:2:3::'
5839 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5841 self.dst_ip6_pfx_len = 96
5842 self.src_ip6_pfx = '4:5:6::'
5843 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5845 self.src_ip6_pfx_len = 96
5846 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5847 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5848 '\x00\x00\x00\x00', 0, is_translation=1,
5851 @unittest.skip('Temporary disabled')
5852 def test_464xlat_ce(self):
5853 """ Test 464XLAT CE with NAT44 """
5855 nat_config = self.vapi.nat_show_config()
5856 self.assertEqual(1, nat_config.out2in_dpo)
5858 self.configure_xlat()
5860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5861 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5863 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5864 self.dst_ip6_pfx_len)
5865 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5866 self.src_ip6_pfx_len)
5869 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5870 self.pg0.add_stream(pkts)
5871 self.pg_enable_capture(self.pg_interfaces)
5873 capture = self.pg1.get_capture(len(pkts))
5874 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5877 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5879 self.pg1.add_stream(pkts)
5880 self.pg_enable_capture(self.pg_interfaces)
5882 capture = self.pg0.get_capture(len(pkts))
5883 self.verify_capture_in(capture, self.pg0)
5885 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5887 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5888 self.nat_addr_n, is_add=0)
5890 @unittest.skip('Temporary disabled')
5891 def test_464xlat_ce_no_nat(self):
5892 """ Test 464XLAT CE without NAT44 """
5894 self.configure_xlat()
5896 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5897 self.dst_ip6_pfx_len)
5898 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
5899 self.src_ip6_pfx_len)
5901 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5902 self.pg0.add_stream(pkts)
5903 self.pg_enable_capture(self.pg_interfaces)
5905 capture = self.pg1.get_capture(len(pkts))
5906 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
5907 nat_ip=out_dst_ip6, same_port=True)
5909 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
5910 self.pg1.add_stream(pkts)
5911 self.pg_enable_capture(self.pg_interfaces)
5913 capture = self.pg0.get_capture(len(pkts))
5914 self.verify_capture_in(capture, self.pg0)
5917 class TestDeterministicNAT(MethodHolder):
5918 """ Deterministic NAT Test Cases """
5921 def setUpConstants(cls):
5922 super(TestDeterministicNAT, cls).setUpConstants()
5923 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
5926 def setUpClass(cls):
5927 super(TestDeterministicNAT, cls).setUpClass()
5928 cls.vapi.cli("set log class nat level debug")
5931 cls.tcp_port_in = 6303
5932 cls.tcp_external_port = 6303
5933 cls.udp_port_in = 6304
5934 cls.udp_external_port = 6304
5935 cls.icmp_id_in = 6305
5936 cls.nat_addr = '10.0.0.3'
5938 cls.create_pg_interfaces(range(3))
5939 cls.interfaces = list(cls.pg_interfaces)
5941 for i in cls.interfaces:
5946 cls.pg0.generate_remote_hosts(2)
5947 cls.pg0.configure_ipv4_neighbors()
5950 super(TestDeterministicNAT, cls).tearDownClass()
5953 def create_stream_in(self, in_if, out_if, ttl=64):
5955 Create packet stream for inside network
5957 :param in_if: Inside interface
5958 :param out_if: Outside interface
5959 :param ttl: TTL of generated packets
5963 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5964 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5965 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5969 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5970 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5971 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
5975 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5976 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5977 ICMP(id=self.icmp_id_in, type='echo-request'))
5982 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5984 Create packet stream for outside network
5986 :param out_if: Outside interface
5987 :param dst_ip: Destination IP address (Default use global NAT address)
5988 :param ttl: TTL of generated packets
5991 dst_ip = self.nat_addr
5994 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5995 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5996 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6000 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6001 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6002 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6006 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6007 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6008 ICMP(id=self.icmp_external_id, type='echo-reply'))
6013 def verify_capture_out(self, capture, nat_ip=None):
6015 Verify captured packets on outside network
6017 :param capture: Captured packets
6018 :param nat_ip: Translated IP address (Default use global NAT address)
6019 :param same_port: Sorce port number is not translated (Default False)
6022 nat_ip = self.nat_addr
6023 for packet in capture:
6025 self.assertEqual(packet[IP].src, nat_ip)
6026 if packet.haslayer(TCP):
6027 self.tcp_port_out = packet[TCP].sport
6028 elif packet.haslayer(UDP):
6029 self.udp_port_out = packet[UDP].sport
6031 self.icmp_external_id = packet[ICMP].id
6033 self.logger.error(ppp("Unexpected or invalid packet "
6034 "(outside network):", packet))
6037 def test_deterministic_mode(self):
6038 """ NAT plugin run deterministic mode """
6039 in_addr = '172.16.255.0'
6040 out_addr = '172.17.255.50'
6041 in_addr_t = '172.16.255.20'
6042 in_addr_n = socket.inet_aton(in_addr)
6043 out_addr_n = socket.inet_aton(out_addr)
6044 in_addr_t_n = socket.inet_aton(in_addr_t)
6048 nat_config = self.vapi.nat_show_config()
6049 self.assertEqual(1, nat_config.deterministic)
6051 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6053 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6054 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6055 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6056 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6058 deterministic_mappings = self.vapi.nat_det_map_dump()
6059 self.assertEqual(len(deterministic_mappings), 1)
6060 dsm = deterministic_mappings[0]
6061 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6062 self.assertEqual(in_plen, dsm.in_plen)
6063 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6064 self.assertEqual(out_plen, dsm.out_plen)
6066 self.clear_nat_det()
6067 deterministic_mappings = self.vapi.nat_det_map_dump()
6068 self.assertEqual(len(deterministic_mappings), 0)
6070 def test_set_timeouts(self):
6071 """ Set deterministic NAT timeouts """
6072 timeouts_before = self.vapi.nat_get_timeouts()
6074 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6075 timeouts_before.tcp_established + 10,
6076 timeouts_before.tcp_transitory + 10,
6077 timeouts_before.icmp + 10)
6079 timeouts_after = self.vapi.nat_get_timeouts()
6081 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6082 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6083 self.assertNotEqual(timeouts_before.tcp_established,
6084 timeouts_after.tcp_established)
6085 self.assertNotEqual(timeouts_before.tcp_transitory,
6086 timeouts_after.tcp_transitory)
6088 def test_det_in(self):
6089 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6091 nat_ip = "10.0.0.10"
6093 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6095 socket.inet_aton(nat_ip),
6097 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6098 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6102 pkts = self.create_stream_in(self.pg0, self.pg1)
6103 self.pg0.add_stream(pkts)
6104 self.pg_enable_capture(self.pg_interfaces)
6106 capture = self.pg1.get_capture(len(pkts))
6107 self.verify_capture_out(capture, nat_ip)
6110 pkts = self.create_stream_out(self.pg1, nat_ip)
6111 self.pg1.add_stream(pkts)
6112 self.pg_enable_capture(self.pg_interfaces)
6114 capture = self.pg0.get_capture(len(pkts))
6115 self.verify_capture_in(capture, self.pg0)
6118 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6119 self.assertEqual(len(sessions), 3)
6123 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6124 self.assertEqual(s.in_port, self.tcp_port_in)
6125 self.assertEqual(s.out_port, self.tcp_port_out)
6126 self.assertEqual(s.ext_port, self.tcp_external_port)
6130 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6131 self.assertEqual(s.in_port, self.udp_port_in)
6132 self.assertEqual(s.out_port, self.udp_port_out)
6133 self.assertEqual(s.ext_port, self.udp_external_port)
6137 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6138 self.assertEqual(s.in_port, self.icmp_id_in)
6139 self.assertEqual(s.out_port, self.icmp_external_id)
6141 def test_multiple_users(self):
6142 """ Deterministic NAT multiple users """
6144 nat_ip = "10.0.0.10"
6146 external_port = 6303
6148 host0 = self.pg0.remote_hosts[0]
6149 host1 = self.pg0.remote_hosts[1]
6151 self.vapi.nat_det_add_del_map(host0.ip4n,
6153 socket.inet_aton(nat_ip),
6155 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6156 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6160 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6161 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6162 TCP(sport=port_in, dport=external_port))
6163 self.pg0.add_stream(p)
6164 self.pg_enable_capture(self.pg_interfaces)
6166 capture = self.pg1.get_capture(1)
6171 self.assertEqual(ip.src, nat_ip)
6172 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6173 self.assertEqual(tcp.dport, external_port)
6174 port_out0 = tcp.sport
6176 self.logger.error(ppp("Unexpected or invalid packet:", p))
6180 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6181 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6182 TCP(sport=port_in, dport=external_port))
6183 self.pg0.add_stream(p)
6184 self.pg_enable_capture(self.pg_interfaces)
6186 capture = self.pg1.get_capture(1)
6191 self.assertEqual(ip.src, nat_ip)
6192 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6193 self.assertEqual(tcp.dport, external_port)
6194 port_out1 = tcp.sport
6196 self.logger.error(ppp("Unexpected or invalid packet:", p))
6199 dms = self.vapi.nat_det_map_dump()
6200 self.assertEqual(1, len(dms))
6201 self.assertEqual(2, dms[0].ses_num)
6204 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6205 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6206 TCP(sport=external_port, dport=port_out0))
6207 self.pg1.add_stream(p)
6208 self.pg_enable_capture(self.pg_interfaces)
6210 capture = self.pg0.get_capture(1)
6215 self.assertEqual(ip.src, self.pg1.remote_ip4)
6216 self.assertEqual(ip.dst, host0.ip4)
6217 self.assertEqual(tcp.dport, port_in)
6218 self.assertEqual(tcp.sport, external_port)
6220 self.logger.error(ppp("Unexpected or invalid packet:", p))
6224 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6225 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6226 TCP(sport=external_port, dport=port_out1))
6227 self.pg1.add_stream(p)
6228 self.pg_enable_capture(self.pg_interfaces)
6230 capture = self.pg0.get_capture(1)
6235 self.assertEqual(ip.src, self.pg1.remote_ip4)
6236 self.assertEqual(ip.dst, host1.ip4)
6237 self.assertEqual(tcp.dport, port_in)
6238 self.assertEqual(tcp.sport, external_port)
6240 self.logger.error(ppp("Unexpected or invalid packet", p))
6243 # session close api test
6244 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6246 self.pg1.remote_ip4n,
6248 dms = self.vapi.nat_det_map_dump()
6249 self.assertEqual(dms[0].ses_num, 1)
6251 self.vapi.nat_det_close_session_in(host0.ip4n,
6253 self.pg1.remote_ip4n,
6255 dms = self.vapi.nat_det_map_dump()
6256 self.assertEqual(dms[0].ses_num, 0)
6258 def test_tcp_session_close_detection_in(self):
6259 """ Deterministic NAT TCP session close from inside network """
6260 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6262 socket.inet_aton(self.nat_addr),
6264 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6265 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6268 self.initiate_tcp_session(self.pg0, self.pg1)
6270 # close the session from inside
6272 # FIN packet in -> out
6273 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6274 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6275 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6277 self.pg0.add_stream(p)
6278 self.pg_enable_capture(self.pg_interfaces)
6280 self.pg1.get_capture(1)
6284 # ACK packet out -> in
6285 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6286 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6287 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6291 # FIN packet out -> in
6292 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6293 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6294 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6298 self.pg1.add_stream(pkts)
6299 self.pg_enable_capture(self.pg_interfaces)
6301 self.pg0.get_capture(2)
6303 # ACK packet in -> out
6304 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6305 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6306 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6308 self.pg0.add_stream(p)
6309 self.pg_enable_capture(self.pg_interfaces)
6311 self.pg1.get_capture(1)
6313 # Check if deterministic NAT44 closed the session
6314 dms = self.vapi.nat_det_map_dump()
6315 self.assertEqual(0, dms[0].ses_num)
6317 self.logger.error("TCP session termination failed")
6320 def test_tcp_session_close_detection_out(self):
6321 """ Deterministic NAT TCP session close from outside network """
6322 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6324 socket.inet_aton(self.nat_addr),
6326 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6327 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6330 self.initiate_tcp_session(self.pg0, self.pg1)
6332 # close the session from outside
6334 # FIN packet out -> in
6335 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6336 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6337 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6339 self.pg1.add_stream(p)
6340 self.pg_enable_capture(self.pg_interfaces)
6342 self.pg0.get_capture(1)
6346 # ACK packet in -> out
6347 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6348 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6349 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6353 # ACK packet in -> out
6354 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6355 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6356 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6360 self.pg0.add_stream(pkts)
6361 self.pg_enable_capture(self.pg_interfaces)
6363 self.pg1.get_capture(2)
6365 # ACK packet out -> in
6366 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6367 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6368 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6370 self.pg1.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6373 self.pg0.get_capture(1)
6375 # Check if deterministic NAT44 closed the session
6376 dms = self.vapi.nat_det_map_dump()
6377 self.assertEqual(0, dms[0].ses_num)
6379 self.logger.error("TCP session termination failed")
6382 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6383 def test_session_timeout(self):
6384 """ Deterministic NAT session timeouts """
6385 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6387 socket.inet_aton(self.nat_addr),
6389 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6390 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6393 self.initiate_tcp_session(self.pg0, self.pg1)
6394 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6395 pkts = self.create_stream_in(self.pg0, self.pg1)
6396 self.pg0.add_stream(pkts)
6397 self.pg_enable_capture(self.pg_interfaces)
6399 capture = self.pg1.get_capture(len(pkts))
6402 dms = self.vapi.nat_det_map_dump()
6403 self.assertEqual(0, dms[0].ses_num)
6405 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6406 def test_session_limit_per_user(self):
6407 """ Deterministic NAT maximum sessions per user limit """
6408 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6410 socket.inet_aton(self.nat_addr),
6412 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6413 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6415 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6416 src_address=self.pg2.local_ip4n,
6418 template_interval=10)
6419 self.vapi.nat_ipfix()
6422 for port in range(1025, 2025):
6423 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6424 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6425 UDP(sport=port, dport=port))
6428 self.pg0.add_stream(pkts)
6429 self.pg_enable_capture(self.pg_interfaces)
6431 capture = self.pg1.get_capture(len(pkts))
6433 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6434 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6435 UDP(sport=3001, dport=3002))
6436 self.pg0.add_stream(p)
6437 self.pg_enable_capture(self.pg_interfaces)
6439 capture = self.pg1.assert_nothing_captured()
6441 # verify ICMP error packet
6442 capture = self.pg0.get_capture(1)
6444 self.assertTrue(p.haslayer(ICMP))
6446 self.assertEqual(icmp.type, 3)
6447 self.assertEqual(icmp.code, 1)
6448 self.assertTrue(icmp.haslayer(IPerror))
6449 inner_ip = icmp[IPerror]
6450 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6451 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6453 dms = self.vapi.nat_det_map_dump()
6455 self.assertEqual(1000, dms[0].ses_num)
6457 # verify IPFIX logging
6458 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6460 capture = self.pg2.get_capture(2)
6461 ipfix = IPFIXDecoder()
6462 # first load template
6464 self.assertTrue(p.haslayer(IPFIX))
6465 if p.haslayer(Template):
6466 ipfix.add_template(p.getlayer(Template))
6467 # verify events in data set
6469 if p.haslayer(Data):
6470 data = ipfix.decode_data_set(p.getlayer(Set))
6471 self.verify_ipfix_max_entries_per_user(data,
6473 self.pg0.remote_ip4n)
6475 def clear_nat_det(self):
6477 Clear deterministic NAT configuration.
6479 self.vapi.nat_ipfix(enable=0)
6480 self.vapi.nat_set_timeouts()
6481 deterministic_mappings = self.vapi.nat_det_map_dump()
6482 for dsm in deterministic_mappings:
6483 self.vapi.nat_det_add_del_map(dsm.in_addr,
6489 interfaces = self.vapi.nat44_interface_dump()
6490 for intf in interfaces:
6491 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6496 super(TestDeterministicNAT, self).tearDown()
6497 if not self.vpp_dead:
6498 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6499 self.logger.info(self.vapi.cli("show nat timeouts"))
6501 self.vapi.cli("show nat44 deterministic mappings"))
6503 self.vapi.cli("show nat44 deterministic sessions"))
6504 self.clear_nat_det()
6507 class TestNAT64(MethodHolder):
6508 """ NAT64 Test Cases """
6511 def setUpConstants(cls):
6512 super(TestNAT64, cls).setUpConstants()
6513 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6514 "nat64 st hash buckets 256", "}"])
6517 def setUpClass(cls):
6518 super(TestNAT64, cls).setUpClass()
6521 cls.tcp_port_in = 6303
6522 cls.tcp_port_out = 6303
6523 cls.udp_port_in = 6304
6524 cls.udp_port_out = 6304
6525 cls.icmp_id_in = 6305
6526 cls.icmp_id_out = 6305
6527 cls.nat_addr = '10.0.0.3'
6528 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6530 cls.vrf1_nat_addr = '10.0.10.3'
6531 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6533 cls.ipfix_src_port = 4739
6534 cls.ipfix_domain_id = 1
6536 cls.create_pg_interfaces(range(6))
6537 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6538 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6539 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6541 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6543 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6545 cls.pg0.generate_remote_hosts(2)
6547 for i in cls.ip6_interfaces:
6550 i.configure_ipv6_neighbors()
6552 for i in cls.ip4_interfaces:
6558 cls.pg3.config_ip4()
6559 cls.pg3.resolve_arp()
6560 cls.pg3.config_ip6()
6561 cls.pg3.configure_ipv6_neighbors()
6564 cls.pg5.config_ip6()
6567 super(TestNAT64, cls).tearDownClass()
6570 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6571 """ NAT64 inside interface handles Neighbor Advertisement """
6573 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6576 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6577 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6578 ICMPv6EchoRequest())
6580 self.pg5.add_stream(pkts)
6581 self.pg_enable_capture(self.pg_interfaces)
6584 # Wait for Neighbor Solicitation
6585 capture = self.pg5.get_capture(len(pkts))
6588 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6589 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6590 tgt = packet[ICMPv6ND_NS].tgt
6592 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6595 # Send Neighbor Advertisement
6596 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6597 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6598 ICMPv6ND_NA(tgt=tgt) /
6599 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6601 self.pg5.add_stream(pkts)
6602 self.pg_enable_capture(self.pg_interfaces)
6605 # Try to send ping again
6607 self.pg5.add_stream(pkts)
6608 self.pg_enable_capture(self.pg_interfaces)
6611 # Wait for ping reply
6612 capture = self.pg5.get_capture(len(pkts))
6615 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6616 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6617 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6619 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6622 def test_pool(self):
6623 """ Add/delete address to NAT64 pool """
6624 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6626 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6628 addresses = self.vapi.nat64_pool_addr_dump()
6629 self.assertEqual(len(addresses), 1)
6630 self.assertEqual(addresses[0].address, nat_addr)
6632 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6634 addresses = self.vapi.nat64_pool_addr_dump()
6635 self.assertEqual(len(addresses), 0)
6637 def test_interface(self):
6638 """ Enable/disable NAT64 feature on the interface """
6639 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6640 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6642 interfaces = self.vapi.nat64_interface_dump()
6643 self.assertEqual(len(interfaces), 2)
6646 for intf in interfaces:
6647 if intf.sw_if_index == self.pg0.sw_if_index:
6648 self.assertEqual(intf.is_inside, 1)
6650 elif intf.sw_if_index == self.pg1.sw_if_index:
6651 self.assertEqual(intf.is_inside, 0)
6653 self.assertTrue(pg0_found)
6654 self.assertTrue(pg1_found)
6656 features = self.vapi.cli("show interface features pg0")
6657 self.assertNotEqual(features.find('nat64-in2out'), -1)
6658 features = self.vapi.cli("show interface features pg1")
6659 self.assertNotEqual(features.find('nat64-out2in'), -1)
6661 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6662 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6664 interfaces = self.vapi.nat64_interface_dump()
6665 self.assertEqual(len(interfaces), 0)
6667 def test_static_bib(self):
6668 """ Add/delete static BIB entry """
6669 in_addr = socket.inet_pton(socket.AF_INET6,
6670 '2001:db8:85a3::8a2e:370:7334')
6671 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6674 proto = IP_PROTOS.tcp
6676 self.vapi.nat64_add_del_static_bib(in_addr,
6681 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6686 self.assertEqual(bibe.i_addr, in_addr)
6687 self.assertEqual(bibe.o_addr, out_addr)
6688 self.assertEqual(bibe.i_port, in_port)
6689 self.assertEqual(bibe.o_port, out_port)
6690 self.assertEqual(static_bib_num, 1)
6692 self.vapi.nat64_add_del_static_bib(in_addr,
6698 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6703 self.assertEqual(static_bib_num, 0)
6705 def test_set_timeouts(self):
6706 """ Set NAT64 timeouts """
6707 # verify default values
6708 timeouts = self.vapi.nat_get_timeouts()
6709 self.assertEqual(timeouts.udp, 300)
6710 self.assertEqual(timeouts.icmp, 60)
6711 self.assertEqual(timeouts.tcp_transitory, 240)
6712 self.assertEqual(timeouts.tcp_established, 7440)
6714 # set and verify custom values
6715 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6716 tcp_established=7450)
6717 timeouts = self.vapi.nat_get_timeouts()
6718 self.assertEqual(timeouts.udp, 200)
6719 self.assertEqual(timeouts.icmp, 30)
6720 self.assertEqual(timeouts.tcp_transitory, 250)
6721 self.assertEqual(timeouts.tcp_established, 7450)
6723 def test_dynamic(self):
6724 """ NAT64 dynamic translation test """
6725 self.tcp_port_in = 6303
6726 self.udp_port_in = 6304
6727 self.icmp_id_in = 6305
6729 ses_num_start = self.nat64_get_ses_num()
6731 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6733 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6734 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6737 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6738 self.pg0.add_stream(pkts)
6739 self.pg_enable_capture(self.pg_interfaces)
6741 capture = self.pg1.get_capture(len(pkts))
6742 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6743 dst_ip=self.pg1.remote_ip4)
6746 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6747 self.pg1.add_stream(pkts)
6748 self.pg_enable_capture(self.pg_interfaces)
6750 capture = self.pg0.get_capture(len(pkts))
6751 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6752 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6755 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6756 self.pg0.add_stream(pkts)
6757 self.pg_enable_capture(self.pg_interfaces)
6759 capture = self.pg1.get_capture(len(pkts))
6760 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6761 dst_ip=self.pg1.remote_ip4)
6764 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6765 self.pg1.add_stream(pkts)
6766 self.pg_enable_capture(self.pg_interfaces)
6768 capture = self.pg0.get_capture(len(pkts))
6769 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6771 ses_num_end = self.nat64_get_ses_num()
6773 self.assertEqual(ses_num_end - ses_num_start, 3)
6775 # tenant with specific VRF
6776 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6777 self.vrf1_nat_addr_n,
6778 vrf_id=self.vrf1_id)
6779 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6781 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6782 self.pg2.add_stream(pkts)
6783 self.pg_enable_capture(self.pg_interfaces)
6785 capture = self.pg1.get_capture(len(pkts))
6786 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6787 dst_ip=self.pg1.remote_ip4)
6789 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6790 self.pg1.add_stream(pkts)
6791 self.pg_enable_capture(self.pg_interfaces)
6793 capture = self.pg2.get_capture(len(pkts))
6794 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6796 def test_static(self):
6797 """ NAT64 static translation test """
6798 self.tcp_port_in = 60303
6799 self.udp_port_in = 60304
6800 self.icmp_id_in = 60305
6801 self.tcp_port_out = 60303
6802 self.udp_port_out = 60304
6803 self.icmp_id_out = 60305
6805 ses_num_start = self.nat64_get_ses_num()
6807 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6809 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6810 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6812 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6817 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6822 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6829 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6830 self.pg0.add_stream(pkts)
6831 self.pg_enable_capture(self.pg_interfaces)
6833 capture = self.pg1.get_capture(len(pkts))
6834 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6835 dst_ip=self.pg1.remote_ip4, same_port=True)
6838 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6839 self.pg1.add_stream(pkts)
6840 self.pg_enable_capture(self.pg_interfaces)
6842 capture = self.pg0.get_capture(len(pkts))
6843 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6844 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6846 ses_num_end = self.nat64_get_ses_num()
6848 self.assertEqual(ses_num_end - ses_num_start, 3)
6850 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6851 def test_session_timeout(self):
6852 """ NAT64 session timeout """
6853 self.icmp_id_in = 1234
6854 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6856 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6857 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6858 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6860 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6861 self.pg0.add_stream(pkts)
6862 self.pg_enable_capture(self.pg_interfaces)
6864 capture = self.pg1.get_capture(len(pkts))
6866 ses_num_before_timeout = self.nat64_get_ses_num()
6870 # ICMP and TCP session after timeout
6871 ses_num_after_timeout = self.nat64_get_ses_num()
6872 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6874 def test_icmp_error(self):
6875 """ NAT64 ICMP Error message translation """
6876 self.tcp_port_in = 6303
6877 self.udp_port_in = 6304
6878 self.icmp_id_in = 6305
6880 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6882 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6883 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6885 # send some packets to create sessions
6886 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6887 self.pg0.add_stream(pkts)
6888 self.pg_enable_capture(self.pg_interfaces)
6890 capture_ip4 = self.pg1.get_capture(len(pkts))
6891 self.verify_capture_out(capture_ip4,
6892 nat_ip=self.nat_addr,
6893 dst_ip=self.pg1.remote_ip4)
6895 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6896 self.pg1.add_stream(pkts)
6897 self.pg_enable_capture(self.pg_interfaces)
6899 capture_ip6 = self.pg0.get_capture(len(pkts))
6900 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6901 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
6902 self.pg0.remote_ip6)
6905 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6906 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
6907 ICMPv6DestUnreach(code=1) /
6908 packet[IPv6] for packet in capture_ip6]
6909 self.pg0.add_stream(pkts)
6910 self.pg_enable_capture(self.pg_interfaces)
6912 capture = self.pg1.get_capture(len(pkts))
6913 for packet in capture:
6915 self.assertEqual(packet[IP].src, self.nat_addr)
6916 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6917 self.assertEqual(packet[ICMP].type, 3)
6918 self.assertEqual(packet[ICMP].code, 13)
6919 inner = packet[IPerror]
6920 self.assertEqual(inner.src, self.pg1.remote_ip4)
6921 self.assertEqual(inner.dst, self.nat_addr)
6922 self.assert_packet_checksums_valid(packet)
6923 if inner.haslayer(TCPerror):
6924 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6925 elif inner.haslayer(UDPerror):
6926 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6928 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6930 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6934 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6935 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6936 ICMP(type=3, code=13) /
6937 packet[IP] for packet in capture_ip4]
6938 self.pg1.add_stream(pkts)
6939 self.pg_enable_capture(self.pg_interfaces)
6941 capture = self.pg0.get_capture(len(pkts))
6942 for packet in capture:
6944 self.assertEqual(packet[IPv6].src, ip.src)
6945 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6946 icmp = packet[ICMPv6DestUnreach]
6947 self.assertEqual(icmp.code, 1)
6948 inner = icmp[IPerror6]
6949 self.assertEqual(inner.src, self.pg0.remote_ip6)
6950 self.assertEqual(inner.dst, ip.src)
6951 self.assert_icmpv6_checksum_valid(packet)
6952 if inner.haslayer(TCPerror):
6953 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6954 elif inner.haslayer(UDPerror):
6955 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6957 self.assertEqual(inner[ICMPv6EchoRequest].id,
6960 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6963 def test_hairpinning(self):
6964 """ NAT64 hairpinning """
6966 client = self.pg0.remote_hosts[0]
6967 server = self.pg0.remote_hosts[1]
6968 server_tcp_in_port = 22
6969 server_tcp_out_port = 4022
6970 server_udp_in_port = 23
6971 server_udp_out_port = 4023
6972 client_tcp_in_port = 1234
6973 client_udp_in_port = 1235
6974 client_tcp_out_port = 0
6975 client_udp_out_port = 0
6976 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6977 nat_addr_ip6 = ip.src
6979 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6981 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6982 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6984 self.vapi.nat64_add_del_static_bib(server.ip6n,
6987 server_tcp_out_port,
6989 self.vapi.nat64_add_del_static_bib(server.ip6n,
6992 server_udp_out_port,
6997 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6998 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6999 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7001 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7002 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7003 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7005 self.pg0.add_stream(pkts)
7006 self.pg_enable_capture(self.pg_interfaces)
7008 capture = self.pg0.get_capture(len(pkts))
7009 for packet in capture:
7011 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7012 self.assertEqual(packet[IPv6].dst, server.ip6)
7013 self.assert_packet_checksums_valid(packet)
7014 if packet.haslayer(TCP):
7015 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7016 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7017 client_tcp_out_port = packet[TCP].sport
7019 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7020 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7021 client_udp_out_port = packet[UDP].sport
7023 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7028 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7029 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7030 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7032 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7033 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7034 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7036 self.pg0.add_stream(pkts)
7037 self.pg_enable_capture(self.pg_interfaces)
7039 capture = self.pg0.get_capture(len(pkts))
7040 for packet in capture:
7042 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7043 self.assertEqual(packet[IPv6].dst, client.ip6)
7044 self.assert_packet_checksums_valid(packet)
7045 if packet.haslayer(TCP):
7046 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7047 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7049 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7050 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7052 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7057 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7058 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7059 ICMPv6DestUnreach(code=1) /
7060 packet[IPv6] for packet in capture]
7061 self.pg0.add_stream(pkts)
7062 self.pg_enable_capture(self.pg_interfaces)
7064 capture = self.pg0.get_capture(len(pkts))
7065 for packet in capture:
7067 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7068 self.assertEqual(packet[IPv6].dst, server.ip6)
7069 icmp = packet[ICMPv6DestUnreach]
7070 self.assertEqual(icmp.code, 1)
7071 inner = icmp[IPerror6]
7072 self.assertEqual(inner.src, server.ip6)
7073 self.assertEqual(inner.dst, nat_addr_ip6)
7074 self.assert_packet_checksums_valid(packet)
7075 if inner.haslayer(TCPerror):
7076 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7077 self.assertEqual(inner[TCPerror].dport,
7078 client_tcp_out_port)
7080 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7081 self.assertEqual(inner[UDPerror].dport,
7082 client_udp_out_port)
7084 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7087 def test_prefix(self):
7088 """ NAT64 Network-Specific Prefix """
7090 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7092 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7093 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7094 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7095 self.vrf1_nat_addr_n,
7096 vrf_id=self.vrf1_id)
7097 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7100 global_pref64 = "2001:db8::"
7101 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7102 global_pref64_len = 32
7103 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7105 prefix = self.vapi.nat64_prefix_dump()
7106 self.assertEqual(len(prefix), 1)
7107 self.assertEqual(prefix[0].prefix, global_pref64_n)
7108 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7109 self.assertEqual(prefix[0].vrf_id, 0)
7111 # Add tenant specific prefix
7112 vrf1_pref64 = "2001:db8:122:300::"
7113 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7114 vrf1_pref64_len = 56
7115 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7117 vrf_id=self.vrf1_id)
7118 prefix = self.vapi.nat64_prefix_dump()
7119 self.assertEqual(len(prefix), 2)
7122 pkts = self.create_stream_in_ip6(self.pg0,
7125 plen=global_pref64_len)
7126 self.pg0.add_stream(pkts)
7127 self.pg_enable_capture(self.pg_interfaces)
7129 capture = self.pg1.get_capture(len(pkts))
7130 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7131 dst_ip=self.pg1.remote_ip4)
7133 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7134 self.pg1.add_stream(pkts)
7135 self.pg_enable_capture(self.pg_interfaces)
7137 capture = self.pg0.get_capture(len(pkts))
7138 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7141 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7143 # Tenant specific prefix
7144 pkts = self.create_stream_in_ip6(self.pg2,
7147 plen=vrf1_pref64_len)
7148 self.pg2.add_stream(pkts)
7149 self.pg_enable_capture(self.pg_interfaces)
7151 capture = self.pg1.get_capture(len(pkts))
7152 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7153 dst_ip=self.pg1.remote_ip4)
7155 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7156 self.pg1.add_stream(pkts)
7157 self.pg_enable_capture(self.pg_interfaces)
7159 capture = self.pg2.get_capture(len(pkts))
7160 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7163 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7165 def test_unknown_proto(self):
7166 """ NAT64 translate packet with unknown protocol """
7168 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7170 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7171 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7172 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7175 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7176 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7177 TCP(sport=self.tcp_port_in, dport=20))
7178 self.pg0.add_stream(p)
7179 self.pg_enable_capture(self.pg_interfaces)
7181 p = self.pg1.get_capture(1)
7183 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7184 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7186 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7187 TCP(sport=1234, dport=1234))
7188 self.pg0.add_stream(p)
7189 self.pg_enable_capture(self.pg_interfaces)
7191 p = self.pg1.get_capture(1)
7194 self.assertEqual(packet[IP].src, self.nat_addr)
7195 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7196 self.assertTrue(packet.haslayer(GRE))
7197 self.assert_packet_checksums_valid(packet)
7199 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7203 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7204 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7206 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7207 TCP(sport=1234, dport=1234))
7208 self.pg1.add_stream(p)
7209 self.pg_enable_capture(self.pg_interfaces)
7211 p = self.pg0.get_capture(1)
7214 self.assertEqual(packet[IPv6].src, remote_ip6)
7215 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7216 self.assertEqual(packet[IPv6].nh, 47)
7218 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7221 def test_hairpinning_unknown_proto(self):
7222 """ NAT64 translate packet with unknown protocol - hairpinning """
7224 client = self.pg0.remote_hosts[0]
7225 server = self.pg0.remote_hosts[1]
7226 server_tcp_in_port = 22
7227 server_tcp_out_port = 4022
7228 client_tcp_in_port = 1234
7229 client_tcp_out_port = 1235
7230 server_nat_ip = "10.0.0.100"
7231 client_nat_ip = "10.0.0.110"
7232 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7233 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7234 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7235 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7237 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7239 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7240 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7242 self.vapi.nat64_add_del_static_bib(server.ip6n,
7245 server_tcp_out_port,
7248 self.vapi.nat64_add_del_static_bib(server.ip6n,
7254 self.vapi.nat64_add_del_static_bib(client.ip6n,
7257 client_tcp_out_port,
7261 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7262 IPv6(src=client.ip6, dst=server_nat_ip6) /
7263 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7264 self.pg0.add_stream(p)
7265 self.pg_enable_capture(self.pg_interfaces)
7267 p = self.pg0.get_capture(1)
7269 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7270 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7272 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7273 TCP(sport=1234, dport=1234))
7274 self.pg0.add_stream(p)
7275 self.pg_enable_capture(self.pg_interfaces)
7277 p = self.pg0.get_capture(1)
7280 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7281 self.assertEqual(packet[IPv6].dst, server.ip6)
7282 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7284 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7288 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7289 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7291 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7292 TCP(sport=1234, dport=1234))
7293 self.pg0.add_stream(p)
7294 self.pg_enable_capture(self.pg_interfaces)
7296 p = self.pg0.get_capture(1)
7299 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7300 self.assertEqual(packet[IPv6].dst, client.ip6)
7301 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7306 def test_one_armed_nat64(self):
7307 """ One armed NAT64 """
7309 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7313 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7315 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7316 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7319 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7320 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7321 TCP(sport=12345, dport=80))
7322 self.pg3.add_stream(p)
7323 self.pg_enable_capture(self.pg_interfaces)
7325 capture = self.pg3.get_capture(1)
7330 self.assertEqual(ip.src, self.nat_addr)
7331 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7332 self.assertNotEqual(tcp.sport, 12345)
7333 external_port = tcp.sport
7334 self.assertEqual(tcp.dport, 80)
7335 self.assert_packet_checksums_valid(p)
7337 self.logger.error(ppp("Unexpected or invalid packet:", p))
7341 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7342 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7343 TCP(sport=80, dport=external_port))
7344 self.pg3.add_stream(p)
7345 self.pg_enable_capture(self.pg_interfaces)
7347 capture = self.pg3.get_capture(1)
7352 self.assertEqual(ip.src, remote_host_ip6)
7353 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7354 self.assertEqual(tcp.sport, 80)
7355 self.assertEqual(tcp.dport, 12345)
7356 self.assert_packet_checksums_valid(p)
7358 self.logger.error(ppp("Unexpected or invalid packet:", p))
7361 def test_frag_in_order(self):
7362 """ NAT64 translate fragments arriving in order """
7363 self.tcp_port_in = random.randint(1025, 65535)
7365 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7367 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7368 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7370 reass = self.vapi.nat_reass_dump()
7371 reass_n_start = len(reass)
7375 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7376 self.tcp_port_in, 20, data)
7377 self.pg0.add_stream(pkts)
7378 self.pg_enable_capture(self.pg_interfaces)
7380 frags = self.pg1.get_capture(len(pkts))
7381 p = self.reass_frags_and_verify(frags,
7383 self.pg1.remote_ip4)
7384 self.assertEqual(p[TCP].dport, 20)
7385 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7386 self.tcp_port_out = p[TCP].sport
7387 self.assertEqual(data, p[Raw].load)
7390 data = "A" * 4 + "b" * 16 + "C" * 3
7391 pkts = self.create_stream_frag(self.pg1,
7396 self.pg1.add_stream(pkts)
7397 self.pg_enable_capture(self.pg_interfaces)
7399 frags = self.pg0.get_capture(len(pkts))
7400 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7401 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7402 self.assertEqual(p[TCP].sport, 20)
7403 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7404 self.assertEqual(data, p[Raw].load)
7406 reass = self.vapi.nat_reass_dump()
7407 reass_n_end = len(reass)
7409 self.assertEqual(reass_n_end - reass_n_start, 2)
7411 def test_reass_hairpinning(self):
7412 """ NAT64 fragments hairpinning """
7414 server = self.pg0.remote_hosts[1]
7415 server_in_port = random.randint(1025, 65535)
7416 server_out_port = random.randint(1025, 65535)
7417 client_in_port = random.randint(1025, 65535)
7418 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7419 nat_addr_ip6 = ip.src
7421 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7423 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7424 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7426 # add static BIB entry for server
7427 self.vapi.nat64_add_del_static_bib(server.ip6n,
7433 # send packet from host to server
7434 pkts = self.create_stream_frag_ip6(self.pg0,
7439 self.pg0.add_stream(pkts)
7440 self.pg_enable_capture(self.pg_interfaces)
7442 frags = self.pg0.get_capture(len(pkts))
7443 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7444 self.assertNotEqual(p[TCP].sport, client_in_port)
7445 self.assertEqual(p[TCP].dport, server_in_port)
7446 self.assertEqual(data, p[Raw].load)
7448 def test_frag_out_of_order(self):
7449 """ NAT64 translate fragments arriving out of order """
7450 self.tcp_port_in = random.randint(1025, 65535)
7452 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7454 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7455 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7459 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7460 self.tcp_port_in, 20, data)
7462 self.pg0.add_stream(pkts)
7463 self.pg_enable_capture(self.pg_interfaces)
7465 frags = self.pg1.get_capture(len(pkts))
7466 p = self.reass_frags_and_verify(frags,
7468 self.pg1.remote_ip4)
7469 self.assertEqual(p[TCP].dport, 20)
7470 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7471 self.tcp_port_out = p[TCP].sport
7472 self.assertEqual(data, p[Raw].load)
7475 data = "A" * 4 + "B" * 16 + "C" * 3
7476 pkts = self.create_stream_frag(self.pg1,
7482 self.pg1.add_stream(pkts)
7483 self.pg_enable_capture(self.pg_interfaces)
7485 frags = self.pg0.get_capture(len(pkts))
7486 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7487 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7488 self.assertEqual(p[TCP].sport, 20)
7489 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7490 self.assertEqual(data, p[Raw].load)
7492 def test_interface_addr(self):
7493 """ Acquire NAT64 pool addresses from interface """
7494 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7496 # no address in NAT64 pool
7497 adresses = self.vapi.nat44_address_dump()
7498 self.assertEqual(0, len(adresses))
7500 # configure interface address and check NAT64 address pool
7501 self.pg4.config_ip4()
7502 addresses = self.vapi.nat64_pool_addr_dump()
7503 self.assertEqual(len(addresses), 1)
7504 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7506 # remove interface address and check NAT64 address pool
7507 self.pg4.unconfig_ip4()
7508 addresses = self.vapi.nat64_pool_addr_dump()
7509 self.assertEqual(0, len(adresses))
7511 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7512 def test_ipfix_max_bibs_sessions(self):
7513 """ IPFIX logging maximum session and BIB entries exceeded """
7516 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7520 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7522 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7523 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7527 for i in range(0, max_bibs):
7528 src = "fd01:aa::%x" % (i)
7529 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7530 IPv6(src=src, dst=remote_host_ip6) /
7531 TCP(sport=12345, dport=80))
7533 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7534 IPv6(src=src, dst=remote_host_ip6) /
7535 TCP(sport=12345, dport=22))
7537 self.pg0.add_stream(pkts)
7538 self.pg_enable_capture(self.pg_interfaces)
7540 self.pg1.get_capture(max_sessions)
7542 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7543 src_address=self.pg3.local_ip4n,
7545 template_interval=10)
7546 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7547 src_port=self.ipfix_src_port)
7549 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7550 IPv6(src=src, dst=remote_host_ip6) /
7551 TCP(sport=12345, dport=25))
7552 self.pg0.add_stream(p)
7553 self.pg_enable_capture(self.pg_interfaces)
7555 self.pg1.assert_nothing_captured()
7557 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7558 capture = self.pg3.get_capture(9)
7559 ipfix = IPFIXDecoder()
7560 # first load template
7562 self.assertTrue(p.haslayer(IPFIX))
7563 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7564 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7565 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7566 self.assertEqual(p[UDP].dport, 4739)
7567 self.assertEqual(p[IPFIX].observationDomainID,
7568 self.ipfix_domain_id)
7569 if p.haslayer(Template):
7570 ipfix.add_template(p.getlayer(Template))
7571 # verify events in data set
7573 if p.haslayer(Data):
7574 data = ipfix.decode_data_set(p.getlayer(Set))
7575 self.verify_ipfix_max_sessions(data, max_sessions)
7577 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7578 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7579 TCP(sport=12345, dport=80))
7580 self.pg0.add_stream(p)
7581 self.pg_enable_capture(self.pg_interfaces)
7583 self.pg1.assert_nothing_captured()
7585 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7586 capture = self.pg3.get_capture(1)
7587 # verify events in data set
7589 self.assertTrue(p.haslayer(IPFIX))
7590 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7591 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7592 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7593 self.assertEqual(p[UDP].dport, 4739)
7594 self.assertEqual(p[IPFIX].observationDomainID,
7595 self.ipfix_domain_id)
7596 if p.haslayer(Data):
7597 data = ipfix.decode_data_set(p.getlayer(Set))
7598 self.verify_ipfix_max_bibs(data, max_bibs)
7600 def test_ipfix_max_frags(self):
7601 """ IPFIX logging maximum fragments pending reassembly exceeded """
7602 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7604 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7605 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7606 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7607 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7608 src_address=self.pg3.local_ip4n,
7610 template_interval=10)
7611 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7612 src_port=self.ipfix_src_port)
7615 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7616 self.tcp_port_in, 20, data)
7618 self.pg0.add_stream(pkts)
7619 self.pg_enable_capture(self.pg_interfaces)
7621 self.pg1.assert_nothing_captured()
7623 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7624 capture = self.pg3.get_capture(9)
7625 ipfix = IPFIXDecoder()
7626 # first load template
7628 self.assertTrue(p.haslayer(IPFIX))
7629 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7630 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7631 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7632 self.assertEqual(p[UDP].dport, 4739)
7633 self.assertEqual(p[IPFIX].observationDomainID,
7634 self.ipfix_domain_id)
7635 if p.haslayer(Template):
7636 ipfix.add_template(p.getlayer(Template))
7637 # verify events in data set
7639 if p.haslayer(Data):
7640 data = ipfix.decode_data_set(p.getlayer(Set))
7641 self.verify_ipfix_max_fragments_ip6(data, 1,
7642 self.pg0.remote_ip6n)
7644 def test_ipfix_bib_ses(self):
7645 """ IPFIX logging NAT64 BIB/session create and delete events """
7646 self.tcp_port_in = random.randint(1025, 65535)
7647 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7651 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7653 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7654 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7655 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7656 src_address=self.pg3.local_ip4n,
7658 template_interval=10)
7659 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7660 src_port=self.ipfix_src_port)
7663 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7664 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7665 TCP(sport=self.tcp_port_in, dport=25))
7666 self.pg0.add_stream(p)
7667 self.pg_enable_capture(self.pg_interfaces)
7669 p = self.pg1.get_capture(1)
7670 self.tcp_port_out = p[0][TCP].sport
7671 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7672 capture = self.pg3.get_capture(10)
7673 ipfix = IPFIXDecoder()
7674 # first load template
7676 self.assertTrue(p.haslayer(IPFIX))
7677 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7678 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7679 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7680 self.assertEqual(p[UDP].dport, 4739)
7681 self.assertEqual(p[IPFIX].observationDomainID,
7682 self.ipfix_domain_id)
7683 if p.haslayer(Template):
7684 ipfix.add_template(p.getlayer(Template))
7685 # verify events in data set
7687 if p.haslayer(Data):
7688 data = ipfix.decode_data_set(p.getlayer(Set))
7689 if ord(data[0][230]) == 10:
7690 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7691 elif ord(data[0][230]) == 6:
7692 self.verify_ipfix_nat64_ses(data,
7694 self.pg0.remote_ip6n,
7695 self.pg1.remote_ip4,
7698 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7701 self.pg_enable_capture(self.pg_interfaces)
7702 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7705 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7706 capture = self.pg3.get_capture(2)
7707 # verify events in data set
7709 self.assertTrue(p.haslayer(IPFIX))
7710 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7711 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7712 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7713 self.assertEqual(p[UDP].dport, 4739)
7714 self.assertEqual(p[IPFIX].observationDomainID,
7715 self.ipfix_domain_id)
7716 if p.haslayer(Data):
7717 data = ipfix.decode_data_set(p.getlayer(Set))
7718 if ord(data[0][230]) == 11:
7719 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7720 elif ord(data[0][230]) == 7:
7721 self.verify_ipfix_nat64_ses(data,
7723 self.pg0.remote_ip6n,
7724 self.pg1.remote_ip4,
7727 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7729 def nat64_get_ses_num(self):
7731 Return number of active NAT64 sessions.
7733 st = self.vapi.nat64_st_dump()
7736 def clear_nat64(self):
7738 Clear NAT64 configuration.
7740 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7741 domain_id=self.ipfix_domain_id)
7742 self.ipfix_src_port = 4739
7743 self.ipfix_domain_id = 1
7745 self.vapi.nat_set_timeouts()
7747 interfaces = self.vapi.nat64_interface_dump()
7748 for intf in interfaces:
7749 if intf.is_inside > 1:
7750 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7753 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7757 bib = self.vapi.nat64_bib_dump(255)
7760 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7768 adresses = self.vapi.nat64_pool_addr_dump()
7769 for addr in adresses:
7770 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7775 prefixes = self.vapi.nat64_prefix_dump()
7776 for prefix in prefixes:
7777 self.vapi.nat64_add_del_prefix(prefix.prefix,
7779 vrf_id=prefix.vrf_id,
7783 super(TestNAT64, self).tearDown()
7784 if not self.vpp_dead:
7785 self.logger.info(self.vapi.cli("show nat64 pool"))
7786 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7787 self.logger.info(self.vapi.cli("show nat64 prefix"))
7788 self.logger.info(self.vapi.cli("show nat64 bib all"))
7789 self.logger.info(self.vapi.cli("show nat64 session table all"))
7790 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7794 class TestDSlite(MethodHolder):
7795 """ DS-Lite Test Cases """
7798 def setUpClass(cls):
7799 super(TestDSlite, cls).setUpClass()
7802 cls.nat_addr = '10.0.0.3'
7803 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7805 cls.create_pg_interfaces(range(2))
7807 cls.pg0.config_ip4()
7808 cls.pg0.resolve_arp()
7810 cls.pg1.config_ip6()
7811 cls.pg1.generate_remote_hosts(2)
7812 cls.pg1.configure_ipv6_neighbors()
7815 super(TestDSlite, cls).tearDownClass()
7818 def test_dslite(self):
7819 """ Test DS-Lite """
7820 nat_config = self.vapi.nat_show_config()
7821 self.assertEqual(0, nat_config.dslite_ce)
7823 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7825 aftr_ip4 = '192.0.0.1'
7826 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7827 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7828 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7829 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7832 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7833 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
7834 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7835 UDP(sport=20000, dport=10000))
7836 self.pg1.add_stream(p)
7837 self.pg_enable_capture(self.pg_interfaces)
7839 capture = self.pg0.get_capture(1)
7840 capture = capture[0]
7841 self.assertFalse(capture.haslayer(IPv6))
7842 self.assertEqual(capture[IP].src, self.nat_addr)
7843 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7844 self.assertNotEqual(capture[UDP].sport, 20000)
7845 self.assertEqual(capture[UDP].dport, 10000)
7846 self.assert_packet_checksums_valid(capture)
7847 out_port = capture[UDP].sport
7849 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7850 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7851 UDP(sport=10000, dport=out_port))
7852 self.pg0.add_stream(p)
7853 self.pg_enable_capture(self.pg_interfaces)
7855 capture = self.pg1.get_capture(1)
7856 capture = capture[0]
7857 self.assertEqual(capture[IPv6].src, aftr_ip6)
7858 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7859 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7860 self.assertEqual(capture[IP].dst, '192.168.1.1')
7861 self.assertEqual(capture[UDP].sport, 10000)
7862 self.assertEqual(capture[UDP].dport, 20000)
7863 self.assert_packet_checksums_valid(capture)
7866 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7867 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7868 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7869 TCP(sport=20001, dport=10001))
7870 self.pg1.add_stream(p)
7871 self.pg_enable_capture(self.pg_interfaces)
7873 capture = self.pg0.get_capture(1)
7874 capture = capture[0]
7875 self.assertFalse(capture.haslayer(IPv6))
7876 self.assertEqual(capture[IP].src, self.nat_addr)
7877 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7878 self.assertNotEqual(capture[TCP].sport, 20001)
7879 self.assertEqual(capture[TCP].dport, 10001)
7880 self.assert_packet_checksums_valid(capture)
7881 out_port = capture[TCP].sport
7883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7884 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7885 TCP(sport=10001, dport=out_port))
7886 self.pg0.add_stream(p)
7887 self.pg_enable_capture(self.pg_interfaces)
7889 capture = self.pg1.get_capture(1)
7890 capture = capture[0]
7891 self.assertEqual(capture[IPv6].src, aftr_ip6)
7892 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7893 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7894 self.assertEqual(capture[IP].dst, '192.168.1.1')
7895 self.assertEqual(capture[TCP].sport, 10001)
7896 self.assertEqual(capture[TCP].dport, 20001)
7897 self.assert_packet_checksums_valid(capture)
7900 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7901 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
7902 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
7903 ICMP(id=4000, type='echo-request'))
7904 self.pg1.add_stream(p)
7905 self.pg_enable_capture(self.pg_interfaces)
7907 capture = self.pg0.get_capture(1)
7908 capture = capture[0]
7909 self.assertFalse(capture.haslayer(IPv6))
7910 self.assertEqual(capture[IP].src, self.nat_addr)
7911 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7912 self.assertNotEqual(capture[ICMP].id, 4000)
7913 self.assert_packet_checksums_valid(capture)
7914 out_id = capture[ICMP].id
7916 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7917 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
7918 ICMP(id=out_id, type='echo-reply'))
7919 self.pg0.add_stream(p)
7920 self.pg_enable_capture(self.pg_interfaces)
7922 capture = self.pg1.get_capture(1)
7923 capture = capture[0]
7924 self.assertEqual(capture[IPv6].src, aftr_ip6)
7925 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7926 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7927 self.assertEqual(capture[IP].dst, '192.168.1.1')
7928 self.assertEqual(capture[ICMP].id, 4000)
7929 self.assert_packet_checksums_valid(capture)
7931 # ping DS-Lite AFTR tunnel endpoint address
7932 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7933 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7934 ICMPv6EchoRequest())
7935 self.pg1.add_stream(p)
7936 self.pg_enable_capture(self.pg_interfaces)
7938 capture = self.pg1.get_capture(1)
7939 capture = capture[0]
7940 self.assertEqual(capture[IPv6].src, aftr_ip6)
7941 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7942 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7945 super(TestDSlite, self).tearDown()
7946 if not self.vpp_dead:
7947 self.logger.info(self.vapi.cli("show dslite pool"))
7949 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7950 self.logger.info(self.vapi.cli("show dslite sessions"))
7953 class TestDSliteCE(MethodHolder):
7954 """ DS-Lite CE Test Cases """
7957 def setUpConstants(cls):
7958 super(TestDSliteCE, cls).setUpConstants()
7959 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7962 def setUpClass(cls):
7963 super(TestDSliteCE, cls).setUpClass()
7966 cls.create_pg_interfaces(range(2))
7968 cls.pg0.config_ip4()
7969 cls.pg0.resolve_arp()
7971 cls.pg1.config_ip6()
7972 cls.pg1.generate_remote_hosts(1)
7973 cls.pg1.configure_ipv6_neighbors()
7976 super(TestDSliteCE, cls).tearDownClass()
7979 def test_dslite_ce(self):
7980 """ Test DS-Lite CE """
7982 nat_config = self.vapi.nat_show_config()
7983 self.assertEqual(1, nat_config.dslite_ce)
7985 b4_ip4 = '192.0.0.2'
7986 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7987 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7988 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7989 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7991 aftr_ip4 = '192.0.0.1'
7992 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7993 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7994 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7995 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7997 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7998 dst_address_length=128,
7999 next_hop_address=self.pg1.remote_ip6n,
8000 next_hop_sw_if_index=self.pg1.sw_if_index,
8004 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8005 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8006 UDP(sport=10000, dport=20000))
8007 self.pg0.add_stream(p)
8008 self.pg_enable_capture(self.pg_interfaces)
8010 capture = self.pg1.get_capture(1)
8011 capture = capture[0]
8012 self.assertEqual(capture[IPv6].src, b4_ip6)
8013 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8014 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8015 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8016 self.assertEqual(capture[UDP].sport, 10000)
8017 self.assertEqual(capture[UDP].dport, 20000)
8018 self.assert_packet_checksums_valid(capture)
8021 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8022 IPv6(dst=b4_ip6, src=aftr_ip6) /
8023 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8024 UDP(sport=20000, dport=10000))
8025 self.pg1.add_stream(p)
8026 self.pg_enable_capture(self.pg_interfaces)
8028 capture = self.pg0.get_capture(1)
8029 capture = capture[0]
8030 self.assertFalse(capture.haslayer(IPv6))
8031 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8032 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8033 self.assertEqual(capture[UDP].sport, 20000)
8034 self.assertEqual(capture[UDP].dport, 10000)
8035 self.assert_packet_checksums_valid(capture)
8037 # ping DS-Lite B4 tunnel endpoint address
8038 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8039 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8040 ICMPv6EchoRequest())
8041 self.pg1.add_stream(p)
8042 self.pg_enable_capture(self.pg_interfaces)
8044 capture = self.pg1.get_capture(1)
8045 capture = capture[0]
8046 self.assertEqual(capture[IPv6].src, b4_ip6)
8047 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8048 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8051 super(TestDSliteCE, self).tearDown()
8052 if not self.vpp_dead:
8054 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8056 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8059 class TestNAT66(MethodHolder):
8060 """ NAT66 Test Cases """
8063 def setUpClass(cls):
8064 super(TestNAT66, cls).setUpClass()
8067 cls.nat_addr = 'fd01:ff::2'
8068 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8070 cls.create_pg_interfaces(range(2))
8071 cls.interfaces = list(cls.pg_interfaces)
8073 for i in cls.interfaces:
8076 i.configure_ipv6_neighbors()
8079 super(TestNAT66, cls).tearDownClass()
8082 def test_static(self):
8083 """ 1:1 NAT66 test """
8084 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8085 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8086 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8091 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8092 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8095 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8096 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8099 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8100 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8101 ICMPv6EchoRequest())
8103 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8104 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8105 GRE() / IP() / TCP())
8107 self.pg0.add_stream(pkts)
8108 self.pg_enable_capture(self.pg_interfaces)
8110 capture = self.pg1.get_capture(len(pkts))
8111 for packet in capture:
8113 self.assertEqual(packet[IPv6].src, self.nat_addr)
8114 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8115 self.assert_packet_checksums_valid(packet)
8117 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8122 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8123 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8126 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8127 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8130 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8131 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8134 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8135 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8136 GRE() / IP() / TCP())
8138 self.pg1.add_stream(pkts)
8139 self.pg_enable_capture(self.pg_interfaces)
8141 capture = self.pg0.get_capture(len(pkts))
8142 for packet in capture:
8144 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8145 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8146 self.assert_packet_checksums_valid(packet)
8148 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8151 sm = self.vapi.nat66_static_mapping_dump()
8152 self.assertEqual(len(sm), 1)
8153 self.assertEqual(sm[0].total_pkts, 8)
8155 def test_check_no_translate(self):
8156 """ NAT66 translate only when egress interface is outside interface """
8157 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8158 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8159 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8163 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8164 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8166 self.pg0.add_stream([p])
8167 self.pg_enable_capture(self.pg_interfaces)
8169 capture = self.pg1.get_capture(1)
8172 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8173 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8175 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8178 def clear_nat66(self):
8180 Clear NAT66 configuration.
8182 interfaces = self.vapi.nat66_interface_dump()
8183 for intf in interfaces:
8184 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8188 static_mappings = self.vapi.nat66_static_mapping_dump()
8189 for sm in static_mappings:
8190 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8191 sm.external_ip_address,
8196 super(TestNAT66, self).tearDown()
8197 if not self.vpp_dead:
8198 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8199 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8203 if __name__ == '__main__':
8204 unittest.main(testRunner=VppTestRunner)