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
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from vpp_papi_provider import SYSLOG_SEVERITY
29 class MethodHolder(VppTestCase):
30 """ NAT create capture and verify method holder """
32 def clear_nat44(self):
34 Clear NAT44 configuration.
36 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
37 # I found no elegant way to do this
38 self.vapi.ip_add_del_route(
39 dst_address=self.pg7.remote_ip4n,
40 dst_address_length=32,
41 next_hop_address=self.pg7.remote_ip4n,
42 next_hop_sw_if_index=self.pg7.sw_if_index,
44 self.vapi.ip_add_del_route(
45 dst_address=self.pg8.remote_ip4n,
46 dst_address_length=32,
47 next_hop_address=self.pg8.remote_ip4n,
48 next_hop_sw_if_index=self.pg8.sw_if_index,
51 for intf in [self.pg7, self.pg8]:
52 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
54 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
59 if self.pg7.has_ip4_config:
60 self.pg7.unconfig_ip4()
62 self.vapi.nat44_forwarding_enable_disable(0)
64 interfaces = self.vapi.nat44_interface_addr_dump()
65 for intf in interfaces:
66 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
67 twice_nat=intf.twice_nat,
70 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
71 domain_id=self.ipfix_domain_id)
72 self.ipfix_src_port = 4739
73 self.ipfix_domain_id = 1
75 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
77 interfaces = self.vapi.nat44_interface_dump()
78 for intf in interfaces:
79 if intf.is_inside > 1:
80 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
83 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
87 interfaces = self.vapi.nat44_interface_output_feature_dump()
88 for intf in interfaces:
89 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
93 static_mappings = self.vapi.nat44_static_mapping_dump()
94 for sm in static_mappings:
95 self.vapi.nat44_add_del_static_mapping(
97 sm.external_ip_address,
98 local_port=sm.local_port,
99 external_port=sm.external_port,
100 addr_only=sm.addr_only,
102 protocol=sm.protocol,
103 twice_nat=sm.twice_nat,
104 self_twice_nat=sm.self_twice_nat,
105 out2in_only=sm.out2in_only,
107 external_sw_if_index=sm.external_sw_if_index,
110 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
111 for lb_sm in lb_static_mappings:
112 self.vapi.nat44_add_del_lb_static_mapping(
116 twice_nat=lb_sm.twice_nat,
117 self_twice_nat=lb_sm.self_twice_nat,
118 out2in_only=lb_sm.out2in_only,
124 identity_mappings = self.vapi.nat44_identity_mapping_dump()
125 for id_m in identity_mappings:
126 self.vapi.nat44_add_del_identity_mapping(
127 addr_only=id_m.addr_only,
130 sw_if_index=id_m.sw_if_index,
132 protocol=id_m.protocol,
135 adresses = self.vapi.nat44_address_dump()
136 for addr in adresses:
137 self.vapi.nat44_add_del_address_range(addr.ip_address,
139 twice_nat=addr.twice_nat,
142 self.vapi.nat_set_reass()
143 self.vapi.nat_set_reass(is_ip6=1)
144 self.verify_no_nat44_user()
145 self.vapi.nat_set_timeouts()
146 self.vapi.nat_set_addr_and_port_alloc_alg()
147 self.vapi.nat_set_mss_clamping()
149 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
150 local_port=0, external_port=0, vrf_id=0,
151 is_add=1, external_sw_if_index=0xFFFFFFFF,
152 proto=0, twice_nat=0, self_twice_nat=0,
153 out2in_only=0, tag=""):
155 Add/delete NAT44 static mapping
157 :param local_ip: Local IP address
158 :param external_ip: External IP address
159 :param local_port: Local port number (Optional)
160 :param external_port: External port number (Optional)
161 :param vrf_id: VRF ID (Default 0)
162 :param is_add: 1 if add, 0 if delete (Default add)
163 :param external_sw_if_index: External interface instead of IP address
164 :param proto: IP protocol (Mandatory if port specified)
165 :param twice_nat: 1 if translate external host address and port
166 :param self_twice_nat: 1 if translate external host address and port
167 whenever external host address equals
168 local address of internal host
169 :param out2in_only: if 1 rule is matching only out2in direction
170 :param tag: Opaque string tag
173 if local_port and external_port:
175 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
176 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
177 self.vapi.nat44_add_del_static_mapping(
180 external_sw_if_index,
192 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
194 Add/delete NAT44 address
196 :param ip: IP address
197 :param is_add: 1 if add, 0 if delete (Default add)
198 :param twice_nat: twice NAT address for extenal hosts
200 nat_addr = socket.inet_pton(socket.AF_INET, ip)
201 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
205 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
207 Create packet stream for inside network
209 :param in_if: Inside interface
210 :param out_if: Outside interface
211 :param dst_ip: Destination address
212 :param ttl: TTL of generated packets
215 dst_ip = out_if.remote_ip4
219 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
220 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
221 TCP(sport=self.tcp_port_in, dport=20))
225 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
226 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
227 UDP(sport=self.udp_port_in, dport=20))
231 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
232 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
233 ICMP(id=self.icmp_id_in, type='echo-request'))
238 def compose_ip6(self, ip4, pref, plen):
240 Compose IPv4-embedded IPv6 addresses
242 :param ip4: IPv4 address
243 :param pref: IPv6 prefix
244 :param plen: IPv6 prefix length
245 :returns: IPv4-embedded IPv6 addresses
247 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
248 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
263 pref_n[10] = ip4_n[3]
267 pref_n[10] = ip4_n[2]
268 pref_n[11] = ip4_n[3]
271 pref_n[10] = ip4_n[1]
272 pref_n[11] = ip4_n[2]
273 pref_n[12] = ip4_n[3]
275 pref_n[12] = ip4_n[0]
276 pref_n[13] = ip4_n[1]
277 pref_n[14] = ip4_n[2]
278 pref_n[15] = ip4_n[3]
279 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
281 def extract_ip4(self, ip6, plen):
283 Extract IPv4 address embedded in IPv6 addresses
285 :param ip6: IPv6 address
286 :param plen: IPv6 prefix length
287 :returns: extracted IPv4 address
289 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
321 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
323 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
325 Create IPv6 packet stream for inside network
327 :param in_if: Inside interface
328 :param out_if: Outside interface
329 :param ttl: Hop Limit of generated packets
330 :param pref: NAT64 prefix
331 :param plen: NAT64 prefix length
335 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
337 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
340 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
341 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
342 TCP(sport=self.tcp_port_in, dport=20))
346 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
347 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
348 UDP(sport=self.udp_port_in, dport=20))
352 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
353 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
354 ICMPv6EchoRequest(id=self.icmp_id_in))
359 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
360 use_inside_ports=False):
362 Create packet stream for outside network
364 :param out_if: Outside interface
365 :param dst_ip: Destination IP address (Default use global NAT address)
366 :param ttl: TTL of generated packets
367 :param use_inside_ports: Use inside NAT ports as destination ports
368 instead of outside ports
371 dst_ip = self.nat_addr
372 if not use_inside_ports:
373 tcp_port = self.tcp_port_out
374 udp_port = self.udp_port_out
375 icmp_id = self.icmp_id_out
377 tcp_port = self.tcp_port_in
378 udp_port = self.udp_port_in
379 icmp_id = self.icmp_id_in
382 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
383 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
384 TCP(dport=tcp_port, sport=20))
388 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
389 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
390 UDP(dport=udp_port, sport=20))
394 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
395 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
396 ICMP(id=icmp_id, type='echo-reply'))
401 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
403 Create packet stream for outside network
405 :param out_if: Outside interface
406 :param dst_ip: Destination IP address (Default use global NAT address)
407 :param hl: HL of generated packets
411 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
412 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
413 TCP(dport=self.tcp_port_out, sport=20))
417 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
418 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
419 UDP(dport=self.udp_port_out, sport=20))
423 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
424 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
425 ICMPv6EchoReply(id=self.icmp_id_out))
430 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
431 dst_ip=None, is_ip6=False):
433 Verify captured packets on outside network
435 :param capture: Captured packets
436 :param nat_ip: Translated IP address (Default use global NAT address)
437 :param same_port: Sorce port number is not translated (Default False)
438 :param dst_ip: Destination IP address (Default do not verify)
439 :param is_ip6: If L3 protocol is IPv6 (Default False)
443 ICMP46 = ICMPv6EchoRequest
448 nat_ip = self.nat_addr
449 for packet in capture:
452 self.assert_packet_checksums_valid(packet)
453 self.assertEqual(packet[IP46].src, nat_ip)
454 if dst_ip is not None:
455 self.assertEqual(packet[IP46].dst, dst_ip)
456 if packet.haslayer(TCP):
458 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
461 packet[TCP].sport, self.tcp_port_in)
462 self.tcp_port_out = packet[TCP].sport
463 self.assert_packet_checksums_valid(packet)
464 elif packet.haslayer(UDP):
466 self.assertEqual(packet[UDP].sport, self.udp_port_in)
469 packet[UDP].sport, self.udp_port_in)
470 self.udp_port_out = packet[UDP].sport
473 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
475 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
476 self.icmp_id_out = packet[ICMP46].id
477 self.assert_packet_checksums_valid(packet)
479 self.logger.error(ppp("Unexpected or invalid packet "
480 "(outside network):", packet))
483 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
486 Verify captured packets on outside network
488 :param capture: Captured packets
489 :param nat_ip: Translated IP address
490 :param same_port: Sorce port number is not translated (Default False)
491 :param dst_ip: Destination IP address (Default do not verify)
493 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
496 def verify_capture_in(self, capture, in_if):
498 Verify captured packets on inside network
500 :param capture: Captured packets
501 :param in_if: Inside interface
503 for packet in capture:
505 self.assert_packet_checksums_valid(packet)
506 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
507 if packet.haslayer(TCP):
508 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
509 elif packet.haslayer(UDP):
510 self.assertEqual(packet[UDP].dport, self.udp_port_in)
512 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
514 self.logger.error(ppp("Unexpected or invalid packet "
515 "(inside network):", packet))
518 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
520 Verify captured IPv6 packets on inside network
522 :param capture: Captured packets
523 :param src_ip: Source IP
524 :param dst_ip: Destination IP address
526 for packet in capture:
528 self.assertEqual(packet[IPv6].src, src_ip)
529 self.assertEqual(packet[IPv6].dst, dst_ip)
530 self.assert_packet_checksums_valid(packet)
531 if packet.haslayer(TCP):
532 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
533 elif packet.haslayer(UDP):
534 self.assertEqual(packet[UDP].dport, self.udp_port_in)
536 self.assertEqual(packet[ICMPv6EchoReply].id,
539 self.logger.error(ppp("Unexpected or invalid packet "
540 "(inside network):", packet))
543 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
545 Verify captured packet that don't have to be translated
547 :param capture: Captured packets
548 :param ingress_if: Ingress interface
549 :param egress_if: Egress interface
551 for packet in capture:
553 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
554 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
555 if packet.haslayer(TCP):
556 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
557 elif packet.haslayer(UDP):
558 self.assertEqual(packet[UDP].sport, self.udp_port_in)
560 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
562 self.logger.error(ppp("Unexpected or invalid packet "
563 "(inside network):", packet))
566 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
569 Verify captured packets with ICMP errors on outside network
571 :param capture: Captured packets
572 :param src_ip: Translated IP address or IP address of VPP
573 (Default use global NAT address)
574 :param icmp_type: Type of error ICMP packet
575 we are expecting (Default 11)
578 src_ip = self.nat_addr
579 for packet in capture:
581 self.assertEqual(packet[IP].src, src_ip)
582 self.assertTrue(packet.haslayer(ICMP))
584 self.assertEqual(icmp.type, icmp_type)
585 self.assertTrue(icmp.haslayer(IPerror))
586 inner_ip = icmp[IPerror]
587 if inner_ip.haslayer(TCPerror):
588 self.assertEqual(inner_ip[TCPerror].dport,
590 elif inner_ip.haslayer(UDPerror):
591 self.assertEqual(inner_ip[UDPerror].dport,
594 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
596 self.logger.error(ppp("Unexpected or invalid packet "
597 "(outside network):", packet))
600 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
602 Verify captured packets with ICMP errors on inside network
604 :param capture: Captured packets
605 :param in_if: Inside interface
606 :param icmp_type: Type of error ICMP packet
607 we are expecting (Default 11)
609 for packet in capture:
611 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
612 self.assertTrue(packet.haslayer(ICMP))
614 self.assertEqual(icmp.type, icmp_type)
615 self.assertTrue(icmp.haslayer(IPerror))
616 inner_ip = icmp[IPerror]
617 if inner_ip.haslayer(TCPerror):
618 self.assertEqual(inner_ip[TCPerror].sport,
620 elif inner_ip.haslayer(UDPerror):
621 self.assertEqual(inner_ip[UDPerror].sport,
624 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
626 self.logger.error(ppp("Unexpected or invalid packet "
627 "(inside network):", packet))
630 def create_stream_frag(self, src_if, dst, sport, dport, data,
631 proto=IP_PROTOS.tcp, echo_reply=False):
633 Create fragmented packet stream
635 :param src_if: Source interface
636 :param dst: Destination IPv4 address
637 :param sport: Source port
638 :param dport: Destination port
639 :param data: Payload data
640 :param proto: protocol (TCP, UDP, ICMP)
641 :param echo_reply: use echo_reply if protocol is ICMP
644 if proto == IP_PROTOS.tcp:
645 p = (IP(src=src_if.remote_ip4, dst=dst) /
646 TCP(sport=sport, dport=dport) /
648 p = p.__class__(str(p))
649 chksum = p['TCP'].chksum
650 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
651 elif proto == IP_PROTOS.udp:
652 proto_header = UDP(sport=sport, dport=dport)
653 elif proto == IP_PROTOS.icmp:
655 proto_header = ICMP(id=sport, type='echo-request')
657 proto_header = ICMP(id=sport, type='echo-reply')
659 raise Exception("Unsupported protocol")
660 id = random.randint(0, 65535)
662 if proto == IP_PROTOS.tcp:
665 raw = Raw(data[0:16])
666 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
667 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
671 if proto == IP_PROTOS.tcp:
672 raw = Raw(data[4:20])
674 raw = Raw(data[16:32])
675 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
676 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
680 if proto == IP_PROTOS.tcp:
684 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
685 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
691 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
692 pref=None, plen=0, frag_size=128):
694 Create fragmented packet stream
696 :param src_if: Source interface
697 :param dst: Destination IPv4 address
698 :param sport: Source TCP port
699 :param dport: Destination TCP port
700 :param data: Payload data
701 :param pref: NAT64 prefix
702 :param plen: NAT64 prefix length
703 :param fragsize: size of fragments
707 dst_ip6 = ''.join(['64:ff9b::', dst])
709 dst_ip6 = self.compose_ip6(dst, pref, plen)
711 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
712 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
713 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
714 TCP(sport=sport, dport=dport) /
717 return fragment6(p, frag_size)
719 def reass_frags_and_verify(self, frags, src, dst):
721 Reassemble and verify fragmented packet
723 :param frags: Captured fragments
724 :param src: Source IPv4 address to verify
725 :param dst: Destination IPv4 address to verify
727 :returns: Reassembled IPv4 packet
729 buffer = StringIO.StringIO()
731 self.assertEqual(p[IP].src, src)
732 self.assertEqual(p[IP].dst, dst)
733 self.assert_ip_checksum_valid(p)
734 buffer.seek(p[IP].frag * 8)
735 buffer.write(p[IP].payload)
736 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
737 proto=frags[0][IP].proto)
738 if ip.proto == IP_PROTOS.tcp:
739 p = (ip / TCP(buffer.getvalue()))
740 self.assert_tcp_checksum_valid(p)
741 elif ip.proto == IP_PROTOS.udp:
742 p = (ip / UDP(buffer.getvalue()[:8]) /
743 Raw(buffer.getvalue()[8:]))
744 elif ip.proto == IP_PROTOS.icmp:
745 p = (ip / ICMP(buffer.getvalue()))
748 def reass_frags_and_verify_ip6(self, frags, src, dst):
750 Reassemble and verify fragmented packet
752 :param frags: Captured fragments
753 :param src: Source IPv6 address to verify
754 :param dst: Destination IPv6 address to verify
756 :returns: Reassembled IPv6 packet
758 buffer = StringIO.StringIO()
760 self.assertEqual(p[IPv6].src, src)
761 self.assertEqual(p[IPv6].dst, dst)
762 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
763 buffer.write(p[IPv6ExtHdrFragment].payload)
764 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
765 nh=frags[0][IPv6ExtHdrFragment].nh)
766 if ip.nh == IP_PROTOS.tcp:
767 p = (ip / TCP(buffer.getvalue()))
768 elif ip.nh == IP_PROTOS.udp:
769 p = (ip / UDP(buffer.getvalue()))
770 self.assert_packet_checksums_valid(p)
773 def initiate_tcp_session(self, in_if, out_if):
775 Initiates TCP session
777 :param in_if: Inside interface
778 :param out_if: Outside interface
782 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
783 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
784 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
787 self.pg_enable_capture(self.pg_interfaces)
789 capture = out_if.get_capture(1)
791 self.tcp_port_out = p[TCP].sport
793 # SYN + ACK packet out->in
794 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
795 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
796 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
799 self.pg_enable_capture(self.pg_interfaces)
804 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
805 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
806 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
809 self.pg_enable_capture(self.pg_interfaces)
811 out_if.get_capture(1)
814 self.logger.error("TCP 3 way handshake failed")
817 def verify_ipfix_nat44_ses(self, data):
819 Verify IPFIX NAT44 session create/delete event
821 :param data: Decoded IPFIX data records
823 nat44_ses_create_num = 0
824 nat44_ses_delete_num = 0
825 self.assertEqual(6, len(data))
828 self.assertIn(ord(record[230]), [4, 5])
829 if ord(record[230]) == 4:
830 nat44_ses_create_num += 1
832 nat44_ses_delete_num += 1
834 self.assertEqual(self.pg0.remote_ip4n, record[8])
835 # postNATSourceIPv4Address
836 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
839 self.assertEqual(struct.pack("!I", 0), record[234])
840 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
841 if IP_PROTOS.icmp == ord(record[4]):
842 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
843 self.assertEqual(struct.pack("!H", self.icmp_id_out),
845 elif IP_PROTOS.tcp == ord(record[4]):
846 self.assertEqual(struct.pack("!H", self.tcp_port_in),
848 self.assertEqual(struct.pack("!H", self.tcp_port_out),
850 elif IP_PROTOS.udp == ord(record[4]):
851 self.assertEqual(struct.pack("!H", self.udp_port_in),
853 self.assertEqual(struct.pack("!H", self.udp_port_out),
856 self.fail("Invalid protocol")
857 self.assertEqual(3, nat44_ses_create_num)
858 self.assertEqual(3, nat44_ses_delete_num)
860 def verify_ipfix_addr_exhausted(self, data):
862 Verify IPFIX NAT addresses event
864 :param data: Decoded IPFIX data records
866 self.assertEqual(1, len(data))
869 self.assertEqual(ord(record[230]), 3)
871 self.assertEqual(struct.pack("!I", 0), record[283])
873 def verify_ipfix_max_sessions(self, data, limit):
875 Verify IPFIX maximum session entries exceeded event
877 :param data: Decoded IPFIX data records
878 :param limit: Number of maximum session entries that can be created.
880 self.assertEqual(1, len(data))
883 self.assertEqual(ord(record[230]), 13)
884 # natQuotaExceededEvent
885 self.assertEqual(struct.pack("I", 1), record[466])
887 self.assertEqual(struct.pack("I", limit), record[471])
889 def verify_ipfix_max_bibs(self, data, limit):
891 Verify IPFIX maximum BIB entries exceeded event
893 :param data: Decoded IPFIX data records
894 :param limit: Number of maximum BIB entries that can be created.
896 self.assertEqual(1, len(data))
899 self.assertEqual(ord(record[230]), 13)
900 # natQuotaExceededEvent
901 self.assertEqual(struct.pack("I", 2), record[466])
903 self.assertEqual(struct.pack("I", limit), record[472])
905 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
907 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
909 :param data: Decoded IPFIX data records
910 :param limit: Number of maximum fragments pending reassembly
911 :param src_addr: IPv6 source address
913 self.assertEqual(1, len(data))
916 self.assertEqual(ord(record[230]), 13)
917 # natQuotaExceededEvent
918 self.assertEqual(struct.pack("I", 5), record[466])
919 # maxFragmentsPendingReassembly
920 self.assertEqual(struct.pack("I", limit), record[475])
922 self.assertEqual(src_addr, record[27])
924 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
926 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
928 :param data: Decoded IPFIX data records
929 :param limit: Number of maximum fragments pending reassembly
930 :param src_addr: IPv4 source address
932 self.assertEqual(1, len(data))
935 self.assertEqual(ord(record[230]), 13)
936 # natQuotaExceededEvent
937 self.assertEqual(struct.pack("I", 5), record[466])
938 # maxFragmentsPendingReassembly
939 self.assertEqual(struct.pack("I", limit), record[475])
941 self.assertEqual(src_addr, record[8])
943 def verify_ipfix_bib(self, data, is_create, src_addr):
945 Verify IPFIX NAT64 BIB create and delete events
947 :param data: Decoded IPFIX data records
948 :param is_create: Create event if nonzero value otherwise delete event
949 :param src_addr: IPv6 source address
951 self.assertEqual(1, len(data))
955 self.assertEqual(ord(record[230]), 10)
957 self.assertEqual(ord(record[230]), 11)
959 self.assertEqual(src_addr, record[27])
960 # postNATSourceIPv4Address
961 self.assertEqual(self.nat_addr_n, record[225])
963 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
965 self.assertEqual(struct.pack("!I", 0), record[234])
966 # sourceTransportPort
967 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
968 # postNAPTSourceTransportPort
969 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
971 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
974 Verify IPFIX NAT64 session create and delete events
976 :param data: Decoded IPFIX data records
977 :param is_create: Create event if nonzero value otherwise delete event
978 :param src_addr: IPv6 source address
979 :param dst_addr: IPv4 destination address
980 :param dst_port: destination TCP port
982 self.assertEqual(1, len(data))
986 self.assertEqual(ord(record[230]), 6)
988 self.assertEqual(ord(record[230]), 7)
990 self.assertEqual(src_addr, record[27])
991 # destinationIPv6Address
992 self.assertEqual(socket.inet_pton(socket.AF_INET6,
993 self.compose_ip6(dst_addr,
997 # postNATSourceIPv4Address
998 self.assertEqual(self.nat_addr_n, record[225])
999 # postNATDestinationIPv4Address
1000 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1002 # protocolIdentifier
1003 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1005 self.assertEqual(struct.pack("!I", 0), record[234])
1006 # sourceTransportPort
1007 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1008 # postNAPTSourceTransportPort
1009 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1010 # destinationTransportPort
1011 self.assertEqual(struct.pack("!H", dst_port), record[11])
1012 # postNAPTDestinationTransportPort
1013 self.assertEqual(struct.pack("!H", dst_port), record[228])
1015 def verify_no_nat44_user(self):
1016 """ Verify that there is no NAT44 user """
1017 users = self.vapi.nat44_user_dump()
1018 self.assertEqual(len(users), 0)
1020 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1022 Verify IPFIX maximum entries per user exceeded event
1024 :param data: Decoded IPFIX data records
1025 :param limit: Number of maximum entries per user
1026 :param src_addr: IPv4 source address
1028 self.assertEqual(1, len(data))
1031 self.assertEqual(ord(record[230]), 13)
1032 # natQuotaExceededEvent
1033 self.assertEqual(struct.pack("I", 3), record[466])
1035 self.assertEqual(struct.pack("I", limit), record[473])
1037 self.assertEqual(src_addr, record[8])
1039 def verify_syslog_apmap(self, data, is_add=True):
1040 message = data.decode('utf-8')
1042 message = SyslogMessage.parse(message)
1043 self.assertEqual(message.severity, SyslogSeverity.info)
1044 self.assertEqual(message.appname, 'NAT')
1045 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1046 sd_params = message.sd.get('napmap')
1047 self.assertTrue(sd_params is not None)
1048 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1049 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1050 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1051 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1052 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1053 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1054 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1055 self.assertTrue(sd_params.get('SSUBIX') is not None)
1056 self.assertEqual(sd_params.get('SVLAN'), '0')
1057 except ParseError as e:
1058 self.logger.error(e)
1060 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1061 message = data.decode('utf-8')
1063 message = SyslogMessage.parse(message)
1064 self.assertEqual(message.severity, SyslogSeverity.info)
1065 self.assertEqual(message.appname, 'NAT')
1066 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1067 sd_params = message.sd.get('nsess')
1068 self.assertTrue(sd_params is not None)
1070 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1071 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1073 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1074 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1075 self.assertTrue(sd_params.get('SSUBIX') is not None)
1076 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1077 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1078 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1079 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1080 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1081 self.assertEqual(sd_params.get('SVLAN'), '0')
1082 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1083 self.assertEqual(sd_params.get('XDPORT'),
1084 "%d" % self.tcp_external_port)
1085 except ParseError as e:
1086 self.logger.error(e)
1088 def verify_mss_value(self, pkt, mss):
1090 Verify TCP MSS value
1095 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1096 raise TypeError("Not a TCP/IP packet")
1098 for option in pkt[TCP].options:
1099 if option[0] == 'MSS':
1100 self.assertEqual(option[1], mss)
1101 self.assert_tcp_checksum_valid(pkt)
1104 def proto2layer(proto):
1105 if proto == IP_PROTOS.tcp:
1107 elif proto == IP_PROTOS.udp:
1109 elif proto == IP_PROTOS.icmp:
1112 raise Exception("Unsupported protocol")
1114 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1115 layer = self.proto2layer(proto)
1117 if proto == IP_PROTOS.tcp:
1118 data = "A" * 4 + "B" * 16 + "C" * 3
1120 data = "A" * 16 + "B" * 16 + "C" * 3
1121 self.port_in = random.randint(1025, 65535)
1123 reass = self.vapi.nat_reass_dump()
1124 reass_n_start = len(reass)
1127 pkts = self.create_stream_frag(self.pg0,
1128 self.pg1.remote_ip4,
1133 self.pg0.add_stream(pkts)
1134 self.pg_enable_capture(self.pg_interfaces)
1136 frags = self.pg1.get_capture(len(pkts))
1137 if not dont_translate:
1138 p = self.reass_frags_and_verify(frags,
1140 self.pg1.remote_ip4)
1142 p = self.reass_frags_and_verify(frags,
1143 self.pg0.remote_ip4,
1144 self.pg1.remote_ip4)
1145 if proto != IP_PROTOS.icmp:
1146 if not dont_translate:
1147 self.assertEqual(p[layer].dport, 20)
1148 self.assertNotEqual(p[layer].sport, self.port_in)
1150 self.assertEqual(p[layer].sport, self.port_in)
1152 if not dont_translate:
1153 self.assertNotEqual(p[layer].id, self.port_in)
1155 self.assertEqual(p[layer].id, self.port_in)
1156 self.assertEqual(data, p[Raw].load)
1159 if not dont_translate:
1160 dst_addr = self.nat_addr
1162 dst_addr = self.pg0.remote_ip4
1163 if proto != IP_PROTOS.icmp:
1165 dport = p[layer].sport
1169 pkts = self.create_stream_frag(self.pg1,
1176 self.pg1.add_stream(pkts)
1177 self.pg_enable_capture(self.pg_interfaces)
1179 frags = self.pg0.get_capture(len(pkts))
1180 p = self.reass_frags_and_verify(frags,
1181 self.pg1.remote_ip4,
1182 self.pg0.remote_ip4)
1183 if proto != IP_PROTOS.icmp:
1184 self.assertEqual(p[layer].sport, 20)
1185 self.assertEqual(p[layer].dport, self.port_in)
1187 self.assertEqual(p[layer].id, self.port_in)
1188 self.assertEqual(data, p[Raw].load)
1190 reass = self.vapi.nat_reass_dump()
1191 reass_n_end = len(reass)
1193 self.assertEqual(reass_n_end - reass_n_start, 2)
1195 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1196 layer = self.proto2layer(proto)
1198 if proto == IP_PROTOS.tcp:
1199 data = "A" * 4 + "B" * 16 + "C" * 3
1201 data = "A" * 16 + "B" * 16 + "C" * 3
1202 self.port_in = random.randint(1025, 65535)
1205 reass = self.vapi.nat_reass_dump()
1206 reass_n_start = len(reass)
1209 pkts = self.create_stream_frag(self.pg0,
1210 self.server_out_addr,
1212 self.server_out_port,
1215 self.pg0.add_stream(pkts)
1216 self.pg_enable_capture(self.pg_interfaces)
1218 frags = self.pg1.get_capture(len(pkts))
1219 p = self.reass_frags_and_verify(frags,
1220 self.pg0.remote_ip4,
1221 self.server_in_addr)
1222 if proto != IP_PROTOS.icmp:
1223 self.assertEqual(p[layer].sport, self.port_in)
1224 self.assertEqual(p[layer].dport, self.server_in_port)
1226 self.assertEqual(p[layer].id, self.port_in)
1227 self.assertEqual(data, p[Raw].load)
1230 if proto != IP_PROTOS.icmp:
1231 pkts = self.create_stream_frag(self.pg1,
1232 self.pg0.remote_ip4,
1233 self.server_in_port,
1238 pkts = self.create_stream_frag(self.pg1,
1239 self.pg0.remote_ip4,
1245 self.pg1.add_stream(pkts)
1246 self.pg_enable_capture(self.pg_interfaces)
1248 frags = self.pg0.get_capture(len(pkts))
1249 p = self.reass_frags_and_verify(frags,
1250 self.server_out_addr,
1251 self.pg0.remote_ip4)
1252 if proto != IP_PROTOS.icmp:
1253 self.assertEqual(p[layer].sport, self.server_out_port)
1254 self.assertEqual(p[layer].dport, self.port_in)
1256 self.assertEqual(p[layer].id, self.port_in)
1257 self.assertEqual(data, p[Raw].load)
1259 reass = self.vapi.nat_reass_dump()
1260 reass_n_end = len(reass)
1262 self.assertEqual(reass_n_end - reass_n_start, 2)
1264 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1265 layer = self.proto2layer(proto)
1267 if proto == IP_PROTOS.tcp:
1268 data = "A" * 4 + "B" * 16 + "C" * 3
1270 data = "A" * 16 + "B" * 16 + "C" * 3
1272 # send packet from host to server
1273 pkts = self.create_stream_frag(self.pg0,
1276 self.server_out_port,
1279 self.pg0.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg0.get_capture(len(pkts))
1283 p = self.reass_frags_and_verify(frags,
1286 if proto != IP_PROTOS.icmp:
1287 self.assertNotEqual(p[layer].sport, self.host_in_port)
1288 self.assertEqual(p[layer].dport, self.server_in_port)
1290 self.assertNotEqual(p[layer].id, self.host_in_port)
1291 self.assertEqual(data, p[Raw].load)
1293 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1294 layer = self.proto2layer(proto)
1296 if proto == IP_PROTOS.tcp:
1297 data = "A" * 4 + "B" * 16 + "C" * 3
1299 data = "A" * 16 + "B" * 16 + "C" * 3
1300 self.port_in = random.randint(1025, 65535)
1304 pkts = self.create_stream_frag(self.pg0,
1305 self.pg1.remote_ip4,
1311 self.pg0.add_stream(pkts)
1312 self.pg_enable_capture(self.pg_interfaces)
1314 frags = self.pg1.get_capture(len(pkts))
1315 if not dont_translate:
1316 p = self.reass_frags_and_verify(frags,
1318 self.pg1.remote_ip4)
1320 p = self.reass_frags_and_verify(frags,
1321 self.pg0.remote_ip4,
1322 self.pg1.remote_ip4)
1323 if proto != IP_PROTOS.icmp:
1324 if not dont_translate:
1325 self.assertEqual(p[layer].dport, 20)
1326 self.assertNotEqual(p[layer].sport, self.port_in)
1328 self.assertEqual(p[layer].sport, self.port_in)
1330 if not dont_translate:
1331 self.assertNotEqual(p[layer].id, self.port_in)
1333 self.assertEqual(p[layer].id, self.port_in)
1334 self.assertEqual(data, p[Raw].load)
1337 if not dont_translate:
1338 dst_addr = self.nat_addr
1340 dst_addr = self.pg0.remote_ip4
1341 if proto != IP_PROTOS.icmp:
1343 dport = p[layer].sport
1347 pkts = self.create_stream_frag(self.pg1,
1355 self.pg1.add_stream(pkts)
1356 self.pg_enable_capture(self.pg_interfaces)
1358 frags = self.pg0.get_capture(len(pkts))
1359 p = self.reass_frags_and_verify(frags,
1360 self.pg1.remote_ip4,
1361 self.pg0.remote_ip4)
1362 if proto != IP_PROTOS.icmp:
1363 self.assertEqual(p[layer].sport, 20)
1364 self.assertEqual(p[layer].dport, self.port_in)
1366 self.assertEqual(p[layer].id, self.port_in)
1367 self.assertEqual(data, p[Raw].load)
1369 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1370 layer = self.proto2layer(proto)
1372 if proto == IP_PROTOS.tcp:
1373 data = "A" * 4 + "B" * 16 + "C" * 3
1375 data = "A" * 16 + "B" * 16 + "C" * 3
1376 self.port_in = random.randint(1025, 65535)
1380 pkts = self.create_stream_frag(self.pg0,
1381 self.server_out_addr,
1383 self.server_out_port,
1387 self.pg0.add_stream(pkts)
1388 self.pg_enable_capture(self.pg_interfaces)
1390 frags = self.pg1.get_capture(len(pkts))
1391 p = self.reass_frags_and_verify(frags,
1392 self.pg0.remote_ip4,
1393 self.server_in_addr)
1394 if proto != IP_PROTOS.icmp:
1395 self.assertEqual(p[layer].dport, self.server_in_port)
1396 self.assertEqual(p[layer].sport, self.port_in)
1397 self.assertEqual(p[layer].dport, self.server_in_port)
1399 self.assertEqual(p[layer].id, self.port_in)
1400 self.assertEqual(data, p[Raw].load)
1403 if proto != IP_PROTOS.icmp:
1404 pkts = self.create_stream_frag(self.pg1,
1405 self.pg0.remote_ip4,
1406 self.server_in_port,
1411 pkts = self.create_stream_frag(self.pg1,
1412 self.pg0.remote_ip4,
1419 self.pg1.add_stream(pkts)
1420 self.pg_enable_capture(self.pg_interfaces)
1422 frags = self.pg0.get_capture(len(pkts))
1423 p = self.reass_frags_and_verify(frags,
1424 self.server_out_addr,
1425 self.pg0.remote_ip4)
1426 if proto != IP_PROTOS.icmp:
1427 self.assertEqual(p[layer].sport, self.server_out_port)
1428 self.assertEqual(p[layer].dport, self.port_in)
1430 self.assertEqual(p[layer].id, self.port_in)
1431 self.assertEqual(data, p[Raw].load)
1434 class TestNAT44(MethodHolder):
1435 """ NAT44 Test Cases """
1438 def setUpClass(cls):
1439 super(TestNAT44, cls).setUpClass()
1440 cls.vapi.cli("set log class nat level debug")
1443 cls.tcp_port_in = 6303
1444 cls.tcp_port_out = 6303
1445 cls.udp_port_in = 6304
1446 cls.udp_port_out = 6304
1447 cls.icmp_id_in = 6305
1448 cls.icmp_id_out = 6305
1449 cls.nat_addr = '10.0.0.3'
1450 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
1451 cls.ipfix_src_port = 4739
1452 cls.ipfix_domain_id = 1
1453 cls.tcp_external_port = 80
1455 cls.create_pg_interfaces(range(10))
1456 cls.interfaces = list(cls.pg_interfaces[0:4])
1458 for i in cls.interfaces:
1463 cls.pg0.generate_remote_hosts(3)
1464 cls.pg0.configure_ipv4_neighbors()
1466 cls.pg1.generate_remote_hosts(1)
1467 cls.pg1.configure_ipv4_neighbors()
1469 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1470 cls.vapi.ip_table_add_del(10, is_add=1)
1471 cls.vapi.ip_table_add_del(20, is_add=1)
1473 cls.pg4._local_ip4 = "172.16.255.1"
1474 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1475 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1476 cls.pg4.set_table_ip4(10)
1477 cls.pg5._local_ip4 = "172.17.255.3"
1478 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1479 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1480 cls.pg5.set_table_ip4(10)
1481 cls.pg6._local_ip4 = "172.16.255.1"
1482 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1483 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1484 cls.pg6.set_table_ip4(20)
1485 for i in cls.overlapping_interfaces:
1493 cls.pg9.generate_remote_hosts(2)
1494 cls.pg9.config_ip4()
1495 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1496 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1500 cls.pg9.resolve_arp()
1501 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1502 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1503 cls.pg9.resolve_arp()
1506 super(TestNAT44, cls).tearDownClass()
1509 def test_dynamic(self):
1510 """ NAT44 dynamic translation test """
1512 self.nat44_add_address(self.nat_addr)
1513 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1514 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1518 pkts = self.create_stream_in(self.pg0, self.pg1)
1519 self.pg0.add_stream(pkts)
1520 self.pg_enable_capture(self.pg_interfaces)
1522 capture = self.pg1.get_capture(len(pkts))
1523 self.verify_capture_out(capture)
1526 pkts = self.create_stream_out(self.pg1)
1527 self.pg1.add_stream(pkts)
1528 self.pg_enable_capture(self.pg_interfaces)
1530 capture = self.pg0.get_capture(len(pkts))
1531 self.verify_capture_in(capture, self.pg0)
1533 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1534 """ NAT44 handling of client packets with TTL=1 """
1536 self.nat44_add_address(self.nat_addr)
1537 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1538 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1541 # Client side - generate traffic
1542 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1543 self.pg0.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_1(self):
1552 """ NAT44 handling of server packets with TTL=1 """
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=1)
1569 self.pg1.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1573 # Server side - verify ICMP type 11 packets
1574 capture = self.pg1.get_capture(len(pkts))
1575 self.verify_capture_out_with_icmp_errors(capture,
1576 src_ip=self.pg1.local_ip4)
1578 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1579 """ NAT44 handling of error responses to client packets with TTL=2 """
1581 self.nat44_add_address(self.nat_addr)
1582 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1583 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1586 # Client side - generate traffic
1587 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1588 self.pg0.add_stream(pkts)
1589 self.pg_enable_capture(self.pg_interfaces)
1592 # Server side - simulate ICMP type 11 response
1593 capture = self.pg1.get_capture(len(pkts))
1594 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1595 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1596 ICMP(type=11) / packet[IP] for packet in capture]
1597 self.pg1.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1601 # Client side - verify ICMP type 11 packets
1602 capture = self.pg0.get_capture(len(pkts))
1603 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1605 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1606 """ NAT44 handling of error responses to server packets with TTL=2 """
1608 self.nat44_add_address(self.nat_addr)
1609 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1610 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1613 # Client side - create sessions
1614 pkts = self.create_stream_in(self.pg0, self.pg1)
1615 self.pg0.add_stream(pkts)
1616 self.pg_enable_capture(self.pg_interfaces)
1619 # Server side - generate traffic
1620 capture = self.pg1.get_capture(len(pkts))
1621 self.verify_capture_out(capture)
1622 pkts = self.create_stream_out(self.pg1, ttl=2)
1623 self.pg1.add_stream(pkts)
1624 self.pg_enable_capture(self.pg_interfaces)
1627 # Client side - simulate ICMP type 11 response
1628 capture = self.pg0.get_capture(len(pkts))
1629 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1630 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1631 ICMP(type=11) / packet[IP] for packet in capture]
1632 self.pg0.add_stream(pkts)
1633 self.pg_enable_capture(self.pg_interfaces)
1636 # Server side - verify ICMP type 11 packets
1637 capture = self.pg1.get_capture(len(pkts))
1638 self.verify_capture_out_with_icmp_errors(capture)
1640 def test_ping_out_interface_from_outside(self):
1641 """ Ping NAT44 out interface from outside network """
1643 self.nat44_add_address(self.nat_addr)
1644 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1645 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1648 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1649 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1650 ICMP(id=self.icmp_id_out, type='echo-request'))
1652 self.pg1.add_stream(pkts)
1653 self.pg_enable_capture(self.pg_interfaces)
1655 capture = self.pg1.get_capture(len(pkts))
1658 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1659 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1660 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1661 self.assertEqual(packet[ICMP].type, 0) # echo reply
1663 self.logger.error(ppp("Unexpected or invalid packet "
1664 "(outside network):", packet))
1667 def test_ping_internal_host_from_outside(self):
1668 """ Ping internal host from outside network """
1670 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1671 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1672 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1676 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1677 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1678 ICMP(id=self.icmp_id_out, type='echo-request'))
1679 self.pg1.add_stream(pkt)
1680 self.pg_enable_capture(self.pg_interfaces)
1682 capture = self.pg0.get_capture(1)
1683 self.verify_capture_in(capture, self.pg0)
1684 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1687 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1688 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1689 ICMP(id=self.icmp_id_in, type='echo-reply'))
1690 self.pg0.add_stream(pkt)
1691 self.pg_enable_capture(self.pg_interfaces)
1693 capture = self.pg1.get_capture(1)
1694 self.verify_capture_out(capture, same_port=True)
1695 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1697 def test_forwarding(self):
1698 """ NAT44 forwarding test """
1700 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1701 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1703 self.vapi.nat44_forwarding_enable_disable(1)
1705 real_ip = self.pg0.remote_ip4n
1706 alias_ip = self.nat_addr_n
1707 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1708 external_ip=alias_ip)
1711 # static mapping match
1713 pkts = self.create_stream_out(self.pg1)
1714 self.pg1.add_stream(pkts)
1715 self.pg_enable_capture(self.pg_interfaces)
1717 capture = self.pg0.get_capture(len(pkts))
1718 self.verify_capture_in(capture, self.pg0)
1720 pkts = self.create_stream_in(self.pg0, self.pg1)
1721 self.pg0.add_stream(pkts)
1722 self.pg_enable_capture(self.pg_interfaces)
1724 capture = self.pg1.get_capture(len(pkts))
1725 self.verify_capture_out(capture, same_port=True)
1727 # no static mapping match
1729 host0 = self.pg0.remote_hosts[0]
1730 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1732 pkts = self.create_stream_out(self.pg1,
1733 dst_ip=self.pg0.remote_ip4,
1734 use_inside_ports=True)
1735 self.pg1.add_stream(pkts)
1736 self.pg_enable_capture(self.pg_interfaces)
1738 capture = self.pg0.get_capture(len(pkts))
1739 self.verify_capture_in(capture, self.pg0)
1741 pkts = self.create_stream_in(self.pg0, self.pg1)
1742 self.pg0.add_stream(pkts)
1743 self.pg_enable_capture(self.pg_interfaces)
1745 capture = self.pg1.get_capture(len(pkts))
1746 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1749 self.pg0.remote_hosts[0] = host0
1752 self.vapi.nat44_forwarding_enable_disable(0)
1753 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1754 external_ip=alias_ip,
1757 def test_static_in(self):
1758 """ 1:1 NAT initialized from inside network """
1760 nat_ip = "10.0.0.10"
1761 self.tcp_port_out = 6303
1762 self.udp_port_out = 6304
1763 self.icmp_id_out = 6305
1765 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1766 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1767 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1769 sm = self.vapi.nat44_static_mapping_dump()
1770 self.assertEqual(len(sm), 1)
1771 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
1772 self.assertEqual(sm[0].protocol, 0)
1773 self.assertEqual(sm[0].local_port, 0)
1774 self.assertEqual(sm[0].external_port, 0)
1777 pkts = self.create_stream_in(self.pg0, self.pg1)
1778 self.pg0.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1781 capture = self.pg1.get_capture(len(pkts))
1782 self.verify_capture_out(capture, nat_ip, True)
1785 pkts = self.create_stream_out(self.pg1, nat_ip)
1786 self.pg1.add_stream(pkts)
1787 self.pg_enable_capture(self.pg_interfaces)
1789 capture = self.pg0.get_capture(len(pkts))
1790 self.verify_capture_in(capture, self.pg0)
1792 def test_static_out(self):
1793 """ 1:1 NAT initialized from outside network """
1795 nat_ip = "10.0.0.20"
1796 self.tcp_port_out = 6303
1797 self.udp_port_out = 6304
1798 self.icmp_id_out = 6305
1801 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1802 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1803 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1805 sm = self.vapi.nat44_static_mapping_dump()
1806 self.assertEqual(len(sm), 1)
1807 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
1810 pkts = self.create_stream_out(self.pg1, nat_ip)
1811 self.pg1.add_stream(pkts)
1812 self.pg_enable_capture(self.pg_interfaces)
1814 capture = self.pg0.get_capture(len(pkts))
1815 self.verify_capture_in(capture, self.pg0)
1818 pkts = self.create_stream_in(self.pg0, self.pg1)
1819 self.pg0.add_stream(pkts)
1820 self.pg_enable_capture(self.pg_interfaces)
1822 capture = self.pg1.get_capture(len(pkts))
1823 self.verify_capture_out(capture, nat_ip, True)
1825 def test_static_with_port_in(self):
1826 """ 1:1 NAPT initialized from inside network """
1828 self.tcp_port_out = 3606
1829 self.udp_port_out = 3607
1830 self.icmp_id_out = 3608
1832 self.nat44_add_address(self.nat_addr)
1833 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1834 self.tcp_port_in, self.tcp_port_out,
1835 proto=IP_PROTOS.tcp)
1836 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1837 self.udp_port_in, self.udp_port_out,
1838 proto=IP_PROTOS.udp)
1839 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1840 self.icmp_id_in, self.icmp_id_out,
1841 proto=IP_PROTOS.icmp)
1842 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1843 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1847 pkts = self.create_stream_in(self.pg0, self.pg1)
1848 self.pg0.add_stream(pkts)
1849 self.pg_enable_capture(self.pg_interfaces)
1851 capture = self.pg1.get_capture(len(pkts))
1852 self.verify_capture_out(capture)
1855 pkts = self.create_stream_out(self.pg1)
1856 self.pg1.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1859 capture = self.pg0.get_capture(len(pkts))
1860 self.verify_capture_in(capture, self.pg0)
1862 def test_static_with_port_out(self):
1863 """ 1:1 NAPT initialized from outside network """
1865 self.tcp_port_out = 30606
1866 self.udp_port_out = 30607
1867 self.icmp_id_out = 30608
1869 self.nat44_add_address(self.nat_addr)
1870 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1871 self.tcp_port_in, self.tcp_port_out,
1872 proto=IP_PROTOS.tcp)
1873 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1874 self.udp_port_in, self.udp_port_out,
1875 proto=IP_PROTOS.udp)
1876 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1877 self.icmp_id_in, self.icmp_id_out,
1878 proto=IP_PROTOS.icmp)
1879 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1880 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1884 pkts = self.create_stream_out(self.pg1)
1885 self.pg1.add_stream(pkts)
1886 self.pg_enable_capture(self.pg_interfaces)
1888 capture = self.pg0.get_capture(len(pkts))
1889 self.verify_capture_in(capture, self.pg0)
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)
1899 def test_static_vrf_aware(self):
1900 """ 1:1 NAT VRF awareness """
1902 nat_ip1 = "10.0.0.30"
1903 nat_ip2 = "10.0.0.40"
1904 self.tcp_port_out = 6303
1905 self.udp_port_out = 6304
1906 self.icmp_id_out = 6305
1908 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1910 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1912 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1914 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1915 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1917 # inside interface VRF match NAT44 static mapping VRF
1918 pkts = self.create_stream_in(self.pg4, self.pg3)
1919 self.pg4.add_stream(pkts)
1920 self.pg_enable_capture(self.pg_interfaces)
1922 capture = self.pg3.get_capture(len(pkts))
1923 self.verify_capture_out(capture, nat_ip1, True)
1925 # inside interface VRF don't match NAT44 static mapping VRF (packets
1927 pkts = self.create_stream_in(self.pg0, self.pg3)
1928 self.pg0.add_stream(pkts)
1929 self.pg_enable_capture(self.pg_interfaces)
1931 self.pg3.assert_nothing_captured()
1933 def test_dynamic_to_static(self):
1934 """ Switch from dynamic translation to 1:1NAT """
1935 nat_ip = "10.0.0.10"
1936 self.tcp_port_out = 6303
1937 self.udp_port_out = 6304
1938 self.icmp_id_out = 6305
1940 self.nat44_add_address(self.nat_addr)
1941 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1942 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1946 pkts = self.create_stream_in(self.pg0, self.pg1)
1947 self.pg0.add_stream(pkts)
1948 self.pg_enable_capture(self.pg_interfaces)
1950 capture = self.pg1.get_capture(len(pkts))
1951 self.verify_capture_out(capture)
1954 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1955 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1956 self.assertEqual(len(sessions), 0)
1957 pkts = self.create_stream_in(self.pg0, self.pg1)
1958 self.pg0.add_stream(pkts)
1959 self.pg_enable_capture(self.pg_interfaces)
1961 capture = self.pg1.get_capture(len(pkts))
1962 self.verify_capture_out(capture, nat_ip, True)
1964 def test_identity_nat(self):
1965 """ Identity NAT """
1967 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1968 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1969 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1972 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1973 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1974 TCP(sport=12345, dport=56789))
1975 self.pg1.add_stream(p)
1976 self.pg_enable_capture(self.pg_interfaces)
1978 capture = self.pg0.get_capture(1)
1983 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1984 self.assertEqual(ip.src, self.pg1.remote_ip4)
1985 self.assertEqual(tcp.dport, 56789)
1986 self.assertEqual(tcp.sport, 12345)
1987 self.assert_packet_checksums_valid(p)
1989 self.logger.error(ppp("Unexpected or invalid packet:", p))
1992 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1993 self.assertEqual(len(sessions), 0)
1994 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
1996 identity_mappings = self.vapi.nat44_identity_mapping_dump()
1997 self.assertEqual(len(identity_mappings), 2)
1999 def test_multiple_inside_interfaces(self):
2000 """ NAT44 multiple non-overlapping address space inside interfaces """
2002 self.nat44_add_address(self.nat_addr)
2003 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2004 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2005 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2008 # between two NAT44 inside interfaces (no translation)
2009 pkts = self.create_stream_in(self.pg0, self.pg1)
2010 self.pg0.add_stream(pkts)
2011 self.pg_enable_capture(self.pg_interfaces)
2013 capture = self.pg1.get_capture(len(pkts))
2014 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2016 # from NAT44 inside to interface without NAT44 feature (no translation)
2017 pkts = self.create_stream_in(self.pg0, self.pg2)
2018 self.pg0.add_stream(pkts)
2019 self.pg_enable_capture(self.pg_interfaces)
2021 capture = self.pg2.get_capture(len(pkts))
2022 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2024 # in2out 1st interface
2025 pkts = self.create_stream_in(self.pg0, self.pg3)
2026 self.pg0.add_stream(pkts)
2027 self.pg_enable_capture(self.pg_interfaces)
2029 capture = self.pg3.get_capture(len(pkts))
2030 self.verify_capture_out(capture)
2032 # out2in 1st interface
2033 pkts = self.create_stream_out(self.pg3)
2034 self.pg3.add_stream(pkts)
2035 self.pg_enable_capture(self.pg_interfaces)
2037 capture = self.pg0.get_capture(len(pkts))
2038 self.verify_capture_in(capture, self.pg0)
2040 # in2out 2nd interface
2041 pkts = self.create_stream_in(self.pg1, self.pg3)
2042 self.pg1.add_stream(pkts)
2043 self.pg_enable_capture(self.pg_interfaces)
2045 capture = self.pg3.get_capture(len(pkts))
2046 self.verify_capture_out(capture)
2048 # out2in 2nd interface
2049 pkts = self.create_stream_out(self.pg3)
2050 self.pg3.add_stream(pkts)
2051 self.pg_enable_capture(self.pg_interfaces)
2053 capture = self.pg1.get_capture(len(pkts))
2054 self.verify_capture_in(capture, self.pg1)
2056 def test_inside_overlapping_interfaces(self):
2057 """ NAT44 multiple inside interfaces with overlapping address space """
2059 static_nat_ip = "10.0.0.10"
2060 self.nat44_add_address(self.nat_addr)
2061 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2063 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2064 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2065 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2066 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2069 # between NAT44 inside interfaces with same VRF (no translation)
2070 pkts = self.create_stream_in(self.pg4, self.pg5)
2071 self.pg4.add_stream(pkts)
2072 self.pg_enable_capture(self.pg_interfaces)
2074 capture = self.pg5.get_capture(len(pkts))
2075 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2077 # between NAT44 inside interfaces with different VRF (hairpinning)
2078 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2079 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2080 TCP(sport=1234, dport=5678))
2081 self.pg4.add_stream(p)
2082 self.pg_enable_capture(self.pg_interfaces)
2084 capture = self.pg6.get_capture(1)
2089 self.assertEqual(ip.src, self.nat_addr)
2090 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2091 self.assertNotEqual(tcp.sport, 1234)
2092 self.assertEqual(tcp.dport, 5678)
2094 self.logger.error(ppp("Unexpected or invalid packet:", p))
2097 # in2out 1st interface
2098 pkts = self.create_stream_in(self.pg4, self.pg3)
2099 self.pg4.add_stream(pkts)
2100 self.pg_enable_capture(self.pg_interfaces)
2102 capture = self.pg3.get_capture(len(pkts))
2103 self.verify_capture_out(capture)
2105 # out2in 1st interface
2106 pkts = self.create_stream_out(self.pg3)
2107 self.pg3.add_stream(pkts)
2108 self.pg_enable_capture(self.pg_interfaces)
2110 capture = self.pg4.get_capture(len(pkts))
2111 self.verify_capture_in(capture, self.pg4)
2113 # in2out 2nd interface
2114 pkts = self.create_stream_in(self.pg5, self.pg3)
2115 self.pg5.add_stream(pkts)
2116 self.pg_enable_capture(self.pg_interfaces)
2118 capture = self.pg3.get_capture(len(pkts))
2119 self.verify_capture_out(capture)
2121 # out2in 2nd interface
2122 pkts = self.create_stream_out(self.pg3)
2123 self.pg3.add_stream(pkts)
2124 self.pg_enable_capture(self.pg_interfaces)
2126 capture = self.pg5.get_capture(len(pkts))
2127 self.verify_capture_in(capture, self.pg5)
2130 addresses = self.vapi.nat44_address_dump()
2131 self.assertEqual(len(addresses), 1)
2132 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2133 self.assertEqual(len(sessions), 3)
2134 for session in sessions:
2135 self.assertFalse(session.is_static)
2136 self.assertEqual(session.inside_ip_address[0:4],
2137 self.pg5.remote_ip4n)
2138 self.assertEqual(session.outside_ip_address,
2139 addresses[0].ip_address)
2140 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2141 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2142 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2143 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2144 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2145 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2146 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2147 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2148 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2150 # in2out 3rd interface
2151 pkts = self.create_stream_in(self.pg6, self.pg3)
2152 self.pg6.add_stream(pkts)
2153 self.pg_enable_capture(self.pg_interfaces)
2155 capture = self.pg3.get_capture(len(pkts))
2156 self.verify_capture_out(capture, static_nat_ip, True)
2158 # out2in 3rd interface
2159 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2160 self.pg3.add_stream(pkts)
2161 self.pg_enable_capture(self.pg_interfaces)
2163 capture = self.pg6.get_capture(len(pkts))
2164 self.verify_capture_in(capture, self.pg6)
2166 # general user and session dump verifications
2167 users = self.vapi.nat44_user_dump()
2168 self.assertGreaterEqual(len(users), 3)
2169 addresses = self.vapi.nat44_address_dump()
2170 self.assertEqual(len(addresses), 1)
2172 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2174 for session in sessions:
2175 self.assertEqual(user.ip_address, session.inside_ip_address)
2176 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2177 self.assertTrue(session.protocol in
2178 [IP_PROTOS.tcp, IP_PROTOS.udp,
2180 self.assertFalse(session.ext_host_valid)
2183 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2184 self.assertGreaterEqual(len(sessions), 4)
2185 for session in sessions:
2186 self.assertFalse(session.is_static)
2187 self.assertEqual(session.inside_ip_address[0:4],
2188 self.pg4.remote_ip4n)
2189 self.assertEqual(session.outside_ip_address,
2190 addresses[0].ip_address)
2193 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2194 self.assertGreaterEqual(len(sessions), 3)
2195 for session in sessions:
2196 self.assertTrue(session.is_static)
2197 self.assertEqual(session.inside_ip_address[0:4],
2198 self.pg6.remote_ip4n)
2199 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2200 map(int, static_nat_ip.split('.')))
2201 self.assertTrue(session.inside_port in
2202 [self.tcp_port_in, self.udp_port_in,
2205 def test_hairpinning(self):
2206 """ NAT44 hairpinning - 1:1 NAPT """
2208 host = self.pg0.remote_hosts[0]
2209 server = self.pg0.remote_hosts[1]
2212 server_in_port = 5678
2213 server_out_port = 8765
2215 self.nat44_add_address(self.nat_addr)
2216 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2217 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2219 # add static mapping for server
2220 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2221 server_in_port, server_out_port,
2222 proto=IP_PROTOS.tcp)
2224 # send packet from host to server
2225 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2226 IP(src=host.ip4, dst=self.nat_addr) /
2227 TCP(sport=host_in_port, dport=server_out_port))
2228 self.pg0.add_stream(p)
2229 self.pg_enable_capture(self.pg_interfaces)
2231 capture = self.pg0.get_capture(1)
2236 self.assertEqual(ip.src, self.nat_addr)
2237 self.assertEqual(ip.dst, server.ip4)
2238 self.assertNotEqual(tcp.sport, host_in_port)
2239 self.assertEqual(tcp.dport, server_in_port)
2240 self.assert_packet_checksums_valid(p)
2241 host_out_port = tcp.sport
2243 self.logger.error(ppp("Unexpected or invalid packet:", p))
2246 # send reply from server to host
2247 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2248 IP(src=server.ip4, dst=self.nat_addr) /
2249 TCP(sport=server_in_port, dport=host_out_port))
2250 self.pg0.add_stream(p)
2251 self.pg_enable_capture(self.pg_interfaces)
2253 capture = self.pg0.get_capture(1)
2258 self.assertEqual(ip.src, self.nat_addr)
2259 self.assertEqual(ip.dst, host.ip4)
2260 self.assertEqual(tcp.sport, server_out_port)
2261 self.assertEqual(tcp.dport, host_in_port)
2262 self.assert_packet_checksums_valid(p)
2264 self.logger.error(ppp("Unexpected or invalid packet:", p))
2267 def test_hairpinning2(self):
2268 """ NAT44 hairpinning - 1:1 NAT"""
2270 server1_nat_ip = "10.0.0.10"
2271 server2_nat_ip = "10.0.0.11"
2272 host = self.pg0.remote_hosts[0]
2273 server1 = self.pg0.remote_hosts[1]
2274 server2 = self.pg0.remote_hosts[2]
2275 server_tcp_port = 22
2276 server_udp_port = 20
2278 self.nat44_add_address(self.nat_addr)
2279 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2280 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2283 # add static mapping for servers
2284 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2285 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2289 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2290 IP(src=host.ip4, dst=server1_nat_ip) /
2291 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2293 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2294 IP(src=host.ip4, dst=server1_nat_ip) /
2295 UDP(sport=self.udp_port_in, dport=server_udp_port))
2297 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2298 IP(src=host.ip4, dst=server1_nat_ip) /
2299 ICMP(id=self.icmp_id_in, type='echo-request'))
2301 self.pg0.add_stream(pkts)
2302 self.pg_enable_capture(self.pg_interfaces)
2304 capture = self.pg0.get_capture(len(pkts))
2305 for packet in capture:
2307 self.assertEqual(packet[IP].src, self.nat_addr)
2308 self.assertEqual(packet[IP].dst, server1.ip4)
2309 if packet.haslayer(TCP):
2310 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2311 self.assertEqual(packet[TCP].dport, server_tcp_port)
2312 self.tcp_port_out = packet[TCP].sport
2313 self.assert_packet_checksums_valid(packet)
2314 elif packet.haslayer(UDP):
2315 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2316 self.assertEqual(packet[UDP].dport, server_udp_port)
2317 self.udp_port_out = packet[UDP].sport
2319 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2320 self.icmp_id_out = packet[ICMP].id
2322 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2327 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2328 IP(src=server1.ip4, dst=self.nat_addr) /
2329 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2331 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2332 IP(src=server1.ip4, dst=self.nat_addr) /
2333 UDP(sport=server_udp_port, dport=self.udp_port_out))
2335 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2336 IP(src=server1.ip4, dst=self.nat_addr) /
2337 ICMP(id=self.icmp_id_out, type='echo-reply'))
2339 self.pg0.add_stream(pkts)
2340 self.pg_enable_capture(self.pg_interfaces)
2342 capture = self.pg0.get_capture(len(pkts))
2343 for packet in capture:
2345 self.assertEqual(packet[IP].src, server1_nat_ip)
2346 self.assertEqual(packet[IP].dst, host.ip4)
2347 if packet.haslayer(TCP):
2348 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2349 self.assertEqual(packet[TCP].sport, server_tcp_port)
2350 self.assert_packet_checksums_valid(packet)
2351 elif packet.haslayer(UDP):
2352 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2353 self.assertEqual(packet[UDP].sport, server_udp_port)
2355 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2357 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2360 # server2 to server1
2362 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2363 IP(src=server2.ip4, dst=server1_nat_ip) /
2364 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2366 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2367 IP(src=server2.ip4, dst=server1_nat_ip) /
2368 UDP(sport=self.udp_port_in, dport=server_udp_port))
2370 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2371 IP(src=server2.ip4, dst=server1_nat_ip) /
2372 ICMP(id=self.icmp_id_in, type='echo-request'))
2374 self.pg0.add_stream(pkts)
2375 self.pg_enable_capture(self.pg_interfaces)
2377 capture = self.pg0.get_capture(len(pkts))
2378 for packet in capture:
2380 self.assertEqual(packet[IP].src, server2_nat_ip)
2381 self.assertEqual(packet[IP].dst, server1.ip4)
2382 if packet.haslayer(TCP):
2383 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2384 self.assertEqual(packet[TCP].dport, server_tcp_port)
2385 self.tcp_port_out = packet[TCP].sport
2386 self.assert_packet_checksums_valid(packet)
2387 elif packet.haslayer(UDP):
2388 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2389 self.assertEqual(packet[UDP].dport, server_udp_port)
2390 self.udp_port_out = packet[UDP].sport
2392 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2393 self.icmp_id_out = packet[ICMP].id
2395 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2398 # server1 to server2
2400 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2401 IP(src=server1.ip4, dst=server2_nat_ip) /
2402 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2404 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2405 IP(src=server1.ip4, dst=server2_nat_ip) /
2406 UDP(sport=server_udp_port, dport=self.udp_port_out))
2408 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2409 IP(src=server1.ip4, dst=server2_nat_ip) /
2410 ICMP(id=self.icmp_id_out, type='echo-reply'))
2412 self.pg0.add_stream(pkts)
2413 self.pg_enable_capture(self.pg_interfaces)
2415 capture = self.pg0.get_capture(len(pkts))
2416 for packet in capture:
2418 self.assertEqual(packet[IP].src, server1_nat_ip)
2419 self.assertEqual(packet[IP].dst, server2.ip4)
2420 if packet.haslayer(TCP):
2421 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2422 self.assertEqual(packet[TCP].sport, server_tcp_port)
2423 self.assert_packet_checksums_valid(packet)
2424 elif packet.haslayer(UDP):
2425 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2426 self.assertEqual(packet[UDP].sport, server_udp_port)
2428 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2430 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2433 def test_max_translations_per_user(self):
2434 """ MAX translations per user - recycle the least recently used """
2436 self.nat44_add_address(self.nat_addr)
2437 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2438 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2441 # get maximum number of translations per user
2442 nat44_config = self.vapi.nat_show_config()
2444 # send more than maximum number of translations per user packets
2445 pkts_num = nat44_config.max_translations_per_user + 5
2447 for port in range(0, pkts_num):
2448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2449 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2450 TCP(sport=1025 + port))
2452 self.pg0.add_stream(pkts)
2453 self.pg_enable_capture(self.pg_interfaces)
2456 # verify number of translated packet
2457 self.pg1.get_capture(pkts_num)
2459 users = self.vapi.nat44_user_dump()
2461 if user.ip_address == self.pg0.remote_ip4n:
2462 self.assertEqual(user.nsessions,
2463 nat44_config.max_translations_per_user)
2464 self.assertEqual(user.nstaticsessions, 0)
2467 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2469 proto=IP_PROTOS.tcp)
2470 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2471 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2472 TCP(sport=tcp_port))
2473 self.pg0.add_stream(p)
2474 self.pg_enable_capture(self.pg_interfaces)
2476 self.pg1.get_capture(1)
2477 users = self.vapi.nat44_user_dump()
2479 if user.ip_address == self.pg0.remote_ip4n:
2480 self.assertEqual(user.nsessions,
2481 nat44_config.max_translations_per_user - 1)
2482 self.assertEqual(user.nstaticsessions, 1)
2484 def test_interface_addr(self):
2485 """ Acquire NAT44 addresses from interface """
2486 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2488 # no address in NAT pool
2489 adresses = self.vapi.nat44_address_dump()
2490 self.assertEqual(0, len(adresses))
2492 # configure interface address and check NAT address pool
2493 self.pg7.config_ip4()
2494 adresses = self.vapi.nat44_address_dump()
2495 self.assertEqual(1, len(adresses))
2496 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
2498 # remove interface address and check NAT address pool
2499 self.pg7.unconfig_ip4()
2500 adresses = self.vapi.nat44_address_dump()
2501 self.assertEqual(0, len(adresses))
2503 def test_interface_addr_static_mapping(self):
2504 """ Static mapping with addresses from interface """
2507 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2508 self.nat44_add_static_mapping(
2510 external_sw_if_index=self.pg7.sw_if_index,
2513 # static mappings with external interface
2514 static_mappings = self.vapi.nat44_static_mapping_dump()
2515 self.assertEqual(1, len(static_mappings))
2516 self.assertEqual(self.pg7.sw_if_index,
2517 static_mappings[0].external_sw_if_index)
2518 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2520 # configure interface address and check static mappings
2521 self.pg7.config_ip4()
2522 static_mappings = self.vapi.nat44_static_mapping_dump()
2523 self.assertEqual(2, len(static_mappings))
2525 for sm in static_mappings:
2526 if sm.external_sw_if_index == 0xFFFFFFFF:
2527 self.assertEqual(sm.external_ip_address[0:4],
2528 self.pg7.local_ip4n)
2529 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2531 self.assertTrue(resolved)
2533 # remove interface address and check static mappings
2534 self.pg7.unconfig_ip4()
2535 static_mappings = self.vapi.nat44_static_mapping_dump()
2536 self.assertEqual(1, len(static_mappings))
2537 self.assertEqual(self.pg7.sw_if_index,
2538 static_mappings[0].external_sw_if_index)
2539 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2541 # configure interface address again and check static mappings
2542 self.pg7.config_ip4()
2543 static_mappings = self.vapi.nat44_static_mapping_dump()
2544 self.assertEqual(2, len(static_mappings))
2546 for sm in static_mappings:
2547 if sm.external_sw_if_index == 0xFFFFFFFF:
2548 self.assertEqual(sm.external_ip_address[0:4],
2549 self.pg7.local_ip4n)
2550 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2552 self.assertTrue(resolved)
2554 # remove static mapping
2555 self.nat44_add_static_mapping(
2557 external_sw_if_index=self.pg7.sw_if_index,
2560 static_mappings = self.vapi.nat44_static_mapping_dump()
2561 self.assertEqual(0, len(static_mappings))
2563 def test_interface_addr_identity_nat(self):
2564 """ Identity NAT with addresses from interface """
2567 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2568 self.vapi.nat44_add_del_identity_mapping(
2569 sw_if_index=self.pg7.sw_if_index,
2571 protocol=IP_PROTOS.tcp,
2574 # identity mappings with external interface
2575 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2576 self.assertEqual(1, len(identity_mappings))
2577 self.assertEqual(self.pg7.sw_if_index,
2578 identity_mappings[0].sw_if_index)
2580 # configure interface address and check identity mappings
2581 self.pg7.config_ip4()
2582 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2584 self.assertEqual(2, len(identity_mappings))
2585 for sm in identity_mappings:
2586 if sm.sw_if_index == 0xFFFFFFFF:
2587 self.assertEqual(identity_mappings[0].ip_address,
2588 self.pg7.local_ip4n)
2589 self.assertEqual(port, identity_mappings[0].port)
2590 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2592 self.assertTrue(resolved)
2594 # remove interface address and check identity mappings
2595 self.pg7.unconfig_ip4()
2596 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2597 self.assertEqual(1, len(identity_mappings))
2598 self.assertEqual(self.pg7.sw_if_index,
2599 identity_mappings[0].sw_if_index)
2601 def test_ipfix_nat44_sess(self):
2602 """ IPFIX logging NAT44 session created/delted """
2603 self.ipfix_domain_id = 10
2604 self.ipfix_src_port = 20202
2605 colector_port = 30303
2606 bind_layers(UDP, IPFIX, dport=30303)
2607 self.nat44_add_address(self.nat_addr)
2608 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2609 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2611 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2612 src_address=self.pg3.local_ip4n,
2614 template_interval=10,
2615 collector_port=colector_port)
2616 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2617 src_port=self.ipfix_src_port)
2619 pkts = self.create_stream_in(self.pg0, self.pg1)
2620 self.pg0.add_stream(pkts)
2621 self.pg_enable_capture(self.pg_interfaces)
2623 capture = self.pg1.get_capture(len(pkts))
2624 self.verify_capture_out(capture)
2625 self.nat44_add_address(self.nat_addr, is_add=0)
2626 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2627 capture = self.pg3.get_capture(9)
2628 ipfix = IPFIXDecoder()
2629 # first load template
2631 self.assertTrue(p.haslayer(IPFIX))
2632 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2633 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2634 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2635 self.assertEqual(p[UDP].dport, colector_port)
2636 self.assertEqual(p[IPFIX].observationDomainID,
2637 self.ipfix_domain_id)
2638 if p.haslayer(Template):
2639 ipfix.add_template(p.getlayer(Template))
2640 # verify events in data set
2642 if p.haslayer(Data):
2643 data = ipfix.decode_data_set(p.getlayer(Set))
2644 self.verify_ipfix_nat44_ses(data)
2646 def test_ipfix_addr_exhausted(self):
2647 """ IPFIX logging NAT addresses exhausted """
2648 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2649 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2651 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2652 src_address=self.pg3.local_ip4n,
2654 template_interval=10)
2655 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2656 src_port=self.ipfix_src_port)
2658 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2659 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2661 self.pg0.add_stream(p)
2662 self.pg_enable_capture(self.pg_interfaces)
2664 self.pg1.assert_nothing_captured()
2666 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2667 capture = self.pg3.get_capture(9)
2668 ipfix = IPFIXDecoder()
2669 # first load template
2671 self.assertTrue(p.haslayer(IPFIX))
2672 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2673 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2674 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2675 self.assertEqual(p[UDP].dport, 4739)
2676 self.assertEqual(p[IPFIX].observationDomainID,
2677 self.ipfix_domain_id)
2678 if p.haslayer(Template):
2679 ipfix.add_template(p.getlayer(Template))
2680 # verify events in data set
2682 if p.haslayer(Data):
2683 data = ipfix.decode_data_set(p.getlayer(Set))
2684 self.verify_ipfix_addr_exhausted(data)
2686 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2687 def test_ipfix_max_sessions(self):
2688 """ IPFIX logging maximum session entries exceeded """
2689 self.nat44_add_address(self.nat_addr)
2690 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2691 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2694 nat44_config = self.vapi.nat_show_config()
2695 max_sessions = 10 * nat44_config.translation_buckets
2698 for i in range(0, max_sessions):
2699 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2700 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2701 IP(src=src, dst=self.pg1.remote_ip4) /
2704 self.pg0.add_stream(pkts)
2705 self.pg_enable_capture(self.pg_interfaces)
2708 self.pg1.get_capture(max_sessions)
2709 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2710 src_address=self.pg3.local_ip4n,
2712 template_interval=10)
2713 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2714 src_port=self.ipfix_src_port)
2716 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2717 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2719 self.pg0.add_stream(p)
2720 self.pg_enable_capture(self.pg_interfaces)
2722 self.pg1.assert_nothing_captured()
2724 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2725 capture = self.pg3.get_capture(9)
2726 ipfix = IPFIXDecoder()
2727 # first load template
2729 self.assertTrue(p.haslayer(IPFIX))
2730 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2731 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2732 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2733 self.assertEqual(p[UDP].dport, 4739)
2734 self.assertEqual(p[IPFIX].observationDomainID,
2735 self.ipfix_domain_id)
2736 if p.haslayer(Template):
2737 ipfix.add_template(p.getlayer(Template))
2738 # verify events in data set
2740 if p.haslayer(Data):
2741 data = ipfix.decode_data_set(p.getlayer(Set))
2742 self.verify_ipfix_max_sessions(data, max_sessions)
2744 def test_syslog_apmap(self):
2745 """ Test syslog address and port mapping creation and deletion """
2746 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2747 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2748 self.nat44_add_address(self.nat_addr)
2749 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2750 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2753 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2754 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2755 TCP(sport=self.tcp_port_in, dport=20))
2756 self.pg0.add_stream(p)
2757 self.pg_enable_capture(self.pg_interfaces)
2759 capture = self.pg1.get_capture(1)
2760 self.tcp_port_out = capture[0][TCP].sport
2761 capture = self.pg3.get_capture(1)
2762 self.verify_syslog_apmap(capture[0][Raw].load)
2764 self.pg_enable_capture(self.pg_interfaces)
2766 self.nat44_add_address(self.nat_addr, is_add=0)
2767 capture = self.pg3.get_capture(1)
2768 self.verify_syslog_apmap(capture[0][Raw].load, False)
2770 def test_pool_addr_fib(self):
2771 """ NAT44 add pool addresses to FIB """
2772 static_addr = '10.0.0.10'
2773 self.nat44_add_address(self.nat_addr)
2774 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2775 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2777 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2780 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2781 ARP(op=ARP.who_has, pdst=self.nat_addr,
2782 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2783 self.pg1.add_stream(p)
2784 self.pg_enable_capture(self.pg_interfaces)
2786 capture = self.pg1.get_capture(1)
2787 self.assertTrue(capture[0].haslayer(ARP))
2788 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2791 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2792 ARP(op=ARP.who_has, pdst=static_addr,
2793 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2794 self.pg1.add_stream(p)
2795 self.pg_enable_capture(self.pg_interfaces)
2797 capture = self.pg1.get_capture(1)
2798 self.assertTrue(capture[0].haslayer(ARP))
2799 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2801 # send ARP to non-NAT44 interface
2802 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2803 ARP(op=ARP.who_has, pdst=self.nat_addr,
2804 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2805 self.pg2.add_stream(p)
2806 self.pg_enable_capture(self.pg_interfaces)
2808 self.pg1.assert_nothing_captured()
2810 # remove addresses and verify
2811 self.nat44_add_address(self.nat_addr, is_add=0)
2812 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2815 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2816 ARP(op=ARP.who_has, pdst=self.nat_addr,
2817 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2818 self.pg1.add_stream(p)
2819 self.pg_enable_capture(self.pg_interfaces)
2821 self.pg1.assert_nothing_captured()
2823 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2824 ARP(op=ARP.who_has, pdst=static_addr,
2825 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2826 self.pg1.add_stream(p)
2827 self.pg_enable_capture(self.pg_interfaces)
2829 self.pg1.assert_nothing_captured()
2831 def test_vrf_mode(self):
2832 """ NAT44 tenant VRF aware address pool mode """
2836 nat_ip1 = "10.0.0.10"
2837 nat_ip2 = "10.0.0.11"
2839 self.pg0.unconfig_ip4()
2840 self.pg1.unconfig_ip4()
2841 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2842 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
2843 self.pg0.set_table_ip4(vrf_id1)
2844 self.pg1.set_table_ip4(vrf_id2)
2845 self.pg0.config_ip4()
2846 self.pg1.config_ip4()
2847 self.pg0.resolve_arp()
2848 self.pg1.resolve_arp()
2850 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2851 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2852 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2853 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2854 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2859 pkts = self.create_stream_in(self.pg0, self.pg2)
2860 self.pg0.add_stream(pkts)
2861 self.pg_enable_capture(self.pg_interfaces)
2863 capture = self.pg2.get_capture(len(pkts))
2864 self.verify_capture_out(capture, nat_ip1)
2867 pkts = self.create_stream_in(self.pg1, self.pg2)
2868 self.pg1.add_stream(pkts)
2869 self.pg_enable_capture(self.pg_interfaces)
2871 capture = self.pg2.get_capture(len(pkts))
2872 self.verify_capture_out(capture, nat_ip2)
2875 self.pg0.unconfig_ip4()
2876 self.pg1.unconfig_ip4()
2877 self.pg0.set_table_ip4(0)
2878 self.pg1.set_table_ip4(0)
2879 self.pg0.config_ip4()
2880 self.pg1.config_ip4()
2881 self.pg0.resolve_arp()
2882 self.pg1.resolve_arp()
2883 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2884 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2886 def test_vrf_feature_independent(self):
2887 """ NAT44 tenant VRF independent address pool mode """
2889 nat_ip1 = "10.0.0.10"
2890 nat_ip2 = "10.0.0.11"
2892 self.nat44_add_address(nat_ip1)
2893 self.nat44_add_address(nat_ip2, vrf_id=99)
2894 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2895 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2896 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2900 pkts = self.create_stream_in(self.pg0, self.pg2)
2901 self.pg0.add_stream(pkts)
2902 self.pg_enable_capture(self.pg_interfaces)
2904 capture = self.pg2.get_capture(len(pkts))
2905 self.verify_capture_out(capture, nat_ip1)
2908 pkts = self.create_stream_in(self.pg1, self.pg2)
2909 self.pg1.add_stream(pkts)
2910 self.pg_enable_capture(self.pg_interfaces)
2912 capture = self.pg2.get_capture(len(pkts))
2913 self.verify_capture_out(capture, nat_ip1)
2915 def test_dynamic_ipless_interfaces(self):
2916 """ NAT44 interfaces without configured IP address """
2918 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2919 mactobinary(self.pg7.remote_mac),
2920 self.pg7.remote_ip4n,
2922 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2923 mactobinary(self.pg8.remote_mac),
2924 self.pg8.remote_ip4n,
2927 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2928 dst_address_length=32,
2929 next_hop_address=self.pg7.remote_ip4n,
2930 next_hop_sw_if_index=self.pg7.sw_if_index)
2931 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2932 dst_address_length=32,
2933 next_hop_address=self.pg8.remote_ip4n,
2934 next_hop_sw_if_index=self.pg8.sw_if_index)
2936 self.nat44_add_address(self.nat_addr)
2937 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2938 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2942 pkts = self.create_stream_in(self.pg7, self.pg8)
2943 self.pg7.add_stream(pkts)
2944 self.pg_enable_capture(self.pg_interfaces)
2946 capture = self.pg8.get_capture(len(pkts))
2947 self.verify_capture_out(capture)
2950 pkts = self.create_stream_out(self.pg8, self.nat_addr)
2951 self.pg8.add_stream(pkts)
2952 self.pg_enable_capture(self.pg_interfaces)
2954 capture = self.pg7.get_capture(len(pkts))
2955 self.verify_capture_in(capture, self.pg7)
2957 def test_static_ipless_interfaces(self):
2958 """ NAT44 interfaces without configured IP address - 1:1 NAT """
2960 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
2961 mactobinary(self.pg7.remote_mac),
2962 self.pg7.remote_ip4n,
2964 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
2965 mactobinary(self.pg8.remote_mac),
2966 self.pg8.remote_ip4n,
2969 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2970 dst_address_length=32,
2971 next_hop_address=self.pg7.remote_ip4n,
2972 next_hop_sw_if_index=self.pg7.sw_if_index)
2973 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2974 dst_address_length=32,
2975 next_hop_address=self.pg8.remote_ip4n,
2976 next_hop_sw_if_index=self.pg8.sw_if_index)
2978 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2979 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2980 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2984 pkts = self.create_stream_out(self.pg8)
2985 self.pg8.add_stream(pkts)
2986 self.pg_enable_capture(self.pg_interfaces)
2988 capture = self.pg7.get_capture(len(pkts))
2989 self.verify_capture_in(capture, self.pg7)
2992 pkts = self.create_stream_in(self.pg7, self.pg8)
2993 self.pg7.add_stream(pkts)
2994 self.pg_enable_capture(self.pg_interfaces)
2996 capture = self.pg8.get_capture(len(pkts))
2997 self.verify_capture_out(capture, self.nat_addr, True)
2999 def test_static_with_port_ipless_interfaces(self):
3000 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3002 self.tcp_port_out = 30606
3003 self.udp_port_out = 30607
3004 self.icmp_id_out = 30608
3006 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
3007 mactobinary(self.pg7.remote_mac),
3008 self.pg7.remote_ip4n,
3010 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
3011 mactobinary(self.pg8.remote_mac),
3012 self.pg8.remote_ip4n,
3015 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3016 dst_address_length=32,
3017 next_hop_address=self.pg7.remote_ip4n,
3018 next_hop_sw_if_index=self.pg7.sw_if_index)
3019 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3020 dst_address_length=32,
3021 next_hop_address=self.pg8.remote_ip4n,
3022 next_hop_sw_if_index=self.pg8.sw_if_index)
3024 self.nat44_add_address(self.nat_addr)
3025 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3026 self.tcp_port_in, self.tcp_port_out,
3027 proto=IP_PROTOS.tcp)
3028 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3029 self.udp_port_in, self.udp_port_out,
3030 proto=IP_PROTOS.udp)
3031 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3032 self.icmp_id_in, self.icmp_id_out,
3033 proto=IP_PROTOS.icmp)
3034 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3035 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3039 pkts = self.create_stream_out(self.pg8)
3040 self.pg8.add_stream(pkts)
3041 self.pg_enable_capture(self.pg_interfaces)
3043 capture = self.pg7.get_capture(len(pkts))
3044 self.verify_capture_in(capture, self.pg7)
3047 pkts = self.create_stream_in(self.pg7, self.pg8)
3048 self.pg7.add_stream(pkts)
3049 self.pg_enable_capture(self.pg_interfaces)
3051 capture = self.pg8.get_capture(len(pkts))
3052 self.verify_capture_out(capture)
3054 def test_static_unknown_proto(self):
3055 """ 1:1 NAT translate packet with unknown protocol """
3056 nat_ip = "10.0.0.10"
3057 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3058 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3059 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3063 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3064 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3066 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3067 TCP(sport=1234, dport=1234))
3068 self.pg0.add_stream(p)
3069 self.pg_enable_capture(self.pg_interfaces)
3071 p = self.pg1.get_capture(1)
3074 self.assertEqual(packet[IP].src, nat_ip)
3075 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3076 self.assertTrue(packet.haslayer(GRE))
3077 self.assert_packet_checksums_valid(packet)
3079 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3083 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3084 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3086 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3087 TCP(sport=1234, dport=1234))
3088 self.pg1.add_stream(p)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 p = self.pg0.get_capture(1)
3094 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3095 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3096 self.assertTrue(packet.haslayer(GRE))
3097 self.assert_packet_checksums_valid(packet)
3099 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3102 def test_hairpinning_static_unknown_proto(self):
3103 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3105 host = self.pg0.remote_hosts[0]
3106 server = self.pg0.remote_hosts[1]
3108 host_nat_ip = "10.0.0.10"
3109 server_nat_ip = "10.0.0.11"
3111 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3112 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3113 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3114 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3118 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3119 IP(src=host.ip4, dst=server_nat_ip) /
3121 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3122 TCP(sport=1234, dport=1234))
3123 self.pg0.add_stream(p)
3124 self.pg_enable_capture(self.pg_interfaces)
3126 p = self.pg0.get_capture(1)
3129 self.assertEqual(packet[IP].src, host_nat_ip)
3130 self.assertEqual(packet[IP].dst, server.ip4)
3131 self.assertTrue(packet.haslayer(GRE))
3132 self.assert_packet_checksums_valid(packet)
3134 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3138 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3139 IP(src=server.ip4, dst=host_nat_ip) /
3141 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3142 TCP(sport=1234, dport=1234))
3143 self.pg0.add_stream(p)
3144 self.pg_enable_capture(self.pg_interfaces)
3146 p = self.pg0.get_capture(1)
3149 self.assertEqual(packet[IP].src, server_nat_ip)
3150 self.assertEqual(packet[IP].dst, host.ip4)
3151 self.assertTrue(packet.haslayer(GRE))
3152 self.assert_packet_checksums_valid(packet)
3154 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3157 def test_output_feature(self):
3158 """ NAT44 interface output feature (in2out postrouting) """
3159 self.nat44_add_address(self.nat_addr)
3160 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3161 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3162 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3166 pkts = self.create_stream_in(self.pg0, self.pg3)
3167 self.pg0.add_stream(pkts)
3168 self.pg_enable_capture(self.pg_interfaces)
3170 capture = self.pg3.get_capture(len(pkts))
3171 self.verify_capture_out(capture)
3174 pkts = self.create_stream_out(self.pg3)
3175 self.pg3.add_stream(pkts)
3176 self.pg_enable_capture(self.pg_interfaces)
3178 capture = self.pg0.get_capture(len(pkts))
3179 self.verify_capture_in(capture, self.pg0)
3181 # from non-NAT interface to NAT inside interface
3182 pkts = self.create_stream_in(self.pg2, self.pg0)
3183 self.pg2.add_stream(pkts)
3184 self.pg_enable_capture(self.pg_interfaces)
3186 capture = self.pg0.get_capture(len(pkts))
3187 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3189 def test_output_feature_vrf_aware(self):
3190 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3191 nat_ip_vrf10 = "10.0.0.10"
3192 nat_ip_vrf20 = "10.0.0.20"
3194 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3195 dst_address_length=32,
3196 next_hop_address=self.pg3.remote_ip4n,
3197 next_hop_sw_if_index=self.pg3.sw_if_index,
3199 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3200 dst_address_length=32,
3201 next_hop_address=self.pg3.remote_ip4n,
3202 next_hop_sw_if_index=self.pg3.sw_if_index,
3205 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3206 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3207 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3208 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3209 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3213 pkts = self.create_stream_in(self.pg4, self.pg3)
3214 self.pg4.add_stream(pkts)
3215 self.pg_enable_capture(self.pg_interfaces)
3217 capture = self.pg3.get_capture(len(pkts))
3218 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3221 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3222 self.pg3.add_stream(pkts)
3223 self.pg_enable_capture(self.pg_interfaces)
3225 capture = self.pg4.get_capture(len(pkts))
3226 self.verify_capture_in(capture, self.pg4)
3229 pkts = self.create_stream_in(self.pg6, self.pg3)
3230 self.pg6.add_stream(pkts)
3231 self.pg_enable_capture(self.pg_interfaces)
3233 capture = self.pg3.get_capture(len(pkts))
3234 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3237 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3238 self.pg3.add_stream(pkts)
3239 self.pg_enable_capture(self.pg_interfaces)
3241 capture = self.pg6.get_capture(len(pkts))
3242 self.verify_capture_in(capture, self.pg6)
3244 def test_output_feature_hairpinning(self):
3245 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3246 host = self.pg0.remote_hosts[0]
3247 server = self.pg0.remote_hosts[1]
3250 server_in_port = 5678
3251 server_out_port = 8765
3253 self.nat44_add_address(self.nat_addr)
3254 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3255 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3258 # add static mapping for server
3259 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3260 server_in_port, server_out_port,
3261 proto=IP_PROTOS.tcp)
3263 # send packet from host to server
3264 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3265 IP(src=host.ip4, dst=self.nat_addr) /
3266 TCP(sport=host_in_port, dport=server_out_port))
3267 self.pg0.add_stream(p)
3268 self.pg_enable_capture(self.pg_interfaces)
3270 capture = self.pg0.get_capture(1)
3275 self.assertEqual(ip.src, self.nat_addr)
3276 self.assertEqual(ip.dst, server.ip4)
3277 self.assertNotEqual(tcp.sport, host_in_port)
3278 self.assertEqual(tcp.dport, server_in_port)
3279 self.assert_packet_checksums_valid(p)
3280 host_out_port = tcp.sport
3282 self.logger.error(ppp("Unexpected or invalid packet:", p))
3285 # send reply from server to host
3286 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3287 IP(src=server.ip4, dst=self.nat_addr) /
3288 TCP(sport=server_in_port, dport=host_out_port))
3289 self.pg0.add_stream(p)
3290 self.pg_enable_capture(self.pg_interfaces)
3292 capture = self.pg0.get_capture(1)
3297 self.assertEqual(ip.src, self.nat_addr)
3298 self.assertEqual(ip.dst, host.ip4)
3299 self.assertEqual(tcp.sport, server_out_port)
3300 self.assertEqual(tcp.dport, host_in_port)
3301 self.assert_packet_checksums_valid(p)
3303 self.logger.error(ppp("Unexpected or invalid packet:", p))
3306 def test_one_armed_nat44(self):
3307 """ One armed NAT44 """
3308 remote_host = self.pg9.remote_hosts[0]
3309 local_host = self.pg9.remote_hosts[1]
3312 self.nat44_add_address(self.nat_addr)
3313 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3314 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3318 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3319 IP(src=local_host.ip4, dst=remote_host.ip4) /
3320 TCP(sport=12345, dport=80))
3321 self.pg9.add_stream(p)
3322 self.pg_enable_capture(self.pg_interfaces)
3324 capture = self.pg9.get_capture(1)
3329 self.assertEqual(ip.src, self.nat_addr)
3330 self.assertEqual(ip.dst, remote_host.ip4)
3331 self.assertNotEqual(tcp.sport, 12345)
3332 external_port = tcp.sport
3333 self.assertEqual(tcp.dport, 80)
3334 self.assert_packet_checksums_valid(p)
3336 self.logger.error(ppp("Unexpected or invalid packet:", p))
3340 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3341 IP(src=remote_host.ip4, dst=self.nat_addr) /
3342 TCP(sport=80, dport=external_port))
3343 self.pg9.add_stream(p)
3344 self.pg_enable_capture(self.pg_interfaces)
3346 capture = self.pg9.get_capture(1)
3351 self.assertEqual(ip.src, remote_host.ip4)
3352 self.assertEqual(ip.dst, local_host.ip4)
3353 self.assertEqual(tcp.sport, 80)
3354 self.assertEqual(tcp.dport, 12345)
3355 self.assert_packet_checksums_valid(p)
3357 self.logger.error(ppp("Unexpected or invalid packet:", p))
3360 def test_del_session(self):
3361 """ Delete NAT44 session """
3362 self.nat44_add_address(self.nat_addr)
3363 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3364 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3367 pkts = self.create_stream_in(self.pg0, self.pg1)
3368 self.pg0.add_stream(pkts)
3369 self.pg_enable_capture(self.pg_interfaces)
3371 self.pg1.get_capture(len(pkts))
3373 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3374 nsessions = len(sessions)
3376 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3377 sessions[0].inside_port,
3378 sessions[0].protocol)
3379 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3380 sessions[1].outside_port,
3381 sessions[1].protocol,
3384 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3385 self.assertEqual(nsessions - len(sessions), 2)
3387 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3388 sessions[0].inside_port,
3389 sessions[0].protocol)
3391 self.verify_no_nat44_user()
3393 def test_set_get_reass(self):
3394 """ NAT44 set/get virtual fragmentation reassembly """
3395 reas_cfg1 = self.vapi.nat_get_reass()
3397 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3398 max_reass=reas_cfg1.ip4_max_reass * 2,
3399 max_frag=reas_cfg1.ip4_max_frag * 2)
3401 reas_cfg2 = self.vapi.nat_get_reass()
3403 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3404 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3405 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3407 self.vapi.nat_set_reass(drop_frag=1)
3408 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3410 def test_frag_in_order(self):
3411 """ NAT44 translate fragments arriving in order """
3413 self.nat44_add_address(self.nat_addr)
3414 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3415 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3418 self.frag_in_order(proto=IP_PROTOS.tcp)
3419 self.frag_in_order(proto=IP_PROTOS.udp)
3420 self.frag_in_order(proto=IP_PROTOS.icmp)
3422 def test_frag_forwarding(self):
3423 """ NAT44 forwarding fragment test """
3424 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3425 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3426 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3428 self.vapi.nat44_forwarding_enable_disable(1)
3430 data = "A" * 16 + "B" * 16 + "C" * 3
3431 pkts = self.create_stream_frag(self.pg1,
3432 self.pg0.remote_ip4,
3436 proto=IP_PROTOS.udp)
3437 self.pg1.add_stream(pkts)
3438 self.pg_enable_capture(self.pg_interfaces)
3440 frags = self.pg0.get_capture(len(pkts))
3441 p = self.reass_frags_and_verify(frags,
3442 self.pg1.remote_ip4,
3443 self.pg0.remote_ip4)
3444 self.assertEqual(p[UDP].sport, 4789)
3445 self.assertEqual(p[UDP].dport, 4789)
3446 self.assertEqual(data, p[Raw].load)
3448 def test_reass_hairpinning(self):
3449 """ NAT44 fragments hairpinning """
3451 self.server = self.pg0.remote_hosts[1]
3452 self.host_in_port = random.randint(1025, 65535)
3453 self.server_in_port = random.randint(1025, 65535)
3454 self.server_out_port = random.randint(1025, 65535)
3456 self.nat44_add_address(self.nat_addr)
3457 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3458 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3460 # add static mapping for server
3461 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3462 self.server_in_port,
3463 self.server_out_port,
3464 proto=IP_PROTOS.tcp)
3465 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3466 self.server_in_port,
3467 self.server_out_port,
3468 proto=IP_PROTOS.udp)
3469 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3471 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3472 self.reass_hairpinning(proto=IP_PROTOS.udp)
3473 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3475 def test_frag_out_of_order(self):
3476 """ NAT44 translate fragments arriving out of order """
3478 self.nat44_add_address(self.nat_addr)
3479 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3480 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3483 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3484 self.frag_out_of_order(proto=IP_PROTOS.udp)
3485 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3487 def test_port_restricted(self):
3488 """ Port restricted NAT44 (MAP-E CE) """
3489 self.nat44_add_address(self.nat_addr)
3490 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3491 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3493 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3498 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3499 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3500 TCP(sport=4567, dport=22))
3501 self.pg0.add_stream(p)
3502 self.pg_enable_capture(self.pg_interfaces)
3504 capture = self.pg1.get_capture(1)
3509 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3510 self.assertEqual(ip.src, self.nat_addr)
3511 self.assertEqual(tcp.dport, 22)
3512 self.assertNotEqual(tcp.sport, 4567)
3513 self.assertEqual((tcp.sport >> 6) & 63, 10)
3514 self.assert_packet_checksums_valid(p)
3516 self.logger.error(ppp("Unexpected or invalid packet:", p))
3519 def test_port_range(self):
3520 """ External address port range """
3521 self.nat44_add_address(self.nat_addr)
3522 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3523 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3525 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3530 for port in range(0, 5):
3531 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3532 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3533 TCP(sport=1125 + port))
3535 self.pg0.add_stream(pkts)
3536 self.pg_enable_capture(self.pg_interfaces)
3538 capture = self.pg1.get_capture(3)
3541 self.assertGreaterEqual(tcp.sport, 1025)
3542 self.assertLessEqual(tcp.sport, 1027)
3544 def test_ipfix_max_frags(self):
3545 """ IPFIX logging maximum fragments pending reassembly exceeded """
3546 self.nat44_add_address(self.nat_addr)
3547 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3548 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3550 self.vapi.nat_set_reass(max_frag=1)
3551 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3552 src_address=self.pg3.local_ip4n,
3554 template_interval=10)
3555 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3556 src_port=self.ipfix_src_port)
3558 data = "A" * 4 + "B" * 16 + "C" * 3
3559 self.tcp_port_in = random.randint(1025, 65535)
3560 pkts = self.create_stream_frag(self.pg0,
3561 self.pg1.remote_ip4,
3566 self.pg0.add_stream(pkts)
3567 self.pg_enable_capture(self.pg_interfaces)
3569 self.pg1.assert_nothing_captured()
3571 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3572 capture = self.pg3.get_capture(9)
3573 ipfix = IPFIXDecoder()
3574 # first load template
3576 self.assertTrue(p.haslayer(IPFIX))
3577 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3578 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3579 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3580 self.assertEqual(p[UDP].dport, 4739)
3581 self.assertEqual(p[IPFIX].observationDomainID,
3582 self.ipfix_domain_id)
3583 if p.haslayer(Template):
3584 ipfix.add_template(p.getlayer(Template))
3585 # verify events in data set
3587 if p.haslayer(Data):
3588 data = ipfix.decode_data_set(p.getlayer(Set))
3589 self.verify_ipfix_max_fragments_ip4(data, 1,
3590 self.pg0.remote_ip4n)
3592 def test_multiple_outside_vrf(self):
3593 """ Multiple outside VRF """
3597 self.pg1.unconfig_ip4()
3598 self.pg2.unconfig_ip4()
3599 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3600 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3601 self.pg1.set_table_ip4(vrf_id1)
3602 self.pg2.set_table_ip4(vrf_id2)
3603 self.pg1.config_ip4()
3604 self.pg2.config_ip4()
3605 self.pg1.resolve_arp()
3606 self.pg2.resolve_arp()
3608 self.nat44_add_address(self.nat_addr)
3609 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3610 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3612 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3617 pkts = self.create_stream_in(self.pg0, self.pg1)
3618 self.pg0.add_stream(pkts)
3619 self.pg_enable_capture(self.pg_interfaces)
3621 capture = self.pg1.get_capture(len(pkts))
3622 self.verify_capture_out(capture, self.nat_addr)
3624 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3625 self.pg1.add_stream(pkts)
3626 self.pg_enable_capture(self.pg_interfaces)
3628 capture = self.pg0.get_capture(len(pkts))
3629 self.verify_capture_in(capture, self.pg0)
3631 self.tcp_port_in = 60303
3632 self.udp_port_in = 60304
3633 self.icmp_id_in = 60305
3636 pkts = self.create_stream_in(self.pg0, self.pg2)
3637 self.pg0.add_stream(pkts)
3638 self.pg_enable_capture(self.pg_interfaces)
3640 capture = self.pg2.get_capture(len(pkts))
3641 self.verify_capture_out(capture, self.nat_addr)
3643 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3644 self.pg2.add_stream(pkts)
3645 self.pg_enable_capture(self.pg_interfaces)
3647 capture = self.pg0.get_capture(len(pkts))
3648 self.verify_capture_in(capture, self.pg0)
3651 self.pg1.unconfig_ip4()
3652 self.pg2.unconfig_ip4()
3653 self.pg1.set_table_ip4(0)
3654 self.pg2.set_table_ip4(0)
3655 self.pg1.config_ip4()
3656 self.pg2.config_ip4()
3657 self.pg1.resolve_arp()
3658 self.pg2.resolve_arp()
3660 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3661 def test_session_timeout(self):
3662 """ NAT44 session timeouts """
3663 self.nat44_add_address(self.nat_addr)
3664 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3665 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3667 self.vapi.nat_set_timeouts(udp=5)
3671 for i in range(0, max_sessions):
3672 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3673 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3674 IP(src=src, dst=self.pg1.remote_ip4) /
3675 UDP(sport=1025, dport=53))
3677 self.pg0.add_stream(pkts)
3678 self.pg_enable_capture(self.pg_interfaces)
3680 self.pg1.get_capture(max_sessions)
3685 for i in range(0, max_sessions):
3686 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3687 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3688 IP(src=src, dst=self.pg1.remote_ip4) /
3689 UDP(sport=1026, dport=53))
3691 self.pg0.add_stream(pkts)
3692 self.pg_enable_capture(self.pg_interfaces)
3694 self.pg1.get_capture(max_sessions)
3697 users = self.vapi.nat44_user_dump()
3699 nsessions = nsessions + user.nsessions
3700 self.assertLess(nsessions, 2 * max_sessions)
3702 def test_mss_clamping(self):
3703 """ TCP MSS clamping """
3704 self.nat44_add_address(self.nat_addr)
3705 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3706 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3709 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3710 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3711 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3712 flags="S", options=[('MSS', 1400)]))
3714 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3715 self.pg0.add_stream(p)
3716 self.pg_enable_capture(self.pg_interfaces)
3718 capture = self.pg1.get_capture(1)
3719 # Negotiated MSS value greater than configured - changed
3720 self.verify_mss_value(capture[0], 1000)
3722 self.vapi.nat_set_mss_clamping(enable=0)
3723 self.pg0.add_stream(p)
3724 self.pg_enable_capture(self.pg_interfaces)
3726 capture = self.pg1.get_capture(1)
3727 # MSS clamping disabled - negotiated MSS unchanged
3728 self.verify_mss_value(capture[0], 1400)
3730 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3731 self.pg0.add_stream(p)
3732 self.pg_enable_capture(self.pg_interfaces)
3734 capture = self.pg1.get_capture(1)
3735 # Negotiated MSS value smaller than configured - unchanged
3736 self.verify_mss_value(capture[0], 1400)
3739 super(TestNAT44, self).tearDown()
3740 if not self.vpp_dead:
3741 self.logger.info(self.vapi.cli("show nat44 addresses"))
3742 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3743 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3744 self.logger.info(self.vapi.cli("show nat44 interface address"))
3745 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3746 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3747 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3748 self.logger.info(self.vapi.cli("show nat timeouts"))
3750 self.vapi.cli("show nat addr-port-assignment-alg"))
3752 self.vapi.cli("clear logging")
3755 class TestNAT44EndpointDependent(MethodHolder):
3756 """ Endpoint-Dependent mapping and filtering test cases """
3759 def setUpConstants(cls):
3760 super(TestNAT44EndpointDependent, cls).setUpConstants()
3761 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3764 def setUpClass(cls):
3765 super(TestNAT44EndpointDependent, cls).setUpClass()
3766 cls.vapi.cli("set log class nat level debug")
3768 cls.tcp_port_in = 6303
3769 cls.tcp_port_out = 6303
3770 cls.udp_port_in = 6304
3771 cls.udp_port_out = 6304
3772 cls.icmp_id_in = 6305
3773 cls.icmp_id_out = 6305
3774 cls.nat_addr = '10.0.0.3'
3775 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3776 cls.ipfix_src_port = 4739
3777 cls.ipfix_domain_id = 1
3778 cls.tcp_external_port = 80
3780 cls.create_pg_interfaces(range(7))
3781 cls.interfaces = list(cls.pg_interfaces[0:3])
3783 for i in cls.interfaces:
3788 cls.pg0.generate_remote_hosts(3)
3789 cls.pg0.configure_ipv4_neighbors()
3793 cls.pg4.generate_remote_hosts(2)
3794 cls.pg4.config_ip4()
3795 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3796 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3800 cls.pg4.resolve_arp()
3801 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3802 cls.pg4.resolve_arp()
3804 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3805 cls.vapi.ip_table_add_del(1, is_add=1)
3807 cls.pg5._local_ip4 = "10.1.1.1"
3808 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3810 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3811 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3812 socket.AF_INET, cls.pg5.remote_ip4)
3813 cls.pg5.set_table_ip4(1)
3814 cls.pg5.config_ip4()
3816 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3817 dst_address_length=32,
3819 next_hop_sw_if_index=cls.pg5.sw_if_index,
3820 next_hop_address=zero_ip4n)
3822 cls.pg6._local_ip4 = "10.1.2.1"
3823 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3825 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3826 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3827 socket.AF_INET, cls.pg6.remote_ip4)
3828 cls.pg6.set_table_ip4(1)
3829 cls.pg6.config_ip4()
3831 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3832 dst_address_length=32,
3834 next_hop_sw_if_index=cls.pg6.sw_if_index,
3835 next_hop_address=zero_ip4n)
3837 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3838 dst_address_length=16,
3839 next_hop_address=zero_ip4n,
3841 next_hop_table_id=1)
3842 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3843 dst_address_length=0,
3844 next_hop_address=zero_ip4n,
3846 next_hop_table_id=0)
3847 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3848 dst_address_length=0,
3850 next_hop_sw_if_index=cls.pg1.sw_if_index,
3851 next_hop_address=cls.pg1.local_ip4n)
3853 cls.pg5.resolve_arp()
3854 cls.pg6.resolve_arp()
3857 super(TestNAT44EndpointDependent, cls).tearDownClass()
3860 def test_frag_in_order(self):
3861 """ NAT44 translate fragments arriving in order """
3862 self.nat44_add_address(self.nat_addr)
3863 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3864 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3866 self.frag_in_order(proto=IP_PROTOS.tcp)
3867 self.frag_in_order(proto=IP_PROTOS.udp)
3868 self.frag_in_order(proto=IP_PROTOS.icmp)
3870 def test_frag_in_order_dont_translate(self):
3871 """ NAT44 don't translate fragments arriving in order """
3872 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3873 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3875 self.vapi.nat44_forwarding_enable_disable(enable=True)
3876 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3878 def test_frag_out_of_order(self):
3879 """ NAT44 translate fragments arriving out of order """
3880 self.nat44_add_address(self.nat_addr)
3881 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3882 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3884 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3885 self.frag_out_of_order(proto=IP_PROTOS.udp)
3886 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3888 def test_frag_out_of_order_dont_translate(self):
3889 """ NAT44 don't translate fragments arriving out of order """
3890 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3891 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3893 self.vapi.nat44_forwarding_enable_disable(enable=True)
3894 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3896 def test_frag_in_order_in_plus_out(self):
3897 """ in+out interface fragments in order """
3898 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3899 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3901 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3902 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3905 self.server = self.pg1.remote_hosts[0]
3907 self.server_in_addr = self.server.ip4
3908 self.server_out_addr = '11.11.11.11'
3909 self.server_in_port = random.randint(1025, 65535)
3910 self.server_out_port = random.randint(1025, 65535)
3912 self.nat44_add_address(self.server_out_addr)
3914 # add static mappings for server
3915 self.nat44_add_static_mapping(self.server_in_addr,
3916 self.server_out_addr,
3917 self.server_in_port,
3918 self.server_out_port,
3919 proto=IP_PROTOS.tcp)
3920 self.nat44_add_static_mapping(self.server_in_addr,
3921 self.server_out_addr,
3922 self.server_in_port,
3923 self.server_out_port,
3924 proto=IP_PROTOS.udp)
3925 self.nat44_add_static_mapping(self.server_in_addr,
3926 self.server_out_addr,
3927 proto=IP_PROTOS.icmp)
3929 self.vapi.nat_set_reass(timeout=10)
3931 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3932 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3933 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3935 def test_frag_out_of_order_in_plus_out(self):
3936 """ in+out interface fragments out of order """
3937 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3938 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3940 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3941 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3944 self.server = self.pg1.remote_hosts[0]
3946 self.server_in_addr = self.server.ip4
3947 self.server_out_addr = '11.11.11.11'
3948 self.server_in_port = random.randint(1025, 65535)
3949 self.server_out_port = random.randint(1025, 65535)
3951 self.nat44_add_address(self.server_out_addr)
3953 # add static mappings for server
3954 self.nat44_add_static_mapping(self.server_in_addr,
3955 self.server_out_addr,
3956 self.server_in_port,
3957 self.server_out_port,
3958 proto=IP_PROTOS.tcp)
3959 self.nat44_add_static_mapping(self.server_in_addr,
3960 self.server_out_addr,
3961 self.server_in_port,
3962 self.server_out_port,
3963 proto=IP_PROTOS.udp)
3964 self.nat44_add_static_mapping(self.server_in_addr,
3965 self.server_out_addr,
3966 proto=IP_PROTOS.icmp)
3968 self.vapi.nat_set_reass(timeout=10)
3970 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
3971 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
3972 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
3974 def test_reass_hairpinning(self):
3975 """ NAT44 fragments hairpinning """
3976 self.server = self.pg0.remote_hosts[1]
3977 self.host_in_port = random.randint(1025, 65535)
3978 self.server_in_port = random.randint(1025, 65535)
3979 self.server_out_port = random.randint(1025, 65535)
3981 self.nat44_add_address(self.nat_addr)
3982 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3983 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3985 # add static mapping for server
3986 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3987 self.server_in_port,
3988 self.server_out_port,
3989 proto=IP_PROTOS.tcp)
3990 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3991 self.server_in_port,
3992 self.server_out_port,
3993 proto=IP_PROTOS.udp)
3994 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3996 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3997 self.reass_hairpinning(proto=IP_PROTOS.udp)
3998 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4000 def test_dynamic(self):
4001 """ NAT44 dynamic translation test """
4003 self.nat44_add_address(self.nat_addr)
4004 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4005 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4008 nat_config = self.vapi.nat_show_config()
4009 self.assertEqual(1, nat_config.endpoint_dependent)
4012 pkts = self.create_stream_in(self.pg0, self.pg1)
4013 self.pg0.add_stream(pkts)
4014 self.pg_enable_capture(self.pg_interfaces)
4016 capture = self.pg1.get_capture(len(pkts))
4017 self.verify_capture_out(capture)
4020 pkts = self.create_stream_out(self.pg1)
4021 self.pg1.add_stream(pkts)
4022 self.pg_enable_capture(self.pg_interfaces)
4024 capture = self.pg0.get_capture(len(pkts))
4025 self.verify_capture_in(capture, self.pg0)
4027 def test_forwarding(self):
4028 """ NAT44 forwarding test """
4030 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4031 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4033 self.vapi.nat44_forwarding_enable_disable(1)
4035 real_ip = self.pg0.remote_ip4n
4036 alias_ip = self.nat_addr_n
4037 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4038 external_ip=alias_ip)
4041 # in2out - static mapping match
4043 pkts = self.create_stream_out(self.pg1)
4044 self.pg1.add_stream(pkts)
4045 self.pg_enable_capture(self.pg_interfaces)
4047 capture = self.pg0.get_capture(len(pkts))
4048 self.verify_capture_in(capture, self.pg0)
4050 pkts = self.create_stream_in(self.pg0, self.pg1)
4051 self.pg0.add_stream(pkts)
4052 self.pg_enable_capture(self.pg_interfaces)
4054 capture = self.pg1.get_capture(len(pkts))
4055 self.verify_capture_out(capture, same_port=True)
4057 # in2out - no static mapping match
4059 host0 = self.pg0.remote_hosts[0]
4060 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4062 pkts = self.create_stream_out(self.pg1,
4063 dst_ip=self.pg0.remote_ip4,
4064 use_inside_ports=True)
4065 self.pg1.add_stream(pkts)
4066 self.pg_enable_capture(self.pg_interfaces)
4068 capture = self.pg0.get_capture(len(pkts))
4069 self.verify_capture_in(capture, self.pg0)
4071 pkts = self.create_stream_in(self.pg0, self.pg1)
4072 self.pg0.add_stream(pkts)
4073 self.pg_enable_capture(self.pg_interfaces)
4075 capture = self.pg1.get_capture(len(pkts))
4076 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4079 self.pg0.remote_hosts[0] = host0
4081 user = self.pg0.remote_hosts[1]
4082 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4083 self.assertEqual(len(sessions), 3)
4084 self.assertTrue(sessions[0].ext_host_valid)
4085 self.vapi.nat44_del_session(
4086 sessions[0].inside_ip_address,
4087 sessions[0].inside_port,
4088 sessions[0].protocol,
4089 ext_host_address=sessions[0].ext_host_address,
4090 ext_host_port=sessions[0].ext_host_port)
4091 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4092 self.assertEqual(len(sessions), 2)
4095 self.vapi.nat44_forwarding_enable_disable(0)
4096 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4097 external_ip=alias_ip,
4100 def test_static_lb(self):
4101 """ NAT44 local service load balancing """
4102 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4105 server1 = self.pg0.remote_hosts[0]
4106 server2 = self.pg0.remote_hosts[1]
4108 locals = [{'addr': server1.ip4n,
4112 {'addr': server2.ip4n,
4117 self.nat44_add_address(self.nat_addr)
4118 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4121 local_num=len(locals),
4123 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4124 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4127 # from client to service
4128 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4129 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4130 TCP(sport=12345, dport=external_port))
4131 self.pg1.add_stream(p)
4132 self.pg_enable_capture(self.pg_interfaces)
4134 capture = self.pg0.get_capture(1)
4140 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4141 if ip.dst == server1.ip4:
4145 self.assertEqual(tcp.dport, local_port)
4146 self.assert_packet_checksums_valid(p)
4148 self.logger.error(ppp("Unexpected or invalid packet:", p))
4151 # from service back to client
4152 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4153 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4154 TCP(sport=local_port, dport=12345))
4155 self.pg0.add_stream(p)
4156 self.pg_enable_capture(self.pg_interfaces)
4158 capture = self.pg1.get_capture(1)
4163 self.assertEqual(ip.src, self.nat_addr)
4164 self.assertEqual(tcp.sport, external_port)
4165 self.assert_packet_checksums_valid(p)
4167 self.logger.error(ppp("Unexpected or invalid packet:", p))
4170 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4171 self.assertEqual(len(sessions), 1)
4172 self.assertTrue(sessions[0].ext_host_valid)
4173 self.vapi.nat44_del_session(
4174 sessions[0].inside_ip_address,
4175 sessions[0].inside_port,
4176 sessions[0].protocol,
4177 ext_host_address=sessions[0].ext_host_address,
4178 ext_host_port=sessions[0].ext_host_port)
4179 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4180 self.assertEqual(len(sessions), 0)
4182 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4183 def test_static_lb_multi_clients(self):
4184 """ NAT44 local service load balancing - multiple clients"""
4186 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4189 server1 = self.pg0.remote_hosts[0]
4190 server2 = self.pg0.remote_hosts[1]
4192 locals = [{'addr': server1.ip4n,
4196 {'addr': server2.ip4n,
4201 self.nat44_add_address(self.nat_addr)
4202 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4205 local_num=len(locals),
4207 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4208 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4213 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4215 for client in clients:
4216 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4217 IP(src=client, dst=self.nat_addr) /
4218 TCP(sport=12345, dport=external_port))
4220 self.pg1.add_stream(pkts)
4221 self.pg_enable_capture(self.pg_interfaces)
4223 capture = self.pg0.get_capture(len(pkts))
4225 if p[IP].dst == server1.ip4:
4229 self.assertGreater(server1_n, server2_n)
4231 def test_static_lb_2(self):
4232 """ NAT44 local service load balancing (asymmetrical rule) """
4233 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4236 server1 = self.pg0.remote_hosts[0]
4237 server2 = self.pg0.remote_hosts[1]
4239 locals = [{'addr': server1.ip4n,
4243 {'addr': server2.ip4n,
4248 self.vapi.nat44_forwarding_enable_disable(1)
4249 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4253 local_num=len(locals),
4255 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4256 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4259 # from client to service
4260 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4261 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4262 TCP(sport=12345, dport=external_port))
4263 self.pg1.add_stream(p)
4264 self.pg_enable_capture(self.pg_interfaces)
4266 capture = self.pg0.get_capture(1)
4272 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4273 if ip.dst == server1.ip4:
4277 self.assertEqual(tcp.dport, local_port)
4278 self.assert_packet_checksums_valid(p)
4280 self.logger.error(ppp("Unexpected or invalid packet:", p))
4283 # from service back to client
4284 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4285 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4286 TCP(sport=local_port, dport=12345))
4287 self.pg0.add_stream(p)
4288 self.pg_enable_capture(self.pg_interfaces)
4290 capture = self.pg1.get_capture(1)
4295 self.assertEqual(ip.src, self.nat_addr)
4296 self.assertEqual(tcp.sport, external_port)
4297 self.assert_packet_checksums_valid(p)
4299 self.logger.error(ppp("Unexpected or invalid packet:", p))
4302 # from client to server (no translation)
4303 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4304 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4305 TCP(sport=12346, dport=local_port))
4306 self.pg1.add_stream(p)
4307 self.pg_enable_capture(self.pg_interfaces)
4309 capture = self.pg0.get_capture(1)
4315 self.assertEqual(ip.dst, server1.ip4)
4316 self.assertEqual(tcp.dport, local_port)
4317 self.assert_packet_checksums_valid(p)
4319 self.logger.error(ppp("Unexpected or invalid packet:", p))
4322 # from service back to client (no translation)
4323 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4324 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4325 TCP(sport=local_port, dport=12346))
4326 self.pg0.add_stream(p)
4327 self.pg_enable_capture(self.pg_interfaces)
4329 capture = self.pg1.get_capture(1)
4334 self.assertEqual(ip.src, server1.ip4)
4335 self.assertEqual(tcp.sport, local_port)
4336 self.assert_packet_checksums_valid(p)
4338 self.logger.error(ppp("Unexpected or invalid packet:", p))
4341 def test_lb_affinity(self):
4342 """ NAT44 local service load balancing affinity """
4343 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4346 server1 = self.pg0.remote_hosts[0]
4347 server2 = self.pg0.remote_hosts[1]
4349 locals = [{'addr': server1.ip4n,
4353 {'addr': server2.ip4n,
4358 self.nat44_add_address(self.nat_addr)
4359 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4363 local_num=len(locals),
4365 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4366 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4369 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4370 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4371 TCP(sport=1025, dport=external_port))
4372 self.pg1.add_stream(p)
4373 self.pg_enable_capture(self.pg_interfaces)
4375 capture = self.pg0.get_capture(1)
4376 backend = capture[0][IP].dst
4378 sessions = self.vapi.nat44_user_session_dump(
4379 socket.inet_pton(socket.AF_INET, backend), 0)
4380 self.assertEqual(len(sessions), 1)
4381 self.assertTrue(sessions[0].ext_host_valid)
4382 self.vapi.nat44_del_session(
4383 sessions[0].inside_ip_address,
4384 sessions[0].inside_port,
4385 sessions[0].protocol,
4386 ext_host_address=sessions[0].ext_host_address,
4387 ext_host_port=sessions[0].ext_host_port)
4390 for port in range(1030, 1100):
4391 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4392 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4393 TCP(sport=port, dport=external_port))
4395 self.pg1.add_stream(pkts)
4396 self.pg_enable_capture(self.pg_interfaces)
4398 capture = self.pg0.get_capture(len(pkts))
4400 self.assertEqual(p[IP].dst, backend)
4402 def test_unknown_proto(self):
4403 """ NAT44 translate packet with unknown protocol """
4404 self.nat44_add_address(self.nat_addr)
4405 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4406 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4410 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4411 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4412 TCP(sport=self.tcp_port_in, dport=20))
4413 self.pg0.add_stream(p)
4414 self.pg_enable_capture(self.pg_interfaces)
4416 p = self.pg1.get_capture(1)
4418 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4419 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4421 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4422 TCP(sport=1234, dport=1234))
4423 self.pg0.add_stream(p)
4424 self.pg_enable_capture(self.pg_interfaces)
4426 p = self.pg1.get_capture(1)
4429 self.assertEqual(packet[IP].src, self.nat_addr)
4430 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
4431 self.assertTrue(packet.haslayer(GRE))
4432 self.assert_packet_checksums_valid(packet)
4434 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4438 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4439 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4441 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4442 TCP(sport=1234, dport=1234))
4443 self.pg1.add_stream(p)
4444 self.pg_enable_capture(self.pg_interfaces)
4446 p = self.pg0.get_capture(1)
4449 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4450 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
4451 self.assertTrue(packet.haslayer(GRE))
4452 self.assert_packet_checksums_valid(packet)
4454 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4457 def test_hairpinning_unknown_proto(self):
4458 """ NAT44 translate packet with unknown protocol - hairpinning """
4459 host = self.pg0.remote_hosts[0]
4460 server = self.pg0.remote_hosts[1]
4462 server_out_port = 8765
4463 server_nat_ip = "10.0.0.11"
4465 self.nat44_add_address(self.nat_addr)
4466 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4467 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4470 # add static mapping for server
4471 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4474 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4475 IP(src=host.ip4, dst=server_nat_ip) /
4476 TCP(sport=host_in_port, dport=server_out_port))
4477 self.pg0.add_stream(p)
4478 self.pg_enable_capture(self.pg_interfaces)
4480 self.pg0.get_capture(1)
4482 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4483 IP(src=host.ip4, dst=server_nat_ip) /
4485 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4486 TCP(sport=1234, dport=1234))
4487 self.pg0.add_stream(p)
4488 self.pg_enable_capture(self.pg_interfaces)
4490 p = self.pg0.get_capture(1)
4493 self.assertEqual(packet[IP].src, self.nat_addr)
4494 self.assertEqual(packet[IP].dst, server.ip4)
4495 self.assertTrue(packet.haslayer(GRE))
4496 self.assert_packet_checksums_valid(packet)
4498 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4502 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4503 IP(src=server.ip4, dst=self.nat_addr) /
4505 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4506 TCP(sport=1234, dport=1234))
4507 self.pg0.add_stream(p)
4508 self.pg_enable_capture(self.pg_interfaces)
4510 p = self.pg0.get_capture(1)
4513 self.assertEqual(packet[IP].src, server_nat_ip)
4514 self.assertEqual(packet[IP].dst, host.ip4)
4515 self.assertTrue(packet.haslayer(GRE))
4516 self.assert_packet_checksums_valid(packet)
4518 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4521 def test_output_feature_and_service(self):
4522 """ NAT44 interface output feature and services """
4523 external_addr = '1.2.3.4'
4527 self.vapi.nat44_forwarding_enable_disable(1)
4528 self.nat44_add_address(self.nat_addr)
4529 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4530 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4531 local_port, external_port,
4532 proto=IP_PROTOS.tcp, out2in_only=1)
4533 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4534 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4536 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4539 # from client to service
4540 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4541 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4542 TCP(sport=12345, dport=external_port))
4543 self.pg1.add_stream(p)
4544 self.pg_enable_capture(self.pg_interfaces)
4546 capture = self.pg0.get_capture(1)
4551 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4552 self.assertEqual(tcp.dport, local_port)
4553 self.assert_packet_checksums_valid(p)
4555 self.logger.error(ppp("Unexpected or invalid packet:", p))
4558 # from service back to client
4559 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4560 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4561 TCP(sport=local_port, dport=12345))
4562 self.pg0.add_stream(p)
4563 self.pg_enable_capture(self.pg_interfaces)
4565 capture = self.pg1.get_capture(1)
4570 self.assertEqual(ip.src, external_addr)
4571 self.assertEqual(tcp.sport, external_port)
4572 self.assert_packet_checksums_valid(p)
4574 self.logger.error(ppp("Unexpected or invalid packet:", p))
4577 # from local network host to external network
4578 pkts = self.create_stream_in(self.pg0, self.pg1)
4579 self.pg0.add_stream(pkts)
4580 self.pg_enable_capture(self.pg_interfaces)
4582 capture = self.pg1.get_capture(len(pkts))
4583 self.verify_capture_out(capture)
4584 pkts = self.create_stream_in(self.pg0, self.pg1)
4585 self.pg0.add_stream(pkts)
4586 self.pg_enable_capture(self.pg_interfaces)
4588 capture = self.pg1.get_capture(len(pkts))
4589 self.verify_capture_out(capture)
4591 # from external network back to local network host
4592 pkts = self.create_stream_out(self.pg1)
4593 self.pg1.add_stream(pkts)
4594 self.pg_enable_capture(self.pg_interfaces)
4596 capture = self.pg0.get_capture(len(pkts))
4597 self.verify_capture_in(capture, self.pg0)
4599 def test_output_feature_and_service2(self):
4600 """ NAT44 interface output feature and service host direct access """
4601 self.vapi.nat44_forwarding_enable_disable(1)
4602 self.nat44_add_address(self.nat_addr)
4603 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4606 # session initiaded from service host - translate
4607 pkts = self.create_stream_in(self.pg0, self.pg1)
4608 self.pg0.add_stream(pkts)
4609 self.pg_enable_capture(self.pg_interfaces)
4611 capture = self.pg1.get_capture(len(pkts))
4612 self.verify_capture_out(capture)
4614 pkts = self.create_stream_out(self.pg1)
4615 self.pg1.add_stream(pkts)
4616 self.pg_enable_capture(self.pg_interfaces)
4618 capture = self.pg0.get_capture(len(pkts))
4619 self.verify_capture_in(capture, self.pg0)
4621 # session initiaded from remote host - do not translate
4622 self.tcp_port_in = 60303
4623 self.udp_port_in = 60304
4624 self.icmp_id_in = 60305
4625 pkts = self.create_stream_out(self.pg1,
4626 self.pg0.remote_ip4,
4627 use_inside_ports=True)
4628 self.pg1.add_stream(pkts)
4629 self.pg_enable_capture(self.pg_interfaces)
4631 capture = self.pg0.get_capture(len(pkts))
4632 self.verify_capture_in(capture, self.pg0)
4634 pkts = self.create_stream_in(self.pg0, self.pg1)
4635 self.pg0.add_stream(pkts)
4636 self.pg_enable_capture(self.pg_interfaces)
4638 capture = self.pg1.get_capture(len(pkts))
4639 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4642 def test_output_feature_and_service3(self):
4643 """ NAT44 interface output feature and DST NAT """
4644 external_addr = '1.2.3.4'
4648 self.vapi.nat44_forwarding_enable_disable(1)
4649 self.nat44_add_address(self.nat_addr)
4650 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4651 local_port, external_port,
4652 proto=IP_PROTOS.tcp, out2in_only=1)
4653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4654 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4656 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4659 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4660 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4661 TCP(sport=12345, dport=external_port))
4662 self.pg0.add_stream(p)
4663 self.pg_enable_capture(self.pg_interfaces)
4665 capture = self.pg1.get_capture(1)
4670 self.assertEqual(ip.src, self.pg0.remote_ip4)
4671 self.assertEqual(tcp.sport, 12345)
4672 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4673 self.assertEqual(tcp.dport, local_port)
4674 self.assert_packet_checksums_valid(p)
4676 self.logger.error(ppp("Unexpected or invalid packet:", p))
4679 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4680 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4681 TCP(sport=local_port, dport=12345))
4682 self.pg1.add_stream(p)
4683 self.pg_enable_capture(self.pg_interfaces)
4685 capture = self.pg0.get_capture(1)
4690 self.assertEqual(ip.src, external_addr)
4691 self.assertEqual(tcp.sport, external_port)
4692 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4693 self.assertEqual(tcp.dport, 12345)
4694 self.assert_packet_checksums_valid(p)
4696 self.logger.error(ppp("Unexpected or invalid packet:", p))
4699 def test_next_src_nat(self):
4700 """ On way back forward packet to nat44-in2out node. """
4701 twice_nat_addr = '10.0.1.3'
4704 post_twice_nat_port = 0
4706 self.vapi.nat44_forwarding_enable_disable(1)
4707 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4708 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4709 local_port, external_port,
4710 proto=IP_PROTOS.tcp, out2in_only=1,
4711 self_twice_nat=1, vrf_id=1)
4712 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4715 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4716 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4717 TCP(sport=12345, dport=external_port))
4718 self.pg6.add_stream(p)
4719 self.pg_enable_capture(self.pg_interfaces)
4721 capture = self.pg6.get_capture(1)
4726 self.assertEqual(ip.src, twice_nat_addr)
4727 self.assertNotEqual(tcp.sport, 12345)
4728 post_twice_nat_port = tcp.sport
4729 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4730 self.assertEqual(tcp.dport, local_port)
4731 self.assert_packet_checksums_valid(p)
4733 self.logger.error(ppp("Unexpected or invalid packet:", p))
4736 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4737 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4738 TCP(sport=local_port, dport=post_twice_nat_port))
4739 self.pg6.add_stream(p)
4740 self.pg_enable_capture(self.pg_interfaces)
4742 capture = self.pg6.get_capture(1)
4747 self.assertEqual(ip.src, self.pg1.remote_ip4)
4748 self.assertEqual(tcp.sport, external_port)
4749 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4750 self.assertEqual(tcp.dport, 12345)
4751 self.assert_packet_checksums_valid(p)
4753 self.logger.error(ppp("Unexpected or invalid packet:", p))
4756 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4758 twice_nat_addr = '10.0.1.3'
4766 port_in1 = port_in+1
4767 port_in2 = port_in+2
4772 server1 = self.pg0.remote_hosts[0]
4773 server2 = self.pg0.remote_hosts[1]
4785 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4788 self.nat44_add_address(self.nat_addr)
4789 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4791 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4793 proto=IP_PROTOS.tcp,
4794 twice_nat=int(not self_twice_nat),
4795 self_twice_nat=int(self_twice_nat))
4797 locals = [{'addr': server1.ip4n,
4801 {'addr': server2.ip4n,
4805 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4806 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4810 not self_twice_nat),
4813 local_num=len(locals),
4815 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4816 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
4823 assert client_id is not None
4825 client = self.pg0.remote_hosts[0]
4826 elif client_id == 2:
4827 client = self.pg0.remote_hosts[1]
4829 client = pg1.remote_hosts[0]
4830 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4831 IP(src=client.ip4, dst=self.nat_addr) /
4832 TCP(sport=eh_port_out, dport=port_out))
4834 self.pg_enable_capture(self.pg_interfaces)
4836 capture = pg0.get_capture(1)
4842 if ip.dst == server1.ip4:
4848 self.assertEqual(ip.dst, server.ip4)
4850 self.assertIn(tcp.dport, [port_in1, port_in2])
4852 self.assertEqual(tcp.dport, port_in)
4854 self.assertEqual(ip.src, twice_nat_addr)
4855 self.assertNotEqual(tcp.sport, eh_port_out)
4857 self.assertEqual(ip.src, client.ip4)
4858 self.assertEqual(tcp.sport, eh_port_out)
4860 eh_port_in = tcp.sport
4861 saved_port_in = tcp.dport
4862 self.assert_packet_checksums_valid(p)
4864 self.logger.error(ppp("Unexpected or invalid packet:", p))
4867 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4868 IP(src=server.ip4, dst=eh_addr_in) /
4869 TCP(sport=saved_port_in, dport=eh_port_in))
4871 self.pg_enable_capture(self.pg_interfaces)
4873 capture = pg1.get_capture(1)
4878 self.assertEqual(ip.dst, client.ip4)
4879 self.assertEqual(ip.src, self.nat_addr)
4880 self.assertEqual(tcp.dport, eh_port_out)
4881 self.assertEqual(tcp.sport, port_out)
4882 self.assert_packet_checksums_valid(p)
4884 self.logger.error(ppp("Unexpected or invalid packet:", p))
4888 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4889 self.assertEqual(len(sessions), 1)
4890 self.assertTrue(sessions[0].ext_host_valid)
4891 self.assertTrue(sessions[0].is_twicenat)
4892 self.vapi.nat44_del_session(
4893 sessions[0].inside_ip_address,
4894 sessions[0].inside_port,
4895 sessions[0].protocol,
4896 ext_host_address=sessions[0].ext_host_nat_address,
4897 ext_host_port=sessions[0].ext_host_nat_port)
4898 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4899 self.assertEqual(len(sessions), 0)
4901 def test_twice_nat(self):
4903 self.twice_nat_common()
4905 def test_self_twice_nat_positive(self):
4906 """ Self Twice NAT44 (positive test) """
4907 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4909 def test_self_twice_nat_negative(self):
4910 """ Self Twice NAT44 (negative test) """
4911 self.twice_nat_common(self_twice_nat=True)
4913 def test_twice_nat_lb(self):
4914 """ Twice NAT44 local service load balancing """
4915 self.twice_nat_common(lb=True)
4917 def test_self_twice_nat_lb_positive(self):
4918 """ Self Twice NAT44 local service load balancing (positive test) """
4919 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4922 def test_self_twice_nat_lb_negative(self):
4923 """ Self Twice NAT44 local service load balancing (negative test) """
4924 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4927 def test_twice_nat_interface_addr(self):
4928 """ Acquire twice NAT44 addresses from interface """
4929 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
4931 # no address in NAT pool
4932 adresses = self.vapi.nat44_address_dump()
4933 self.assertEqual(0, len(adresses))
4935 # configure interface address and check NAT address pool
4936 self.pg3.config_ip4()
4937 adresses = self.vapi.nat44_address_dump()
4938 self.assertEqual(1, len(adresses))
4939 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
4940 self.assertEqual(adresses[0].twice_nat, 1)
4942 # remove interface address and check NAT address pool
4943 self.pg3.unconfig_ip4()
4944 adresses = self.vapi.nat44_address_dump()
4945 self.assertEqual(0, len(adresses))
4947 def test_tcp_close(self):
4948 """ Close TCP session from inside network - output feature """
4949 self.vapi.nat44_forwarding_enable_disable(1)
4950 self.nat44_add_address(self.pg1.local_ip4)
4951 twice_nat_addr = '10.0.1.3'
4952 service_ip = '192.168.16.150'
4953 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4954 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4955 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4957 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4959 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4963 proto=IP_PROTOS.tcp,
4966 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4967 start_sessnum = len(sessions)
4969 # SYN packet out->in
4970 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4971 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4972 TCP(sport=33898, dport=80, flags="S"))
4973 self.pg1.add_stream(p)
4974 self.pg_enable_capture(self.pg_interfaces)
4976 capture = self.pg0.get_capture(1)
4978 tcp_port = p[TCP].sport
4980 # SYN + ACK packet in->out
4981 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4982 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
4983 TCP(sport=80, dport=tcp_port, flags="SA"))
4984 self.pg0.add_stream(p)
4985 self.pg_enable_capture(self.pg_interfaces)
4987 self.pg1.get_capture(1)
4989 # ACK packet out->in
4990 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4991 IP(src=self.pg1.remote_ip4, dst=service_ip) /
4992 TCP(sport=33898, dport=80, flags="A"))
4993 self.pg1.add_stream(p)
4994 self.pg_enable_capture(self.pg_interfaces)
4996 self.pg0.get_capture(1)
4998 # FIN packet in -> out
4999 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5000 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5001 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5002 self.pg0.add_stream(p)
5003 self.pg_enable_capture(self.pg_interfaces)
5005 self.pg1.get_capture(1)
5007 # FIN+ACK packet out -> in
5008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5009 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5010 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5011 self.pg1.add_stream(p)
5012 self.pg_enable_capture(self.pg_interfaces)
5014 self.pg0.get_capture(1)
5016 # ACK packet in -> out
5017 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5018 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5019 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5020 self.pg0.add_stream(p)
5021 self.pg_enable_capture(self.pg_interfaces)
5023 self.pg1.get_capture(1)
5025 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5027 self.assertEqual(len(sessions) - start_sessnum, 0)
5029 def test_tcp_session_close_in(self):
5030 """ Close TCP session from inside network """
5031 self.tcp_port_out = 10505
5032 self.nat44_add_address(self.nat_addr)
5033 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5037 proto=IP_PROTOS.tcp,
5039 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5040 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5043 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5044 start_sessnum = len(sessions)
5046 self.initiate_tcp_session(self.pg0, self.pg1)
5048 # FIN packet in -> out
5049 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5050 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5051 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5052 flags="FA", seq=100, ack=300))
5053 self.pg0.add_stream(p)
5054 self.pg_enable_capture(self.pg_interfaces)
5056 self.pg1.get_capture(1)
5060 # ACK packet out -> in
5061 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5062 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5063 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5064 flags="A", seq=300, ack=101))
5067 # FIN packet out -> in
5068 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5069 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5070 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5071 flags="FA", seq=300, ack=101))
5074 self.pg1.add_stream(pkts)
5075 self.pg_enable_capture(self.pg_interfaces)
5077 self.pg0.get_capture(2)
5079 # ACK packet in -> out
5080 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5081 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5082 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5083 flags="A", seq=101, ack=301))
5084 self.pg0.add_stream(p)
5085 self.pg_enable_capture(self.pg_interfaces)
5087 self.pg1.get_capture(1)
5089 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5091 self.assertEqual(len(sessions) - start_sessnum, 0)
5093 def test_tcp_session_close_out(self):
5094 """ Close TCP session from outside network """
5095 self.tcp_port_out = 10505
5096 self.nat44_add_address(self.nat_addr)
5097 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5101 proto=IP_PROTOS.tcp,
5103 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5104 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5107 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5108 start_sessnum = len(sessions)
5110 self.initiate_tcp_session(self.pg0, self.pg1)
5112 # FIN packet out -> in
5113 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5114 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5115 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5116 flags="FA", seq=100, ack=300))
5117 self.pg1.add_stream(p)
5118 self.pg_enable_capture(self.pg_interfaces)
5120 self.pg0.get_capture(1)
5122 # FIN+ACK packet in -> out
5123 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5124 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5125 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5126 flags="FA", seq=300, ack=101))
5128 self.pg0.add_stream(p)
5129 self.pg_enable_capture(self.pg_interfaces)
5131 self.pg1.get_capture(1)
5133 # ACK packet out -> in
5134 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5135 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5136 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5137 flags="A", seq=101, ack=301))
5138 self.pg1.add_stream(p)
5139 self.pg_enable_capture(self.pg_interfaces)
5141 self.pg0.get_capture(1)
5143 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5145 self.assertEqual(len(sessions) - start_sessnum, 0)
5147 def test_tcp_session_close_simultaneous(self):
5148 """ Close TCP session from inside network """
5149 self.tcp_port_out = 10505
5150 self.nat44_add_address(self.nat_addr)
5151 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5155 proto=IP_PROTOS.tcp,
5157 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5158 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5161 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5162 start_sessnum = len(sessions)
5164 self.initiate_tcp_session(self.pg0, self.pg1)
5166 # FIN packet in -> out
5167 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5168 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5169 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5170 flags="FA", seq=100, ack=300))
5171 self.pg0.add_stream(p)
5172 self.pg_enable_capture(self.pg_interfaces)
5174 self.pg1.get_capture(1)
5176 # FIN packet out -> in
5177 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5178 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5179 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5180 flags="FA", seq=300, ack=100))
5181 self.pg1.add_stream(p)
5182 self.pg_enable_capture(self.pg_interfaces)
5184 self.pg0.get_capture(1)
5186 # ACK packet in -> out
5187 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5188 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5189 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5190 flags="A", seq=101, ack=301))
5191 self.pg0.add_stream(p)
5192 self.pg_enable_capture(self.pg_interfaces)
5194 self.pg1.get_capture(1)
5196 # ACK packet out -> in
5197 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5198 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5199 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5200 flags="A", seq=301, ack=101))
5201 self.pg1.add_stream(p)
5202 self.pg_enable_capture(self.pg_interfaces)
5204 self.pg0.get_capture(1)
5206 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5208 self.assertEqual(len(sessions) - start_sessnum, 0)
5210 def test_one_armed_nat44_static(self):
5211 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5212 remote_host = self.pg4.remote_hosts[0]
5213 local_host = self.pg4.remote_hosts[1]
5218 self.vapi.nat44_forwarding_enable_disable(1)
5219 self.nat44_add_address(self.nat_addr, twice_nat=1)
5220 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5221 local_port, external_port,
5222 proto=IP_PROTOS.tcp, out2in_only=1,
5224 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5225 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5228 # from client to service
5229 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5230 IP(src=remote_host.ip4, dst=self.nat_addr) /
5231 TCP(sport=12345, dport=external_port))
5232 self.pg4.add_stream(p)
5233 self.pg_enable_capture(self.pg_interfaces)
5235 capture = self.pg4.get_capture(1)
5240 self.assertEqual(ip.dst, local_host.ip4)
5241 self.assertEqual(ip.src, self.nat_addr)
5242 self.assertEqual(tcp.dport, local_port)
5243 self.assertNotEqual(tcp.sport, 12345)
5244 eh_port_in = tcp.sport
5245 self.assert_packet_checksums_valid(p)
5247 self.logger.error(ppp("Unexpected or invalid packet:", p))
5250 # from service back to client
5251 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5252 IP(src=local_host.ip4, dst=self.nat_addr) /
5253 TCP(sport=local_port, dport=eh_port_in))
5254 self.pg4.add_stream(p)
5255 self.pg_enable_capture(self.pg_interfaces)
5257 capture = self.pg4.get_capture(1)
5262 self.assertEqual(ip.src, self.nat_addr)
5263 self.assertEqual(ip.dst, remote_host.ip4)
5264 self.assertEqual(tcp.sport, external_port)
5265 self.assertEqual(tcp.dport, 12345)
5266 self.assert_packet_checksums_valid(p)
5268 self.logger.error(ppp("Unexpected or invalid packet:", p))
5271 def test_static_with_port_out2(self):
5272 """ 1:1 NAPT asymmetrical rule """
5277 self.vapi.nat44_forwarding_enable_disable(1)
5278 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5279 local_port, external_port,
5280 proto=IP_PROTOS.tcp, out2in_only=1)
5281 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5282 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5285 # from client to service
5286 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5287 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5288 TCP(sport=12345, dport=external_port))
5289 self.pg1.add_stream(p)
5290 self.pg_enable_capture(self.pg_interfaces)
5292 capture = self.pg0.get_capture(1)
5297 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5298 self.assertEqual(tcp.dport, local_port)
5299 self.assert_packet_checksums_valid(p)
5301 self.logger.error(ppp("Unexpected or invalid packet:", p))
5305 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5306 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5307 ICMP(type=11) / capture[0][IP])
5308 self.pg0.add_stream(p)
5309 self.pg_enable_capture(self.pg_interfaces)
5311 capture = self.pg1.get_capture(1)
5314 self.assertEqual(p[IP].src, self.nat_addr)
5316 self.assertEqual(inner.dst, self.nat_addr)
5317 self.assertEqual(inner[TCPerror].dport, external_port)
5319 self.logger.error(ppp("Unexpected or invalid packet:", p))
5322 # from service back to client
5323 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5324 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5325 TCP(sport=local_port, dport=12345))
5326 self.pg0.add_stream(p)
5327 self.pg_enable_capture(self.pg_interfaces)
5329 capture = self.pg1.get_capture(1)
5334 self.assertEqual(ip.src, self.nat_addr)
5335 self.assertEqual(tcp.sport, external_port)
5336 self.assert_packet_checksums_valid(p)
5338 self.logger.error(ppp("Unexpected or invalid packet:", p))
5342 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5343 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5344 ICMP(type=11) / capture[0][IP])
5345 self.pg1.add_stream(p)
5346 self.pg_enable_capture(self.pg_interfaces)
5348 capture = self.pg0.get_capture(1)
5351 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5353 self.assertEqual(inner.src, self.pg0.remote_ip4)
5354 self.assertEqual(inner[TCPerror].sport, local_port)
5356 self.logger.error(ppp("Unexpected or invalid packet:", p))
5359 # from client to server (no translation)
5360 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5361 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5362 TCP(sport=12346, dport=local_port))
5363 self.pg1.add_stream(p)
5364 self.pg_enable_capture(self.pg_interfaces)
5366 capture = self.pg0.get_capture(1)
5371 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5372 self.assertEqual(tcp.dport, local_port)
5373 self.assert_packet_checksums_valid(p)
5375 self.logger.error(ppp("Unexpected or invalid packet:", p))
5378 # from service back to client (no translation)
5379 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5380 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5381 TCP(sport=local_port, dport=12346))
5382 self.pg0.add_stream(p)
5383 self.pg_enable_capture(self.pg_interfaces)
5385 capture = self.pg1.get_capture(1)
5390 self.assertEqual(ip.src, self.pg0.remote_ip4)
5391 self.assertEqual(tcp.sport, local_port)
5392 self.assert_packet_checksums_valid(p)
5394 self.logger.error(ppp("Unexpected or invalid packet:", p))
5397 def test_output_feature(self):
5398 """ NAT44 interface output feature (in2out postrouting) """
5399 self.vapi.nat44_forwarding_enable_disable(1)
5400 self.nat44_add_address(self.nat_addr)
5401 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5403 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5407 pkts = self.create_stream_in(self.pg0, self.pg1)
5408 self.pg0.add_stream(pkts)
5409 self.pg_enable_capture(self.pg_interfaces)
5411 capture = self.pg1.get_capture(len(pkts))
5412 self.verify_capture_out(capture)
5415 pkts = self.create_stream_out(self.pg1)
5416 self.pg1.add_stream(pkts)
5417 self.pg_enable_capture(self.pg_interfaces)
5419 capture = self.pg0.get_capture(len(pkts))
5420 self.verify_capture_in(capture, self.pg0)
5422 def test_multiple_vrf(self):
5423 """ Multiple VRF setup """
5424 external_addr = '1.2.3.4'
5429 self.vapi.nat44_forwarding_enable_disable(1)
5430 self.nat44_add_address(self.nat_addr)
5431 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5432 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5434 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5436 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5437 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5439 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5441 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5442 local_port, external_port, vrf_id=1,
5443 proto=IP_PROTOS.tcp, out2in_only=1)
5444 self.nat44_add_static_mapping(
5445 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5446 local_port=local_port, vrf_id=0, external_port=external_port,
5447 proto=IP_PROTOS.tcp, out2in_only=1)
5449 # from client to service (both VRF1)
5450 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5451 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5452 TCP(sport=12345, dport=external_port))
5453 self.pg6.add_stream(p)
5454 self.pg_enable_capture(self.pg_interfaces)
5456 capture = self.pg5.get_capture(1)
5461 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5462 self.assertEqual(tcp.dport, local_port)
5463 self.assert_packet_checksums_valid(p)
5465 self.logger.error(ppp("Unexpected or invalid packet:", p))
5468 # from service back to client (both VRF1)
5469 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5470 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5471 TCP(sport=local_port, dport=12345))
5472 self.pg5.add_stream(p)
5473 self.pg_enable_capture(self.pg_interfaces)
5475 capture = self.pg6.get_capture(1)
5480 self.assertEqual(ip.src, external_addr)
5481 self.assertEqual(tcp.sport, external_port)
5482 self.assert_packet_checksums_valid(p)
5484 self.logger.error(ppp("Unexpected or invalid packet:", p))
5487 # dynamic NAT from VRF1 to VRF0 (output-feature)
5488 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5489 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5490 TCP(sport=2345, dport=22))
5491 self.pg5.add_stream(p)
5492 self.pg_enable_capture(self.pg_interfaces)
5494 capture = self.pg1.get_capture(1)
5499 self.assertEqual(ip.src, self.nat_addr)
5500 self.assertNotEqual(tcp.sport, 2345)
5501 self.assert_packet_checksums_valid(p)
5504 self.logger.error(ppp("Unexpected or invalid packet:", p))
5507 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5508 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5509 TCP(sport=22, dport=port))
5510 self.pg1.add_stream(p)
5511 self.pg_enable_capture(self.pg_interfaces)
5513 capture = self.pg5.get_capture(1)
5518 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5519 self.assertEqual(tcp.dport, 2345)
5520 self.assert_packet_checksums_valid(p)
5522 self.logger.error(ppp("Unexpected or invalid packet:", p))
5525 # from client VRF1 to service VRF0
5526 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5527 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5528 TCP(sport=12346, dport=external_port))
5529 self.pg6.add_stream(p)
5530 self.pg_enable_capture(self.pg_interfaces)
5532 capture = self.pg0.get_capture(1)
5537 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5538 self.assertEqual(tcp.dport, local_port)
5539 self.assert_packet_checksums_valid(p)
5541 self.logger.error(ppp("Unexpected or invalid packet:", p))
5544 # from service VRF0 back to client VRF1
5545 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5546 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5547 TCP(sport=local_port, dport=12346))
5548 self.pg0.add_stream(p)
5549 self.pg_enable_capture(self.pg_interfaces)
5551 capture = self.pg6.get_capture(1)
5556 self.assertEqual(ip.src, self.pg0.local_ip4)
5557 self.assertEqual(tcp.sport, external_port)
5558 self.assert_packet_checksums_valid(p)
5560 self.logger.error(ppp("Unexpected or invalid packet:", p))
5563 # from client VRF0 to service VRF1
5564 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5565 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5566 TCP(sport=12347, dport=external_port))
5567 self.pg0.add_stream(p)
5568 self.pg_enable_capture(self.pg_interfaces)
5570 capture = self.pg5.get_capture(1)
5575 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5576 self.assertEqual(tcp.dport, local_port)
5577 self.assert_packet_checksums_valid(p)
5579 self.logger.error(ppp("Unexpected or invalid packet:", p))
5582 # from service VRF1 back to client VRF0
5583 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5584 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5585 TCP(sport=local_port, dport=12347))
5586 self.pg5.add_stream(p)
5587 self.pg_enable_capture(self.pg_interfaces)
5589 capture = self.pg0.get_capture(1)
5594 self.assertEqual(ip.src, external_addr)
5595 self.assertEqual(tcp.sport, external_port)
5596 self.assert_packet_checksums_valid(p)
5598 self.logger.error(ppp("Unexpected or invalid packet:", p))
5601 # from client to server (both VRF1, no translation)
5602 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5603 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5604 TCP(sport=12348, dport=local_port))
5605 self.pg6.add_stream(p)
5606 self.pg_enable_capture(self.pg_interfaces)
5608 capture = self.pg5.get_capture(1)
5613 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5614 self.assertEqual(tcp.dport, local_port)
5615 self.assert_packet_checksums_valid(p)
5617 self.logger.error(ppp("Unexpected or invalid packet:", p))
5620 # from server back to client (both VRF1, no translation)
5621 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5622 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5623 TCP(sport=local_port, dport=12348))
5624 self.pg5.add_stream(p)
5625 self.pg_enable_capture(self.pg_interfaces)
5627 capture = self.pg6.get_capture(1)
5632 self.assertEqual(ip.src, self.pg5.remote_ip4)
5633 self.assertEqual(tcp.sport, local_port)
5634 self.assert_packet_checksums_valid(p)
5636 self.logger.error(ppp("Unexpected or invalid packet:", p))
5639 # from client VRF1 to server VRF0 (no translation)
5640 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5641 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5642 TCP(sport=local_port, dport=12349))
5643 self.pg0.add_stream(p)
5644 self.pg_enable_capture(self.pg_interfaces)
5646 capture = self.pg6.get_capture(1)
5651 self.assertEqual(ip.src, self.pg0.remote_ip4)
5652 self.assertEqual(tcp.sport, local_port)
5653 self.assert_packet_checksums_valid(p)
5655 self.logger.error(ppp("Unexpected or invalid packet:", p))
5658 # from server VRF0 back to client VRF1 (no translation)
5659 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5660 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5661 TCP(sport=local_port, dport=12349))
5662 self.pg0.add_stream(p)
5663 self.pg_enable_capture(self.pg_interfaces)
5665 capture = self.pg6.get_capture(1)
5670 self.assertEqual(ip.src, self.pg0.remote_ip4)
5671 self.assertEqual(tcp.sport, local_port)
5672 self.assert_packet_checksums_valid(p)
5674 self.logger.error(ppp("Unexpected or invalid packet:", p))
5677 # from client VRF0 to server VRF1 (no translation)
5678 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5679 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5680 TCP(sport=12344, dport=local_port))
5681 self.pg0.add_stream(p)
5682 self.pg_enable_capture(self.pg_interfaces)
5684 capture = self.pg5.get_capture(1)
5689 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5690 self.assertEqual(tcp.dport, local_port)
5691 self.assert_packet_checksums_valid(p)
5693 self.logger.error(ppp("Unexpected or invalid packet:", p))
5696 # from server VRF1 back to client VRF0 (no translation)
5697 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5698 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5699 TCP(sport=local_port, dport=12344))
5700 self.pg5.add_stream(p)
5701 self.pg_enable_capture(self.pg_interfaces)
5703 capture = self.pg0.get_capture(1)
5708 self.assertEqual(ip.src, self.pg5.remote_ip4)
5709 self.assertEqual(tcp.sport, local_port)
5710 self.assert_packet_checksums_valid(p)
5712 self.logger.error(ppp("Unexpected or invalid packet:", p))
5715 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5716 def test_session_timeout(self):
5717 """ NAT44 session timeouts """
5718 self.nat44_add_address(self.nat_addr)
5719 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5720 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5722 self.vapi.nat_set_timeouts(icmp=5)
5726 for i in range(0, max_sessions):
5727 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5728 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5729 IP(src=src, dst=self.pg1.remote_ip4) /
5730 ICMP(id=1025, type='echo-request'))
5732 self.pg0.add_stream(pkts)
5733 self.pg_enable_capture(self.pg_interfaces)
5735 self.pg1.get_capture(max_sessions)
5740 for i in range(0, max_sessions):
5741 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5742 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5743 IP(src=src, dst=self.pg1.remote_ip4) /
5744 ICMP(id=1026, type='echo-request'))
5746 self.pg0.add_stream(pkts)
5747 self.pg_enable_capture(self.pg_interfaces)
5749 self.pg1.get_capture(max_sessions)
5752 users = self.vapi.nat44_user_dump()
5754 nsessions = nsessions + user.nsessions
5755 self.assertLess(nsessions, 2 * max_sessions)
5757 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5758 def test_session_rst_timeout(self):
5759 """ NAT44 session RST timeouts """
5760 self.nat44_add_address(self.nat_addr)
5761 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5762 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5764 self.vapi.nat_set_timeouts(tcp_transitory=5)
5766 self.initiate_tcp_session(self.pg0, self.pg1)
5767 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5768 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5769 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5771 self.pg0.add_stream(p)
5772 self.pg_enable_capture(self.pg_interfaces)
5774 self.pg1.get_capture(1)
5778 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5779 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5780 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5782 self.pg0.add_stream(p)
5783 self.pg_enable_capture(self.pg_interfaces)
5785 self.pg1.get_capture(1)
5788 users = self.vapi.nat44_user_dump()
5789 self.assertEqual(len(users), 1)
5790 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
5791 self.assertEqual(users[0].nsessions, 1)
5793 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5794 def test_session_limit_per_user(self):
5795 """ Maximum sessions per user limit """
5796 self.nat44_add_address(self.nat_addr)
5797 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5798 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5800 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5801 src_address=self.pg2.local_ip4n,
5803 template_interval=10)
5804 self.vapi.nat_set_timeouts(udp=5)
5806 # get maximum number of translations per user
5807 nat44_config = self.vapi.nat_show_config()
5810 for port in range(0, nat44_config.max_translations_per_user):
5811 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5812 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5813 UDP(sport=1025 + port, dport=1025 + port))
5816 self.pg0.add_stream(pkts)
5817 self.pg_enable_capture(self.pg_interfaces)
5819 capture = self.pg1.get_capture(len(pkts))
5821 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5822 src_port=self.ipfix_src_port)
5824 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5825 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5826 UDP(sport=3001, dport=3002))
5827 self.pg0.add_stream(p)
5828 self.pg_enable_capture(self.pg_interfaces)
5830 capture = self.pg1.assert_nothing_captured()
5832 # verify IPFIX logging
5833 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5835 capture = self.pg2.get_capture(10)
5836 ipfix = IPFIXDecoder()
5837 # first load template
5839 self.assertTrue(p.haslayer(IPFIX))
5840 if p.haslayer(Template):
5841 ipfix.add_template(p.getlayer(Template))
5842 # verify events in data set
5844 if p.haslayer(Data):
5845 data = ipfix.decode_data_set(p.getlayer(Set))
5846 self.verify_ipfix_max_entries_per_user(
5848 nat44_config.max_translations_per_user,
5849 self.pg0.remote_ip4n)
5852 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5853 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5854 UDP(sport=3001, dport=3002))
5855 self.pg0.add_stream(p)
5856 self.pg_enable_capture(self.pg_interfaces)
5858 self.pg1.get_capture(1)
5860 def test_syslog_sess(self):
5861 """ Test syslog session creation and deletion """
5862 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
5863 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
5864 self.nat44_add_address(self.nat_addr)
5865 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5866 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5869 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5870 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5871 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5872 self.pg0.add_stream(p)
5873 self.pg_enable_capture(self.pg_interfaces)
5875 capture = self.pg1.get_capture(1)
5876 self.tcp_port_out = capture[0][TCP].sport
5877 capture = self.pg2.get_capture(1)
5878 self.verify_syslog_sess(capture[0][Raw].load)
5880 self.pg_enable_capture(self.pg_interfaces)
5882 self.nat44_add_address(self.nat_addr, is_add=0)
5883 capture = self.pg2.get_capture(1)
5884 self.verify_syslog_sess(capture[0][Raw].load, False)
5887 super(TestNAT44EndpointDependent, self).tearDown()
5888 if not self.vpp_dead:
5889 self.logger.info(self.vapi.cli("show nat44 addresses"))
5890 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5891 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5892 self.logger.info(self.vapi.cli("show nat44 interface address"))
5893 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5894 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
5895 self.logger.info(self.vapi.cli("show nat timeouts"))
5897 self.vapi.cli("clear logging")
5900 class TestNAT44Out2InDPO(MethodHolder):
5901 """ NAT44 Test Cases using out2in DPO """
5904 def setUpConstants(cls):
5905 super(TestNAT44Out2InDPO, cls).setUpConstants()
5906 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5909 def setUpClass(cls):
5910 super(TestNAT44Out2InDPO, cls).setUpClass()
5911 cls.vapi.cli("set log class nat level debug")
5914 cls.tcp_port_in = 6303
5915 cls.tcp_port_out = 6303
5916 cls.udp_port_in = 6304
5917 cls.udp_port_out = 6304
5918 cls.icmp_id_in = 6305
5919 cls.icmp_id_out = 6305
5920 cls.nat_addr = '10.0.0.3'
5921 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
5922 cls.dst_ip4 = '192.168.70.1'
5924 cls.create_pg_interfaces(range(2))
5927 cls.pg0.config_ip4()
5928 cls.pg0.resolve_arp()
5931 cls.pg1.config_ip6()
5932 cls.pg1.resolve_ndp()
5934 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
5935 dst_address_length=0,
5936 next_hop_address=cls.pg1.remote_ip6n,
5937 next_hop_sw_if_index=cls.pg1.sw_if_index)
5940 super(TestNAT44Out2InDPO, cls).tearDownClass()
5943 def configure_xlat(self):
5944 self.dst_ip6_pfx = '1:2:3::'
5945 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5947 self.dst_ip6_pfx_len = 96
5948 self.src_ip6_pfx = '4:5:6::'
5949 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
5951 self.src_ip6_pfx_len = 96
5952 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
5953 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
5954 '\x00\x00\x00\x00', 0, is_translation=1,
5957 @unittest.skip('Temporary disabled')
5958 def test_464xlat_ce(self):
5959 """ Test 464XLAT CE with NAT44 """
5961 nat_config = self.vapi.nat_show_config()
5962 self.assertEqual(1, nat_config.out2in_dpo)
5964 self.configure_xlat()
5966 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5967 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
5969 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
5970 self.dst_ip6_pfx_len)
5971 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
5972 self.src_ip6_pfx_len)
5975 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
5976 self.pg0.add_stream(pkts)
5977 self.pg_enable_capture(self.pg_interfaces)
5979 capture = self.pg1.get_capture(len(pkts))
5980 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
5983 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
5985 self.pg1.add_stream(pkts)
5986 self.pg_enable_capture(self.pg_interfaces)
5988 capture = self.pg0.get_capture(len(pkts))
5989 self.verify_capture_in(capture, self.pg0)
5991 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5993 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
5994 self.nat_addr_n, is_add=0)
5996 @unittest.skip('Temporary disabled')
5997 def test_464xlat_ce_no_nat(self):
5998 """ Test 464XLAT CE without NAT44 """
6000 self.configure_xlat()
6002 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6003 self.dst_ip6_pfx_len)
6004 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6005 self.src_ip6_pfx_len)
6007 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6008 self.pg0.add_stream(pkts)
6009 self.pg_enable_capture(self.pg_interfaces)
6011 capture = self.pg1.get_capture(len(pkts))
6012 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6013 nat_ip=out_dst_ip6, same_port=True)
6015 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6016 self.pg1.add_stream(pkts)
6017 self.pg_enable_capture(self.pg_interfaces)
6019 capture = self.pg0.get_capture(len(pkts))
6020 self.verify_capture_in(capture, self.pg0)
6023 class TestDeterministicNAT(MethodHolder):
6024 """ Deterministic NAT Test Cases """
6027 def setUpConstants(cls):
6028 super(TestDeterministicNAT, cls).setUpConstants()
6029 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6032 def setUpClass(cls):
6033 super(TestDeterministicNAT, cls).setUpClass()
6034 cls.vapi.cli("set log class nat level debug")
6037 cls.tcp_port_in = 6303
6038 cls.tcp_external_port = 6303
6039 cls.udp_port_in = 6304
6040 cls.udp_external_port = 6304
6041 cls.icmp_id_in = 6305
6042 cls.nat_addr = '10.0.0.3'
6044 cls.create_pg_interfaces(range(3))
6045 cls.interfaces = list(cls.pg_interfaces)
6047 for i in cls.interfaces:
6052 cls.pg0.generate_remote_hosts(2)
6053 cls.pg0.configure_ipv4_neighbors()
6056 super(TestDeterministicNAT, cls).tearDownClass()
6059 def create_stream_in(self, in_if, out_if, ttl=64):
6061 Create packet stream for inside network
6063 :param in_if: Inside interface
6064 :param out_if: Outside interface
6065 :param ttl: TTL of generated packets
6069 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6070 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6071 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6075 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6076 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6077 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
6081 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6082 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6083 ICMP(id=self.icmp_id_in, type='echo-request'))
6088 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6090 Create packet stream for outside network
6092 :param out_if: Outside interface
6093 :param dst_ip: Destination IP address (Default use global NAT address)
6094 :param ttl: TTL of generated packets
6097 dst_ip = self.nat_addr
6100 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6101 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6102 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
6106 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6107 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6108 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
6112 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6113 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6114 ICMP(id=self.icmp_external_id, type='echo-reply'))
6119 def verify_capture_out(self, capture, nat_ip=None):
6121 Verify captured packets on outside network
6123 :param capture: Captured packets
6124 :param nat_ip: Translated IP address (Default use global NAT address)
6125 :param same_port: Sorce port number is not translated (Default False)
6128 nat_ip = self.nat_addr
6129 for packet in capture:
6131 self.assertEqual(packet[IP].src, nat_ip)
6132 if packet.haslayer(TCP):
6133 self.tcp_port_out = packet[TCP].sport
6134 elif packet.haslayer(UDP):
6135 self.udp_port_out = packet[UDP].sport
6137 self.icmp_external_id = packet[ICMP].id
6139 self.logger.error(ppp("Unexpected or invalid packet "
6140 "(outside network):", packet))
6143 def test_deterministic_mode(self):
6144 """ NAT plugin run deterministic mode """
6145 in_addr = '172.16.255.0'
6146 out_addr = '172.17.255.50'
6147 in_addr_t = '172.16.255.20'
6148 in_addr_n = socket.inet_aton(in_addr)
6149 out_addr_n = socket.inet_aton(out_addr)
6150 in_addr_t_n = socket.inet_aton(in_addr_t)
6154 nat_config = self.vapi.nat_show_config()
6155 self.assertEqual(1, nat_config.deterministic)
6157 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
6159 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
6160 self.assertEqual(rep1.out_addr[:4], out_addr_n)
6161 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
6162 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6164 deterministic_mappings = self.vapi.nat_det_map_dump()
6165 self.assertEqual(len(deterministic_mappings), 1)
6166 dsm = deterministic_mappings[0]
6167 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6168 self.assertEqual(in_plen, dsm.in_plen)
6169 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6170 self.assertEqual(out_plen, dsm.out_plen)
6172 self.clear_nat_det()
6173 deterministic_mappings = self.vapi.nat_det_map_dump()
6174 self.assertEqual(len(deterministic_mappings), 0)
6176 def test_set_timeouts(self):
6177 """ Set deterministic NAT timeouts """
6178 timeouts_before = self.vapi.nat_get_timeouts()
6180 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6181 timeouts_before.tcp_established + 10,
6182 timeouts_before.tcp_transitory + 10,
6183 timeouts_before.icmp + 10)
6185 timeouts_after = self.vapi.nat_get_timeouts()
6187 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6188 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6189 self.assertNotEqual(timeouts_before.tcp_established,
6190 timeouts_after.tcp_established)
6191 self.assertNotEqual(timeouts_before.tcp_transitory,
6192 timeouts_after.tcp_transitory)
6194 def test_det_in(self):
6195 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
6197 nat_ip = "10.0.0.10"
6199 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6201 socket.inet_aton(nat_ip),
6203 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6204 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6208 pkts = self.create_stream_in(self.pg0, self.pg1)
6209 self.pg0.add_stream(pkts)
6210 self.pg_enable_capture(self.pg_interfaces)
6212 capture = self.pg1.get_capture(len(pkts))
6213 self.verify_capture_out(capture, nat_ip)
6216 pkts = self.create_stream_out(self.pg1, nat_ip)
6217 self.pg1.add_stream(pkts)
6218 self.pg_enable_capture(self.pg_interfaces)
6220 capture = self.pg0.get_capture(len(pkts))
6221 self.verify_capture_in(capture, self.pg0)
6224 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
6225 self.assertEqual(len(sessions), 3)
6229 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6230 self.assertEqual(s.in_port, self.tcp_port_in)
6231 self.assertEqual(s.out_port, self.tcp_port_out)
6232 self.assertEqual(s.ext_port, self.tcp_external_port)
6236 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6237 self.assertEqual(s.in_port, self.udp_port_in)
6238 self.assertEqual(s.out_port, self.udp_port_out)
6239 self.assertEqual(s.ext_port, self.udp_external_port)
6243 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6244 self.assertEqual(s.in_port, self.icmp_id_in)
6245 self.assertEqual(s.out_port, self.icmp_external_id)
6247 def test_multiple_users(self):
6248 """ Deterministic NAT multiple users """
6250 nat_ip = "10.0.0.10"
6252 external_port = 6303
6254 host0 = self.pg0.remote_hosts[0]
6255 host1 = self.pg0.remote_hosts[1]
6257 self.vapi.nat_det_add_del_map(host0.ip4n,
6259 socket.inet_aton(nat_ip),
6261 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6262 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6266 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6267 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
6268 TCP(sport=port_in, dport=external_port))
6269 self.pg0.add_stream(p)
6270 self.pg_enable_capture(self.pg_interfaces)
6272 capture = self.pg1.get_capture(1)
6277 self.assertEqual(ip.src, nat_ip)
6278 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6279 self.assertEqual(tcp.dport, external_port)
6280 port_out0 = tcp.sport
6282 self.logger.error(ppp("Unexpected or invalid packet:", p))
6286 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6287 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
6288 TCP(sport=port_in, dport=external_port))
6289 self.pg0.add_stream(p)
6290 self.pg_enable_capture(self.pg_interfaces)
6292 capture = self.pg1.get_capture(1)
6297 self.assertEqual(ip.src, nat_ip)
6298 self.assertEqual(ip.dst, self.pg1.remote_ip4)
6299 self.assertEqual(tcp.dport, external_port)
6300 port_out1 = tcp.sport
6302 self.logger.error(ppp("Unexpected or invalid packet:", p))
6305 dms = self.vapi.nat_det_map_dump()
6306 self.assertEqual(1, len(dms))
6307 self.assertEqual(2, dms[0].ses_num)
6310 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6311 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6312 TCP(sport=external_port, dport=port_out0))
6313 self.pg1.add_stream(p)
6314 self.pg_enable_capture(self.pg_interfaces)
6316 capture = self.pg0.get_capture(1)
6321 self.assertEqual(ip.src, self.pg1.remote_ip4)
6322 self.assertEqual(ip.dst, host0.ip4)
6323 self.assertEqual(tcp.dport, port_in)
6324 self.assertEqual(tcp.sport, external_port)
6326 self.logger.error(ppp("Unexpected or invalid packet:", p))
6330 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6331 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
6332 TCP(sport=external_port, dport=port_out1))
6333 self.pg1.add_stream(p)
6334 self.pg_enable_capture(self.pg_interfaces)
6336 capture = self.pg0.get_capture(1)
6341 self.assertEqual(ip.src, self.pg1.remote_ip4)
6342 self.assertEqual(ip.dst, host1.ip4)
6343 self.assertEqual(tcp.dport, port_in)
6344 self.assertEqual(tcp.sport, external_port)
6346 self.logger.error(ppp("Unexpected or invalid packet", p))
6349 # session close api test
6350 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6352 self.pg1.remote_ip4n,
6354 dms = self.vapi.nat_det_map_dump()
6355 self.assertEqual(dms[0].ses_num, 1)
6357 self.vapi.nat_det_close_session_in(host0.ip4n,
6359 self.pg1.remote_ip4n,
6361 dms = self.vapi.nat_det_map_dump()
6362 self.assertEqual(dms[0].ses_num, 0)
6364 def test_tcp_session_close_detection_in(self):
6365 """ Deterministic NAT TCP session close from inside network """
6366 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6368 socket.inet_aton(self.nat_addr),
6370 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6371 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6374 self.initiate_tcp_session(self.pg0, self.pg1)
6376 # close the session from inside
6378 # FIN packet in -> out
6379 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6380 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6381 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6383 self.pg0.add_stream(p)
6384 self.pg_enable_capture(self.pg_interfaces)
6386 self.pg1.get_capture(1)
6390 # ACK packet out -> in
6391 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6392 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6393 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6397 # FIN packet out -> in
6398 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6399 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6400 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6404 self.pg1.add_stream(pkts)
6405 self.pg_enable_capture(self.pg_interfaces)
6407 self.pg0.get_capture(2)
6409 # ACK packet in -> out
6410 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6411 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6412 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6414 self.pg0.add_stream(p)
6415 self.pg_enable_capture(self.pg_interfaces)
6417 self.pg1.get_capture(1)
6419 # Check if deterministic NAT44 closed the session
6420 dms = self.vapi.nat_det_map_dump()
6421 self.assertEqual(0, dms[0].ses_num)
6423 self.logger.error("TCP session termination failed")
6426 def test_tcp_session_close_detection_out(self):
6427 """ Deterministic NAT TCP session close from outside network """
6428 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6430 socket.inet_aton(self.nat_addr),
6432 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6433 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6436 self.initiate_tcp_session(self.pg0, self.pg1)
6438 # close the session from outside
6440 # FIN packet out -> in
6441 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6442 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6443 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6445 self.pg1.add_stream(p)
6446 self.pg_enable_capture(self.pg_interfaces)
6448 self.pg0.get_capture(1)
6452 # ACK packet in -> out
6453 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6454 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6455 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6459 # ACK packet in -> out
6460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6462 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6466 self.pg0.add_stream(pkts)
6467 self.pg_enable_capture(self.pg_interfaces)
6469 self.pg1.get_capture(2)
6471 # ACK packet out -> in
6472 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6473 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6474 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6476 self.pg1.add_stream(p)
6477 self.pg_enable_capture(self.pg_interfaces)
6479 self.pg0.get_capture(1)
6481 # Check if deterministic NAT44 closed the session
6482 dms = self.vapi.nat_det_map_dump()
6483 self.assertEqual(0, dms[0].ses_num)
6485 self.logger.error("TCP session termination failed")
6488 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6489 def test_session_timeout(self):
6490 """ Deterministic NAT session timeouts """
6491 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6493 socket.inet_aton(self.nat_addr),
6495 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6496 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6499 self.initiate_tcp_session(self.pg0, self.pg1)
6500 self.vapi.nat_set_timeouts(5, 5, 5, 5)
6501 pkts = self.create_stream_in(self.pg0, self.pg1)
6502 self.pg0.add_stream(pkts)
6503 self.pg_enable_capture(self.pg_interfaces)
6505 capture = self.pg1.get_capture(len(pkts))
6508 dms = self.vapi.nat_det_map_dump()
6509 self.assertEqual(0, dms[0].ses_num)
6511 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6512 def test_session_limit_per_user(self):
6513 """ Deterministic NAT maximum sessions per user limit """
6514 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6516 socket.inet_aton(self.nat_addr),
6518 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6519 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6521 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6522 src_address=self.pg2.local_ip4n,
6524 template_interval=10)
6525 self.vapi.nat_ipfix()
6528 for port in range(1025, 2025):
6529 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6530 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6531 UDP(sport=port, dport=port))
6534 self.pg0.add_stream(pkts)
6535 self.pg_enable_capture(self.pg_interfaces)
6537 capture = self.pg1.get_capture(len(pkts))
6539 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6540 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6541 UDP(sport=3001, dport=3002))
6542 self.pg0.add_stream(p)
6543 self.pg_enable_capture(self.pg_interfaces)
6545 capture = self.pg1.assert_nothing_captured()
6547 # verify ICMP error packet
6548 capture = self.pg0.get_capture(1)
6550 self.assertTrue(p.haslayer(ICMP))
6552 self.assertEqual(icmp.type, 3)
6553 self.assertEqual(icmp.code, 1)
6554 self.assertTrue(icmp.haslayer(IPerror))
6555 inner_ip = icmp[IPerror]
6556 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6557 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6559 dms = self.vapi.nat_det_map_dump()
6561 self.assertEqual(1000, dms[0].ses_num)
6563 # verify IPFIX logging
6564 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6566 capture = self.pg2.get_capture(2)
6567 ipfix = IPFIXDecoder()
6568 # first load template
6570 self.assertTrue(p.haslayer(IPFIX))
6571 if p.haslayer(Template):
6572 ipfix.add_template(p.getlayer(Template))
6573 # verify events in data set
6575 if p.haslayer(Data):
6576 data = ipfix.decode_data_set(p.getlayer(Set))
6577 self.verify_ipfix_max_entries_per_user(data,
6579 self.pg0.remote_ip4n)
6581 def clear_nat_det(self):
6583 Clear deterministic NAT configuration.
6585 self.vapi.nat_ipfix(enable=0)
6586 self.vapi.nat_set_timeouts()
6587 deterministic_mappings = self.vapi.nat_det_map_dump()
6588 for dsm in deterministic_mappings:
6589 self.vapi.nat_det_add_del_map(dsm.in_addr,
6595 interfaces = self.vapi.nat44_interface_dump()
6596 for intf in interfaces:
6597 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6602 super(TestDeterministicNAT, self).tearDown()
6603 if not self.vpp_dead:
6604 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6605 self.logger.info(self.vapi.cli("show nat timeouts"))
6607 self.vapi.cli("show nat44 deterministic mappings"))
6609 self.vapi.cli("show nat44 deterministic sessions"))
6610 self.clear_nat_det()
6613 class TestNAT64(MethodHolder):
6614 """ NAT64 Test Cases """
6617 def setUpConstants(cls):
6618 super(TestNAT64, cls).setUpConstants()
6619 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6620 "nat64 st hash buckets 256", "}"])
6623 def setUpClass(cls):
6624 super(TestNAT64, cls).setUpClass()
6627 cls.tcp_port_in = 6303
6628 cls.tcp_port_out = 6303
6629 cls.udp_port_in = 6304
6630 cls.udp_port_out = 6304
6631 cls.icmp_id_in = 6305
6632 cls.icmp_id_out = 6305
6633 cls.tcp_external_port = 80
6634 cls.nat_addr = '10.0.0.3'
6635 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6637 cls.vrf1_nat_addr = '10.0.10.3'
6638 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6640 cls.ipfix_src_port = 4739
6641 cls.ipfix_domain_id = 1
6643 cls.create_pg_interfaces(range(6))
6644 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
6645 cls.ip6_interfaces.append(cls.pg_interfaces[2])
6646 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6648 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6650 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6652 cls.pg0.generate_remote_hosts(2)
6654 for i in cls.ip6_interfaces:
6657 i.configure_ipv6_neighbors()
6659 for i in cls.ip4_interfaces:
6665 cls.pg3.config_ip4()
6666 cls.pg3.resolve_arp()
6667 cls.pg3.config_ip6()
6668 cls.pg3.configure_ipv6_neighbors()
6671 cls.pg5.config_ip6()
6674 super(TestNAT64, cls).tearDownClass()
6677 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6678 """ NAT64 inside interface handles Neighbor Advertisement """
6680 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6683 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6684 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6685 ICMPv6EchoRequest())
6687 self.pg5.add_stream(pkts)
6688 self.pg_enable_capture(self.pg_interfaces)
6691 # Wait for Neighbor Solicitation
6692 capture = self.pg5.get_capture(len(pkts))
6695 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6696 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
6697 tgt = packet[ICMPv6ND_NS].tgt
6699 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6702 # Send Neighbor Advertisement
6703 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6704 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6705 ICMPv6ND_NA(tgt=tgt) /
6706 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6708 self.pg5.add_stream(pkts)
6709 self.pg_enable_capture(self.pg_interfaces)
6712 # Try to send ping again
6714 self.pg5.add_stream(pkts)
6715 self.pg_enable_capture(self.pg_interfaces)
6718 # Wait for ping reply
6719 capture = self.pg5.get_capture(len(pkts))
6722 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6723 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
6724 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
6726 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6729 def test_pool(self):
6730 """ Add/delete address to NAT64 pool """
6731 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6733 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6735 addresses = self.vapi.nat64_pool_addr_dump()
6736 self.assertEqual(len(addresses), 1)
6737 self.assertEqual(addresses[0].address, nat_addr)
6739 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6741 addresses = self.vapi.nat64_pool_addr_dump()
6742 self.assertEqual(len(addresses), 0)
6744 def test_interface(self):
6745 """ Enable/disable NAT64 feature on the interface """
6746 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6747 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6749 interfaces = self.vapi.nat64_interface_dump()
6750 self.assertEqual(len(interfaces), 2)
6753 for intf in interfaces:
6754 if intf.sw_if_index == self.pg0.sw_if_index:
6755 self.assertEqual(intf.is_inside, 1)
6757 elif intf.sw_if_index == self.pg1.sw_if_index:
6758 self.assertEqual(intf.is_inside, 0)
6760 self.assertTrue(pg0_found)
6761 self.assertTrue(pg1_found)
6763 features = self.vapi.cli("show interface features pg0")
6764 self.assertNotEqual(features.find('nat64-in2out'), -1)
6765 features = self.vapi.cli("show interface features pg1")
6766 self.assertNotEqual(features.find('nat64-out2in'), -1)
6768 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6769 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6771 interfaces = self.vapi.nat64_interface_dump()
6772 self.assertEqual(len(interfaces), 0)
6774 def test_static_bib(self):
6775 """ Add/delete static BIB entry """
6776 in_addr = socket.inet_pton(socket.AF_INET6,
6777 '2001:db8:85a3::8a2e:370:7334')
6778 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6781 proto = IP_PROTOS.tcp
6783 self.vapi.nat64_add_del_static_bib(in_addr,
6788 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6793 self.assertEqual(bibe.i_addr, in_addr)
6794 self.assertEqual(bibe.o_addr, out_addr)
6795 self.assertEqual(bibe.i_port, in_port)
6796 self.assertEqual(bibe.o_port, out_port)
6797 self.assertEqual(static_bib_num, 1)
6799 self.vapi.nat64_add_del_static_bib(in_addr,
6805 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6810 self.assertEqual(static_bib_num, 0)
6812 def test_set_timeouts(self):
6813 """ Set NAT64 timeouts """
6814 # verify default values
6815 timeouts = self.vapi.nat_get_timeouts()
6816 self.assertEqual(timeouts.udp, 300)
6817 self.assertEqual(timeouts.icmp, 60)
6818 self.assertEqual(timeouts.tcp_transitory, 240)
6819 self.assertEqual(timeouts.tcp_established, 7440)
6821 # set and verify custom values
6822 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6823 tcp_established=7450)
6824 timeouts = self.vapi.nat_get_timeouts()
6825 self.assertEqual(timeouts.udp, 200)
6826 self.assertEqual(timeouts.icmp, 30)
6827 self.assertEqual(timeouts.tcp_transitory, 250)
6828 self.assertEqual(timeouts.tcp_established, 7450)
6830 def test_dynamic(self):
6831 """ NAT64 dynamic translation test """
6832 self.tcp_port_in = 6303
6833 self.udp_port_in = 6304
6834 self.icmp_id_in = 6305
6836 ses_num_start = self.nat64_get_ses_num()
6838 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6840 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6841 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6844 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6845 self.pg0.add_stream(pkts)
6846 self.pg_enable_capture(self.pg_interfaces)
6848 capture = self.pg1.get_capture(len(pkts))
6849 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6850 dst_ip=self.pg1.remote_ip4)
6853 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6854 self.pg1.add_stream(pkts)
6855 self.pg_enable_capture(self.pg_interfaces)
6857 capture = self.pg0.get_capture(len(pkts))
6858 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6859 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6862 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6863 self.pg0.add_stream(pkts)
6864 self.pg_enable_capture(self.pg_interfaces)
6866 capture = self.pg1.get_capture(len(pkts))
6867 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6868 dst_ip=self.pg1.remote_ip4)
6871 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6872 self.pg1.add_stream(pkts)
6873 self.pg_enable_capture(self.pg_interfaces)
6875 capture = self.pg0.get_capture(len(pkts))
6876 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6878 ses_num_end = self.nat64_get_ses_num()
6880 self.assertEqual(ses_num_end - ses_num_start, 3)
6882 # tenant with specific VRF
6883 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6884 self.vrf1_nat_addr_n,
6885 vrf_id=self.vrf1_id)
6886 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6888 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
6889 self.pg2.add_stream(pkts)
6890 self.pg_enable_capture(self.pg_interfaces)
6892 capture = self.pg1.get_capture(len(pkts))
6893 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6894 dst_ip=self.pg1.remote_ip4)
6896 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6897 self.pg1.add_stream(pkts)
6898 self.pg_enable_capture(self.pg_interfaces)
6900 capture = self.pg2.get_capture(len(pkts))
6901 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
6903 def test_static(self):
6904 """ NAT64 static translation test """
6905 self.tcp_port_in = 60303
6906 self.udp_port_in = 60304
6907 self.icmp_id_in = 60305
6908 self.tcp_port_out = 60303
6909 self.udp_port_out = 60304
6910 self.icmp_id_out = 60305
6912 ses_num_start = self.nat64_get_ses_num()
6914 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6916 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6917 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6919 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6924 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6929 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
6936 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6937 self.pg0.add_stream(pkts)
6938 self.pg_enable_capture(self.pg_interfaces)
6940 capture = self.pg1.get_capture(len(pkts))
6941 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6942 dst_ip=self.pg1.remote_ip4, same_port=True)
6945 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6946 self.pg1.add_stream(pkts)
6947 self.pg_enable_capture(self.pg_interfaces)
6949 capture = self.pg0.get_capture(len(pkts))
6950 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6951 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6953 ses_num_end = self.nat64_get_ses_num()
6955 self.assertEqual(ses_num_end - ses_num_start, 3)
6957 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6958 def test_session_timeout(self):
6959 """ NAT64 session timeout """
6960 self.icmp_id_in = 1234
6961 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6963 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6964 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6965 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
6967 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6968 self.pg0.add_stream(pkts)
6969 self.pg_enable_capture(self.pg_interfaces)
6971 capture = self.pg1.get_capture(len(pkts))
6973 ses_num_before_timeout = self.nat64_get_ses_num()
6977 # ICMP and TCP session after timeout
6978 ses_num_after_timeout = self.nat64_get_ses_num()
6979 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
6981 def test_icmp_error(self):
6982 """ NAT64 ICMP Error message translation """
6983 self.tcp_port_in = 6303
6984 self.udp_port_in = 6304
6985 self.icmp_id_in = 6305
6987 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6989 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6990 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6992 # send some packets to create sessions
6993 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6994 self.pg0.add_stream(pkts)
6995 self.pg_enable_capture(self.pg_interfaces)
6997 capture_ip4 = self.pg1.get_capture(len(pkts))
6998 self.verify_capture_out(capture_ip4,
6999 nat_ip=self.nat_addr,
7000 dst_ip=self.pg1.remote_ip4)
7002 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7003 self.pg1.add_stream(pkts)
7004 self.pg_enable_capture(self.pg_interfaces)
7006 capture_ip6 = self.pg0.get_capture(len(pkts))
7007 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7008 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7009 self.pg0.remote_ip6)
7012 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7013 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7014 ICMPv6DestUnreach(code=1) /
7015 packet[IPv6] for packet in capture_ip6]
7016 self.pg0.add_stream(pkts)
7017 self.pg_enable_capture(self.pg_interfaces)
7019 capture = self.pg1.get_capture(len(pkts))
7020 for packet in capture:
7022 self.assertEqual(packet[IP].src, self.nat_addr)
7023 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7024 self.assertEqual(packet[ICMP].type, 3)
7025 self.assertEqual(packet[ICMP].code, 13)
7026 inner = packet[IPerror]
7027 self.assertEqual(inner.src, self.pg1.remote_ip4)
7028 self.assertEqual(inner.dst, self.nat_addr)
7029 self.assert_packet_checksums_valid(packet)
7030 if inner.haslayer(TCPerror):
7031 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7032 elif inner.haslayer(UDPerror):
7033 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7035 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7037 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7041 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7042 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7043 ICMP(type=3, code=13) /
7044 packet[IP] for packet in capture_ip4]
7045 self.pg1.add_stream(pkts)
7046 self.pg_enable_capture(self.pg_interfaces)
7048 capture = self.pg0.get_capture(len(pkts))
7049 for packet in capture:
7051 self.assertEqual(packet[IPv6].src, ip.src)
7052 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7053 icmp = packet[ICMPv6DestUnreach]
7054 self.assertEqual(icmp.code, 1)
7055 inner = icmp[IPerror6]
7056 self.assertEqual(inner.src, self.pg0.remote_ip6)
7057 self.assertEqual(inner.dst, ip.src)
7058 self.assert_icmpv6_checksum_valid(packet)
7059 if inner.haslayer(TCPerror):
7060 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7061 elif inner.haslayer(UDPerror):
7062 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7064 self.assertEqual(inner[ICMPv6EchoRequest].id,
7067 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7070 def test_hairpinning(self):
7071 """ NAT64 hairpinning """
7073 client = self.pg0.remote_hosts[0]
7074 server = self.pg0.remote_hosts[1]
7075 server_tcp_in_port = 22
7076 server_tcp_out_port = 4022
7077 server_udp_in_port = 23
7078 server_udp_out_port = 4023
7079 client_tcp_in_port = 1234
7080 client_udp_in_port = 1235
7081 client_tcp_out_port = 0
7082 client_udp_out_port = 0
7083 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7084 nat_addr_ip6 = ip.src
7086 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7088 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7089 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7091 self.vapi.nat64_add_del_static_bib(server.ip6n,
7094 server_tcp_out_port,
7096 self.vapi.nat64_add_del_static_bib(server.ip6n,
7099 server_udp_out_port,
7104 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7105 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7106 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7108 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7109 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7110 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7112 self.pg0.add_stream(pkts)
7113 self.pg_enable_capture(self.pg_interfaces)
7115 capture = self.pg0.get_capture(len(pkts))
7116 for packet in capture:
7118 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7119 self.assertEqual(packet[IPv6].dst, server.ip6)
7120 self.assert_packet_checksums_valid(packet)
7121 if packet.haslayer(TCP):
7122 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7123 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
7124 client_tcp_out_port = packet[TCP].sport
7126 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7127 self.assertEqual(packet[UDP].dport, server_udp_in_port)
7128 client_udp_out_port = packet[UDP].sport
7130 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7135 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7136 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7137 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7139 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7140 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7141 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7143 self.pg0.add_stream(pkts)
7144 self.pg_enable_capture(self.pg_interfaces)
7146 capture = self.pg0.get_capture(len(pkts))
7147 for packet in capture:
7149 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7150 self.assertEqual(packet[IPv6].dst, client.ip6)
7151 self.assert_packet_checksums_valid(packet)
7152 if packet.haslayer(TCP):
7153 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7154 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
7156 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7157 self.assertEqual(packet[UDP].dport, client_udp_in_port)
7159 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7164 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7165 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7166 ICMPv6DestUnreach(code=1) /
7167 packet[IPv6] for packet in capture]
7168 self.pg0.add_stream(pkts)
7169 self.pg_enable_capture(self.pg_interfaces)
7171 capture = self.pg0.get_capture(len(pkts))
7172 for packet in capture:
7174 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7175 self.assertEqual(packet[IPv6].dst, server.ip6)
7176 icmp = packet[ICMPv6DestUnreach]
7177 self.assertEqual(icmp.code, 1)
7178 inner = icmp[IPerror6]
7179 self.assertEqual(inner.src, server.ip6)
7180 self.assertEqual(inner.dst, nat_addr_ip6)
7181 self.assert_packet_checksums_valid(packet)
7182 if inner.haslayer(TCPerror):
7183 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7184 self.assertEqual(inner[TCPerror].dport,
7185 client_tcp_out_port)
7187 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7188 self.assertEqual(inner[UDPerror].dport,
7189 client_udp_out_port)
7191 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7194 def test_prefix(self):
7195 """ NAT64 Network-Specific Prefix """
7197 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7199 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7200 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7201 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7202 self.vrf1_nat_addr_n,
7203 vrf_id=self.vrf1_id)
7204 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7207 global_pref64 = "2001:db8::"
7208 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7209 global_pref64_len = 32
7210 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7212 prefix = self.vapi.nat64_prefix_dump()
7213 self.assertEqual(len(prefix), 1)
7214 self.assertEqual(prefix[0].prefix, global_pref64_n)
7215 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7216 self.assertEqual(prefix[0].vrf_id, 0)
7218 # Add tenant specific prefix
7219 vrf1_pref64 = "2001:db8:122:300::"
7220 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7221 vrf1_pref64_len = 56
7222 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7224 vrf_id=self.vrf1_id)
7225 prefix = self.vapi.nat64_prefix_dump()
7226 self.assertEqual(len(prefix), 2)
7229 pkts = self.create_stream_in_ip6(self.pg0,
7232 plen=global_pref64_len)
7233 self.pg0.add_stream(pkts)
7234 self.pg_enable_capture(self.pg_interfaces)
7236 capture = self.pg1.get_capture(len(pkts))
7237 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7238 dst_ip=self.pg1.remote_ip4)
7240 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7241 self.pg1.add_stream(pkts)
7242 self.pg_enable_capture(self.pg_interfaces)
7244 capture = self.pg0.get_capture(len(pkts))
7245 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7248 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7250 # Tenant specific prefix
7251 pkts = self.create_stream_in_ip6(self.pg2,
7254 plen=vrf1_pref64_len)
7255 self.pg2.add_stream(pkts)
7256 self.pg_enable_capture(self.pg_interfaces)
7258 capture = self.pg1.get_capture(len(pkts))
7259 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7260 dst_ip=self.pg1.remote_ip4)
7262 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7263 self.pg1.add_stream(pkts)
7264 self.pg_enable_capture(self.pg_interfaces)
7266 capture = self.pg2.get_capture(len(pkts))
7267 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7270 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7272 def test_unknown_proto(self):
7273 """ NAT64 translate packet with unknown protocol """
7275 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7277 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7278 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7279 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7282 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7283 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7284 TCP(sport=self.tcp_port_in, dport=20))
7285 self.pg0.add_stream(p)
7286 self.pg_enable_capture(self.pg_interfaces)
7288 p = self.pg1.get_capture(1)
7290 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7291 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
7293 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7294 TCP(sport=1234, dport=1234))
7295 self.pg0.add_stream(p)
7296 self.pg_enable_capture(self.pg_interfaces)
7298 p = self.pg1.get_capture(1)
7301 self.assertEqual(packet[IP].src, self.nat_addr)
7302 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7303 self.assertTrue(packet.haslayer(GRE))
7304 self.assert_packet_checksums_valid(packet)
7306 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7310 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7311 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7313 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7314 TCP(sport=1234, dport=1234))
7315 self.pg1.add_stream(p)
7316 self.pg_enable_capture(self.pg_interfaces)
7318 p = self.pg0.get_capture(1)
7321 self.assertEqual(packet[IPv6].src, remote_ip6)
7322 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7323 self.assertEqual(packet[IPv6].nh, 47)
7325 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7328 def test_hairpinning_unknown_proto(self):
7329 """ NAT64 translate packet with unknown protocol - hairpinning """
7331 client = self.pg0.remote_hosts[0]
7332 server = self.pg0.remote_hosts[1]
7333 server_tcp_in_port = 22
7334 server_tcp_out_port = 4022
7335 client_tcp_in_port = 1234
7336 client_tcp_out_port = 1235
7337 server_nat_ip = "10.0.0.100"
7338 client_nat_ip = "10.0.0.110"
7339 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7340 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7341 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7342 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
7344 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7346 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7347 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7349 self.vapi.nat64_add_del_static_bib(server.ip6n,
7352 server_tcp_out_port,
7355 self.vapi.nat64_add_del_static_bib(server.ip6n,
7361 self.vapi.nat64_add_del_static_bib(client.ip6n,
7364 client_tcp_out_port,
7368 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7369 IPv6(src=client.ip6, dst=server_nat_ip6) /
7370 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7371 self.pg0.add_stream(p)
7372 self.pg_enable_capture(self.pg_interfaces)
7374 p = self.pg0.get_capture(1)
7376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7377 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
7379 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7380 TCP(sport=1234, dport=1234))
7381 self.pg0.add_stream(p)
7382 self.pg_enable_capture(self.pg_interfaces)
7384 p = self.pg0.get_capture(1)
7387 self.assertEqual(packet[IPv6].src, client_nat_ip6)
7388 self.assertEqual(packet[IPv6].dst, server.ip6)
7389 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7391 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7396 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
7398 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7399 TCP(sport=1234, dport=1234))
7400 self.pg0.add_stream(p)
7401 self.pg_enable_capture(self.pg_interfaces)
7403 p = self.pg0.get_capture(1)
7406 self.assertEqual(packet[IPv6].src, server_nat_ip6)
7407 self.assertEqual(packet[IPv6].dst, client.ip6)
7408 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
7410 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7413 def test_one_armed_nat64(self):
7414 """ One armed NAT64 """
7416 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7420 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7422 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7423 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7426 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7427 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7428 TCP(sport=12345, dport=80))
7429 self.pg3.add_stream(p)
7430 self.pg_enable_capture(self.pg_interfaces)
7432 capture = self.pg3.get_capture(1)
7437 self.assertEqual(ip.src, self.nat_addr)
7438 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7439 self.assertNotEqual(tcp.sport, 12345)
7440 external_port = tcp.sport
7441 self.assertEqual(tcp.dport, 80)
7442 self.assert_packet_checksums_valid(p)
7444 self.logger.error(ppp("Unexpected or invalid packet:", p))
7448 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7449 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7450 TCP(sport=80, dport=external_port))
7451 self.pg3.add_stream(p)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 capture = self.pg3.get_capture(1)
7459 self.assertEqual(ip.src, remote_host_ip6)
7460 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7461 self.assertEqual(tcp.sport, 80)
7462 self.assertEqual(tcp.dport, 12345)
7463 self.assert_packet_checksums_valid(p)
7465 self.logger.error(ppp("Unexpected or invalid packet:", p))
7468 def test_frag_in_order(self):
7469 """ NAT64 translate fragments arriving in order """
7470 self.tcp_port_in = random.randint(1025, 65535)
7472 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7474 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7475 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7477 reass = self.vapi.nat_reass_dump()
7478 reass_n_start = len(reass)
7482 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7483 self.tcp_port_in, 20, data)
7484 self.pg0.add_stream(pkts)
7485 self.pg_enable_capture(self.pg_interfaces)
7487 frags = self.pg1.get_capture(len(pkts))
7488 p = self.reass_frags_and_verify(frags,
7490 self.pg1.remote_ip4)
7491 self.assertEqual(p[TCP].dport, 20)
7492 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7493 self.tcp_port_out = p[TCP].sport
7494 self.assertEqual(data, p[Raw].load)
7497 data = "A" * 4 + "b" * 16 + "C" * 3
7498 pkts = self.create_stream_frag(self.pg1,
7503 self.pg1.add_stream(pkts)
7504 self.pg_enable_capture(self.pg_interfaces)
7506 frags = self.pg0.get_capture(len(pkts))
7507 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7508 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7509 self.assertEqual(p[TCP].sport, 20)
7510 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7511 self.assertEqual(data, p[Raw].load)
7513 reass = self.vapi.nat_reass_dump()
7514 reass_n_end = len(reass)
7516 self.assertEqual(reass_n_end - reass_n_start, 2)
7518 def test_reass_hairpinning(self):
7519 """ NAT64 fragments hairpinning """
7521 server = self.pg0.remote_hosts[1]
7522 server_in_port = random.randint(1025, 65535)
7523 server_out_port = random.randint(1025, 65535)
7524 client_in_port = random.randint(1025, 65535)
7525 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7526 nat_addr_ip6 = ip.src
7528 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7530 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7531 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7533 # add static BIB entry for server
7534 self.vapi.nat64_add_del_static_bib(server.ip6n,
7540 # send packet from host to server
7541 pkts = self.create_stream_frag_ip6(self.pg0,
7546 self.pg0.add_stream(pkts)
7547 self.pg_enable_capture(self.pg_interfaces)
7549 frags = self.pg0.get_capture(len(pkts))
7550 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7551 self.assertNotEqual(p[TCP].sport, client_in_port)
7552 self.assertEqual(p[TCP].dport, server_in_port)
7553 self.assertEqual(data, p[Raw].load)
7555 def test_frag_out_of_order(self):
7556 """ NAT64 translate fragments arriving out of order """
7557 self.tcp_port_in = random.randint(1025, 65535)
7559 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7561 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7562 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7566 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7567 self.tcp_port_in, 20, data)
7569 self.pg0.add_stream(pkts)
7570 self.pg_enable_capture(self.pg_interfaces)
7572 frags = self.pg1.get_capture(len(pkts))
7573 p = self.reass_frags_and_verify(frags,
7575 self.pg1.remote_ip4)
7576 self.assertEqual(p[TCP].dport, 20)
7577 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7578 self.tcp_port_out = p[TCP].sport
7579 self.assertEqual(data, p[Raw].load)
7582 data = "A" * 4 + "B" * 16 + "C" * 3
7583 pkts = self.create_stream_frag(self.pg1,
7589 self.pg1.add_stream(pkts)
7590 self.pg_enable_capture(self.pg_interfaces)
7592 frags = self.pg0.get_capture(len(pkts))
7593 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7594 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7595 self.assertEqual(p[TCP].sport, 20)
7596 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7597 self.assertEqual(data, p[Raw].load)
7599 def test_interface_addr(self):
7600 """ Acquire NAT64 pool addresses from interface """
7601 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7603 # no address in NAT64 pool
7604 adresses = self.vapi.nat44_address_dump()
7605 self.assertEqual(0, len(adresses))
7607 # configure interface address and check NAT64 address pool
7608 self.pg4.config_ip4()
7609 addresses = self.vapi.nat64_pool_addr_dump()
7610 self.assertEqual(len(addresses), 1)
7611 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7613 # remove interface address and check NAT64 address pool
7614 self.pg4.unconfig_ip4()
7615 addresses = self.vapi.nat64_pool_addr_dump()
7616 self.assertEqual(0, len(adresses))
7618 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7619 def test_ipfix_max_bibs_sessions(self):
7620 """ IPFIX logging maximum session and BIB entries exceeded """
7623 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7627 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7629 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7630 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7634 for i in range(0, max_bibs):
7635 src = "fd01:aa::%x" % (i)
7636 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7637 IPv6(src=src, dst=remote_host_ip6) /
7638 TCP(sport=12345, dport=80))
7640 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7641 IPv6(src=src, dst=remote_host_ip6) /
7642 TCP(sport=12345, dport=22))
7644 self.pg0.add_stream(pkts)
7645 self.pg_enable_capture(self.pg_interfaces)
7647 self.pg1.get_capture(max_sessions)
7649 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7650 src_address=self.pg3.local_ip4n,
7652 template_interval=10)
7653 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7654 src_port=self.ipfix_src_port)
7656 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7657 IPv6(src=src, dst=remote_host_ip6) /
7658 TCP(sport=12345, dport=25))
7659 self.pg0.add_stream(p)
7660 self.pg_enable_capture(self.pg_interfaces)
7662 self.pg1.assert_nothing_captured()
7664 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7665 capture = self.pg3.get_capture(9)
7666 ipfix = IPFIXDecoder()
7667 # first load template
7669 self.assertTrue(p.haslayer(IPFIX))
7670 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7671 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7672 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7673 self.assertEqual(p[UDP].dport, 4739)
7674 self.assertEqual(p[IPFIX].observationDomainID,
7675 self.ipfix_domain_id)
7676 if p.haslayer(Template):
7677 ipfix.add_template(p.getlayer(Template))
7678 # verify events in data set
7680 if p.haslayer(Data):
7681 data = ipfix.decode_data_set(p.getlayer(Set))
7682 self.verify_ipfix_max_sessions(data, max_sessions)
7684 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7685 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7686 TCP(sport=12345, dport=80))
7687 self.pg0.add_stream(p)
7688 self.pg_enable_capture(self.pg_interfaces)
7690 self.pg1.assert_nothing_captured()
7692 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7693 capture = self.pg3.get_capture(1)
7694 # verify events in data set
7696 self.assertTrue(p.haslayer(IPFIX))
7697 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7698 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7699 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7700 self.assertEqual(p[UDP].dport, 4739)
7701 self.assertEqual(p[IPFIX].observationDomainID,
7702 self.ipfix_domain_id)
7703 if p.haslayer(Data):
7704 data = ipfix.decode_data_set(p.getlayer(Set))
7705 self.verify_ipfix_max_bibs(data, max_bibs)
7707 def test_ipfix_max_frags(self):
7708 """ IPFIX logging maximum fragments pending reassembly exceeded """
7709 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7711 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7712 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7713 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
7714 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7715 src_address=self.pg3.local_ip4n,
7717 template_interval=10)
7718 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7719 src_port=self.ipfix_src_port)
7722 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7723 self.tcp_port_in, 20, data)
7725 self.pg0.add_stream(pkts)
7726 self.pg_enable_capture(self.pg_interfaces)
7728 self.pg1.assert_nothing_captured()
7730 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7731 capture = self.pg3.get_capture(9)
7732 ipfix = IPFIXDecoder()
7733 # first load template
7735 self.assertTrue(p.haslayer(IPFIX))
7736 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7737 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7738 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7739 self.assertEqual(p[UDP].dport, 4739)
7740 self.assertEqual(p[IPFIX].observationDomainID,
7741 self.ipfix_domain_id)
7742 if p.haslayer(Template):
7743 ipfix.add_template(p.getlayer(Template))
7744 # verify events in data set
7746 if p.haslayer(Data):
7747 data = ipfix.decode_data_set(p.getlayer(Set))
7748 self.verify_ipfix_max_fragments_ip6(data, 1,
7749 self.pg0.remote_ip6n)
7751 def test_ipfix_bib_ses(self):
7752 """ IPFIX logging NAT64 BIB/session create and delete events """
7753 self.tcp_port_in = random.randint(1025, 65535)
7754 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7758 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7760 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7761 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7762 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7763 src_address=self.pg3.local_ip4n,
7765 template_interval=10)
7766 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7767 src_port=self.ipfix_src_port)
7770 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7771 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7772 TCP(sport=self.tcp_port_in, dport=25))
7773 self.pg0.add_stream(p)
7774 self.pg_enable_capture(self.pg_interfaces)
7776 p = self.pg1.get_capture(1)
7777 self.tcp_port_out = p[0][TCP].sport
7778 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7779 capture = self.pg3.get_capture(10)
7780 ipfix = IPFIXDecoder()
7781 # first load template
7783 self.assertTrue(p.haslayer(IPFIX))
7784 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7785 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7786 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7787 self.assertEqual(p[UDP].dport, 4739)
7788 self.assertEqual(p[IPFIX].observationDomainID,
7789 self.ipfix_domain_id)
7790 if p.haslayer(Template):
7791 ipfix.add_template(p.getlayer(Template))
7792 # verify events in data set
7794 if p.haslayer(Data):
7795 data = ipfix.decode_data_set(p.getlayer(Set))
7796 if ord(data[0][230]) == 10:
7797 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7798 elif ord(data[0][230]) == 6:
7799 self.verify_ipfix_nat64_ses(data,
7801 self.pg0.remote_ip6n,
7802 self.pg1.remote_ip4,
7805 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7808 self.pg_enable_capture(self.pg_interfaces)
7809 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7812 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7813 capture = self.pg3.get_capture(2)
7814 # verify events in data set
7816 self.assertTrue(p.haslayer(IPFIX))
7817 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7818 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7819 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7820 self.assertEqual(p[UDP].dport, 4739)
7821 self.assertEqual(p[IPFIX].observationDomainID,
7822 self.ipfix_domain_id)
7823 if p.haslayer(Data):
7824 data = ipfix.decode_data_set(p.getlayer(Set))
7825 if ord(data[0][230]) == 11:
7826 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7827 elif ord(data[0][230]) == 7:
7828 self.verify_ipfix_nat64_ses(data,
7830 self.pg0.remote_ip6n,
7831 self.pg1.remote_ip4,
7834 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7836 def test_syslog_sess(self):
7837 """ Test syslog session creation and deletion """
7838 self.tcp_port_in = random.randint(1025, 65535)
7839 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7843 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7845 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7846 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7847 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
7848 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
7850 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7851 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7852 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7853 self.pg0.add_stream(p)
7854 self.pg_enable_capture(self.pg_interfaces)
7856 p = self.pg1.get_capture(1)
7857 self.tcp_port_out = p[0][TCP].sport
7858 capture = self.pg3.get_capture(1)
7859 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
7861 self.pg_enable_capture(self.pg_interfaces)
7863 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7866 capture = self.pg3.get_capture(1)
7867 self.verify_syslog_sess(capture[0][Raw].load, False, True)
7869 def nat64_get_ses_num(self):
7871 Return number of active NAT64 sessions.
7873 st = self.vapi.nat64_st_dump()
7876 def clear_nat64(self):
7878 Clear NAT64 configuration.
7880 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7881 domain_id=self.ipfix_domain_id)
7882 self.ipfix_src_port = 4739
7883 self.ipfix_domain_id = 1
7885 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
7887 self.vapi.nat_set_timeouts()
7889 interfaces = self.vapi.nat64_interface_dump()
7890 for intf in interfaces:
7891 if intf.is_inside > 1:
7892 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7895 self.vapi.nat64_add_del_interface(intf.sw_if_index,
7899 bib = self.vapi.nat64_bib_dump(255)
7902 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
7910 adresses = self.vapi.nat64_pool_addr_dump()
7911 for addr in adresses:
7912 self.vapi.nat64_add_del_pool_addr_range(addr.address,
7917 prefixes = self.vapi.nat64_prefix_dump()
7918 for prefix in prefixes:
7919 self.vapi.nat64_add_del_prefix(prefix.prefix,
7921 vrf_id=prefix.vrf_id,
7925 super(TestNAT64, self).tearDown()
7926 if not self.vpp_dead:
7927 self.logger.info(self.vapi.cli("show nat64 pool"))
7928 self.logger.info(self.vapi.cli("show nat64 interfaces"))
7929 self.logger.info(self.vapi.cli("show nat64 prefix"))
7930 self.logger.info(self.vapi.cli("show nat64 bib all"))
7931 self.logger.info(self.vapi.cli("show nat64 session table all"))
7932 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
7936 class TestDSlite(MethodHolder):
7937 """ DS-Lite Test Cases """
7940 def setUpClass(cls):
7941 super(TestDSlite, cls).setUpClass()
7944 cls.nat_addr = '10.0.0.3'
7945 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7947 cls.create_pg_interfaces(range(3))
7949 cls.pg0.config_ip4()
7950 cls.pg0.resolve_arp()
7952 cls.pg1.config_ip6()
7953 cls.pg1.generate_remote_hosts(2)
7954 cls.pg1.configure_ipv6_neighbors()
7956 cls.pg2.config_ip4()
7957 cls.pg2.resolve_arp()
7960 super(TestDSlite, cls).tearDownClass()
7963 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
7965 message = data.decode('utf-8')
7967 message = SyslogMessage.parse(message)
7968 self.assertEqual(message.severity, SyslogSeverity.info)
7969 self.assertEqual(message.appname, 'NAT')
7970 self.assertEqual(message.msgid, 'APMADD')
7971 sd_params = message.sd.get('napmap')
7972 self.assertTrue(sd_params is not None)
7973 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
7974 self.assertEqual(sd_params.get('ISADDR'), isaddr)
7975 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
7976 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
7977 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
7978 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
7979 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
7980 self.assertTrue(sd_params.get('SSUBIX') is not None)
7981 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
7982 except ParseError as e:
7983 self.logger.error(e)
7985 def test_dslite(self):
7986 """ Test DS-Lite """
7987 nat_config = self.vapi.nat_show_config()
7988 self.assertEqual(0, nat_config.dslite_ce)
7990 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
7992 aftr_ip4 = '192.0.0.1'
7993 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7994 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7995 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7996 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7997 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
8000 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8001 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8002 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8003 UDP(sport=20000, dport=10000))
8004 self.pg1.add_stream(p)
8005 self.pg_enable_capture(self.pg_interfaces)
8007 capture = self.pg0.get_capture(1)
8008 capture = capture[0]
8009 self.assertFalse(capture.haslayer(IPv6))
8010 self.assertEqual(capture[IP].src, self.nat_addr)
8011 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8012 self.assertNotEqual(capture[UDP].sport, 20000)
8013 self.assertEqual(capture[UDP].dport, 10000)
8014 self.assert_packet_checksums_valid(capture)
8015 out_port = capture[UDP].sport
8016 capture = self.pg2.get_capture(1)
8017 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8018 20000, self.nat_addr, out_port,
8019 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
8021 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8022 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8023 UDP(sport=10000, dport=out_port))
8024 self.pg0.add_stream(p)
8025 self.pg_enable_capture(self.pg_interfaces)
8027 capture = self.pg1.get_capture(1)
8028 capture = capture[0]
8029 self.assertEqual(capture[IPv6].src, aftr_ip6)
8030 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8031 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8032 self.assertEqual(capture[IP].dst, '192.168.1.1')
8033 self.assertEqual(capture[UDP].sport, 10000)
8034 self.assertEqual(capture[UDP].dport, 20000)
8035 self.assert_packet_checksums_valid(capture)
8038 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8039 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8040 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8041 TCP(sport=20001, dport=10001))
8042 self.pg1.add_stream(p)
8043 self.pg_enable_capture(self.pg_interfaces)
8045 capture = self.pg0.get_capture(1)
8046 capture = capture[0]
8047 self.assertFalse(capture.haslayer(IPv6))
8048 self.assertEqual(capture[IP].src, self.nat_addr)
8049 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8050 self.assertNotEqual(capture[TCP].sport, 20001)
8051 self.assertEqual(capture[TCP].dport, 10001)
8052 self.assert_packet_checksums_valid(capture)
8053 out_port = capture[TCP].sport
8055 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8056 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8057 TCP(sport=10001, dport=out_port))
8058 self.pg0.add_stream(p)
8059 self.pg_enable_capture(self.pg_interfaces)
8061 capture = self.pg1.get_capture(1)
8062 capture = capture[0]
8063 self.assertEqual(capture[IPv6].src, aftr_ip6)
8064 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8065 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8066 self.assertEqual(capture[IP].dst, '192.168.1.1')
8067 self.assertEqual(capture[TCP].sport, 10001)
8068 self.assertEqual(capture[TCP].dport, 20001)
8069 self.assert_packet_checksums_valid(capture)
8072 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8073 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8074 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8075 ICMP(id=4000, type='echo-request'))
8076 self.pg1.add_stream(p)
8077 self.pg_enable_capture(self.pg_interfaces)
8079 capture = self.pg0.get_capture(1)
8080 capture = capture[0]
8081 self.assertFalse(capture.haslayer(IPv6))
8082 self.assertEqual(capture[IP].src, self.nat_addr)
8083 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8084 self.assertNotEqual(capture[ICMP].id, 4000)
8085 self.assert_packet_checksums_valid(capture)
8086 out_id = capture[ICMP].id
8088 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8089 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8090 ICMP(id=out_id, type='echo-reply'))
8091 self.pg0.add_stream(p)
8092 self.pg_enable_capture(self.pg_interfaces)
8094 capture = self.pg1.get_capture(1)
8095 capture = capture[0]
8096 self.assertEqual(capture[IPv6].src, aftr_ip6)
8097 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8098 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8099 self.assertEqual(capture[IP].dst, '192.168.1.1')
8100 self.assertEqual(capture[ICMP].id, 4000)
8101 self.assert_packet_checksums_valid(capture)
8103 # ping DS-Lite AFTR tunnel endpoint address
8104 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8105 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8106 ICMPv6EchoRequest())
8107 self.pg1.add_stream(p)
8108 self.pg_enable_capture(self.pg_interfaces)
8110 capture = self.pg1.get_capture(1)
8111 capture = capture[0]
8112 self.assertEqual(capture[IPv6].src, aftr_ip6)
8113 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8114 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8117 super(TestDSlite, self).tearDown()
8118 if not self.vpp_dead:
8119 self.logger.info(self.vapi.cli("show dslite pool"))
8121 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8122 self.logger.info(self.vapi.cli("show dslite sessions"))
8125 class TestDSliteCE(MethodHolder):
8126 """ DS-Lite CE Test Cases """
8129 def setUpConstants(cls):
8130 super(TestDSliteCE, cls).setUpConstants()
8131 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8134 def setUpClass(cls):
8135 super(TestDSliteCE, cls).setUpClass()
8138 cls.create_pg_interfaces(range(2))
8140 cls.pg0.config_ip4()
8141 cls.pg0.resolve_arp()
8143 cls.pg1.config_ip6()
8144 cls.pg1.generate_remote_hosts(1)
8145 cls.pg1.configure_ipv6_neighbors()
8148 super(TestDSliteCE, cls).tearDownClass()
8151 def test_dslite_ce(self):
8152 """ Test DS-Lite CE """
8154 nat_config = self.vapi.nat_show_config()
8155 self.assertEqual(1, nat_config.dslite_ce)
8157 b4_ip4 = '192.0.0.2'
8158 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8159 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8160 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8161 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8163 aftr_ip4 = '192.0.0.1'
8164 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8165 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8166 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8167 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8169 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8170 dst_address_length=128,
8171 next_hop_address=self.pg1.remote_ip6n,
8172 next_hop_sw_if_index=self.pg1.sw_if_index,
8176 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8177 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8178 UDP(sport=10000, dport=20000))
8179 self.pg0.add_stream(p)
8180 self.pg_enable_capture(self.pg_interfaces)
8182 capture = self.pg1.get_capture(1)
8183 capture = capture[0]
8184 self.assertEqual(capture[IPv6].src, b4_ip6)
8185 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8186 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8187 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8188 self.assertEqual(capture[UDP].sport, 10000)
8189 self.assertEqual(capture[UDP].dport, 20000)
8190 self.assert_packet_checksums_valid(capture)
8193 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8194 IPv6(dst=b4_ip6, src=aftr_ip6) /
8195 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8196 UDP(sport=20000, dport=10000))
8197 self.pg1.add_stream(p)
8198 self.pg_enable_capture(self.pg_interfaces)
8200 capture = self.pg0.get_capture(1)
8201 capture = capture[0]
8202 self.assertFalse(capture.haslayer(IPv6))
8203 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8204 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8205 self.assertEqual(capture[UDP].sport, 20000)
8206 self.assertEqual(capture[UDP].dport, 10000)
8207 self.assert_packet_checksums_valid(capture)
8209 # ping DS-Lite B4 tunnel endpoint address
8210 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8211 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8212 ICMPv6EchoRequest())
8213 self.pg1.add_stream(p)
8214 self.pg_enable_capture(self.pg_interfaces)
8216 capture = self.pg1.get_capture(1)
8217 capture = capture[0]
8218 self.assertEqual(capture[IPv6].src, b4_ip6)
8219 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8220 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8223 super(TestDSliteCE, self).tearDown()
8224 if not self.vpp_dead:
8226 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8228 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8231 class TestNAT66(MethodHolder):
8232 """ NAT66 Test Cases """
8235 def setUpClass(cls):
8236 super(TestNAT66, cls).setUpClass()
8239 cls.nat_addr = 'fd01:ff::2'
8240 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8242 cls.create_pg_interfaces(range(2))
8243 cls.interfaces = list(cls.pg_interfaces)
8245 for i in cls.interfaces:
8248 i.configure_ipv6_neighbors()
8251 super(TestNAT66, cls).tearDownClass()
8254 def test_static(self):
8255 """ 1:1 NAT66 test """
8256 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8257 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8258 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8263 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8264 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8267 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8268 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8271 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8272 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8273 ICMPv6EchoRequest())
8275 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8276 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8277 GRE() / IP() / TCP())
8279 self.pg0.add_stream(pkts)
8280 self.pg_enable_capture(self.pg_interfaces)
8282 capture = self.pg1.get_capture(len(pkts))
8283 for packet in capture:
8285 self.assertEqual(packet[IPv6].src, self.nat_addr)
8286 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8287 self.assert_packet_checksums_valid(packet)
8289 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8294 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8295 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8298 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8299 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8302 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8303 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8306 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8307 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8308 GRE() / IP() / TCP())
8310 self.pg1.add_stream(pkts)
8311 self.pg_enable_capture(self.pg_interfaces)
8313 capture = self.pg0.get_capture(len(pkts))
8314 for packet in capture:
8316 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8317 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8318 self.assert_packet_checksums_valid(packet)
8320 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8323 sm = self.vapi.nat66_static_mapping_dump()
8324 self.assertEqual(len(sm), 1)
8325 self.assertEqual(sm[0].total_pkts, 8)
8327 def test_check_no_translate(self):
8328 """ NAT66 translate only when egress interface is outside interface """
8329 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8330 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8331 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8335 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8336 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8338 self.pg0.add_stream([p])
8339 self.pg_enable_capture(self.pg_interfaces)
8341 capture = self.pg1.get_capture(1)
8344 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8345 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8347 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8350 def clear_nat66(self):
8352 Clear NAT66 configuration.
8354 interfaces = self.vapi.nat66_interface_dump()
8355 for intf in interfaces:
8356 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8360 static_mappings = self.vapi.nat66_static_mapping_dump()
8361 for sm in static_mappings:
8362 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8363 sm.external_ip_address,
8368 super(TestNAT66, self).tearDown()
8369 if not self.vpp_dead:
8370 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8371 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8375 if __name__ == '__main__':
8376 unittest.main(testRunner=VppTestRunner)