8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
33 from ipaddress import IPv6Network
36 # NAT HA protocol event data
39 fields_desc = [ByteEnumField("event_type", None,
40 {1: "add", 2: "del", 3: "refresh"}),
41 ByteEnumField("protocol", None,
42 {0: "udp", 1: "tcp", 2: "icmp"}),
43 ShortField("flags", 0),
44 IPField("in_addr", None),
45 IPField("out_addr", None),
46 ShortField("in_port", None),
47 ShortField("out_port", None),
48 IPField("eh_addr", None),
49 IPField("ehn_addr", None),
50 ShortField("eh_port", None),
51 ShortField("ehn_port", None),
52 IntField("fib_index", None),
53 IntField("total_pkts", 0),
54 LongField("total_bytes", 0)]
56 def extract_padding(self, s):
60 # NAT HA protocol header
61 class HANATStateSync(Packet):
62 name = "HA NAT state sync"
63 fields_desc = [XByteField("version", 1),
64 FlagsField("flags", 0, 8, ['ACK']),
65 FieldLenField("count", None, count_of="events"),
66 IntField("sequence_number", 1),
67 IntField("thread_index", 0),
68 PacketListField("events", [], Event,
69 count_from=lambda pkt: pkt.count)]
72 class MethodHolder(VppTestCase):
73 """ NAT create capture and verify method holder """
76 def config_flags(self):
77 return VppEnum.vl_api_nat_config_flags_t
80 def SYSLOG_SEVERITY(self):
81 return VppEnum.vl_api_syslog_severity_t
83 def clear_nat44(self):
85 Clear NAT44 configuration.
87 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
88 if self.pg7.has_ip4_config:
89 self.pg7.unconfig_ip4()
91 self.vapi.nat44_forwarding_enable_disable(enable=0)
93 interfaces = self.vapi.nat44_interface_addr_dump()
94 for intf in interfaces:
95 self.vapi.nat44_add_del_interface_addr(
97 sw_if_index=intf.sw_if_index,
100 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
101 src_port=self.ipfix_src_port,
103 self.ipfix_src_port = 4739
104 self.ipfix_domain_id = 1
106 self.vapi.syslog_set_filter(
107 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
109 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
111 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
112 session_refresh_interval=10)
114 interfaces = self.vapi.nat44_interface_dump()
115 for intf in interfaces:
116 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
117 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
118 self.vapi.nat44_interface_add_del_feature(
119 sw_if_index=intf.sw_if_index)
120 self.vapi.nat44_interface_add_del_feature(
121 sw_if_index=intf.sw_if_index,
124 interfaces = self.vapi.nat44_interface_output_feature_dump()
125 for intf in interfaces:
126 self.vapi.nat44_interface_add_del_output_feature(
129 sw_if_index=intf.sw_if_index)
130 static_mappings = self.vapi.nat44_static_mapping_dump()
131 for sm in static_mappings:
132 self.vapi.nat44_add_del_static_mapping(
134 local_ip_address=sm.local_ip_address,
135 external_ip_address=sm.external_ip_address,
136 external_sw_if_index=sm.external_sw_if_index,
137 local_port=sm.local_port,
138 external_port=sm.external_port,
140 protocol=sm.protocol,
141 flags=sm.flags, tag=sm.tag)
143 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
144 for lb_sm in lb_static_mappings:
145 self.vapi.nat44_add_del_lb_static_mapping(
148 external_addr=lb_sm.external_addr,
149 external_port=lb_sm.external_port,
150 protocol=lb_sm.protocol,
151 local_num=0, locals=[],
154 identity_mappings = self.vapi.nat44_identity_mapping_dump()
155 for id_m in identity_mappings:
156 self.vapi.nat44_add_del_identity_mapping(
157 ip_address=id_m.ip_address,
158 sw_if_index=id_m.sw_if_index,
162 protocol=id_m.protocol)
164 addresses = self.vapi.nat44_address_dump()
165 for addr in addresses:
166 self.vapi.nat44_add_del_address_range(
167 first_ip_address=addr.ip_address,
168 last_ip_address=addr.ip_address,
169 vrf_id=0xFFFFFFFF, flags=addr.flags)
171 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
173 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
174 drop_frag=0, is_ip6=1)
175 self.verify_no_nat44_user()
176 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
177 tcp_transitory=240, icmp=60)
178 self.vapi.nat_set_addr_and_port_alloc_alg()
179 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
181 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
182 local_port=0, external_port=0, vrf_id=0,
183 is_add=1, external_sw_if_index=0xFFFFFFFF,
184 proto=0, tag="", flags=0):
186 Add/delete NAT44 static mapping
188 :param local_ip: Local IP address
189 :param external_ip: External IP address
190 :param local_port: Local port number (Optional)
191 :param external_port: External port number (Optional)
192 :param vrf_id: VRF ID (Default 0)
193 :param is_add: 1 if add, 0 if delete (Default add)
194 :param external_sw_if_index: External interface instead of IP address
195 :param proto: IP protocol (Mandatory if port specified)
196 :param tag: Opaque string tag
197 :param flags: NAT configuration flags
200 if not (local_port and external_port):
201 flags |= self.config_flags.NAT_IS_ADDR_ONLY
203 self.vapi.nat44_add_del_static_mapping(
205 local_ip_address=local_ip,
206 external_ip_address=external_ip,
207 external_sw_if_index=external_sw_if_index,
208 local_port=local_port,
209 external_port=external_port,
210 vrf_id=vrf_id, protocol=proto,
214 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
216 Add/delete NAT44 address
218 :param ip: IP address
219 :param is_add: 1 if add, 0 if delete (Default add)
220 :param twice_nat: twice NAT address for external hosts
222 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
223 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
229 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
231 Create packet stream for inside network
233 :param in_if: Inside interface
234 :param out_if: Outside interface
235 :param dst_ip: Destination address
236 :param ttl: TTL of generated packets
239 dst_ip = out_if.remote_ip4
243 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
244 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
245 TCP(sport=self.tcp_port_in, dport=20))
249 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
250 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
251 UDP(sport=self.udp_port_in, dport=20))
255 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
256 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
257 ICMP(id=self.icmp_id_in, type='echo-request'))
262 def compose_ip6(self, ip4, pref, plen):
264 Compose IPv4-embedded IPv6 addresses
266 :param ip4: IPv4 address
267 :param pref: IPv6 prefix
268 :param plen: IPv6 prefix length
269 :returns: IPv4-embedded IPv6 addresses
271 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
272 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
287 pref_n[10] = ip4_n[3]
291 pref_n[10] = ip4_n[2]
292 pref_n[11] = ip4_n[3]
295 pref_n[10] = ip4_n[1]
296 pref_n[11] = ip4_n[2]
297 pref_n[12] = ip4_n[3]
299 pref_n[12] = ip4_n[0]
300 pref_n[13] = ip4_n[1]
301 pref_n[14] = ip4_n[2]
302 pref_n[15] = ip4_n[3]
303 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
304 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
306 def extract_ip4(self, ip6, plen):
308 Extract IPv4 address embedded in IPv6 addresses
310 :param ip6: IPv6 address
311 :param plen: IPv6 prefix length
312 :returns: extracted IPv4 address
314 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
346 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
348 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
350 Create IPv6 packet stream for inside network
352 :param in_if: Inside interface
353 :param out_if: Outside interface
354 :param ttl: Hop Limit of generated packets
355 :param pref: NAT64 prefix
356 :param plen: NAT64 prefix length
360 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
362 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
365 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
366 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
367 TCP(sport=self.tcp_port_in, dport=20))
371 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
372 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
373 UDP(sport=self.udp_port_in, dport=20))
377 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
378 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
379 ICMPv6EchoRequest(id=self.icmp_id_in))
384 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
385 use_inside_ports=False):
387 Create packet stream for outside network
389 :param out_if: Outside interface
390 :param dst_ip: Destination IP address (Default use global NAT address)
391 :param ttl: TTL of generated packets
392 :param use_inside_ports: Use inside NAT ports as destination ports
393 instead of outside ports
396 dst_ip = self.nat_addr
397 if not use_inside_ports:
398 tcp_port = self.tcp_port_out
399 udp_port = self.udp_port_out
400 icmp_id = self.icmp_id_out
402 tcp_port = self.tcp_port_in
403 udp_port = self.udp_port_in
404 icmp_id = self.icmp_id_in
407 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
408 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
409 TCP(dport=tcp_port, sport=20))
413 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
414 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
415 UDP(dport=udp_port, sport=20))
419 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
420 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
421 ICMP(id=icmp_id, type='echo-reply'))
426 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
428 Create packet stream for outside network
430 :param out_if: Outside interface
431 :param dst_ip: Destination IP address (Default use global NAT address)
432 :param hl: HL of generated packets
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
438 TCP(dport=self.tcp_port_out, sport=20))
442 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
443 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
444 UDP(dport=self.udp_port_out, sport=20))
448 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
449 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
450 ICMPv6EchoReply(id=self.icmp_id_out))
455 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
456 dst_ip=None, is_ip6=False):
458 Verify captured packets on outside network
460 :param capture: Captured packets
461 :param nat_ip: Translated IP address (Default use global NAT address)
462 :param same_port: Source port number is not translated (Default False)
463 :param dst_ip: Destination IP address (Default do not verify)
464 :param is_ip6: If L3 protocol is IPv6 (Default False)
468 ICMP46 = ICMPv6EchoRequest
473 nat_ip = self.nat_addr
474 for packet in capture:
477 self.assert_packet_checksums_valid(packet)
478 self.assertEqual(packet[IP46].src, nat_ip)
479 if dst_ip is not None:
480 self.assertEqual(packet[IP46].dst, dst_ip)
481 if packet.haslayer(TCP):
483 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
486 packet[TCP].sport, self.tcp_port_in)
487 self.tcp_port_out = packet[TCP].sport
488 self.assert_packet_checksums_valid(packet)
489 elif packet.haslayer(UDP):
491 self.assertEqual(packet[UDP].sport, self.udp_port_in)
494 packet[UDP].sport, self.udp_port_in)
495 self.udp_port_out = packet[UDP].sport
498 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
500 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
501 self.icmp_id_out = packet[ICMP46].id
502 self.assert_packet_checksums_valid(packet)
504 self.logger.error(ppp("Unexpected or invalid packet "
505 "(outside network):", packet))
508 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
511 Verify captured packets on outside network
513 :param capture: Captured packets
514 :param nat_ip: Translated IP address
515 :param same_port: Source port number is not translated (Default False)
516 :param dst_ip: Destination IP address (Default do not verify)
518 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
521 def verify_capture_in(self, capture, in_if):
523 Verify captured packets on inside network
525 :param capture: Captured packets
526 :param in_if: Inside interface
528 for packet in capture:
530 self.assert_packet_checksums_valid(packet)
531 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
532 if packet.haslayer(TCP):
533 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
534 elif packet.haslayer(UDP):
535 self.assertEqual(packet[UDP].dport, self.udp_port_in)
537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
539 self.logger.error(ppp("Unexpected or invalid packet "
540 "(inside network):", packet))
543 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
545 Verify captured IPv6 packets on inside network
547 :param capture: Captured packets
548 :param src_ip: Source IP
549 :param dst_ip: Destination IP address
551 for packet in capture:
553 self.assertEqual(packet[IPv6].src, src_ip)
554 self.assertEqual(packet[IPv6].dst, dst_ip)
555 self.assert_packet_checksums_valid(packet)
556 if packet.haslayer(TCP):
557 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
558 elif packet.haslayer(UDP):
559 self.assertEqual(packet[UDP].dport, self.udp_port_in)
561 self.assertEqual(packet[ICMPv6EchoReply].id,
564 self.logger.error(ppp("Unexpected or invalid packet "
565 "(inside network):", packet))
568 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
570 Verify captured packet that don't have to be translated
572 :param capture: Captured packets
573 :param ingress_if: Ingress interface
574 :param egress_if: Egress interface
576 for packet in capture:
578 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
579 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
580 if packet.haslayer(TCP):
581 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
582 elif packet.haslayer(UDP):
583 self.assertEqual(packet[UDP].sport, self.udp_port_in)
585 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(inside network):", packet))
591 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
594 Verify captured packets with ICMP errors on outside network
596 :param capture: Captured packets
597 :param src_ip: Translated IP address or IP address of VPP
598 (Default use global NAT address)
599 :param icmp_type: Type of error ICMP packet
600 we are expecting (Default 11)
603 src_ip = self.nat_addr
604 for packet in capture:
606 self.assertEqual(packet[IP].src, src_ip)
607 self.assertEqual(packet.haslayer(ICMP), 1)
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].dport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].dport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(outside network):", packet))
625 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
627 Verify captured packets with ICMP errors on inside network
629 :param capture: Captured packets
630 :param in_if: Inside interface
631 :param icmp_type: Type of error ICMP packet
632 we are expecting (Default 11)
634 for packet in capture:
636 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
637 self.assertEqual(packet.haslayer(ICMP), 1)
639 self.assertEqual(icmp.type, icmp_type)
640 self.assertTrue(icmp.haslayer(IPerror))
641 inner_ip = icmp[IPerror]
642 if inner_ip.haslayer(TCPerror):
643 self.assertEqual(inner_ip[TCPerror].sport,
645 elif inner_ip.haslayer(UDPerror):
646 self.assertEqual(inner_ip[UDPerror].sport,
649 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
651 self.logger.error(ppp("Unexpected or invalid packet "
652 "(inside network):", packet))
655 def create_stream_frag(self, src_if, dst, sport, dport, data,
656 proto=IP_PROTOS.tcp, echo_reply=False):
658 Create fragmented packet stream
660 :param src_if: Source interface
661 :param dst: Destination IPv4 address
662 :param sport: Source port
663 :param dport: Destination port
664 :param data: Payload data
665 :param proto: protocol (TCP, UDP, ICMP)
666 :param echo_reply: use echo_reply if protocol is ICMP
669 if proto == IP_PROTOS.tcp:
670 p = (IP(src=src_if.remote_ip4, dst=dst) /
671 TCP(sport=sport, dport=dport) /
673 p = p.__class__(scapy.compat.raw(p))
674 chksum = p[TCP].chksum
675 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
676 elif proto == IP_PROTOS.udp:
677 proto_header = UDP(sport=sport, dport=dport)
678 elif proto == IP_PROTOS.icmp:
680 proto_header = ICMP(id=sport, type='echo-request')
682 proto_header = ICMP(id=sport, type='echo-reply')
684 raise Exception("Unsupported protocol")
685 id = random.randint(0, 65535)
687 if proto == IP_PROTOS.tcp:
690 raw = Raw(data[0:16])
691 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
692 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
696 if proto == IP_PROTOS.tcp:
697 raw = Raw(data[4:20])
699 raw = Raw(data[16:32])
700 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
701 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
705 if proto == IP_PROTOS.tcp:
709 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
710 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
716 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
717 pref=None, plen=0, frag_size=128):
719 Create fragmented packet stream
721 :param src_if: Source interface
722 :param dst: Destination IPv4 address
723 :param sport: Source TCP port
724 :param dport: Destination TCP port
725 :param data: Payload data
726 :param pref: NAT64 prefix
727 :param plen: NAT64 prefix length
728 :param fragsize: size of fragments
732 dst_ip6 = ''.join(['64:ff9b::', dst])
734 dst_ip6 = self.compose_ip6(dst, pref, plen)
736 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
737 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
738 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
739 TCP(sport=sport, dport=dport) /
742 return fragment6(p, frag_size)
744 def reass_frags_and_verify(self, frags, src, dst):
746 Reassemble and verify fragmented packet
748 :param frags: Captured fragments
749 :param src: Source IPv4 address to verify
750 :param dst: Destination IPv4 address to verify
752 :returns: Reassembled IPv4 packet
756 self.assertEqual(p[IP].src, src)
757 self.assertEqual(p[IP].dst, dst)
758 self.assert_ip_checksum_valid(p)
759 buffer.seek(p[IP].frag * 8)
760 buffer.write(bytes(p[IP].payload))
761 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
762 proto=frags[0][IP].proto)
763 if ip.proto == IP_PROTOS.tcp:
764 p = (ip / TCP(buffer.getvalue()))
765 self.assert_tcp_checksum_valid(p)
766 elif ip.proto == IP_PROTOS.udp:
767 p = (ip / UDP(buffer.getvalue()[:8]) /
768 Raw(buffer.getvalue()[8:]))
769 elif ip.proto == IP_PROTOS.icmp:
770 p = (ip / ICMP(buffer.getvalue()))
773 def reass_frags_and_verify_ip6(self, frags, src, dst):
775 Reassemble and verify fragmented packet
777 :param frags: Captured fragments
778 :param src: Source IPv6 address to verify
779 :param dst: Destination IPv6 address to verify
781 :returns: Reassembled IPv6 packet
785 self.assertEqual(p[IPv6].src, src)
786 self.assertEqual(p[IPv6].dst, dst)
787 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
788 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
789 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
790 nh=frags[0][IPv6ExtHdrFragment].nh)
791 if ip.nh == IP_PROTOS.tcp:
792 p = (ip / TCP(buffer.getvalue()))
793 elif ip.nh == IP_PROTOS.udp:
794 p = (ip / UDP(buffer.getvalue()))
795 self.assert_packet_checksums_valid(p)
798 def initiate_tcp_session(self, in_if, out_if):
800 Initiates TCP session
802 :param in_if: Inside interface
803 :param out_if: Outside interface
807 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
808 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
809 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
812 self.pg_enable_capture(self.pg_interfaces)
814 capture = out_if.get_capture(1)
816 self.tcp_port_out = p[TCP].sport
818 # SYN + ACK packet out->in
819 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
820 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
821 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
824 self.pg_enable_capture(self.pg_interfaces)
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 out_if.get_capture(1)
839 self.logger.error("TCP 3 way handshake failed")
842 def verify_ipfix_nat44_ses(self, data):
844 Verify IPFIX NAT44 session create/delete event
846 :param data: Decoded IPFIX data records
848 nat44_ses_create_num = 0
849 nat44_ses_delete_num = 0
850 self.assertEqual(6, len(data))
853 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
854 if scapy.compat.orb(record[230]) == 4:
855 nat44_ses_create_num += 1
857 nat44_ses_delete_num += 1
859 self.assertEqual(self.pg0.remote_ip4n, record[8])
860 # postNATSourceIPv4Address
861 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
864 self.assertEqual(struct.pack("!I", 0), record[234])
865 # protocolIdentifier/sourceTransportPort
866 # /postNAPTSourceTransportPort
867 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
868 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
869 self.assertEqual(struct.pack("!H", self.icmp_id_out),
871 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
872 self.assertEqual(struct.pack("!H", self.tcp_port_in),
874 self.assertEqual(struct.pack("!H", self.tcp_port_out),
876 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.udp_port_in),
879 self.assertEqual(struct.pack("!H", self.udp_port_out),
882 self.fail("Invalid protocol")
883 self.assertEqual(3, nat44_ses_create_num)
884 self.assertEqual(3, nat44_ses_delete_num)
886 def verify_ipfix_addr_exhausted(self, data):
888 Verify IPFIX NAT addresses event
890 :param data: Decoded IPFIX data records
892 self.assertEqual(1, len(data))
895 self.assertEqual(scapy.compat.orb(record[230]), 3)
897 self.assertEqual(struct.pack("!I", 0), record[283])
899 def verify_ipfix_max_sessions(self, data, limit):
901 Verify IPFIX maximum session entries exceeded event
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum session entries that can be created.
906 self.assertEqual(1, len(data))
909 self.assertEqual(scapy.compat.orb(record[230]), 13)
910 # natQuotaExceededEvent
911 self.assertEqual(struct.pack("I", 1), record[466])
913 self.assertEqual(struct.pack("I", limit), record[471])
915 def verify_ipfix_max_bibs(self, data, limit):
917 Verify IPFIX maximum BIB entries exceeded event
919 :param data: Decoded IPFIX data records
920 :param limit: Number of maximum BIB entries that can be created.
922 self.assertEqual(1, len(data))
925 self.assertEqual(scapy.compat.orb(record[230]), 13)
926 # natQuotaExceededEvent
927 self.assertEqual(struct.pack("I", 2), record[466])
929 self.assertEqual(struct.pack("I", limit), record[472])
931 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
933 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
935 :param data: Decoded IPFIX data records
936 :param limit: Number of maximum fragments pending reassembly
937 :param src_addr: IPv6 source address
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 5), record[466])
945 # maxFragmentsPendingReassembly
946 self.assertEqual(struct.pack("I", limit), record[475])
948 self.assertEqual(src_addr, record[27])
950 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
952 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
954 :param data: Decoded IPFIX data records
955 :param limit: Number of maximum fragments pending reassembly
956 :param src_addr: IPv4 source address
958 self.assertEqual(1, len(data))
961 self.assertEqual(scapy.compat.orb(record[230]), 13)
962 # natQuotaExceededEvent
963 self.assertEqual(struct.pack("I", 5), record[466])
964 # maxFragmentsPendingReassembly
965 self.assertEqual(struct.pack("I", limit), record[475])
967 self.assertEqual(src_addr, record[8])
969 def verify_ipfix_bib(self, data, is_create, src_addr):
971 Verify IPFIX NAT64 BIB create and delete events
973 :param data: Decoded IPFIX data records
974 :param is_create: Create event if nonzero value otherwise delete event
975 :param src_addr: IPv6 source address
977 self.assertEqual(1, len(data))
981 self.assertEqual(scapy.compat.orb(record[230]), 10)
983 self.assertEqual(scapy.compat.orb(record[230]), 11)
985 self.assertEqual(src_addr, record[27])
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
997 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1000 Verify IPFIX NAT64 session create and delete events
1002 :param data: Decoded IPFIX data records
1003 :param is_create: Create event if nonzero value otherwise delete event
1004 :param src_addr: IPv6 source address
1005 :param dst_addr: IPv4 destination address
1006 :param dst_port: destination TCP port
1008 self.assertEqual(1, len(data))
1012 self.assertEqual(scapy.compat.orb(record[230]), 6)
1014 self.assertEqual(scapy.compat.orb(record[230]), 7)
1016 self.assertEqual(src_addr, record[27])
1017 # destinationIPv6Address
1018 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1019 self.compose_ip6(dst_addr,
1023 # postNATSourceIPv4Address
1024 self.assertEqual(self.nat_addr_n, record[225])
1025 # postNATDestinationIPv4Address
1026 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1028 # protocolIdentifier
1029 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1031 self.assertEqual(struct.pack("!I", 0), record[234])
1032 # sourceTransportPort
1033 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1034 # postNAPTSourceTransportPort
1035 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1036 # destinationTransportPort
1037 self.assertEqual(struct.pack("!H", dst_port), record[11])
1038 # postNAPTDestinationTransportPort
1039 self.assertEqual(struct.pack("!H", dst_port), record[228])
1041 def verify_no_nat44_user(self):
1042 """ Verify that there is no NAT44 user """
1043 users = self.vapi.nat44_user_dump()
1044 self.assertEqual(len(users), 0)
1045 users = self.statistics.get_counter('/nat44/total-users')
1046 self.assertEqual(users[0][0], 0)
1047 sessions = self.statistics.get_counter('/nat44/total-sessions')
1048 self.assertEqual(sessions[0][0], 0)
1050 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1052 Verify IPFIX maximum entries per user exceeded event
1054 :param data: Decoded IPFIX data records
1055 :param limit: Number of maximum entries per user
1056 :param src_addr: IPv4 source address
1058 self.assertEqual(1, len(data))
1061 self.assertEqual(scapy.compat.orb(record[230]), 13)
1062 # natQuotaExceededEvent
1063 self.assertEqual(struct.pack("I", 3), record[466])
1065 self.assertEqual(struct.pack("I", limit), record[473])
1067 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1069 def verify_syslog_apmap(self, data, is_add=True):
1070 message = data.decode('utf-8')
1072 message = SyslogMessage.parse(message)
1073 except ParseError as e:
1074 self.logger.error(e)
1077 self.assertEqual(message.severity, SyslogSeverity.info)
1078 self.assertEqual(message.appname, 'NAT')
1079 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1080 sd_params = message.sd.get('napmap')
1081 self.assertTrue(sd_params is not None)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1085 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1086 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1087 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1088 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1089 self.assertTrue(sd_params.get('SSUBIX') is not None)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1092 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1093 message = data.decode('utf-8')
1095 message = SyslogMessage.parse(message)
1096 except ParseError as e:
1097 self.logger.error(e)
1100 self.assertEqual(message.severity, SyslogSeverity.info)
1101 self.assertEqual(message.appname, 'NAT')
1102 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1103 sd_params = message.sd.get('nsess')
1104 self.assertTrue(sd_params is not None)
1106 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1107 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1109 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1110 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1113 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1114 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1115 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1116 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1117 self.assertEqual(sd_params.get('SVLAN'), '0')
1118 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1119 self.assertEqual(sd_params.get('XDPORT'),
1120 "%d" % self.tcp_external_port)
1122 def verify_mss_value(self, pkt, mss):
1124 Verify TCP MSS value
1129 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1130 raise TypeError("Not a TCP/IP packet")
1132 for option in pkt[TCP].options:
1133 if option[0] == 'MSS':
1134 self.assertEqual(option[1], mss)
1135 self.assert_tcp_checksum_valid(pkt)
1138 def proto2layer(proto):
1139 if proto == IP_PROTOS.tcp:
1141 elif proto == IP_PROTOS.udp:
1143 elif proto == IP_PROTOS.icmp:
1146 raise Exception("Unsupported protocol")
1148 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1149 layer = self.proto2layer(proto)
1151 if proto == IP_PROTOS.tcp:
1152 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1154 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1155 self.port_in = random.randint(1025, 65535)
1157 reass = self.vapi.nat_reass_dump()
1158 reass_n_start = len(reass)
1161 pkts = self.create_stream_frag(self.pg0,
1162 self.pg1.remote_ip4,
1167 self.pg0.add_stream(pkts)
1168 self.pg_enable_capture(self.pg_interfaces)
1170 frags = self.pg1.get_capture(len(pkts))
1171 if not dont_translate:
1172 p = self.reass_frags_and_verify(frags,
1174 self.pg1.remote_ip4)
1176 p = self.reass_frags_and_verify(frags,
1177 self.pg0.remote_ip4,
1178 self.pg1.remote_ip4)
1179 if proto != IP_PROTOS.icmp:
1180 if not dont_translate:
1181 self.assertEqual(p[layer].dport, 20)
1182 self.assertNotEqual(p[layer].sport, self.port_in)
1184 self.assertEqual(p[layer].sport, self.port_in)
1186 if not dont_translate:
1187 self.assertNotEqual(p[layer].id, self.port_in)
1189 self.assertEqual(p[layer].id, self.port_in)
1190 self.assertEqual(data, p[Raw].load)
1193 if not dont_translate:
1194 dst_addr = self.nat_addr
1196 dst_addr = self.pg0.remote_ip4
1197 if proto != IP_PROTOS.icmp:
1199 dport = p[layer].sport
1203 pkts = self.create_stream_frag(self.pg1,
1210 self.pg1.add_stream(pkts)
1211 self.pg_enable_capture(self.pg_interfaces)
1213 frags = self.pg0.get_capture(len(pkts))
1214 p = self.reass_frags_and_verify(frags,
1215 self.pg1.remote_ip4,
1216 self.pg0.remote_ip4)
1217 if proto != IP_PROTOS.icmp:
1218 self.assertEqual(p[layer].sport, 20)
1219 self.assertEqual(p[layer].dport, self.port_in)
1221 self.assertEqual(p[layer].id, self.port_in)
1222 self.assertEqual(data, p[Raw].load)
1224 reass = self.vapi.nat_reass_dump()
1225 reass_n_end = len(reass)
1227 self.assertEqual(reass_n_end - reass_n_start, 2)
1229 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1230 layer = self.proto2layer(proto)
1232 if proto == IP_PROTOS.tcp:
1233 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1235 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1236 self.port_in = random.randint(1025, 65535)
1239 reass = self.vapi.nat_reass_dump()
1240 reass_n_start = len(reass)
1243 pkts = self.create_stream_frag(self.pg0,
1244 self.server_out_addr,
1246 self.server_out_port,
1249 self.pg0.add_stream(pkts)
1250 self.pg_enable_capture(self.pg_interfaces)
1252 frags = self.pg1.get_capture(len(pkts))
1253 p = self.reass_frags_and_verify(frags,
1254 self.pg0.remote_ip4,
1255 self.server_in_addr)
1256 if proto != IP_PROTOS.icmp:
1257 self.assertEqual(p[layer].sport, self.port_in)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1260 self.assertEqual(p[layer].id, self.port_in)
1261 self.assertEqual(data, p[Raw].load)
1264 if proto != IP_PROTOS.icmp:
1265 pkts = self.create_stream_frag(self.pg1,
1266 self.pg0.remote_ip4,
1267 self.server_in_port,
1272 pkts = self.create_stream_frag(self.pg1,
1273 self.pg0.remote_ip4,
1279 self.pg1.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,
1284 self.server_out_addr,
1285 self.pg0.remote_ip4)
1286 if proto != IP_PROTOS.icmp:
1287 self.assertEqual(p[layer].sport, self.server_out_port)
1288 self.assertEqual(p[layer].dport, self.port_in)
1290 self.assertEqual(p[layer].id, self.port_in)
1291 self.assertEqual(data, p[Raw].load)
1293 reass = self.vapi.nat_reass_dump()
1294 reass_n_end = len(reass)
1296 self.assertEqual(reass_n_end - reass_n_start, 2)
1298 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1299 layer = self.proto2layer(proto)
1301 if proto == IP_PROTOS.tcp:
1302 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1304 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1306 # send packet from host to server
1307 pkts = self.create_stream_frag(self.pg0,
1310 self.server_out_port,
1313 self.pg0.add_stream(pkts)
1314 self.pg_enable_capture(self.pg_interfaces)
1316 frags = self.pg0.get_capture(len(pkts))
1317 p = self.reass_frags_and_verify(frags,
1320 if proto != IP_PROTOS.icmp:
1321 self.assertNotEqual(p[layer].sport, self.host_in_port)
1322 self.assertEqual(p[layer].dport, self.server_in_port)
1324 self.assertNotEqual(p[layer].id, self.host_in_port)
1325 self.assertEqual(data, p[Raw].load)
1327 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1328 layer = self.proto2layer(proto)
1330 if proto == IP_PROTOS.tcp:
1331 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1333 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1334 self.port_in = random.randint(1025, 65535)
1338 pkts = self.create_stream_frag(self.pg0,
1339 self.pg1.remote_ip4,
1345 self.pg0.add_stream(pkts)
1346 self.pg_enable_capture(self.pg_interfaces)
1348 frags = self.pg1.get_capture(len(pkts))
1349 if not dont_translate:
1350 p = self.reass_frags_and_verify(frags,
1352 self.pg1.remote_ip4)
1354 p = self.reass_frags_and_verify(frags,
1355 self.pg0.remote_ip4,
1356 self.pg1.remote_ip4)
1357 if proto != IP_PROTOS.icmp:
1358 if not dont_translate:
1359 self.assertEqual(p[layer].dport, 20)
1360 self.assertNotEqual(p[layer].sport, self.port_in)
1362 self.assertEqual(p[layer].sport, self.port_in)
1364 if not dont_translate:
1365 self.assertNotEqual(p[layer].id, self.port_in)
1367 self.assertEqual(p[layer].id, self.port_in)
1368 self.assertEqual(data, p[Raw].load)
1371 if not dont_translate:
1372 dst_addr = self.nat_addr
1374 dst_addr = self.pg0.remote_ip4
1375 if proto != IP_PROTOS.icmp:
1377 dport = p[layer].sport
1381 pkts = self.create_stream_frag(self.pg1,
1389 self.pg1.add_stream(pkts)
1390 self.pg_enable_capture(self.pg_interfaces)
1392 frags = self.pg0.get_capture(len(pkts))
1393 p = self.reass_frags_and_verify(frags,
1394 self.pg1.remote_ip4,
1395 self.pg0.remote_ip4)
1396 if proto != IP_PROTOS.icmp:
1397 self.assertEqual(p[layer].sport, 20)
1398 self.assertEqual(p[layer].dport, self.port_in)
1400 self.assertEqual(p[layer].id, self.port_in)
1401 self.assertEqual(data, p[Raw].load)
1403 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1404 layer = self.proto2layer(proto)
1406 if proto == IP_PROTOS.tcp:
1407 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1409 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1410 self.port_in = random.randint(1025, 65535)
1414 pkts = self.create_stream_frag(self.pg0,
1415 self.server_out_addr,
1417 self.server_out_port,
1421 self.pg0.add_stream(pkts)
1422 self.pg_enable_capture(self.pg_interfaces)
1424 frags = self.pg1.get_capture(len(pkts))
1425 p = self.reass_frags_and_verify(frags,
1426 self.pg0.remote_ip4,
1427 self.server_in_addr)
1428 if proto != IP_PROTOS.icmp:
1429 self.assertEqual(p[layer].dport, self.server_in_port)
1430 self.assertEqual(p[layer].sport, self.port_in)
1431 self.assertEqual(p[layer].dport, self.server_in_port)
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1437 if proto != IP_PROTOS.icmp:
1438 pkts = self.create_stream_frag(self.pg1,
1439 self.pg0.remote_ip4,
1440 self.server_in_port,
1445 pkts = self.create_stream_frag(self.pg1,
1446 self.pg0.remote_ip4,
1453 self.pg1.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1456 frags = self.pg0.get_capture(len(pkts))
1457 p = self.reass_frags_and_verify(frags,
1458 self.server_out_addr,
1459 self.pg0.remote_ip4)
1460 if proto != IP_PROTOS.icmp:
1461 self.assertEqual(p[layer].sport, self.server_out_port)
1462 self.assertEqual(p[layer].dport, self.port_in)
1464 self.assertEqual(p[layer].id, self.port_in)
1465 self.assertEqual(data, p[Raw].load)
1468 class TestNAT44(MethodHolder):
1469 """ NAT44 Test Cases """
1472 def setUpClass(cls):
1473 super(TestNAT44, cls).setUpClass()
1474 cls.vapi.cli("set log class nat level debug")
1477 cls.tcp_port_in = 6303
1478 cls.tcp_port_out = 6303
1479 cls.udp_port_in = 6304
1480 cls.udp_port_out = 6304
1481 cls.icmp_id_in = 6305
1482 cls.icmp_id_out = 6305
1483 cls.nat_addr = '10.0.0.3'
1484 cls.ipfix_src_port = 4739
1485 cls.ipfix_domain_id = 1
1486 cls.tcp_external_port = 80
1487 cls.udp_external_port = 69
1489 cls.create_pg_interfaces(range(10))
1490 cls.interfaces = list(cls.pg_interfaces[0:4])
1492 for i in cls.interfaces:
1497 cls.pg0.generate_remote_hosts(3)
1498 cls.pg0.configure_ipv4_neighbors()
1500 cls.pg1.generate_remote_hosts(1)
1501 cls.pg1.configure_ipv4_neighbors()
1503 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1504 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1505 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1507 cls.pg4._local_ip4 = "172.16.255.1"
1508 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1509 cls.pg4.set_table_ip4(10)
1510 cls.pg5._local_ip4 = "172.17.255.3"
1511 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1512 cls.pg5.set_table_ip4(10)
1513 cls.pg6._local_ip4 = "172.16.255.1"
1514 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1515 cls.pg6.set_table_ip4(20)
1516 for i in cls.overlapping_interfaces:
1524 cls.pg9.generate_remote_hosts(2)
1525 cls.pg9.config_ip4()
1526 cls.vapi.sw_interface_add_del_address(
1527 sw_if_index=cls.pg9.sw_if_index,
1528 prefix="10.0.0.1/24")
1531 cls.pg9.resolve_arp()
1532 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1533 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1534 cls.pg9.resolve_arp()
1537 super(TestNAT44, cls).tearDownClass()
1541 def tearDownClass(cls):
1542 super(TestNAT44, cls).tearDownClass()
1544 def test_dynamic(self):
1545 """ NAT44 dynamic translation test """
1546 self.nat44_add_address(self.nat_addr)
1547 flags = self.config_flags.NAT_IS_INSIDE
1548 self.vapi.nat44_interface_add_del_feature(
1549 sw_if_index=self.pg0.sw_if_index,
1550 flags=flags, is_add=1)
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg1.sw_if_index,
1556 tcpn = self.statistics.get_err_counter(
1557 '/err/nat44-in2out-slowpath/TCP packets')
1558 udpn = self.statistics.get_err_counter(
1559 '/err/nat44-in2out-slowpath/UDP packets')
1560 icmpn = self.statistics.get_err_counter(
1561 '/err/nat44-in2out-slowpath/ICMP packets')
1562 totaln = self.statistics.get_err_counter(
1563 '/err/nat44-in2out-slowpath/good in2out packets processed')
1565 pkts = self.create_stream_in(self.pg0, self.pg1)
1566 self.pg0.add_stream(pkts)
1567 self.pg_enable_capture(self.pg_interfaces)
1569 capture = self.pg1.get_capture(len(pkts))
1570 self.verify_capture_out(capture)
1572 err = self.statistics.get_err_counter(
1573 '/err/nat44-in2out-slowpath/TCP packets')
1574 self.assertEqual(err - tcpn, 2)
1575 err = self.statistics.get_err_counter(
1576 '/err/nat44-in2out-slowpath/UDP packets')
1577 self.assertEqual(err - udpn, 1)
1578 err = self.statistics.get_err_counter(
1579 '/err/nat44-in2out-slowpath/ICMP packets')
1580 self.assertEqual(err - icmpn, 1)
1581 err = self.statistics.get_err_counter(
1582 '/err/nat44-in2out-slowpath/good in2out packets processed')
1583 self.assertEqual(err - totaln, 4)
1586 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1587 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1588 icmpn = self.statistics.get_err_counter(
1589 '/err/nat44-out2in/ICMP packets')
1590 totaln = self.statistics.get_err_counter(
1591 '/err/nat44-out2in/good out2in packets processed')
1593 pkts = self.create_stream_out(self.pg1)
1594 self.pg1.add_stream(pkts)
1595 self.pg_enable_capture(self.pg_interfaces)
1597 capture = self.pg0.get_capture(len(pkts))
1598 self.verify_capture_in(capture, self.pg0)
1600 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1601 self.assertEqual(err - tcpn, 2)
1602 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1603 self.assertEqual(err - udpn, 1)
1604 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1605 self.assertEqual(err - icmpn, 1)
1606 err = self.statistics.get_err_counter(
1607 '/err/nat44-out2in/good out2in packets processed')
1608 self.assertEqual(err - totaln, 4)
1610 users = self.statistics.get_counter('/nat44/total-users')
1611 self.assertEqual(users[0][0], 1)
1612 sessions = self.statistics.get_counter('/nat44/total-sessions')
1613 self.assertEqual(sessions[0][0], 3)
1615 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1616 """ NAT44 handling of client packets with TTL=1 """
1618 self.nat44_add_address(self.nat_addr)
1619 flags = self.config_flags.NAT_IS_INSIDE
1620 self.vapi.nat44_interface_add_del_feature(
1621 sw_if_index=self.pg0.sw_if_index,
1622 flags=flags, is_add=1)
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg1.sw_if_index,
1627 # Client side - generate traffic
1628 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1629 self.pg0.add_stream(pkts)
1630 self.pg_enable_capture(self.pg_interfaces)
1633 # Client side - verify ICMP type 11 packets
1634 capture = self.pg0.get_capture(len(pkts))
1635 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1637 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1638 """ NAT44 handling of server packets with TTL=1 """
1640 self.nat44_add_address(self.nat_addr)
1641 flags = self.config_flags.NAT_IS_INSIDE
1642 self.vapi.nat44_interface_add_del_feature(
1643 sw_if_index=self.pg0.sw_if_index,
1644 flags=flags, is_add=1)
1645 self.vapi.nat44_interface_add_del_feature(
1646 sw_if_index=self.pg1.sw_if_index,
1649 # Client side - create sessions
1650 pkts = self.create_stream_in(self.pg0, self.pg1)
1651 self.pg0.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1655 # Server side - generate traffic
1656 capture = self.pg1.get_capture(len(pkts))
1657 self.verify_capture_out(capture)
1658 pkts = self.create_stream_out(self.pg1, ttl=1)
1659 self.pg1.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1663 # Server side - verify ICMP type 11 packets
1664 capture = self.pg1.get_capture(len(pkts))
1665 self.verify_capture_out_with_icmp_errors(capture,
1666 src_ip=self.pg1.local_ip4)
1668 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1669 """ NAT44 handling of error responses to client packets with TTL=2 """
1671 self.nat44_add_address(self.nat_addr)
1672 flags = self.config_flags.NAT_IS_INSIDE
1673 self.vapi.nat44_interface_add_del_feature(
1674 sw_if_index=self.pg0.sw_if_index,
1675 flags=flags, is_add=1)
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg1.sw_if_index,
1680 # Client side - generate traffic
1681 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1682 self.pg0.add_stream(pkts)
1683 self.pg_enable_capture(self.pg_interfaces)
1686 # Server side - simulate ICMP type 11 response
1687 capture = self.pg1.get_capture(len(pkts))
1688 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1689 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1690 ICMP(type=11) / packet[IP] for packet in capture]
1691 self.pg1.add_stream(pkts)
1692 self.pg_enable_capture(self.pg_interfaces)
1695 # Client side - verify ICMP type 11 packets
1696 capture = self.pg0.get_capture(len(pkts))
1697 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1699 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1700 """ NAT44 handling of error responses to server packets with TTL=2 """
1702 self.nat44_add_address(self.nat_addr)
1703 flags = self.config_flags.NAT_IS_INSIDE
1704 self.vapi.nat44_interface_add_del_feature(
1705 sw_if_index=self.pg0.sw_if_index,
1706 flags=flags, is_add=1)
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg1.sw_if_index,
1711 # Client side - create sessions
1712 pkts = self.create_stream_in(self.pg0, self.pg1)
1713 self.pg0.add_stream(pkts)
1714 self.pg_enable_capture(self.pg_interfaces)
1717 # Server side - generate traffic
1718 capture = self.pg1.get_capture(len(pkts))
1719 self.verify_capture_out(capture)
1720 pkts = self.create_stream_out(self.pg1, ttl=2)
1721 self.pg1.add_stream(pkts)
1722 self.pg_enable_capture(self.pg_interfaces)
1725 # Client side - simulate ICMP type 11 response
1726 capture = self.pg0.get_capture(len(pkts))
1727 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1728 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1729 ICMP(type=11) / packet[IP] for packet in capture]
1730 self.pg0.add_stream(pkts)
1731 self.pg_enable_capture(self.pg_interfaces)
1734 # Server side - verify ICMP type 11 packets
1735 capture = self.pg1.get_capture(len(pkts))
1736 self.verify_capture_out_with_icmp_errors(capture)
1738 def test_ping_out_interface_from_outside(self):
1739 """ Ping NAT44 out interface from outside network """
1741 self.nat44_add_address(self.nat_addr)
1742 flags = self.config_flags.NAT_IS_INSIDE
1743 self.vapi.nat44_interface_add_del_feature(
1744 sw_if_index=self.pg0.sw_if_index,
1745 flags=flags, is_add=1)
1746 self.vapi.nat44_interface_add_del_feature(
1747 sw_if_index=self.pg1.sw_if_index,
1750 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1751 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1752 ICMP(id=self.icmp_id_out, type='echo-request'))
1754 self.pg1.add_stream(pkts)
1755 self.pg_enable_capture(self.pg_interfaces)
1757 capture = self.pg1.get_capture(len(pkts))
1760 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1761 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1762 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1763 self.assertEqual(packet[ICMP].type, 0) # echo reply
1765 self.logger.error(ppp("Unexpected or invalid packet "
1766 "(outside network):", packet))
1769 def test_ping_internal_host_from_outside(self):
1770 """ Ping internal host from outside network """
1772 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1773 flags = self.config_flags.NAT_IS_INSIDE
1774 self.vapi.nat44_interface_add_del_feature(
1775 sw_if_index=self.pg0.sw_if_index,
1776 flags=flags, is_add=1)
1777 self.vapi.nat44_interface_add_del_feature(
1778 sw_if_index=self.pg1.sw_if_index,
1782 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1783 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1784 ICMP(id=self.icmp_id_out, type='echo-request'))
1785 self.pg1.add_stream(pkt)
1786 self.pg_enable_capture(self.pg_interfaces)
1788 capture = self.pg0.get_capture(1)
1789 self.verify_capture_in(capture, self.pg0)
1790 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1793 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1794 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1795 ICMP(id=self.icmp_id_in, type='echo-reply'))
1796 self.pg0.add_stream(pkt)
1797 self.pg_enable_capture(self.pg_interfaces)
1799 capture = self.pg1.get_capture(1)
1800 self.verify_capture_out(capture, same_port=True)
1801 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1803 def test_forwarding(self):
1804 """ NAT44 forwarding test """
1806 flags = self.config_flags.NAT_IS_INSIDE
1807 self.vapi.nat44_interface_add_del_feature(
1808 sw_if_index=self.pg0.sw_if_index,
1809 flags=flags, is_add=1)
1810 self.vapi.nat44_interface_add_del_feature(
1811 sw_if_index=self.pg1.sw_if_index,
1813 self.vapi.nat44_forwarding_enable_disable(enable=1)
1815 real_ip = self.pg0.remote_ip4
1816 alias_ip = self.nat_addr
1817 flags = self.config_flags.NAT_IS_ADDR_ONLY
1818 self.vapi.nat44_add_del_static_mapping(is_add=1,
1819 local_ip_address=real_ip,
1820 external_ip_address=alias_ip,
1821 external_sw_if_index=0xFFFFFFFF,
1825 # static mapping match
1827 pkts = self.create_stream_out(self.pg1)
1828 self.pg1.add_stream(pkts)
1829 self.pg_enable_capture(self.pg_interfaces)
1831 capture = self.pg0.get_capture(len(pkts))
1832 self.verify_capture_in(capture, self.pg0)
1834 pkts = self.create_stream_in(self.pg0, self.pg1)
1835 self.pg0.add_stream(pkts)
1836 self.pg_enable_capture(self.pg_interfaces)
1838 capture = self.pg1.get_capture(len(pkts))
1839 self.verify_capture_out(capture, same_port=True)
1841 # no static mapping match
1843 host0 = self.pg0.remote_hosts[0]
1844 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1846 pkts = self.create_stream_out(self.pg1,
1847 dst_ip=self.pg0.remote_ip4,
1848 use_inside_ports=True)
1849 self.pg1.add_stream(pkts)
1850 self.pg_enable_capture(self.pg_interfaces)
1852 capture = self.pg0.get_capture(len(pkts))
1853 self.verify_capture_in(capture, self.pg0)
1855 pkts = self.create_stream_in(self.pg0, self.pg1)
1856 self.pg0.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1859 capture = self.pg1.get_capture(len(pkts))
1860 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1863 self.pg0.remote_hosts[0] = host0
1866 self.vapi.nat44_forwarding_enable_disable(enable=0)
1867 flags = self.config_flags.NAT_IS_ADDR_ONLY
1868 self.vapi.nat44_add_del_static_mapping(
1870 local_ip_address=real_ip,
1871 external_ip_address=alias_ip,
1872 external_sw_if_index=0xFFFFFFFF,
1875 def test_static_in(self):
1876 """ 1:1 NAT initialized from inside network """
1878 nat_ip = "10.0.0.10"
1879 self.tcp_port_out = 6303
1880 self.udp_port_out = 6304
1881 self.icmp_id_out = 6305
1883 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1884 flags = self.config_flags.NAT_IS_INSIDE
1885 self.vapi.nat44_interface_add_del_feature(
1886 sw_if_index=self.pg0.sw_if_index,
1887 flags=flags, is_add=1)
1888 self.vapi.nat44_interface_add_del_feature(
1889 sw_if_index=self.pg1.sw_if_index,
1891 sm = self.vapi.nat44_static_mapping_dump()
1892 self.assertEqual(len(sm), 1)
1893 self.assertEqual(sm[0].tag, '')
1894 self.assertEqual(sm[0].protocol, 0)
1895 self.assertEqual(sm[0].local_port, 0)
1896 self.assertEqual(sm[0].external_port, 0)
1899 pkts = self.create_stream_in(self.pg0, self.pg1)
1900 self.pg0.add_stream(pkts)
1901 self.pg_enable_capture(self.pg_interfaces)
1903 capture = self.pg1.get_capture(len(pkts))
1904 self.verify_capture_out(capture, nat_ip, True)
1907 pkts = self.create_stream_out(self.pg1, nat_ip)
1908 self.pg1.add_stream(pkts)
1909 self.pg_enable_capture(self.pg_interfaces)
1911 capture = self.pg0.get_capture(len(pkts))
1912 self.verify_capture_in(capture, self.pg0)
1914 def test_static_out(self):
1915 """ 1:1 NAT initialized from outside network """
1917 nat_ip = "10.0.0.20"
1918 self.tcp_port_out = 6303
1919 self.udp_port_out = 6304
1920 self.icmp_id_out = 6305
1923 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1924 flags = self.config_flags.NAT_IS_INSIDE
1925 self.vapi.nat44_interface_add_del_feature(
1926 sw_if_index=self.pg0.sw_if_index,
1927 flags=flags, is_add=1)
1928 self.vapi.nat44_interface_add_del_feature(
1929 sw_if_index=self.pg1.sw_if_index,
1931 sm = self.vapi.nat44_static_mapping_dump()
1932 self.assertEqual(len(sm), 1)
1933 self.assertEqual(sm[0].tag, tag)
1936 pkts = self.create_stream_out(self.pg1, nat_ip)
1937 self.pg1.add_stream(pkts)
1938 self.pg_enable_capture(self.pg_interfaces)
1940 capture = self.pg0.get_capture(len(pkts))
1941 self.verify_capture_in(capture, self.pg0)
1944 pkts = self.create_stream_in(self.pg0, self.pg1)
1945 self.pg0.add_stream(pkts)
1946 self.pg_enable_capture(self.pg_interfaces)
1948 capture = self.pg1.get_capture(len(pkts))
1949 self.verify_capture_out(capture, nat_ip, True)
1951 def test_static_with_port_in(self):
1952 """ 1:1 NAPT initialized from inside network """
1954 self.tcp_port_out = 3606
1955 self.udp_port_out = 3607
1956 self.icmp_id_out = 3608
1958 self.nat44_add_address(self.nat_addr)
1959 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1960 self.tcp_port_in, self.tcp_port_out,
1961 proto=IP_PROTOS.tcp)
1962 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1963 self.udp_port_in, self.udp_port_out,
1964 proto=IP_PROTOS.udp)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.icmp_id_in, self.icmp_id_out,
1967 proto=IP_PROTOS.icmp)
1968 flags = self.config_flags.NAT_IS_INSIDE
1969 self.vapi.nat44_interface_add_del_feature(
1970 sw_if_index=self.pg0.sw_if_index,
1971 flags=flags, is_add=1)
1972 self.vapi.nat44_interface_add_del_feature(
1973 sw_if_index=self.pg1.sw_if_index,
1977 pkts = self.create_stream_in(self.pg0, self.pg1)
1978 self.pg0.add_stream(pkts)
1979 self.pg_enable_capture(self.pg_interfaces)
1981 capture = self.pg1.get_capture(len(pkts))
1982 self.verify_capture_out(capture)
1985 pkts = self.create_stream_out(self.pg1)
1986 self.pg1.add_stream(pkts)
1987 self.pg_enable_capture(self.pg_interfaces)
1989 capture = self.pg0.get_capture(len(pkts))
1990 self.verify_capture_in(capture, self.pg0)
1992 def test_static_with_port_out(self):
1993 """ 1:1 NAPT initialized from outside network """
1995 self.tcp_port_out = 30606
1996 self.udp_port_out = 30607
1997 self.icmp_id_out = 30608
1999 self.nat44_add_address(self.nat_addr)
2000 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2001 self.tcp_port_in, self.tcp_port_out,
2002 proto=IP_PROTOS.tcp)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2004 self.udp_port_in, self.udp_port_out,
2005 proto=IP_PROTOS.udp)
2006 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2007 self.icmp_id_in, self.icmp_id_out,
2008 proto=IP_PROTOS.icmp)
2009 flags = self.config_flags.NAT_IS_INSIDE
2010 self.vapi.nat44_interface_add_del_feature(
2011 sw_if_index=self.pg0.sw_if_index,
2012 flags=flags, is_add=1)
2013 self.vapi.nat44_interface_add_del_feature(
2014 sw_if_index=self.pg1.sw_if_index,
2018 pkts = self.create_stream_out(self.pg1)
2019 self.pg1.add_stream(pkts)
2020 self.pg_enable_capture(self.pg_interfaces)
2022 capture = self.pg0.get_capture(len(pkts))
2023 self.verify_capture_in(capture, self.pg0)
2026 pkts = self.create_stream_in(self.pg0, self.pg1)
2027 self.pg0.add_stream(pkts)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg1.get_capture(len(pkts))
2031 self.verify_capture_out(capture)
2033 def test_static_vrf_aware(self):
2034 """ 1:1 NAT VRF awareness """
2036 nat_ip1 = "10.0.0.30"
2037 nat_ip2 = "10.0.0.40"
2038 self.tcp_port_out = 6303
2039 self.udp_port_out = 6304
2040 self.icmp_id_out = 6305
2042 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2044 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2046 flags = self.config_flags.NAT_IS_INSIDE
2047 self.vapi.nat44_interface_add_del_feature(
2048 sw_if_index=self.pg3.sw_if_index,
2050 self.vapi.nat44_interface_add_del_feature(
2051 sw_if_index=self.pg0.sw_if_index,
2052 flags=flags, is_add=1)
2053 self.vapi.nat44_interface_add_del_feature(
2054 sw_if_index=self.pg4.sw_if_index,
2055 flags=flags, is_add=1)
2057 # inside interface VRF match NAT44 static mapping VRF
2058 pkts = self.create_stream_in(self.pg4, self.pg3)
2059 self.pg4.add_stream(pkts)
2060 self.pg_enable_capture(self.pg_interfaces)
2062 capture = self.pg3.get_capture(len(pkts))
2063 self.verify_capture_out(capture, nat_ip1, True)
2065 # inside interface VRF don't match NAT44 static mapping VRF (packets
2067 pkts = self.create_stream_in(self.pg0, self.pg3)
2068 self.pg0.add_stream(pkts)
2069 self.pg_enable_capture(self.pg_interfaces)
2071 self.pg3.assert_nothing_captured()
2073 def test_dynamic_to_static(self):
2074 """ Switch from dynamic translation to 1:1NAT """
2075 nat_ip = "10.0.0.10"
2076 self.tcp_port_out = 6303
2077 self.udp_port_out = 6304
2078 self.icmp_id_out = 6305
2080 self.nat44_add_address(self.nat_addr)
2081 flags = self.config_flags.NAT_IS_INSIDE
2082 self.vapi.nat44_interface_add_del_feature(
2083 sw_if_index=self.pg0.sw_if_index,
2084 flags=flags, is_add=1)
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg1.sw_if_index,
2090 pkts = self.create_stream_in(self.pg0, self.pg1)
2091 self.pg0.add_stream(pkts)
2092 self.pg_enable_capture(self.pg_interfaces)
2094 capture = self.pg1.get_capture(len(pkts))
2095 self.verify_capture_out(capture)
2098 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2099 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2100 self.assertEqual(len(sessions), 0)
2101 pkts = self.create_stream_in(self.pg0, self.pg1)
2102 self.pg0.add_stream(pkts)
2103 self.pg_enable_capture(self.pg_interfaces)
2105 capture = self.pg1.get_capture(len(pkts))
2106 self.verify_capture_out(capture, nat_ip, True)
2108 def test_identity_nat(self):
2109 """ Identity NAT """
2110 flags = self.config_flags.NAT_IS_ADDR_ONLY
2111 self.vapi.nat44_add_del_identity_mapping(
2112 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2113 flags=flags, is_add=1)
2114 flags = self.config_flags.NAT_IS_INSIDE
2115 self.vapi.nat44_interface_add_del_feature(
2116 sw_if_index=self.pg0.sw_if_index,
2117 flags=flags, is_add=1)
2118 self.vapi.nat44_interface_add_del_feature(
2119 sw_if_index=self.pg1.sw_if_index,
2122 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2123 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2124 TCP(sport=12345, dport=56789))
2125 self.pg1.add_stream(p)
2126 self.pg_enable_capture(self.pg_interfaces)
2128 capture = self.pg0.get_capture(1)
2133 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2134 self.assertEqual(ip.src, self.pg1.remote_ip4)
2135 self.assertEqual(tcp.dport, 56789)
2136 self.assertEqual(tcp.sport, 12345)
2137 self.assert_packet_checksums_valid(p)
2139 self.logger.error(ppp("Unexpected or invalid packet:", p))
2142 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2143 self.assertEqual(len(sessions), 0)
2144 flags = self.config_flags.NAT_IS_ADDR_ONLY
2145 self.vapi.nat44_add_del_identity_mapping(
2146 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2147 flags=flags, vrf_id=1, is_add=1)
2148 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2149 self.assertEqual(len(identity_mappings), 2)
2151 def test_multiple_inside_interfaces(self):
2152 """ NAT44 multiple non-overlapping address space inside interfaces """
2154 self.nat44_add_address(self.nat_addr)
2155 flags = self.config_flags.NAT_IS_INSIDE
2156 self.vapi.nat44_interface_add_del_feature(
2157 sw_if_index=self.pg0.sw_if_index,
2158 flags=flags, is_add=1)
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg1.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg3.sw_if_index,
2166 # between two NAT44 inside interfaces (no translation)
2167 pkts = self.create_stream_in(self.pg0, self.pg1)
2168 self.pg0.add_stream(pkts)
2169 self.pg_enable_capture(self.pg_interfaces)
2171 capture = self.pg1.get_capture(len(pkts))
2172 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2174 # from NAT44 inside to interface without NAT44 feature (no translation)
2175 pkts = self.create_stream_in(self.pg0, self.pg2)
2176 self.pg0.add_stream(pkts)
2177 self.pg_enable_capture(self.pg_interfaces)
2179 capture = self.pg2.get_capture(len(pkts))
2180 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2182 # in2out 1st interface
2183 pkts = self.create_stream_in(self.pg0, self.pg3)
2184 self.pg0.add_stream(pkts)
2185 self.pg_enable_capture(self.pg_interfaces)
2187 capture = self.pg3.get_capture(len(pkts))
2188 self.verify_capture_out(capture)
2190 # out2in 1st interface
2191 pkts = self.create_stream_out(self.pg3)
2192 self.pg3.add_stream(pkts)
2193 self.pg_enable_capture(self.pg_interfaces)
2195 capture = self.pg0.get_capture(len(pkts))
2196 self.verify_capture_in(capture, self.pg0)
2198 # in2out 2nd interface
2199 pkts = self.create_stream_in(self.pg1, self.pg3)
2200 self.pg1.add_stream(pkts)
2201 self.pg_enable_capture(self.pg_interfaces)
2203 capture = self.pg3.get_capture(len(pkts))
2204 self.verify_capture_out(capture)
2206 # out2in 2nd interface
2207 pkts = self.create_stream_out(self.pg3)
2208 self.pg3.add_stream(pkts)
2209 self.pg_enable_capture(self.pg_interfaces)
2211 capture = self.pg1.get_capture(len(pkts))
2212 self.verify_capture_in(capture, self.pg1)
2214 def test_inside_overlapping_interfaces(self):
2215 """ NAT44 multiple inside interfaces with overlapping address space """
2217 static_nat_ip = "10.0.0.10"
2218 self.nat44_add_address(self.nat_addr)
2219 flags = self.config_flags.NAT_IS_INSIDE
2220 self.vapi.nat44_interface_add_del_feature(
2221 sw_if_index=self.pg3.sw_if_index,
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg4.sw_if_index,
2225 flags=flags, is_add=1)
2226 self.vapi.nat44_interface_add_del_feature(
2227 sw_if_index=self.pg5.sw_if_index,
2228 flags=flags, is_add=1)
2229 self.vapi.nat44_interface_add_del_feature(
2230 sw_if_index=self.pg6.sw_if_index,
2231 flags=flags, is_add=1)
2232 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2235 # between NAT44 inside interfaces with same VRF (no translation)
2236 pkts = self.create_stream_in(self.pg4, self.pg5)
2237 self.pg4.add_stream(pkts)
2238 self.pg_enable_capture(self.pg_interfaces)
2240 capture = self.pg5.get_capture(len(pkts))
2241 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2243 # between NAT44 inside interfaces with different VRF (hairpinning)
2244 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2245 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2246 TCP(sport=1234, dport=5678))
2247 self.pg4.add_stream(p)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg6.get_capture(1)
2255 self.assertEqual(ip.src, self.nat_addr)
2256 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2257 self.assertNotEqual(tcp.sport, 1234)
2258 self.assertEqual(tcp.dport, 5678)
2260 self.logger.error(ppp("Unexpected or invalid packet:", p))
2263 # in2out 1st interface
2264 pkts = self.create_stream_in(self.pg4, self.pg3)
2265 self.pg4.add_stream(pkts)
2266 self.pg_enable_capture(self.pg_interfaces)
2268 capture = self.pg3.get_capture(len(pkts))
2269 self.verify_capture_out(capture)
2271 # out2in 1st interface
2272 pkts = self.create_stream_out(self.pg3)
2273 self.pg3.add_stream(pkts)
2274 self.pg_enable_capture(self.pg_interfaces)
2276 capture = self.pg4.get_capture(len(pkts))
2277 self.verify_capture_in(capture, self.pg4)
2279 # in2out 2nd interface
2280 pkts = self.create_stream_in(self.pg5, self.pg3)
2281 self.pg5.add_stream(pkts)
2282 self.pg_enable_capture(self.pg_interfaces)
2284 capture = self.pg3.get_capture(len(pkts))
2285 self.verify_capture_out(capture)
2287 # out2in 2nd interface
2288 pkts = self.create_stream_out(self.pg3)
2289 self.pg3.add_stream(pkts)
2290 self.pg_enable_capture(self.pg_interfaces)
2292 capture = self.pg5.get_capture(len(pkts))
2293 self.verify_capture_in(capture, self.pg5)
2296 addresses = self.vapi.nat44_address_dump()
2297 self.assertEqual(len(addresses), 1)
2298 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2299 self.assertEqual(len(sessions), 3)
2300 for session in sessions:
2301 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2302 self.assertEqual(str(session.inside_ip_address),
2303 self.pg5.remote_ip4)
2304 self.assertEqual(session.outside_ip_address,
2305 addresses[0].ip_address)
2306 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2307 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2308 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2309 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2310 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2311 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2312 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2313 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2314 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2316 # in2out 3rd interface
2317 pkts = self.create_stream_in(self.pg6, self.pg3)
2318 self.pg6.add_stream(pkts)
2319 self.pg_enable_capture(self.pg_interfaces)
2321 capture = self.pg3.get_capture(len(pkts))
2322 self.verify_capture_out(capture, static_nat_ip, True)
2324 # out2in 3rd interface
2325 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2326 self.pg3.add_stream(pkts)
2327 self.pg_enable_capture(self.pg_interfaces)
2329 capture = self.pg6.get_capture(len(pkts))
2330 self.verify_capture_in(capture, self.pg6)
2332 # general user and session dump verifications
2333 users = self.vapi.nat44_user_dump()
2334 self.assertGreaterEqual(len(users), 3)
2335 addresses = self.vapi.nat44_address_dump()
2336 self.assertEqual(len(addresses), 1)
2338 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2340 for session in sessions:
2341 self.assertEqual(user.ip_address, session.inside_ip_address)
2342 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2343 self.assertTrue(session.protocol in
2344 [IP_PROTOS.tcp, IP_PROTOS.udp,
2346 self.assertFalse(session.flags &
2347 self.config_flags.NAT_IS_EXT_HOST_VALID)
2350 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2351 self.assertGreaterEqual(len(sessions), 4)
2352 for session in sessions:
2353 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2354 self.assertEqual(str(session.inside_ip_address),
2355 self.pg4.remote_ip4)
2356 self.assertEqual(session.outside_ip_address,
2357 addresses[0].ip_address)
2360 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2361 self.assertGreaterEqual(len(sessions), 3)
2362 for session in sessions:
2363 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2364 self.assertEqual(str(session.inside_ip_address),
2365 self.pg6.remote_ip4)
2366 self.assertEqual(str(session.outside_ip_address),
2368 self.assertTrue(session.inside_port in
2369 [self.tcp_port_in, self.udp_port_in,
2372 def test_hairpinning(self):
2373 """ NAT44 hairpinning - 1:1 NAPT """
2375 host = self.pg0.remote_hosts[0]
2376 server = self.pg0.remote_hosts[1]
2379 server_in_port = 5678
2380 server_out_port = 8765
2382 self.nat44_add_address(self.nat_addr)
2383 flags = self.config_flags.NAT_IS_INSIDE
2384 self.vapi.nat44_interface_add_del_feature(
2385 sw_if_index=self.pg0.sw_if_index,
2386 flags=flags, is_add=1)
2387 self.vapi.nat44_interface_add_del_feature(
2388 sw_if_index=self.pg1.sw_if_index,
2391 # add static mapping for server
2392 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2393 server_in_port, server_out_port,
2394 proto=IP_PROTOS.tcp)
2396 # send packet from host to server
2397 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2398 IP(src=host.ip4, dst=self.nat_addr) /
2399 TCP(sport=host_in_port, dport=server_out_port))
2400 self.pg0.add_stream(p)
2401 self.pg_enable_capture(self.pg_interfaces)
2403 capture = self.pg0.get_capture(1)
2408 self.assertEqual(ip.src, self.nat_addr)
2409 self.assertEqual(ip.dst, server.ip4)
2410 self.assertNotEqual(tcp.sport, host_in_port)
2411 self.assertEqual(tcp.dport, server_in_port)
2412 self.assert_packet_checksums_valid(p)
2413 host_out_port = tcp.sport
2415 self.logger.error(ppp("Unexpected or invalid packet:", p))
2418 # send reply from server to host
2419 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2420 IP(src=server.ip4, dst=self.nat_addr) /
2421 TCP(sport=server_in_port, dport=host_out_port))
2422 self.pg0.add_stream(p)
2423 self.pg_enable_capture(self.pg_interfaces)
2425 capture = self.pg0.get_capture(1)
2430 self.assertEqual(ip.src, self.nat_addr)
2431 self.assertEqual(ip.dst, host.ip4)
2432 self.assertEqual(tcp.sport, server_out_port)
2433 self.assertEqual(tcp.dport, host_in_port)
2434 self.assert_packet_checksums_valid(p)
2436 self.logger.error(ppp("Unexpected or invalid packet:", p))
2439 def test_hairpinning2(self):
2440 """ NAT44 hairpinning - 1:1 NAT"""
2442 server1_nat_ip = "10.0.0.10"
2443 server2_nat_ip = "10.0.0.11"
2444 host = self.pg0.remote_hosts[0]
2445 server1 = self.pg0.remote_hosts[1]
2446 server2 = self.pg0.remote_hosts[2]
2447 server_tcp_port = 22
2448 server_udp_port = 20
2450 self.nat44_add_address(self.nat_addr)
2451 flags = self.config_flags.NAT_IS_INSIDE
2452 self.vapi.nat44_interface_add_del_feature(
2453 sw_if_index=self.pg0.sw_if_index,
2454 flags=flags, is_add=1)
2455 self.vapi.nat44_interface_add_del_feature(
2456 sw_if_index=self.pg1.sw_if_index,
2459 # add static mapping for servers
2460 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2461 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2466 IP(src=host.ip4, dst=server1_nat_ip) /
2467 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=host.ip4, dst=server1_nat_ip) /
2471 UDP(sport=self.udp_port_in, dport=server_udp_port))
2473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2474 IP(src=host.ip4, dst=server1_nat_ip) /
2475 ICMP(id=self.icmp_id_in, type='echo-request'))
2477 self.pg0.add_stream(pkts)
2478 self.pg_enable_capture(self.pg_interfaces)
2480 capture = self.pg0.get_capture(len(pkts))
2481 for packet in capture:
2483 self.assertEqual(packet[IP].src, self.nat_addr)
2484 self.assertEqual(packet[IP].dst, server1.ip4)
2485 if packet.haslayer(TCP):
2486 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2487 self.assertEqual(packet[TCP].dport, server_tcp_port)
2488 self.tcp_port_out = packet[TCP].sport
2489 self.assert_packet_checksums_valid(packet)
2490 elif packet.haslayer(UDP):
2491 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2492 self.assertEqual(packet[UDP].dport, server_udp_port)
2493 self.udp_port_out = packet[UDP].sport
2495 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2496 self.icmp_id_out = packet[ICMP].id
2498 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2503 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2504 IP(src=server1.ip4, dst=self.nat_addr) /
2505 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server1.ip4, dst=self.nat_addr) /
2509 UDP(sport=server_udp_port, dport=self.udp_port_out))
2511 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2512 IP(src=server1.ip4, dst=self.nat_addr) /
2513 ICMP(id=self.icmp_id_out, type='echo-reply'))
2515 self.pg0.add_stream(pkts)
2516 self.pg_enable_capture(self.pg_interfaces)
2518 capture = self.pg0.get_capture(len(pkts))
2519 for packet in capture:
2521 self.assertEqual(packet[IP].src, server1_nat_ip)
2522 self.assertEqual(packet[IP].dst, host.ip4)
2523 if packet.haslayer(TCP):
2524 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2525 self.assertEqual(packet[TCP].sport, server_tcp_port)
2526 self.assert_packet_checksums_valid(packet)
2527 elif packet.haslayer(UDP):
2528 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2529 self.assertEqual(packet[UDP].sport, server_udp_port)
2531 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2533 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2536 # server2 to server1
2538 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2539 IP(src=server2.ip4, dst=server1_nat_ip) /
2540 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2542 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2543 IP(src=server2.ip4, dst=server1_nat_ip) /
2544 UDP(sport=self.udp_port_in, dport=server_udp_port))
2546 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2547 IP(src=server2.ip4, dst=server1_nat_ip) /
2548 ICMP(id=self.icmp_id_in, type='echo-request'))
2550 self.pg0.add_stream(pkts)
2551 self.pg_enable_capture(self.pg_interfaces)
2553 capture = self.pg0.get_capture(len(pkts))
2554 for packet in capture:
2556 self.assertEqual(packet[IP].src, server2_nat_ip)
2557 self.assertEqual(packet[IP].dst, server1.ip4)
2558 if packet.haslayer(TCP):
2559 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2560 self.assertEqual(packet[TCP].dport, server_tcp_port)
2561 self.tcp_port_out = packet[TCP].sport
2562 self.assert_packet_checksums_valid(packet)
2563 elif packet.haslayer(UDP):
2564 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2565 self.assertEqual(packet[UDP].dport, server_udp_port)
2566 self.udp_port_out = packet[UDP].sport
2568 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2569 self.icmp_id_out = packet[ICMP].id
2571 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2574 # server1 to server2
2576 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2577 IP(src=server1.ip4, dst=server2_nat_ip) /
2578 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2581 IP(src=server1.ip4, dst=server2_nat_ip) /
2582 UDP(sport=server_udp_port, dport=self.udp_port_out))
2584 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2585 IP(src=server1.ip4, dst=server2_nat_ip) /
2586 ICMP(id=self.icmp_id_out, type='echo-reply'))
2588 self.pg0.add_stream(pkts)
2589 self.pg_enable_capture(self.pg_interfaces)
2591 capture = self.pg0.get_capture(len(pkts))
2592 for packet in capture:
2594 self.assertEqual(packet[IP].src, server1_nat_ip)
2595 self.assertEqual(packet[IP].dst, server2.ip4)
2596 if packet.haslayer(TCP):
2597 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2598 self.assertEqual(packet[TCP].sport, server_tcp_port)
2599 self.assert_packet_checksums_valid(packet)
2600 elif packet.haslayer(UDP):
2601 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2602 self.assertEqual(packet[UDP].sport, server_udp_port)
2604 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2606 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2609 def test_max_translations_per_user(self):
2610 """ MAX translations per user - recycle the least recently used """
2612 self.nat44_add_address(self.nat_addr)
2613 flags = self.config_flags.NAT_IS_INSIDE
2614 self.vapi.nat44_interface_add_del_feature(
2615 sw_if_index=self.pg0.sw_if_index,
2616 flags=flags, is_add=1)
2617 self.vapi.nat44_interface_add_del_feature(
2618 sw_if_index=self.pg1.sw_if_index,
2621 # get maximum number of translations per user
2622 nat44_config = self.vapi.nat_show_config()
2624 # send more than maximum number of translations per user packets
2625 pkts_num = nat44_config.max_translations_per_user + 5
2627 for port in range(0, pkts_num):
2628 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2629 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2630 TCP(sport=1025 + port))
2632 self.pg0.add_stream(pkts)
2633 self.pg_enable_capture(self.pg_interfaces)
2636 # verify number of translated packet
2637 self.pg1.get_capture(pkts_num)
2639 users = self.vapi.nat44_user_dump()
2641 if user.ip_address == self.pg0.remote_ip4:
2642 self.assertEqual(user.nsessions,
2643 nat44_config.max_translations_per_user)
2644 self.assertEqual(user.nstaticsessions, 0)
2647 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2649 proto=IP_PROTOS.tcp)
2650 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2651 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2652 TCP(sport=tcp_port))
2653 self.pg0.add_stream(p)
2654 self.pg_enable_capture(self.pg_interfaces)
2656 self.pg1.get_capture(1)
2657 users = self.vapi.nat44_user_dump()
2659 if user.ip_address == self.pg0.remote_ip4:
2660 self.assertEqual(user.nsessions,
2661 nat44_config.max_translations_per_user - 1)
2662 self.assertEqual(user.nstaticsessions, 1)
2664 def test_interface_addr(self):
2665 """ Acquire NAT44 addresses from interface """
2666 self.vapi.nat44_add_del_interface_addr(
2668 sw_if_index=self.pg7.sw_if_index)
2670 # no address in NAT pool
2671 addresses = self.vapi.nat44_address_dump()
2672 self.assertEqual(0, len(addresses))
2674 # configure interface address and check NAT address pool
2675 self.pg7.config_ip4()
2676 addresses = self.vapi.nat44_address_dump()
2677 self.assertEqual(1, len(addresses))
2678 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2680 # remove interface address and check NAT address pool
2681 self.pg7.unconfig_ip4()
2682 addresses = self.vapi.nat44_address_dump()
2683 self.assertEqual(0, len(addresses))
2685 def test_interface_addr_static_mapping(self):
2686 """ Static mapping with addresses from interface """
2689 self.vapi.nat44_add_del_interface_addr(
2691 sw_if_index=self.pg7.sw_if_index)
2692 self.nat44_add_static_mapping(
2694 external_sw_if_index=self.pg7.sw_if_index,
2697 # static mappings with external interface
2698 static_mappings = self.vapi.nat44_static_mapping_dump()
2699 self.assertEqual(1, len(static_mappings))
2700 self.assertEqual(self.pg7.sw_if_index,
2701 static_mappings[0].external_sw_if_index)
2702 self.assertEqual(static_mappings[0].tag, tag)
2704 # configure interface address and check static mappings
2705 self.pg7.config_ip4()
2706 static_mappings = self.vapi.nat44_static_mapping_dump()
2707 self.assertEqual(2, len(static_mappings))
2709 for sm in static_mappings:
2710 if sm.external_sw_if_index == 0xFFFFFFFF:
2711 self.assertEqual(str(sm.external_ip_address),
2713 self.assertEqual(sm.tag, tag)
2715 self.assertTrue(resolved)
2717 # remove interface address and check static mappings
2718 self.pg7.unconfig_ip4()
2719 static_mappings = self.vapi.nat44_static_mapping_dump()
2720 self.assertEqual(1, len(static_mappings))
2721 self.assertEqual(self.pg7.sw_if_index,
2722 static_mappings[0].external_sw_if_index)
2723 self.assertEqual(static_mappings[0].tag, tag)
2725 # configure interface address again and check static mappings
2726 self.pg7.config_ip4()
2727 static_mappings = self.vapi.nat44_static_mapping_dump()
2728 self.assertEqual(2, len(static_mappings))
2730 for sm in static_mappings:
2731 if sm.external_sw_if_index == 0xFFFFFFFF:
2732 self.assertEqual(str(sm.external_ip_address),
2734 self.assertEqual(sm.tag, tag)
2736 self.assertTrue(resolved)
2738 # remove static mapping
2739 self.nat44_add_static_mapping(
2741 external_sw_if_index=self.pg7.sw_if_index,
2744 static_mappings = self.vapi.nat44_static_mapping_dump()
2745 self.assertEqual(0, len(static_mappings))
2747 def test_interface_addr_identity_nat(self):
2748 """ Identity NAT with addresses from interface """
2751 self.vapi.nat44_add_del_interface_addr(
2753 sw_if_index=self.pg7.sw_if_index)
2754 self.vapi.nat44_add_del_identity_mapping(
2756 sw_if_index=self.pg7.sw_if_index,
2758 protocol=IP_PROTOS.tcp,
2761 # identity mappings with external interface
2762 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2763 self.assertEqual(1, len(identity_mappings))
2764 self.assertEqual(self.pg7.sw_if_index,
2765 identity_mappings[0].sw_if_index)
2767 # configure interface address and check identity mappings
2768 self.pg7.config_ip4()
2769 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2771 self.assertEqual(2, len(identity_mappings))
2772 for sm in identity_mappings:
2773 if sm.sw_if_index == 0xFFFFFFFF:
2774 self.assertEqual(str(identity_mappings[0].ip_address),
2776 self.assertEqual(port, identity_mappings[0].port)
2777 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2779 self.assertTrue(resolved)
2781 # remove interface address and check identity mappings
2782 self.pg7.unconfig_ip4()
2783 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2784 self.assertEqual(1, len(identity_mappings))
2785 self.assertEqual(self.pg7.sw_if_index,
2786 identity_mappings[0].sw_if_index)
2788 def test_ipfix_nat44_sess(self):
2789 """ IPFIX logging NAT44 session created/deleted """
2790 self.ipfix_domain_id = 10
2791 self.ipfix_src_port = 20202
2792 collector_port = 30303
2793 bind_layers(UDP, IPFIX, dport=30303)
2794 self.nat44_add_address(self.nat_addr)
2795 flags = self.config_flags.NAT_IS_INSIDE
2796 self.vapi.nat44_interface_add_del_feature(
2797 sw_if_index=self.pg0.sw_if_index,
2798 flags=flags, is_add=1)
2799 self.vapi.nat44_interface_add_del_feature(
2800 sw_if_index=self.pg1.sw_if_index,
2802 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2803 src_address=self.pg3.local_ip4,
2805 template_interval=10,
2806 collector_port=collector_port)
2807 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2808 src_port=self.ipfix_src_port,
2811 pkts = self.create_stream_in(self.pg0, self.pg1)
2812 self.pg0.add_stream(pkts)
2813 self.pg_enable_capture(self.pg_interfaces)
2815 capture = self.pg1.get_capture(len(pkts))
2816 self.verify_capture_out(capture)
2817 self.nat44_add_address(self.nat_addr, is_add=0)
2818 self.vapi.ipfix_flush()
2819 capture = self.pg3.get_capture(9)
2820 ipfix = IPFIXDecoder()
2821 # first load template
2823 self.assertTrue(p.haslayer(IPFIX))
2824 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2825 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2826 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2827 self.assertEqual(p[UDP].dport, collector_port)
2828 self.assertEqual(p[IPFIX].observationDomainID,
2829 self.ipfix_domain_id)
2830 if p.haslayer(Template):
2831 ipfix.add_template(p.getlayer(Template))
2832 # verify events in data set
2834 if p.haslayer(Data):
2835 data = ipfix.decode_data_set(p.getlayer(Set))
2836 self.verify_ipfix_nat44_ses(data)
2838 def test_ipfix_addr_exhausted(self):
2839 """ IPFIX logging NAT addresses exhausted """
2840 flags = self.config_flags.NAT_IS_INSIDE
2841 self.vapi.nat44_interface_add_del_feature(
2842 sw_if_index=self.pg0.sw_if_index,
2843 flags=flags, is_add=1)
2844 self.vapi.nat44_interface_add_del_feature(
2845 sw_if_index=self.pg1.sw_if_index,
2847 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2848 src_address=self.pg3.local_ip4,
2850 template_interval=10)
2851 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2852 src_port=self.ipfix_src_port,
2855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2856 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2858 self.pg0.add_stream(p)
2859 self.pg_enable_capture(self.pg_interfaces)
2861 self.pg1.assert_nothing_captured()
2863 self.vapi.ipfix_flush()
2864 capture = self.pg3.get_capture(9)
2865 ipfix = IPFIXDecoder()
2866 # first load template
2868 self.assertTrue(p.haslayer(IPFIX))
2869 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2870 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2871 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2872 self.assertEqual(p[UDP].dport, 4739)
2873 self.assertEqual(p[IPFIX].observationDomainID,
2874 self.ipfix_domain_id)
2875 if p.haslayer(Template):
2876 ipfix.add_template(p.getlayer(Template))
2877 # verify events in data set
2879 if p.haslayer(Data):
2880 data = ipfix.decode_data_set(p.getlayer(Set))
2881 self.verify_ipfix_addr_exhausted(data)
2883 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2884 def test_ipfix_max_sessions(self):
2885 """ IPFIX logging maximum session entries exceeded """
2886 self.nat44_add_address(self.nat_addr)
2887 flags = self.config_flags.NAT_IS_INSIDE
2888 self.vapi.nat44_interface_add_del_feature(
2889 sw_if_index=self.pg0.sw_if_index,
2890 flags=flags, is_add=1)
2891 self.vapi.nat44_interface_add_del_feature(
2892 sw_if_index=self.pg1.sw_if_index,
2895 nat44_config = self.vapi.nat_show_config()
2896 max_sessions = 10 * nat44_config.translation_buckets
2899 for i in range(0, max_sessions):
2900 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2901 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2902 IP(src=src, dst=self.pg1.remote_ip4) /
2905 self.pg0.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2909 self.pg1.get_capture(max_sessions)
2910 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2911 src_address=self.pg3.local_ip4,
2913 template_interval=10)
2914 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2915 src_port=self.ipfix_src_port,
2918 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2919 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2921 self.pg0.add_stream(p)
2922 self.pg_enable_capture(self.pg_interfaces)
2924 self.pg1.assert_nothing_captured()
2926 self.vapi.ipfix_flush()
2927 capture = self.pg3.get_capture(9)
2928 ipfix = IPFIXDecoder()
2929 # first load template
2931 self.assertTrue(p.haslayer(IPFIX))
2932 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2933 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2934 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2935 self.assertEqual(p[UDP].dport, 4739)
2936 self.assertEqual(p[IPFIX].observationDomainID,
2937 self.ipfix_domain_id)
2938 if p.haslayer(Template):
2939 ipfix.add_template(p.getlayer(Template))
2940 # verify events in data set
2942 if p.haslayer(Data):
2943 data = ipfix.decode_data_set(p.getlayer(Set))
2944 self.verify_ipfix_max_sessions(data, max_sessions)
2946 def test_syslog_apmap(self):
2947 """ Test syslog address and port mapping creation and deletion """
2948 self.vapi.syslog_set_filter(
2949 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2950 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2951 self.nat44_add_address(self.nat_addr)
2952 flags = self.config_flags.NAT_IS_INSIDE
2953 self.vapi.nat44_interface_add_del_feature(
2954 sw_if_index=self.pg0.sw_if_index,
2955 flags=flags, is_add=1)
2956 self.vapi.nat44_interface_add_del_feature(
2957 sw_if_index=self.pg1.sw_if_index,
2960 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2961 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2962 TCP(sport=self.tcp_port_in, dport=20))
2963 self.pg0.add_stream(p)
2964 self.pg_enable_capture(self.pg_interfaces)
2966 capture = self.pg1.get_capture(1)
2967 self.tcp_port_out = capture[0][TCP].sport
2968 capture = self.pg3.get_capture(1)
2969 self.verify_syslog_apmap(capture[0][Raw].load)
2971 self.pg_enable_capture(self.pg_interfaces)
2973 self.nat44_add_address(self.nat_addr, is_add=0)
2974 capture = self.pg3.get_capture(1)
2975 self.verify_syslog_apmap(capture[0][Raw].load, False)
2977 def test_pool_addr_fib(self):
2978 """ NAT44 add pool addresses to FIB """
2979 static_addr = '10.0.0.10'
2980 self.nat44_add_address(self.nat_addr)
2981 flags = self.config_flags.NAT_IS_INSIDE
2982 self.vapi.nat44_interface_add_del_feature(
2983 sw_if_index=self.pg0.sw_if_index,
2984 flags=flags, is_add=1)
2985 self.vapi.nat44_interface_add_del_feature(
2986 sw_if_index=self.pg1.sw_if_index,
2988 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2991 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2992 ARP(op=ARP.who_has, pdst=self.nat_addr,
2993 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2994 self.pg1.add_stream(p)
2995 self.pg_enable_capture(self.pg_interfaces)
2997 capture = self.pg1.get_capture(1)
2998 self.assertTrue(capture[0].haslayer(ARP))
2999 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3002 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3003 ARP(op=ARP.who_has, pdst=static_addr,
3004 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3005 self.pg1.add_stream(p)
3006 self.pg_enable_capture(self.pg_interfaces)
3008 capture = self.pg1.get_capture(1)
3009 self.assertTrue(capture[0].haslayer(ARP))
3010 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3012 # send ARP to non-NAT44 interface
3013 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3014 ARP(op=ARP.who_has, pdst=self.nat_addr,
3015 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3016 self.pg2.add_stream(p)
3017 self.pg_enable_capture(self.pg_interfaces)
3019 self.pg1.assert_nothing_captured()
3021 # remove addresses and verify
3022 self.nat44_add_address(self.nat_addr, is_add=0)
3023 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3026 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3027 ARP(op=ARP.who_has, pdst=self.nat_addr,
3028 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3029 self.pg1.add_stream(p)
3030 self.pg_enable_capture(self.pg_interfaces)
3032 self.pg1.assert_nothing_captured()
3034 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3035 ARP(op=ARP.who_has, pdst=static_addr,
3036 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3037 self.pg1.add_stream(p)
3038 self.pg_enable_capture(self.pg_interfaces)
3040 self.pg1.assert_nothing_captured()
3042 def test_vrf_mode(self):
3043 """ NAT44 tenant VRF aware address pool mode """
3047 nat_ip1 = "10.0.0.10"
3048 nat_ip2 = "10.0.0.11"
3050 self.pg0.unconfig_ip4()
3051 self.pg1.unconfig_ip4()
3052 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3053 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3054 self.pg0.set_table_ip4(vrf_id1)
3055 self.pg1.set_table_ip4(vrf_id2)
3056 self.pg0.config_ip4()
3057 self.pg1.config_ip4()
3058 self.pg0.resolve_arp()
3059 self.pg1.resolve_arp()
3061 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3062 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3063 flags = self.config_flags.NAT_IS_INSIDE
3064 self.vapi.nat44_interface_add_del_feature(
3065 sw_if_index=self.pg0.sw_if_index,
3066 flags=flags, is_add=1)
3067 self.vapi.nat44_interface_add_del_feature(
3068 sw_if_index=self.pg1.sw_if_index,
3069 flags=flags, is_add=1)
3070 self.vapi.nat44_interface_add_del_feature(
3071 sw_if_index=self.pg2.sw_if_index,
3076 pkts = self.create_stream_in(self.pg0, self.pg2)
3077 self.pg0.add_stream(pkts)
3078 self.pg_enable_capture(self.pg_interfaces)
3080 capture = self.pg2.get_capture(len(pkts))
3081 self.verify_capture_out(capture, nat_ip1)
3084 pkts = self.create_stream_in(self.pg1, self.pg2)
3085 self.pg1.add_stream(pkts)
3086 self.pg_enable_capture(self.pg_interfaces)
3088 capture = self.pg2.get_capture(len(pkts))
3089 self.verify_capture_out(capture, nat_ip2)
3092 self.pg0.unconfig_ip4()
3093 self.pg1.unconfig_ip4()
3094 self.pg0.set_table_ip4(0)
3095 self.pg1.set_table_ip4(0)
3096 self.pg0.config_ip4()
3097 self.pg1.config_ip4()
3098 self.pg0.resolve_arp()
3099 self.pg1.resolve_arp()
3100 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3101 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3103 def test_vrf_feature_independent(self):
3104 """ NAT44 tenant VRF independent address pool mode """
3106 nat_ip1 = "10.0.0.10"
3107 nat_ip2 = "10.0.0.11"
3109 self.nat44_add_address(nat_ip1)
3110 self.nat44_add_address(nat_ip2, vrf_id=99)
3111 flags = self.config_flags.NAT_IS_INSIDE
3112 self.vapi.nat44_interface_add_del_feature(
3113 sw_if_index=self.pg0.sw_if_index,
3114 flags=flags, is_add=1)
3115 self.vapi.nat44_interface_add_del_feature(
3116 sw_if_index=self.pg1.sw_if_index,
3117 flags=flags, is_add=1)
3118 self.vapi.nat44_interface_add_del_feature(
3119 sw_if_index=self.pg2.sw_if_index,
3123 pkts = self.create_stream_in(self.pg0, self.pg2)
3124 self.pg0.add_stream(pkts)
3125 self.pg_enable_capture(self.pg_interfaces)
3127 capture = self.pg2.get_capture(len(pkts))
3128 self.verify_capture_out(capture, nat_ip1)
3131 pkts = self.create_stream_in(self.pg1, self.pg2)
3132 self.pg1.add_stream(pkts)
3133 self.pg_enable_capture(self.pg_interfaces)
3135 capture = self.pg2.get_capture(len(pkts))
3136 self.verify_capture_out(capture, nat_ip1)
3138 def create_routes_and_neigbors(self):
3139 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3140 [VppRoutePath(self.pg7.remote_ip4,
3141 self.pg7.sw_if_index)])
3142 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3143 [VppRoutePath(self.pg8.remote_ip4,
3144 self.pg8.sw_if_index)])
3148 n1 = VppNeighbor(self,
3149 self.pg7.sw_if_index,
3150 self.pg7.remote_mac,
3151 self.pg7.remote_ip4,
3153 n2 = VppNeighbor(self,
3154 self.pg8.sw_if_index,
3155 self.pg8.remote_mac,
3156 self.pg8.remote_ip4,
3161 def test_dynamic_ipless_interfaces(self):
3162 """ NAT44 interfaces without configured IP address """
3163 self.create_routes_and_neigbors()
3164 self.nat44_add_address(self.nat_addr)
3165 flags = self.config_flags.NAT_IS_INSIDE
3166 self.vapi.nat44_interface_add_del_feature(
3167 sw_if_index=self.pg7.sw_if_index,
3168 flags=flags, is_add=1)
3169 self.vapi.nat44_interface_add_del_feature(
3170 sw_if_index=self.pg8.sw_if_index,
3174 pkts = self.create_stream_in(self.pg7, self.pg8)
3175 self.pg7.add_stream(pkts)
3176 self.pg_enable_capture(self.pg_interfaces)
3178 capture = self.pg8.get_capture(len(pkts))
3179 self.verify_capture_out(capture)
3182 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3183 self.pg8.add_stream(pkts)
3184 self.pg_enable_capture(self.pg_interfaces)
3186 capture = self.pg7.get_capture(len(pkts))
3187 self.verify_capture_in(capture, self.pg7)
3189 def test_static_ipless_interfaces(self):
3190 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3192 self.create_routes_and_neigbors()
3193 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3194 flags = self.config_flags.NAT_IS_INSIDE
3195 self.vapi.nat44_interface_add_del_feature(
3196 sw_if_index=self.pg7.sw_if_index,
3197 flags=flags, is_add=1)
3198 self.vapi.nat44_interface_add_del_feature(
3199 sw_if_index=self.pg8.sw_if_index,
3203 pkts = self.create_stream_out(self.pg8)
3204 self.pg8.add_stream(pkts)
3205 self.pg_enable_capture(self.pg_interfaces)
3207 capture = self.pg7.get_capture(len(pkts))
3208 self.verify_capture_in(capture, self.pg7)
3211 pkts = self.create_stream_in(self.pg7, self.pg8)
3212 self.pg7.add_stream(pkts)
3213 self.pg_enable_capture(self.pg_interfaces)
3215 capture = self.pg8.get_capture(len(pkts))
3216 self.verify_capture_out(capture, self.nat_addr, True)
3218 def test_static_with_port_ipless_interfaces(self):
3219 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3221 self.tcp_port_out = 30606
3222 self.udp_port_out = 30607
3223 self.icmp_id_out = 30608
3225 self.create_routes_and_neigbors()
3226 self.nat44_add_address(self.nat_addr)
3227 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3228 self.tcp_port_in, self.tcp_port_out,
3229 proto=IP_PROTOS.tcp)
3230 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3231 self.udp_port_in, self.udp_port_out,
3232 proto=IP_PROTOS.udp)
3233 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3234 self.icmp_id_in, self.icmp_id_out,
3235 proto=IP_PROTOS.icmp)
3236 flags = self.config_flags.NAT_IS_INSIDE
3237 self.vapi.nat44_interface_add_del_feature(
3238 sw_if_index=self.pg7.sw_if_index,
3239 flags=flags, is_add=1)
3240 self.vapi.nat44_interface_add_del_feature(
3241 sw_if_index=self.pg8.sw_if_index,
3245 pkts = self.create_stream_out(self.pg8)
3246 self.pg8.add_stream(pkts)
3247 self.pg_enable_capture(self.pg_interfaces)
3249 capture = self.pg7.get_capture(len(pkts))
3250 self.verify_capture_in(capture, self.pg7)
3253 pkts = self.create_stream_in(self.pg7, self.pg8)
3254 self.pg7.add_stream(pkts)
3255 self.pg_enable_capture(self.pg_interfaces)
3257 capture = self.pg8.get_capture(len(pkts))
3258 self.verify_capture_out(capture)
3260 def test_static_unknown_proto(self):
3261 """ 1:1 NAT translate packet with unknown protocol """
3262 nat_ip = "10.0.0.10"
3263 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3264 flags = self.config_flags.NAT_IS_INSIDE
3265 self.vapi.nat44_interface_add_del_feature(
3266 sw_if_index=self.pg0.sw_if_index,
3267 flags=flags, is_add=1)
3268 self.vapi.nat44_interface_add_del_feature(
3269 sw_if_index=self.pg1.sw_if_index,
3273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3274 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3276 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3277 TCP(sport=1234, dport=1234))
3278 self.pg0.add_stream(p)
3279 self.pg_enable_capture(self.pg_interfaces)
3281 p = self.pg1.get_capture(1)
3284 self.assertEqual(packet[IP].src, nat_ip)
3285 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3286 self.assertEqual(packet.haslayer(GRE), 1)
3287 self.assert_packet_checksums_valid(packet)
3289 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3293 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3294 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3296 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3297 TCP(sport=1234, dport=1234))
3298 self.pg1.add_stream(p)
3299 self.pg_enable_capture(self.pg_interfaces)
3301 p = self.pg0.get_capture(1)
3304 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3305 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3306 self.assertEqual(packet.haslayer(GRE), 1)
3307 self.assert_packet_checksums_valid(packet)
3309 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3312 def test_hairpinning_static_unknown_proto(self):
3313 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3315 host = self.pg0.remote_hosts[0]
3316 server = self.pg0.remote_hosts[1]
3318 host_nat_ip = "10.0.0.10"
3319 server_nat_ip = "10.0.0.11"
3321 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3322 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3323 flags = self.config_flags.NAT_IS_INSIDE
3324 self.vapi.nat44_interface_add_del_feature(
3325 sw_if_index=self.pg0.sw_if_index,
3326 flags=flags, is_add=1)
3327 self.vapi.nat44_interface_add_del_feature(
3328 sw_if_index=self.pg1.sw_if_index,
3332 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3333 IP(src=host.ip4, dst=server_nat_ip) /
3335 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3336 TCP(sport=1234, dport=1234))
3337 self.pg0.add_stream(p)
3338 self.pg_enable_capture(self.pg_interfaces)
3340 p = self.pg0.get_capture(1)
3343 self.assertEqual(packet[IP].src, host_nat_ip)
3344 self.assertEqual(packet[IP].dst, server.ip4)
3345 self.assertEqual(packet.haslayer(GRE), 1)
3346 self.assert_packet_checksums_valid(packet)
3348 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3352 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3353 IP(src=server.ip4, dst=host_nat_ip) /
3355 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3356 TCP(sport=1234, dport=1234))
3357 self.pg0.add_stream(p)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 p = self.pg0.get_capture(1)
3363 self.assertEqual(packet[IP].src, server_nat_ip)
3364 self.assertEqual(packet[IP].dst, host.ip4)
3365 self.assertEqual(packet.haslayer(GRE), 1)
3366 self.assert_packet_checksums_valid(packet)
3368 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3371 def test_output_feature(self):
3372 """ NAT44 interface output feature (in2out postrouting) """
3373 self.nat44_add_address(self.nat_addr)
3374 flags = self.config_flags.NAT_IS_INSIDE
3375 self.vapi.nat44_interface_add_del_output_feature(
3376 is_add=1, flags=flags,
3377 sw_if_index=self.pg0.sw_if_index)
3378 self.vapi.nat44_interface_add_del_output_feature(
3379 is_add=1, flags=flags,
3380 sw_if_index=self.pg1.sw_if_index)
3381 self.vapi.nat44_interface_add_del_output_feature(
3383 sw_if_index=self.pg3.sw_if_index)
3386 pkts = self.create_stream_in(self.pg0, self.pg3)
3387 self.pg0.add_stream(pkts)
3388 self.pg_enable_capture(self.pg_interfaces)
3390 capture = self.pg3.get_capture(len(pkts))
3391 self.verify_capture_out(capture)
3394 pkts = self.create_stream_out(self.pg3)
3395 self.pg3.add_stream(pkts)
3396 self.pg_enable_capture(self.pg_interfaces)
3398 capture = self.pg0.get_capture(len(pkts))
3399 self.verify_capture_in(capture, self.pg0)
3401 # from non-NAT interface to NAT inside interface
3402 pkts = self.create_stream_in(self.pg2, self.pg0)
3403 self.pg2.add_stream(pkts)
3404 self.pg_enable_capture(self.pg_interfaces)
3406 capture = self.pg0.get_capture(len(pkts))
3407 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3409 def test_output_feature_vrf_aware(self):
3410 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3411 nat_ip_vrf10 = "10.0.0.10"
3412 nat_ip_vrf20 = "10.0.0.20"
3414 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3415 [VppRoutePath(self.pg3.remote_ip4,
3416 self.pg3.sw_if_index)],
3418 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3419 [VppRoutePath(self.pg3.remote_ip4,
3420 self.pg3.sw_if_index)],
3425 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3426 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3427 flags = self.config_flags.NAT_IS_INSIDE
3428 self.vapi.nat44_interface_add_del_output_feature(
3429 is_add=1, flags=flags,
3430 sw_if_index=self.pg4.sw_if_index)
3431 self.vapi.nat44_interface_add_del_output_feature(
3432 is_add=1, flags=flags,
3433 sw_if_index=self.pg6.sw_if_index)
3434 self.vapi.nat44_interface_add_del_output_feature(
3436 sw_if_index=self.pg3.sw_if_index)
3439 pkts = self.create_stream_in(self.pg4, self.pg3)
3440 self.pg4.add_stream(pkts)
3441 self.pg_enable_capture(self.pg_interfaces)
3443 capture = self.pg3.get_capture(len(pkts))
3444 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3447 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3448 self.pg3.add_stream(pkts)
3449 self.pg_enable_capture(self.pg_interfaces)
3451 capture = self.pg4.get_capture(len(pkts))
3452 self.verify_capture_in(capture, self.pg4)
3455 pkts = self.create_stream_in(self.pg6, self.pg3)
3456 self.pg6.add_stream(pkts)
3457 self.pg_enable_capture(self.pg_interfaces)
3459 capture = self.pg3.get_capture(len(pkts))
3460 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3463 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3464 self.pg3.add_stream(pkts)
3465 self.pg_enable_capture(self.pg_interfaces)
3467 capture = self.pg6.get_capture(len(pkts))
3468 self.verify_capture_in(capture, self.pg6)
3470 def test_output_feature_hairpinning(self):
3471 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3472 host = self.pg0.remote_hosts[0]
3473 server = self.pg0.remote_hosts[1]
3476 server_in_port = 5678
3477 server_out_port = 8765
3479 self.nat44_add_address(self.nat_addr)
3480 flags = self.config_flags.NAT_IS_INSIDE
3481 self.vapi.nat44_interface_add_del_output_feature(
3482 is_add=1, flags=flags,
3483 sw_if_index=self.pg0.sw_if_index)
3484 self.vapi.nat44_interface_add_del_output_feature(
3486 sw_if_index=self.pg1.sw_if_index)
3488 # add static mapping for server
3489 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3490 server_in_port, server_out_port,
3491 proto=IP_PROTOS.tcp)
3493 # send packet from host to server
3494 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3495 IP(src=host.ip4, dst=self.nat_addr) /
3496 TCP(sport=host_in_port, dport=server_out_port))
3497 self.pg0.add_stream(p)
3498 self.pg_enable_capture(self.pg_interfaces)
3500 capture = self.pg0.get_capture(1)
3505 self.assertEqual(ip.src, self.nat_addr)
3506 self.assertEqual(ip.dst, server.ip4)
3507 self.assertNotEqual(tcp.sport, host_in_port)
3508 self.assertEqual(tcp.dport, server_in_port)
3509 self.assert_packet_checksums_valid(p)
3510 host_out_port = tcp.sport
3512 self.logger.error(ppp("Unexpected or invalid packet:", p))
3515 # send reply from server to host
3516 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3517 IP(src=server.ip4, dst=self.nat_addr) /
3518 TCP(sport=server_in_port, dport=host_out_port))
3519 self.pg0.add_stream(p)
3520 self.pg_enable_capture(self.pg_interfaces)
3522 capture = self.pg0.get_capture(1)
3527 self.assertEqual(ip.src, self.nat_addr)
3528 self.assertEqual(ip.dst, host.ip4)
3529 self.assertEqual(tcp.sport, server_out_port)
3530 self.assertEqual(tcp.dport, host_in_port)
3531 self.assert_packet_checksums_valid(p)
3533 self.logger.error(ppp("Unexpected or invalid packet:", p))
3536 def test_one_armed_nat44(self):
3537 """ One armed NAT44 """
3538 remote_host = self.pg9.remote_hosts[0]
3539 local_host = self.pg9.remote_hosts[1]
3542 self.nat44_add_address(self.nat_addr)
3543 flags = self.config_flags.NAT_IS_INSIDE
3544 self.vapi.nat44_interface_add_del_feature(
3545 sw_if_index=self.pg9.sw_if_index,
3547 self.vapi.nat44_interface_add_del_feature(
3548 sw_if_index=self.pg9.sw_if_index,
3549 flags=flags, is_add=1)
3552 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3553 IP(src=local_host.ip4, dst=remote_host.ip4) /
3554 TCP(sport=12345, dport=80))
3555 self.pg9.add_stream(p)
3556 self.pg_enable_capture(self.pg_interfaces)
3558 capture = self.pg9.get_capture(1)
3563 self.assertEqual(ip.src, self.nat_addr)
3564 self.assertEqual(ip.dst, remote_host.ip4)
3565 self.assertNotEqual(tcp.sport, 12345)
3566 external_port = tcp.sport
3567 self.assertEqual(tcp.dport, 80)
3568 self.assert_packet_checksums_valid(p)
3570 self.logger.error(ppp("Unexpected or invalid packet:", p))
3574 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3575 IP(src=remote_host.ip4, dst=self.nat_addr) /
3576 TCP(sport=80, dport=external_port))
3577 self.pg9.add_stream(p)
3578 self.pg_enable_capture(self.pg_interfaces)
3580 capture = self.pg9.get_capture(1)
3585 self.assertEqual(ip.src, remote_host.ip4)
3586 self.assertEqual(ip.dst, local_host.ip4)
3587 self.assertEqual(tcp.sport, 80)
3588 self.assertEqual(tcp.dport, 12345)
3589 self.assert_packet_checksums_valid(p)
3591 self.logger.error(ppp("Unexpected or invalid packet:", p))
3594 err = self.statistics.get_err_counter(
3595 '/err/nat44-classify/next in2out')
3596 self.assertEqual(err, 1)
3597 err = self.statistics.get_err_counter(
3598 '/err/nat44-classify/next out2in')
3599 self.assertEqual(err, 1)
3601 def test_del_session(self):
3602 """ Delete NAT44 session """
3603 self.nat44_add_address(self.nat_addr)
3604 flags = self.config_flags.NAT_IS_INSIDE
3605 self.vapi.nat44_interface_add_del_feature(
3606 sw_if_index=self.pg0.sw_if_index,
3607 flags=flags, is_add=1)
3608 self.vapi.nat44_interface_add_del_feature(
3609 sw_if_index=self.pg1.sw_if_index,
3612 pkts = self.create_stream_in(self.pg0, self.pg1)
3613 self.pg0.add_stream(pkts)
3614 self.pg_enable_capture(self.pg_interfaces)
3616 self.pg1.get_capture(len(pkts))
3618 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3619 nsessions = len(sessions)
3621 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3622 port=sessions[0].inside_port,
3623 protocol=sessions[0].protocol,
3624 flags=self.config_flags.NAT_IS_INSIDE)
3625 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3626 port=sessions[1].outside_port,
3627 protocol=sessions[1].protocol)
3629 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3630 self.assertEqual(nsessions - len(sessions), 2)
3632 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3633 port=sessions[0].inside_port,
3634 protocol=sessions[0].protocol,
3635 flags=self.config_flags.NAT_IS_INSIDE)
3637 self.verify_no_nat44_user()
3639 def test_set_get_reass(self):
3640 """ NAT44 set/get virtual fragmentation reassembly """
3641 reas_cfg1 = self.vapi.nat_get_reass()
3643 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3644 max_reass=reas_cfg1.ip4_max_reass * 2,
3645 max_frag=reas_cfg1.ip4_max_frag * 2,
3648 reas_cfg2 = self.vapi.nat_get_reass()
3650 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3651 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3652 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3654 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3656 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3658 def test_frag_in_order(self):
3659 """ NAT44 translate fragments arriving in order """
3661 self.nat44_add_address(self.nat_addr)
3662 flags = self.config_flags.NAT_IS_INSIDE
3663 self.vapi.nat44_interface_add_del_feature(
3664 sw_if_index=self.pg0.sw_if_index,
3665 flags=flags, is_add=1)
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg1.sw_if_index,
3670 reas_cfg1 = self.vapi.nat_get_reass()
3671 # this test was intermittently failing in some cases
3672 # until we temporarily bump the reassembly timeouts
3673 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
3676 self.frag_in_order(proto=IP_PROTOS.tcp)
3677 self.frag_in_order(proto=IP_PROTOS.udp)
3678 self.frag_in_order(proto=IP_PROTOS.icmp)
3680 # restore the reassembly timeouts
3681 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
3682 max_reass=reas_cfg1.ip4_max_reass,
3683 max_frag=reas_cfg1.ip4_max_frag,
3684 drop_frag=reas_cfg1.ip4_drop_frag)
3686 def test_frag_forwarding(self):
3687 """ NAT44 forwarding fragment test """
3688 self.vapi.nat44_add_del_interface_addr(
3690 sw_if_index=self.pg1.sw_if_index)
3691 flags = self.config_flags.NAT_IS_INSIDE
3692 self.vapi.nat44_interface_add_del_feature(
3693 sw_if_index=self.pg0.sw_if_index,
3694 flags=flags, is_add=1)
3695 self.vapi.nat44_interface_add_del_feature(
3696 sw_if_index=self.pg1.sw_if_index,
3698 self.vapi.nat44_forwarding_enable_disable(enable=1)
3700 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3701 pkts = self.create_stream_frag(self.pg1,
3702 self.pg0.remote_ip4,
3706 proto=IP_PROTOS.udp)
3707 self.pg1.add_stream(pkts)
3708 self.pg_enable_capture(self.pg_interfaces)
3710 frags = self.pg0.get_capture(len(pkts))
3711 p = self.reass_frags_and_verify(frags,
3712 self.pg1.remote_ip4,
3713 self.pg0.remote_ip4)
3714 self.assertEqual(p[UDP].sport, 4789)
3715 self.assertEqual(p[UDP].dport, 4789)
3716 self.assertEqual(data, p[Raw].load)
3718 def test_reass_hairpinning(self):
3719 """ NAT44 fragments hairpinning """
3721 self.server = self.pg0.remote_hosts[1]
3722 self.host_in_port = random.randint(1025, 65535)
3723 self.server_in_port = random.randint(1025, 65535)
3724 self.server_out_port = random.randint(1025, 65535)
3726 self.nat44_add_address(self.nat_addr)
3727 flags = self.config_flags.NAT_IS_INSIDE
3728 self.vapi.nat44_interface_add_del_feature(
3729 sw_if_index=self.pg0.sw_if_index,
3730 flags=flags, is_add=1)
3731 self.vapi.nat44_interface_add_del_feature(
3732 sw_if_index=self.pg1.sw_if_index,
3734 # add static mapping for server
3735 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3736 self.server_in_port,
3737 self.server_out_port,
3738 proto=IP_PROTOS.tcp)
3739 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3740 self.server_in_port,
3741 self.server_out_port,
3742 proto=IP_PROTOS.udp)
3743 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3745 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3746 self.reass_hairpinning(proto=IP_PROTOS.udp)
3747 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3749 def test_frag_out_of_order(self):
3750 """ NAT44 translate fragments arriving out of order """
3752 self.nat44_add_address(self.nat_addr)
3753 flags = self.config_flags.NAT_IS_INSIDE
3754 self.vapi.nat44_interface_add_del_feature(
3755 sw_if_index=self.pg0.sw_if_index,
3756 flags=flags, is_add=1)
3757 self.vapi.nat44_interface_add_del_feature(
3758 sw_if_index=self.pg1.sw_if_index,
3761 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3762 self.frag_out_of_order(proto=IP_PROTOS.udp)
3763 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3765 def test_port_restricted(self):
3766 """ Port restricted NAT44 (MAP-E CE) """
3767 self.nat44_add_address(self.nat_addr)
3768 flags = self.config_flags.NAT_IS_INSIDE
3769 self.vapi.nat44_interface_add_del_feature(
3770 sw_if_index=self.pg0.sw_if_index,
3771 flags=flags, is_add=1)
3772 self.vapi.nat44_interface_add_del_feature(
3773 sw_if_index=self.pg1.sw_if_index,
3775 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3780 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3781 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3782 TCP(sport=4567, dport=22))
3783 self.pg0.add_stream(p)
3784 self.pg_enable_capture(self.pg_interfaces)
3786 capture = self.pg1.get_capture(1)
3791 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3792 self.assertEqual(ip.src, self.nat_addr)
3793 self.assertEqual(tcp.dport, 22)
3794 self.assertNotEqual(tcp.sport, 4567)
3795 self.assertEqual((tcp.sport >> 6) & 63, 10)
3796 self.assert_packet_checksums_valid(p)
3798 self.logger.error(ppp("Unexpected or invalid packet:", p))
3801 def test_port_range(self):
3802 """ External address port range """
3803 self.nat44_add_address(self.nat_addr)
3804 flags = self.config_flags.NAT_IS_INSIDE
3805 self.vapi.nat44_interface_add_del_feature(
3806 sw_if_index=self.pg0.sw_if_index,
3807 flags=flags, is_add=1)
3808 self.vapi.nat44_interface_add_del_feature(
3809 sw_if_index=self.pg1.sw_if_index,
3811 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3816 for port in range(0, 5):
3817 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3818 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3819 TCP(sport=1125 + port))
3821 self.pg0.add_stream(pkts)
3822 self.pg_enable_capture(self.pg_interfaces)
3824 capture = self.pg1.get_capture(3)
3827 self.assertGreaterEqual(tcp.sport, 1025)
3828 self.assertLessEqual(tcp.sport, 1027)
3830 def test_ipfix_max_frags(self):
3831 """ IPFIX logging maximum fragments pending reassembly exceeded """
3832 self.nat44_add_address(self.nat_addr)
3833 flags = self.config_flags.NAT_IS_INSIDE
3834 self.vapi.nat44_interface_add_del_feature(
3835 sw_if_index=self.pg0.sw_if_index,
3836 flags=flags, is_add=1)
3837 self.vapi.nat44_interface_add_del_feature(
3838 sw_if_index=self.pg1.sw_if_index,
3840 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3842 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
3843 src_address=self.pg3.local_ip4,
3845 template_interval=10)
3846 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3847 src_port=self.ipfix_src_port,
3850 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3851 self.tcp_port_in = random.randint(1025, 65535)
3852 pkts = self.create_stream_frag(self.pg0,
3853 self.pg1.remote_ip4,
3858 self.pg0.add_stream(pkts)
3859 self.pg_enable_capture(self.pg_interfaces)
3861 self.pg1.assert_nothing_captured()
3863 self.vapi.ipfix_flush()
3864 capture = self.pg3.get_capture(9)
3865 ipfix = IPFIXDecoder()
3866 # first load template
3868 self.assertTrue(p.haslayer(IPFIX))
3869 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3870 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3871 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3872 self.assertEqual(p[UDP].dport, 4739)
3873 self.assertEqual(p[IPFIX].observationDomainID,
3874 self.ipfix_domain_id)
3875 if p.haslayer(Template):
3876 ipfix.add_template(p.getlayer(Template))
3877 # verify events in data set
3879 if p.haslayer(Data):
3880 data = ipfix.decode_data_set(p.getlayer(Set))
3881 self.verify_ipfix_max_fragments_ip4(data, 1,
3882 self.pg0.remote_ip4n)
3884 def test_multiple_outside_vrf(self):
3885 """ Multiple outside VRF """
3889 self.pg1.unconfig_ip4()
3890 self.pg2.unconfig_ip4()
3891 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3892 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3893 self.pg1.set_table_ip4(vrf_id1)
3894 self.pg2.set_table_ip4(vrf_id2)
3895 self.pg1.config_ip4()
3896 self.pg2.config_ip4()
3897 self.pg1.resolve_arp()
3898 self.pg2.resolve_arp()
3900 self.nat44_add_address(self.nat_addr)
3901 flags = self.config_flags.NAT_IS_INSIDE
3902 self.vapi.nat44_interface_add_del_feature(
3903 sw_if_index=self.pg0.sw_if_index,
3904 flags=flags, is_add=1)
3905 self.vapi.nat44_interface_add_del_feature(
3906 sw_if_index=self.pg1.sw_if_index,
3908 self.vapi.nat44_interface_add_del_feature(
3909 sw_if_index=self.pg2.sw_if_index,
3914 pkts = self.create_stream_in(self.pg0, self.pg1)
3915 self.pg0.add_stream(pkts)
3916 self.pg_enable_capture(self.pg_interfaces)
3918 capture = self.pg1.get_capture(len(pkts))
3919 self.verify_capture_out(capture, self.nat_addr)
3921 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3922 self.pg1.add_stream(pkts)
3923 self.pg_enable_capture(self.pg_interfaces)
3925 capture = self.pg0.get_capture(len(pkts))
3926 self.verify_capture_in(capture, self.pg0)
3928 self.tcp_port_in = 60303
3929 self.udp_port_in = 60304
3930 self.icmp_id_in = 60305
3933 pkts = self.create_stream_in(self.pg0, self.pg2)
3934 self.pg0.add_stream(pkts)
3935 self.pg_enable_capture(self.pg_interfaces)
3937 capture = self.pg2.get_capture(len(pkts))
3938 self.verify_capture_out(capture, self.nat_addr)
3940 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3941 self.pg2.add_stream(pkts)
3942 self.pg_enable_capture(self.pg_interfaces)
3944 capture = self.pg0.get_capture(len(pkts))
3945 self.verify_capture_in(capture, self.pg0)
3948 self.nat44_add_address(self.nat_addr, is_add=0)
3949 self.pg1.unconfig_ip4()
3950 self.pg2.unconfig_ip4()
3951 self.pg1.set_table_ip4(0)
3952 self.pg2.set_table_ip4(0)
3953 self.pg1.config_ip4()
3954 self.pg2.config_ip4()
3955 self.pg1.resolve_arp()
3956 self.pg2.resolve_arp()
3958 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3959 def test_session_timeout(self):
3960 """ NAT44 session timeouts """
3961 self.nat44_add_address(self.nat_addr)
3962 flags = self.config_flags.NAT_IS_INSIDE
3963 self.vapi.nat44_interface_add_del_feature(
3964 sw_if_index=self.pg0.sw_if_index,
3965 flags=flags, is_add=1)
3966 self.vapi.nat44_interface_add_del_feature(
3967 sw_if_index=self.pg1.sw_if_index,
3969 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3970 tcp_transitory=240, icmp=60)
3974 for i in range(0, max_sessions):
3975 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3976 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3977 IP(src=src, dst=self.pg1.remote_ip4) /
3978 UDP(sport=1025, dport=53))
3980 self.pg0.add_stream(pkts)
3981 self.pg_enable_capture(self.pg_interfaces)
3983 self.pg1.get_capture(max_sessions)
3988 for i in range(0, max_sessions):
3989 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3990 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3991 IP(src=src, dst=self.pg1.remote_ip4) /
3992 UDP(sport=1026, dport=53))
3994 self.pg0.add_stream(pkts)
3995 self.pg_enable_capture(self.pg_interfaces)
3997 self.pg1.get_capture(max_sessions)
4000 users = self.vapi.nat44_user_dump()
4002 nsessions = nsessions + user.nsessions
4003 self.assertLess(nsessions, 2 * max_sessions)
4005 def test_mss_clamping(self):
4006 """ TCP MSS clamping """
4007 self.nat44_add_address(self.nat_addr)
4008 flags = self.config_flags.NAT_IS_INSIDE
4009 self.vapi.nat44_interface_add_del_feature(
4010 sw_if_index=self.pg0.sw_if_index,
4011 flags=flags, is_add=1)
4012 self.vapi.nat44_interface_add_del_feature(
4013 sw_if_index=self.pg1.sw_if_index,
4016 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4017 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4018 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4019 flags="S", options=[('MSS', 1400)]))
4021 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4022 self.pg0.add_stream(p)
4023 self.pg_enable_capture(self.pg_interfaces)
4025 capture = self.pg1.get_capture(1)
4026 # Negotiated MSS value greater than configured - changed
4027 self.verify_mss_value(capture[0], 1000)
4029 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4030 self.pg0.add_stream(p)
4031 self.pg_enable_capture(self.pg_interfaces)
4033 capture = self.pg1.get_capture(1)
4034 # MSS clamping disabled - negotiated MSS unchanged
4035 self.verify_mss_value(capture[0], 1400)
4037 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4038 self.pg0.add_stream(p)
4039 self.pg_enable_capture(self.pg_interfaces)
4041 capture = self.pg1.get_capture(1)
4042 # Negotiated MSS value smaller than configured - unchanged
4043 self.verify_mss_value(capture[0], 1400)
4045 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4046 def test_ha_send(self):
4047 """ Send HA session synchronization events (active) """
4048 self.nat44_add_address(self.nat_addr)
4049 flags = self.config_flags.NAT_IS_INSIDE
4050 self.vapi.nat44_interface_add_del_feature(
4051 sw_if_index=self.pg0.sw_if_index,
4052 flags=flags, is_add=1)
4053 self.vapi.nat44_interface_add_del_feature(
4054 sw_if_index=self.pg1.sw_if_index,
4056 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4059 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4060 port=12346, session_refresh_interval=10)
4061 bind_layers(UDP, HANATStateSync, sport=12345)
4064 pkts = self.create_stream_in(self.pg0, self.pg1)
4065 self.pg0.add_stream(pkts)
4066 self.pg_enable_capture(self.pg_interfaces)
4068 capture = self.pg1.get_capture(len(pkts))
4069 self.verify_capture_out(capture)
4070 # active send HA events
4071 self.vapi.nat_ha_flush()
4072 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4073 self.assertEqual(stats[0][0], 3)
4074 capture = self.pg3.get_capture(1)
4076 self.assert_packet_checksums_valid(p)
4080 hanat = p[HANATStateSync]
4082 self.logger.error(ppp("Invalid packet:", p))
4085 self.assertEqual(ip.src, self.pg3.local_ip4)
4086 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4087 self.assertEqual(udp.sport, 12345)
4088 self.assertEqual(udp.dport, 12346)
4089 self.assertEqual(hanat.version, 1)
4090 self.assertEqual(hanat.thread_index, 0)
4091 self.assertEqual(hanat.count, 3)
4092 seq = hanat.sequence_number
4093 for event in hanat.events:
4094 self.assertEqual(event.event_type, 1)
4095 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4096 self.assertEqual(event.out_addr, self.nat_addr)
4097 self.assertEqual(event.fib_index, 0)
4099 # ACK received events
4100 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4101 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4102 UDP(sport=12346, dport=12345) /
4103 HANATStateSync(sequence_number=seq, flags='ACK'))
4104 self.pg3.add_stream(ack)
4106 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4107 self.assertEqual(stats[0][0], 1)
4109 # delete one session
4110 self.pg_enable_capture(self.pg_interfaces)
4111 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
4112 port=self.tcp_port_in,
4113 protocol=IP_PROTOS.tcp,
4114 flags=self.config_flags.NAT_IS_INSIDE)
4115 self.vapi.nat_ha_flush()
4116 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4117 self.assertEqual(stats[0][0], 1)
4118 capture = self.pg3.get_capture(1)
4121 hanat = p[HANATStateSync]
4123 self.logger.error(ppp("Invalid packet:", p))
4126 self.assertGreater(hanat.sequence_number, seq)
4128 # do not send ACK, active retry send HA event again
4129 self.pg_enable_capture(self.pg_interfaces)
4131 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4132 self.assertEqual(stats[0][0], 3)
4133 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4134 self.assertEqual(stats[0][0], 1)
4135 capture = self.pg3.get_capture(3)
4136 for packet in capture:
4137 self.assertEqual(packet, p)
4139 # session counters refresh
4140 pkts = self.create_stream_out(self.pg1)
4141 self.pg1.add_stream(pkts)
4142 self.pg_enable_capture(self.pg_interfaces)
4144 self.pg0.get_capture(2)
4145 self.vapi.nat_ha_flush()
4146 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4147 self.assertEqual(stats[0][0], 2)
4148 capture = self.pg3.get_capture(1)
4150 self.assert_packet_checksums_valid(p)
4154 hanat = p[HANATStateSync]
4156 self.logger.error(ppp("Invalid packet:", p))
4159 self.assertEqual(ip.src, self.pg3.local_ip4)
4160 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4161 self.assertEqual(udp.sport, 12345)
4162 self.assertEqual(udp.dport, 12346)
4163 self.assertEqual(hanat.version, 1)
4164 self.assertEqual(hanat.count, 2)
4165 seq = hanat.sequence_number
4166 for event in hanat.events:
4167 self.assertEqual(event.event_type, 3)
4168 self.assertEqual(event.out_addr, self.nat_addr)
4169 self.assertEqual(event.fib_index, 0)
4170 self.assertEqual(event.total_pkts, 2)
4171 self.assertGreater(event.total_bytes, 0)
4173 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4174 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4175 UDP(sport=12346, dport=12345) /
4176 HANATStateSync(sequence_number=seq, flags='ACK'))
4177 self.pg3.add_stream(ack)
4179 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4180 self.assertEqual(stats[0][0], 2)
4182 def test_ha_recv(self):
4183 """ Receive HA session synchronization events (passive) """
4184 self.nat44_add_address(self.nat_addr)
4185 flags = self.config_flags.NAT_IS_INSIDE
4186 self.vapi.nat44_interface_add_del_feature(
4187 sw_if_index=self.pg0.sw_if_index,
4188 flags=flags, is_add=1)
4189 self.vapi.nat44_interface_add_del_feature(
4190 sw_if_index=self.pg1.sw_if_index,
4192 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4195 bind_layers(UDP, HANATStateSync, sport=12345)
4197 self.tcp_port_out = random.randint(1025, 65535)
4198 self.udp_port_out = random.randint(1025, 65535)
4200 # send HA session add events to failover/passive
4201 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4202 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4203 UDP(sport=12346, dport=12345) /
4204 HANATStateSync(sequence_number=1, events=[
4205 Event(event_type='add', protocol='tcp',
4206 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4207 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4208 eh_addr=self.pg1.remote_ip4,
4209 ehn_addr=self.pg1.remote_ip4,
4210 eh_port=self.tcp_external_port,
4211 ehn_port=self.tcp_external_port, fib_index=0),
4212 Event(event_type='add', protocol='udp',
4213 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4214 in_port=self.udp_port_in, out_port=self.udp_port_out,
4215 eh_addr=self.pg1.remote_ip4,
4216 ehn_addr=self.pg1.remote_ip4,
4217 eh_port=self.udp_external_port,
4218 ehn_port=self.udp_external_port, fib_index=0)]))
4220 self.pg3.add_stream(p)
4221 self.pg_enable_capture(self.pg_interfaces)
4224 capture = self.pg3.get_capture(1)
4227 hanat = p[HANATStateSync]
4229 self.logger.error(ppp("Invalid packet:", p))
4232 self.assertEqual(hanat.sequence_number, 1)
4233 self.assertEqual(hanat.flags, 'ACK')
4234 self.assertEqual(hanat.version, 1)
4235 self.assertEqual(hanat.thread_index, 0)
4236 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4237 self.assertEqual(stats[0][0], 1)
4238 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4239 self.assertEqual(stats[0][0], 2)
4240 users = self.statistics.get_counter('/nat44/total-users')
4241 self.assertEqual(users[0][0], 1)
4242 sessions = self.statistics.get_counter('/nat44/total-sessions')
4243 self.assertEqual(sessions[0][0], 2)
4244 users = self.vapi.nat44_user_dump()
4245 self.assertEqual(len(users), 1)
4246 self.assertEqual(str(users[0].ip_address),
4247 self.pg0.remote_ip4)
4248 # there should be 2 sessions created by HA
4249 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4251 self.assertEqual(len(sessions), 2)
4252 for session in sessions:
4253 self.assertEqual(str(session.inside_ip_address),
4254 self.pg0.remote_ip4)
4255 self.assertEqual(str(session.outside_ip_address),
4257 self.assertIn(session.inside_port,
4258 [self.tcp_port_in, self.udp_port_in])
4259 self.assertIn(session.outside_port,
4260 [self.tcp_port_out, self.udp_port_out])
4261 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4263 # send HA session delete event to failover/passive
4264 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4265 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4266 UDP(sport=12346, dport=12345) /
4267 HANATStateSync(sequence_number=2, events=[
4268 Event(event_type='del', protocol='udp',
4269 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4270 in_port=self.udp_port_in, out_port=self.udp_port_out,
4271 eh_addr=self.pg1.remote_ip4,
4272 ehn_addr=self.pg1.remote_ip4,
4273 eh_port=self.udp_external_port,
4274 ehn_port=self.udp_external_port, fib_index=0)]))
4276 self.pg3.add_stream(p)
4277 self.pg_enable_capture(self.pg_interfaces)
4280 capture = self.pg3.get_capture(1)
4283 hanat = p[HANATStateSync]
4285 self.logger.error(ppp("Invalid packet:", p))
4288 self.assertEqual(hanat.sequence_number, 2)
4289 self.assertEqual(hanat.flags, 'ACK')
4290 self.assertEqual(hanat.version, 1)
4291 users = self.vapi.nat44_user_dump()
4292 self.assertEqual(len(users), 1)
4293 self.assertEqual(str(users[0].ip_address),
4294 self.pg0.remote_ip4)
4295 # now we should have only 1 session, 1 deleted by HA
4296 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4298 self.assertEqual(len(sessions), 1)
4299 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4300 self.assertEqual(stats[0][0], 1)
4302 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4303 self.assertEqual(stats, 2)
4305 # send HA session refresh event to failover/passive
4306 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4307 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4308 UDP(sport=12346, dport=12345) /
4309 HANATStateSync(sequence_number=3, events=[
4310 Event(event_type='refresh', protocol='tcp',
4311 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4312 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4313 eh_addr=self.pg1.remote_ip4,
4314 ehn_addr=self.pg1.remote_ip4,
4315 eh_port=self.tcp_external_port,
4316 ehn_port=self.tcp_external_port, fib_index=0,
4317 total_bytes=1024, total_pkts=2)]))
4318 self.pg3.add_stream(p)
4319 self.pg_enable_capture(self.pg_interfaces)
4322 capture = self.pg3.get_capture(1)
4325 hanat = p[HANATStateSync]
4327 self.logger.error(ppp("Invalid packet:", p))
4330 self.assertEqual(hanat.sequence_number, 3)
4331 self.assertEqual(hanat.flags, 'ACK')
4332 self.assertEqual(hanat.version, 1)
4333 users = self.vapi.nat44_user_dump()
4334 self.assertEqual(len(users), 1)
4335 self.assertEqual(str(users[0].ip_address),
4336 self.pg0.remote_ip4)
4337 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4339 self.assertEqual(len(sessions), 1)
4340 session = sessions[0]
4341 self.assertEqual(session.total_bytes, 1024)
4342 self.assertEqual(session.total_pkts, 2)
4343 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4344 self.assertEqual(stats[0][0], 1)
4346 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4347 self.assertEqual(stats, 3)
4349 # send packet to test session created by HA
4350 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4351 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4352 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4353 self.pg1.add_stream(p)
4354 self.pg_enable_capture(self.pg_interfaces)
4356 capture = self.pg0.get_capture(1)
4362 self.logger.error(ppp("Invalid packet:", p))
4365 self.assertEqual(ip.src, self.pg1.remote_ip4)
4366 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4367 self.assertEqual(tcp.sport, self.tcp_external_port)
4368 self.assertEqual(tcp.dport, self.tcp_port_in)
4371 super(TestNAT44, self).tearDown()
4373 self.vapi.cli("clear logging")
4375 def show_commands_at_teardown(self):
4376 self.logger.info(self.vapi.cli("show nat44 addresses"))
4377 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4378 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4379 self.logger.info(self.vapi.cli("show nat44 interface address"))
4380 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4381 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4382 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4383 self.logger.info(self.vapi.cli("show nat timeouts"))
4385 self.vapi.cli("show nat addr-port-assignment-alg"))
4386 self.logger.info(self.vapi.cli("show nat ha"))
4389 class TestNAT44EndpointDependent(MethodHolder):
4390 """ Endpoint-Dependent mapping and filtering test cases """
4393 def setUpConstants(cls):
4394 super(TestNAT44EndpointDependent, cls).setUpConstants()
4395 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4398 def setUpClass(cls):
4399 super(TestNAT44EndpointDependent, cls).setUpClass()
4400 cls.vapi.cli("set log class nat level debug")
4402 cls.tcp_port_in = 6303
4403 cls.tcp_port_out = 6303
4404 cls.udp_port_in = 6304
4405 cls.udp_port_out = 6304
4406 cls.icmp_id_in = 6305
4407 cls.icmp_id_out = 6305
4408 cls.nat_addr = '10.0.0.3'
4409 cls.ipfix_src_port = 4739
4410 cls.ipfix_domain_id = 1
4411 cls.tcp_external_port = 80
4413 cls.create_pg_interfaces(range(9))
4414 cls.interfaces = list(cls.pg_interfaces[0:3])
4416 for i in cls.interfaces:
4421 cls.pg0.generate_remote_hosts(3)
4422 cls.pg0.configure_ipv4_neighbors()
4426 cls.pg4.generate_remote_hosts(2)
4427 cls.pg4.config_ip4()
4428 cls.vapi.sw_interface_add_del_address(
4429 sw_if_index=cls.pg4.sw_if_index,
4430 prefix="10.0.0.1/24")
4433 cls.pg4.resolve_arp()
4434 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4435 cls.pg4.resolve_arp()
4437 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4438 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4440 cls.pg5._local_ip4 = "10.1.1.1"
4441 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4442 cls.pg5.set_table_ip4(1)
4443 cls.pg5.config_ip4()
4445 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4446 [VppRoutePath("0.0.0.0",
4447 cls.pg5.sw_if_index)],
4452 cls.pg6._local_ip4 = "10.1.2.1"
4453 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4454 cls.pg6.set_table_ip4(1)
4455 cls.pg6.config_ip4()
4458 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4459 [VppRoutePath("0.0.0.0",
4460 cls.pg6.sw_if_index)],
4463 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4464 [VppRoutePath("0.0.0.0",
4469 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4470 [VppRoutePath("0.0.0.0", 0xffffffff,
4474 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4475 [VppRoutePath(cls.pg1.local_ip4,
4476 cls.pg1.sw_if_index)],
4483 cls.pg5.resolve_arp()
4484 cls.pg6.resolve_arp()
4487 cls.pg7.config_ip4()
4488 cls.pg7.resolve_arp()
4489 cls.pg7.generate_remote_hosts(3)
4490 cls.pg7.configure_ipv4_neighbors()
4493 cls.pg8.config_ip4()
4494 cls.pg8.resolve_arp()
4497 super(TestNAT44EndpointDependent, cls).tearDownClass()
4501 def tearDownClass(cls):
4502 super(TestNAT44EndpointDependent, cls).tearDownClass()
4504 def test_frag_in_order(self):
4505 """ NAT44 translate fragments arriving in order """
4506 self.nat44_add_address(self.nat_addr)
4507 flags = self.config_flags.NAT_IS_INSIDE
4508 self.vapi.nat44_interface_add_del_feature(
4509 sw_if_index=self.pg0.sw_if_index,
4510 flags=flags, is_add=1)
4511 self.vapi.nat44_interface_add_del_feature(
4512 sw_if_index=self.pg1.sw_if_index,
4514 self.frag_in_order(proto=IP_PROTOS.tcp)
4515 self.frag_in_order(proto=IP_PROTOS.udp)
4516 self.frag_in_order(proto=IP_PROTOS.icmp)
4518 def test_frag_in_order_dont_translate(self):
4519 """ NAT44 don't translate fragments arriving in order """
4520 flags = self.config_flags.NAT_IS_INSIDE
4521 self.vapi.nat44_interface_add_del_feature(
4522 sw_if_index=self.pg0.sw_if_index,
4523 flags=flags, is_add=1)
4524 self.vapi.nat44_interface_add_del_feature(
4525 sw_if_index=self.pg1.sw_if_index,
4527 self.vapi.nat44_forwarding_enable_disable(enable=True)
4528 reas_cfg1 = self.vapi.nat_get_reass()
4529 # this test was intermittently failing in some cases
4530 # until we temporarily bump the reassembly timeouts
4531 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4533 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4534 # restore the reassembly timeouts
4535 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4536 max_reass=reas_cfg1.ip4_max_reass,
4537 max_frag=reas_cfg1.ip4_max_frag,
4538 drop_frag=reas_cfg1.ip4_drop_frag)
4540 def test_frag_out_of_order(self):
4541 """ NAT44 translate fragments arriving out of order """
4542 self.nat44_add_address(self.nat_addr)
4543 flags = self.config_flags.NAT_IS_INSIDE
4544 self.vapi.nat44_interface_add_del_feature(
4545 sw_if_index=self.pg0.sw_if_index,
4546 flags=flags, is_add=1)
4547 self.vapi.nat44_interface_add_del_feature(
4548 sw_if_index=self.pg1.sw_if_index,
4550 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4551 self.frag_out_of_order(proto=IP_PROTOS.udp)
4552 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4554 def test_frag_out_of_order_dont_translate(self):
4555 """ NAT44 don't translate fragments arriving out of order """
4556 flags = self.config_flags.NAT_IS_INSIDE
4557 self.vapi.nat44_interface_add_del_feature(
4558 sw_if_index=self.pg0.sw_if_index,
4559 flags=flags, is_add=1)
4560 self.vapi.nat44_interface_add_del_feature(
4561 sw_if_index=self.pg1.sw_if_index,
4563 self.vapi.nat44_forwarding_enable_disable(enable=True)
4564 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4566 def test_frag_in_order_in_plus_out(self):
4567 """ in+out interface fragments in order """
4568 flags = self.config_flags.NAT_IS_INSIDE
4569 self.vapi.nat44_interface_add_del_feature(
4570 sw_if_index=self.pg0.sw_if_index,
4572 self.vapi.nat44_interface_add_del_feature(
4573 sw_if_index=self.pg0.sw_if_index,
4574 flags=flags, is_add=1)
4575 self.vapi.nat44_interface_add_del_feature(
4576 sw_if_index=self.pg1.sw_if_index,
4578 self.vapi.nat44_interface_add_del_feature(
4579 sw_if_index=self.pg1.sw_if_index,
4580 flags=flags, is_add=1)
4582 self.server = self.pg1.remote_hosts[0]
4584 self.server_in_addr = self.server.ip4
4585 self.server_out_addr = '11.11.11.11'
4586 self.server_in_port = random.randint(1025, 65535)
4587 self.server_out_port = random.randint(1025, 65535)
4589 self.nat44_add_address(self.server_out_addr)
4591 # add static mappings for server
4592 self.nat44_add_static_mapping(self.server_in_addr,
4593 self.server_out_addr,
4594 self.server_in_port,
4595 self.server_out_port,
4596 proto=IP_PROTOS.tcp)
4597 self.nat44_add_static_mapping(self.server_in_addr,
4598 self.server_out_addr,
4599 self.server_in_port,
4600 self.server_out_port,
4601 proto=IP_PROTOS.udp)
4602 self.nat44_add_static_mapping(self.server_in_addr,
4603 self.server_out_addr,
4604 proto=IP_PROTOS.icmp)
4606 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4609 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4610 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4611 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4613 def test_frag_out_of_order_in_plus_out(self):
4614 """ in+out interface fragments out of order """
4615 flags = self.config_flags.NAT_IS_INSIDE
4616 self.vapi.nat44_interface_add_del_feature(
4617 sw_if_index=self.pg0.sw_if_index,
4619 self.vapi.nat44_interface_add_del_feature(
4620 sw_if_index=self.pg0.sw_if_index,
4621 flags=flags, is_add=1)
4622 self.vapi.nat44_interface_add_del_feature(
4623 sw_if_index=self.pg1.sw_if_index,
4625 self.vapi.nat44_interface_add_del_feature(
4626 sw_if_index=self.pg1.sw_if_index,
4627 flags=flags, is_add=1)
4629 self.server = self.pg1.remote_hosts[0]
4631 self.server_in_addr = self.server.ip4
4632 self.server_out_addr = '11.11.11.11'
4633 self.server_in_port = random.randint(1025, 65535)
4634 self.server_out_port = random.randint(1025, 65535)
4636 self.nat44_add_address(self.server_out_addr)
4638 # add static mappings for server
4639 self.nat44_add_static_mapping(self.server_in_addr,
4640 self.server_out_addr,
4641 self.server_in_port,
4642 self.server_out_port,
4643 proto=IP_PROTOS.tcp)
4644 self.nat44_add_static_mapping(self.server_in_addr,
4645 self.server_out_addr,
4646 self.server_in_port,
4647 self.server_out_port,
4648 proto=IP_PROTOS.udp)
4649 self.nat44_add_static_mapping(self.server_in_addr,
4650 self.server_out_addr,
4651 proto=IP_PROTOS.icmp)
4653 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4656 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4657 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4658 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4660 def test_reass_hairpinning(self):
4661 """ NAT44 fragments hairpinning """
4662 self.server = self.pg0.remote_hosts[1]
4663 self.host_in_port = random.randint(1025, 65535)
4664 self.server_in_port = random.randint(1025, 65535)
4665 self.server_out_port = random.randint(1025, 65535)
4667 self.nat44_add_address(self.nat_addr)
4668 flags = self.config_flags.NAT_IS_INSIDE
4669 self.vapi.nat44_interface_add_del_feature(
4670 sw_if_index=self.pg0.sw_if_index,
4671 flags=flags, is_add=1)
4672 self.vapi.nat44_interface_add_del_feature(
4673 sw_if_index=self.pg1.sw_if_index,
4675 # add static mapping for server
4676 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4677 self.server_in_port,
4678 self.server_out_port,
4679 proto=IP_PROTOS.tcp)
4680 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4681 self.server_in_port,
4682 self.server_out_port,
4683 proto=IP_PROTOS.udp)
4684 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4686 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4687 self.reass_hairpinning(proto=IP_PROTOS.udp)
4688 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4690 def test_dynamic(self):
4691 """ NAT44 dynamic translation test """
4693 self.nat44_add_address(self.nat_addr)
4694 flags = self.config_flags.NAT_IS_INSIDE
4695 self.vapi.nat44_interface_add_del_feature(
4696 sw_if_index=self.pg0.sw_if_index,
4697 flags=flags, is_add=1)
4698 self.vapi.nat44_interface_add_del_feature(
4699 sw_if_index=self.pg1.sw_if_index,
4702 nat_config = self.vapi.nat_show_config()
4703 self.assertEqual(1, nat_config.endpoint_dependent)
4706 tcpn = self.statistics.get_err_counter(
4707 '/err/nat44-ed-in2out-slowpath/TCP packets')
4708 udpn = self.statistics.get_err_counter(
4709 '/err/nat44-ed-in2out-slowpath/UDP packets')
4710 icmpn = self.statistics.get_err_counter(
4711 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4712 totaln = self.statistics.get_err_counter(
4713 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4715 pkts = self.create_stream_in(self.pg0, self.pg1)
4716 self.pg0.add_stream(pkts)
4717 self.pg_enable_capture(self.pg_interfaces)
4719 capture = self.pg1.get_capture(len(pkts))
4720 self.verify_capture_out(capture)
4722 err = self.statistics.get_err_counter(
4723 '/err/nat44-ed-in2out-slowpath/TCP packets')
4724 self.assertEqual(err - tcpn, 2)
4725 err = self.statistics.get_err_counter(
4726 '/err/nat44-ed-in2out-slowpath/UDP packets')
4727 self.assertEqual(err - udpn, 1)
4728 err = self.statistics.get_err_counter(
4729 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4730 self.assertEqual(err - icmpn, 1)
4731 err = self.statistics.get_err_counter(
4732 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4733 self.assertEqual(err - totaln, 4)
4736 tcpn = self.statistics.get_err_counter(
4737 '/err/nat44-ed-out2in/TCP packets')
4738 udpn = self.statistics.get_err_counter(
4739 '/err/nat44-ed-out2in/UDP packets')
4740 icmpn = self.statistics.get_err_counter(
4741 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4742 totaln = self.statistics.get_err_counter(
4743 '/err/nat44-ed-out2in/good out2in packets processed')
4745 pkts = self.create_stream_out(self.pg1)
4746 self.pg1.add_stream(pkts)
4747 self.pg_enable_capture(self.pg_interfaces)
4749 capture = self.pg0.get_capture(len(pkts))
4750 self.verify_capture_in(capture, self.pg0)
4752 err = self.statistics.get_err_counter(
4753 '/err/nat44-ed-out2in/TCP packets')
4754 self.assertEqual(err - tcpn, 2)
4755 err = self.statistics.get_err_counter(
4756 '/err/nat44-ed-out2in/UDP packets')
4757 self.assertEqual(err - udpn, 1)
4758 err = self.statistics.get_err_counter(
4759 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4760 self.assertEqual(err - icmpn, 1)
4761 err = self.statistics.get_err_counter(
4762 '/err/nat44-ed-out2in/good out2in packets processed')
4763 self.assertEqual(err - totaln, 3)
4765 users = self.statistics.get_counter('/nat44/total-users')
4766 self.assertEqual(users[0][0], 1)
4767 sessions = self.statistics.get_counter('/nat44/total-sessions')
4768 self.assertEqual(sessions[0][0], 3)
4770 def test_dynamic_output_feature_vrf(self):
4771 """ NAT44 dynamic translation test: output-feature, VRF"""
4773 # other then default (0)
4776 self.nat44_add_address(self.nat_addr)
4777 flags = self.config_flags.NAT_IS_INSIDE
4778 self.vapi.nat44_interface_add_del_output_feature(
4779 sw_if_index=self.pg7.sw_if_index,
4780 flags=flags, is_add=1)
4781 self.vapi.nat44_interface_add_del_output_feature(
4782 sw_if_index=self.pg8.sw_if_index,
4786 self.vapi.ip_table_add_del(is_add=1,
4787 table={'table_id': new_vrf_id})
4789 self.pg7.unconfig_ip4()
4790 self.pg7.set_table_ip4(new_vrf_id)
4791 self.pg7.config_ip4()
4792 self.pg7.resolve_arp()
4794 self.pg8.unconfig_ip4()
4795 self.pg8.set_table_ip4(new_vrf_id)
4796 self.pg8.config_ip4()
4797 self.pg8.resolve_arp()
4799 nat_config = self.vapi.nat_show_config()
4800 self.assertEqual(1, nat_config.endpoint_dependent)
4803 tcpn = self.statistics.get_err_counter(
4804 '/err/nat44-ed-in2out-slowpath/TCP packets')
4805 udpn = self.statistics.get_err_counter(
4806 '/err/nat44-ed-in2out-slowpath/UDP packets')
4807 icmpn = self.statistics.get_err_counter(
4808 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4809 totaln = self.statistics.get_err_counter(
4810 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4812 pkts = self.create_stream_in(self.pg7, self.pg8)
4813 self.pg7.add_stream(pkts)
4814 self.pg_enable_capture(self.pg_interfaces)
4816 capture = self.pg8.get_capture(len(pkts))
4817 self.verify_capture_out(capture)
4819 err = self.statistics.get_err_counter(
4820 '/err/nat44-ed-in2out-slowpath/TCP packets')
4821 self.assertEqual(err - tcpn, 2)
4822 err = self.statistics.get_err_counter(
4823 '/err/nat44-ed-in2out-slowpath/UDP packets')
4824 self.assertEqual(err - udpn, 1)
4825 err = self.statistics.get_err_counter(
4826 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4827 self.assertEqual(err - icmpn, 1)
4828 err = self.statistics.get_err_counter(
4829 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4830 self.assertEqual(err - totaln, 4)
4833 tcpn = self.statistics.get_err_counter(
4834 '/err/nat44-ed-out2in/TCP packets')
4835 udpn = self.statistics.get_err_counter(
4836 '/err/nat44-ed-out2in/UDP packets')
4837 icmpn = self.statistics.get_err_counter(
4838 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4839 totaln = self.statistics.get_err_counter(
4840 '/err/nat44-ed-out2in/good out2in packets processed')
4842 pkts = self.create_stream_out(self.pg8)
4843 self.pg8.add_stream(pkts)
4844 self.pg_enable_capture(self.pg_interfaces)
4846 capture = self.pg7.get_capture(len(pkts))
4847 self.verify_capture_in(capture, self.pg7)
4849 err = self.statistics.get_err_counter(
4850 '/err/nat44-ed-out2in/TCP packets')
4851 self.assertEqual(err - tcpn, 2)
4852 err = self.statistics.get_err_counter(
4853 '/err/nat44-ed-out2in/UDP packets')
4854 self.assertEqual(err - udpn, 1)
4855 err = self.statistics.get_err_counter(
4856 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4857 self.assertEqual(err - icmpn, 1)
4858 err = self.statistics.get_err_counter(
4859 '/err/nat44-ed-out2in/good out2in packets processed')
4860 self.assertEqual(err - totaln, 3)
4862 users = self.statistics.get_counter('/nat44/total-users')
4863 self.assertEqual(users[0][0], 1)
4864 sessions = self.statistics.get_counter('/nat44/total-sessions')
4865 self.assertEqual(sessions[0][0], 3)
4868 self.pg7.unconfig_ip4()
4869 self.pg7.set_table_ip4(1)
4870 self.pg7.config_ip4()
4871 self.pg7.resolve_arp()
4873 self.pg8.unconfig_ip4()
4874 self.pg8.set_table_ip4(1)
4875 self.pg8.config_ip4()
4876 self.pg8.resolve_arp()
4878 self.vapi.ip_table_add_del(is_add=0,
4879 table={'table_id': new_vrf_id})
4881 def test_forwarding(self):
4882 """ NAT44 forwarding test """
4884 flags = self.config_flags.NAT_IS_INSIDE
4885 self.vapi.nat44_interface_add_del_feature(
4886 sw_if_index=self.pg0.sw_if_index,
4887 flags=flags, is_add=1)
4888 self.vapi.nat44_interface_add_del_feature(
4889 sw_if_index=self.pg1.sw_if_index,
4891 self.vapi.nat44_forwarding_enable_disable(enable=1)
4893 real_ip = self.pg0.remote_ip4
4894 alias_ip = self.nat_addr
4895 flags = self.config_flags.NAT_IS_ADDR_ONLY
4896 self.vapi.nat44_add_del_static_mapping(is_add=1,
4897 local_ip_address=real_ip,
4898 external_ip_address=alias_ip,
4899 external_sw_if_index=0xFFFFFFFF,
4903 # in2out - static mapping match
4905 pkts = self.create_stream_out(self.pg1)
4906 self.pg1.add_stream(pkts)
4907 self.pg_enable_capture(self.pg_interfaces)
4909 capture = self.pg0.get_capture(len(pkts))
4910 self.verify_capture_in(capture, self.pg0)
4912 pkts = self.create_stream_in(self.pg0, self.pg1)
4913 self.pg0.add_stream(pkts)
4914 self.pg_enable_capture(self.pg_interfaces)
4916 capture = self.pg1.get_capture(len(pkts))
4917 self.verify_capture_out(capture, same_port=True)
4919 # in2out - no static mapping match
4921 host0 = self.pg0.remote_hosts[0]
4922 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4924 pkts = self.create_stream_out(self.pg1,
4925 dst_ip=self.pg0.remote_ip4,
4926 use_inside_ports=True)
4927 self.pg1.add_stream(pkts)
4928 self.pg_enable_capture(self.pg_interfaces)
4930 capture = self.pg0.get_capture(len(pkts))
4931 self.verify_capture_in(capture, self.pg0)
4933 pkts = self.create_stream_in(self.pg0, self.pg1)
4934 self.pg0.add_stream(pkts)
4935 self.pg_enable_capture(self.pg_interfaces)
4937 capture = self.pg1.get_capture(len(pkts))
4938 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4941 self.pg0.remote_hosts[0] = host0
4943 user = self.pg0.remote_hosts[1]
4944 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4945 self.assertEqual(len(sessions), 3)
4946 self.assertTrue(sessions[0].flags &
4947 self.config_flags.NAT_IS_EXT_HOST_VALID)
4948 self.vapi.nat44_del_session(
4949 address=sessions[0].inside_ip_address,
4950 port=sessions[0].inside_port,
4951 protocol=sessions[0].protocol,
4952 flags=(self.config_flags.NAT_IS_INSIDE |
4953 self.config_flags.NAT_IS_EXT_HOST_VALID),
4954 ext_host_address=sessions[0].ext_host_address,
4955 ext_host_port=sessions[0].ext_host_port)
4956 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4957 self.assertEqual(len(sessions), 2)
4960 self.vapi.nat44_forwarding_enable_disable(enable=0)
4961 flags = self.config_flags.NAT_IS_ADDR_ONLY
4962 self.vapi.nat44_add_del_static_mapping(
4964 local_ip_address=real_ip,
4965 external_ip_address=alias_ip,
4966 external_sw_if_index=0xFFFFFFFF,
4969 def test_static_lb(self):
4970 """ NAT44 local service load balancing """
4971 external_addr_n = self.nat_addr
4974 server1 = self.pg0.remote_hosts[0]
4975 server2 = self.pg0.remote_hosts[1]
4977 locals = [{'addr': server1.ip4,
4981 {'addr': server2.ip4,
4986 self.nat44_add_address(self.nat_addr)
4987 self.vapi.nat44_add_del_lb_static_mapping(
4989 external_addr=external_addr_n,
4990 external_port=external_port,
4991 protocol=IP_PROTOS.tcp,
4992 local_num=len(locals),
4994 flags = self.config_flags.NAT_IS_INSIDE
4995 self.vapi.nat44_interface_add_del_feature(
4996 sw_if_index=self.pg0.sw_if_index,
4997 flags=flags, is_add=1)
4998 self.vapi.nat44_interface_add_del_feature(
4999 sw_if_index=self.pg1.sw_if_index,
5002 # from client to service
5003 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5004 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5005 TCP(sport=12345, dport=external_port))
5006 self.pg1.add_stream(p)
5007 self.pg_enable_capture(self.pg_interfaces)
5009 capture = self.pg0.get_capture(1)
5015 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5016 if ip.dst == server1.ip4:
5020 self.assertEqual(tcp.dport, local_port)
5021 self.assert_packet_checksums_valid(p)
5023 self.logger.error(ppp("Unexpected or invalid packet:", p))
5026 # from service back to client
5027 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5028 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5029 TCP(sport=local_port, dport=12345))
5030 self.pg0.add_stream(p)
5031 self.pg_enable_capture(self.pg_interfaces)
5033 capture = self.pg1.get_capture(1)
5038 self.assertEqual(ip.src, self.nat_addr)
5039 self.assertEqual(tcp.sport, external_port)
5040 self.assert_packet_checksums_valid(p)
5042 self.logger.error(ppp("Unexpected or invalid packet:", p))
5045 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5046 self.assertEqual(len(sessions), 1)
5047 self.assertTrue(sessions[0].flags &
5048 self.config_flags.NAT_IS_EXT_HOST_VALID)
5049 self.vapi.nat44_del_session(
5050 address=sessions[0].inside_ip_address,
5051 port=sessions[0].inside_port,
5052 protocol=sessions[0].protocol,
5053 flags=(self.config_flags.NAT_IS_INSIDE |
5054 self.config_flags.NAT_IS_EXT_HOST_VALID),
5055 ext_host_address=sessions[0].ext_host_address,
5056 ext_host_port=sessions[0].ext_host_port)
5057 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5058 self.assertEqual(len(sessions), 0)
5060 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5061 def test_static_lb_multi_clients(self):
5062 """ NAT44 local service load balancing - multiple clients"""
5064 external_addr = self.nat_addr
5067 server1 = self.pg0.remote_hosts[0]
5068 server2 = self.pg0.remote_hosts[1]
5069 server3 = self.pg0.remote_hosts[2]
5071 locals = [{'addr': server1.ip4,
5075 {'addr': server2.ip4,
5080 self.nat44_add_address(self.nat_addr)
5081 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5082 external_addr=external_addr,
5083 external_port=external_port,
5084 protocol=IP_PROTOS.tcp,
5085 local_num=len(locals),
5087 flags = self.config_flags.NAT_IS_INSIDE
5088 self.vapi.nat44_interface_add_del_feature(
5089 sw_if_index=self.pg0.sw_if_index,
5090 flags=flags, is_add=1)
5091 self.vapi.nat44_interface_add_del_feature(
5092 sw_if_index=self.pg1.sw_if_index,
5097 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5099 for client in clients:
5100 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5101 IP(src=client, dst=self.nat_addr) /
5102 TCP(sport=12345, dport=external_port))
5104 self.pg1.add_stream(pkts)
5105 self.pg_enable_capture(self.pg_interfaces)
5107 capture = self.pg0.get_capture(len(pkts))
5109 if p[IP].dst == server1.ip4:
5113 self.assertGreater(server1_n, server2_n)
5116 'addr': server3.ip4,
5123 self.vapi.nat44_lb_static_mapping_add_del_local(
5125 external_addr=external_addr,
5126 external_port=external_port,
5128 protocol=IP_PROTOS.tcp)
5132 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5134 for client in clients:
5135 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5136 IP(src=client, dst=self.nat_addr) /
5137 TCP(sport=12346, dport=external_port))
5139 self.assertGreater(len(pkts), 0)
5140 self.pg1.add_stream(pkts)
5141 self.pg_enable_capture(self.pg_interfaces)
5143 capture = self.pg0.get_capture(len(pkts))
5145 if p[IP].dst == server1.ip4:
5147 elif p[IP].dst == server2.ip4:
5151 self.assertGreater(server1_n, 0)
5152 self.assertGreater(server2_n, 0)
5153 self.assertGreater(server3_n, 0)
5156 'addr': server2.ip4,
5162 # remove one back-end
5163 self.vapi.nat44_lb_static_mapping_add_del_local(
5165 external_addr=external_addr,
5166 external_port=external_port,
5168 protocol=IP_PROTOS.tcp)
5172 self.pg1.add_stream(pkts)
5173 self.pg_enable_capture(self.pg_interfaces)
5175 capture = self.pg0.get_capture(len(pkts))
5177 if p[IP].dst == server1.ip4:
5179 elif p[IP].dst == server2.ip4:
5183 self.assertGreater(server1_n, 0)
5184 self.assertEqual(server2_n, 0)
5185 self.assertGreater(server3_n, 0)
5187 def test_static_lb_2(self):
5188 """ NAT44 local service load balancing (asymmetrical rule) """
5189 external_addr = self.nat_addr
5192 server1 = self.pg0.remote_hosts[0]
5193 server2 = self.pg0.remote_hosts[1]
5195 locals = [{'addr': server1.ip4,
5199 {'addr': server2.ip4,
5204 self.vapi.nat44_forwarding_enable_disable(enable=1)
5205 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5206 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5207 external_addr=external_addr,
5208 external_port=external_port,
5209 protocol=IP_PROTOS.tcp,
5210 local_num=len(locals),
5212 flags = self.config_flags.NAT_IS_INSIDE
5213 self.vapi.nat44_interface_add_del_feature(
5214 sw_if_index=self.pg0.sw_if_index,
5215 flags=flags, is_add=1)
5216 self.vapi.nat44_interface_add_del_feature(
5217 sw_if_index=self.pg1.sw_if_index,
5220 # from client to service
5221 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5222 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5223 TCP(sport=12345, dport=external_port))
5224 self.pg1.add_stream(p)
5225 self.pg_enable_capture(self.pg_interfaces)
5227 capture = self.pg0.get_capture(1)
5233 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5234 if ip.dst == server1.ip4:
5238 self.assertEqual(tcp.dport, local_port)
5239 self.assert_packet_checksums_valid(p)
5241 self.logger.error(ppp("Unexpected or invalid packet:", p))
5244 # from service back to client
5245 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5246 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5247 TCP(sport=local_port, dport=12345))
5248 self.pg0.add_stream(p)
5249 self.pg_enable_capture(self.pg_interfaces)
5251 capture = self.pg1.get_capture(1)
5256 self.assertEqual(ip.src, self.nat_addr)
5257 self.assertEqual(tcp.sport, external_port)
5258 self.assert_packet_checksums_valid(p)
5260 self.logger.error(ppp("Unexpected or invalid packet:", p))
5263 # from client to server (no translation)
5264 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5265 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5266 TCP(sport=12346, dport=local_port))
5267 self.pg1.add_stream(p)
5268 self.pg_enable_capture(self.pg_interfaces)
5270 capture = self.pg0.get_capture(1)
5276 self.assertEqual(ip.dst, server1.ip4)
5277 self.assertEqual(tcp.dport, local_port)
5278 self.assert_packet_checksums_valid(p)
5280 self.logger.error(ppp("Unexpected or invalid packet:", p))
5283 # from service back to client (no translation)
5284 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5285 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5286 TCP(sport=local_port, dport=12346))
5287 self.pg0.add_stream(p)
5288 self.pg_enable_capture(self.pg_interfaces)
5290 capture = self.pg1.get_capture(1)
5295 self.assertEqual(ip.src, server1.ip4)
5296 self.assertEqual(tcp.sport, local_port)
5297 self.assert_packet_checksums_valid(p)
5299 self.logger.error(ppp("Unexpected or invalid packet:", p))
5302 def test_lb_affinity(self):
5303 """ NAT44 local service load balancing affinity """
5304 external_addr = self.nat_addr
5307 server1 = self.pg0.remote_hosts[0]
5308 server2 = self.pg0.remote_hosts[1]
5310 locals = [{'addr': server1.ip4,
5314 {'addr': server2.ip4,
5319 self.nat44_add_address(self.nat_addr)
5320 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5321 external_addr=external_addr,
5322 external_port=external_port,
5323 protocol=IP_PROTOS.tcp,
5325 local_num=len(locals),
5327 flags = self.config_flags.NAT_IS_INSIDE
5328 self.vapi.nat44_interface_add_del_feature(
5329 sw_if_index=self.pg0.sw_if_index,
5330 flags=flags, is_add=1)
5331 self.vapi.nat44_interface_add_del_feature(
5332 sw_if_index=self.pg1.sw_if_index,
5335 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5336 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5337 TCP(sport=1025, dport=external_port))
5338 self.pg1.add_stream(p)
5339 self.pg_enable_capture(self.pg_interfaces)
5341 capture = self.pg0.get_capture(1)
5342 backend = capture[0][IP].dst
5344 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5345 self.assertEqual(len(sessions), 1)
5346 self.assertTrue(sessions[0].flags &
5347 self.config_flags.NAT_IS_EXT_HOST_VALID)
5348 self.vapi.nat44_del_session(
5349 address=sessions[0].inside_ip_address,
5350 port=sessions[0].inside_port,
5351 protocol=sessions[0].protocol,
5352 flags=(self.config_flags.NAT_IS_INSIDE |
5353 self.config_flags.NAT_IS_EXT_HOST_VALID),
5354 ext_host_address=sessions[0].ext_host_address,
5355 ext_host_port=sessions[0].ext_host_port)
5358 for port in range(1030, 1100):
5359 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5360 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5361 TCP(sport=port, dport=external_port))
5363 self.pg1.add_stream(pkts)
5364 self.pg_enable_capture(self.pg_interfaces)
5366 capture = self.pg0.get_capture(len(pkts))
5368 self.assertEqual(p[IP].dst, backend)
5370 def test_unknown_proto(self):
5371 """ NAT44 translate packet with unknown protocol """
5372 self.nat44_add_address(self.nat_addr)
5373 flags = self.config_flags.NAT_IS_INSIDE
5374 self.vapi.nat44_interface_add_del_feature(
5375 sw_if_index=self.pg0.sw_if_index,
5376 flags=flags, is_add=1)
5377 self.vapi.nat44_interface_add_del_feature(
5378 sw_if_index=self.pg1.sw_if_index,
5382 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5383 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5384 TCP(sport=self.tcp_port_in, dport=20))
5385 self.pg0.add_stream(p)
5386 self.pg_enable_capture(self.pg_interfaces)
5388 p = self.pg1.get_capture(1)
5390 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5391 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5393 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5394 TCP(sport=1234, dport=1234))
5395 self.pg0.add_stream(p)
5396 self.pg_enable_capture(self.pg_interfaces)
5398 p = self.pg1.get_capture(1)
5401 self.assertEqual(packet[IP].src, self.nat_addr)
5402 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5403 self.assertEqual(packet.haslayer(GRE), 1)
5404 self.assert_packet_checksums_valid(packet)
5406 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5410 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5411 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5413 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5414 TCP(sport=1234, dport=1234))
5415 self.pg1.add_stream(p)
5416 self.pg_enable_capture(self.pg_interfaces)
5418 p = self.pg0.get_capture(1)
5421 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5422 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5423 self.assertEqual(packet.haslayer(GRE), 1)
5424 self.assert_packet_checksums_valid(packet)
5426 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5429 def test_hairpinning_unknown_proto(self):
5430 """ NAT44 translate packet with unknown protocol - hairpinning """
5431 host = self.pg0.remote_hosts[0]
5432 server = self.pg0.remote_hosts[1]
5434 server_out_port = 8765
5435 server_nat_ip = "10.0.0.11"
5437 self.nat44_add_address(self.nat_addr)
5438 flags = self.config_flags.NAT_IS_INSIDE
5439 self.vapi.nat44_interface_add_del_feature(
5440 sw_if_index=self.pg0.sw_if_index,
5441 flags=flags, is_add=1)
5442 self.vapi.nat44_interface_add_del_feature(
5443 sw_if_index=self.pg1.sw_if_index,
5446 # add static mapping for server
5447 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5450 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5451 IP(src=host.ip4, dst=server_nat_ip) /
5452 TCP(sport=host_in_port, dport=server_out_port))
5453 self.pg0.add_stream(p)
5454 self.pg_enable_capture(self.pg_interfaces)
5456 self.pg0.get_capture(1)
5458 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5459 IP(src=host.ip4, dst=server_nat_ip) /
5461 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5462 TCP(sport=1234, dport=1234))
5463 self.pg0.add_stream(p)
5464 self.pg_enable_capture(self.pg_interfaces)
5466 p = self.pg0.get_capture(1)
5469 self.assertEqual(packet[IP].src, self.nat_addr)
5470 self.assertEqual(packet[IP].dst, server.ip4)
5471 self.assertEqual(packet.haslayer(GRE), 1)
5472 self.assert_packet_checksums_valid(packet)
5474 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5478 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5479 IP(src=server.ip4, dst=self.nat_addr) /
5481 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5482 TCP(sport=1234, dport=1234))
5483 self.pg0.add_stream(p)
5484 self.pg_enable_capture(self.pg_interfaces)
5486 p = self.pg0.get_capture(1)
5489 self.assertEqual(packet[IP].src, server_nat_ip)
5490 self.assertEqual(packet[IP].dst, host.ip4)
5491 self.assertEqual(packet.haslayer(GRE), 1)
5492 self.assert_packet_checksums_valid(packet)
5494 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5497 def test_output_feature_and_service(self):
5498 """ NAT44 interface output feature and services """
5499 external_addr = '1.2.3.4'
5503 self.vapi.nat44_forwarding_enable_disable(enable=1)
5504 self.nat44_add_address(self.nat_addr)
5505 flags = self.config_flags.NAT_IS_ADDR_ONLY
5506 self.vapi.nat44_add_del_identity_mapping(
5507 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5508 flags=flags, is_add=1)
5509 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5510 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5511 local_port, external_port,
5512 proto=IP_PROTOS.tcp, flags=flags)
5513 flags = self.config_flags.NAT_IS_INSIDE
5514 self.vapi.nat44_interface_add_del_feature(
5515 sw_if_index=self.pg0.sw_if_index,
5517 self.vapi.nat44_interface_add_del_feature(
5518 sw_if_index=self.pg0.sw_if_index,
5519 flags=flags, is_add=1)
5520 self.vapi.nat44_interface_add_del_output_feature(
5522 sw_if_index=self.pg1.sw_if_index)
5524 # from client to service
5525 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5526 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5527 TCP(sport=12345, dport=external_port))
5528 self.pg1.add_stream(p)
5529 self.pg_enable_capture(self.pg_interfaces)
5531 capture = self.pg0.get_capture(1)
5536 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5537 self.assertEqual(tcp.dport, local_port)
5538 self.assert_packet_checksums_valid(p)
5540 self.logger.error(ppp("Unexpected or invalid packet:", p))
5543 # from service back to client
5544 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5545 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5546 TCP(sport=local_port, dport=12345))
5547 self.pg0.add_stream(p)
5548 self.pg_enable_capture(self.pg_interfaces)
5550 capture = self.pg1.get_capture(1)
5555 self.assertEqual(ip.src, external_addr)
5556 self.assertEqual(tcp.sport, external_port)
5557 self.assert_packet_checksums_valid(p)
5559 self.logger.error(ppp("Unexpected or invalid packet:", p))
5562 # from local network host to external network
5563 pkts = self.create_stream_in(self.pg0, self.pg1)
5564 self.pg0.add_stream(pkts)
5565 self.pg_enable_capture(self.pg_interfaces)
5567 capture = self.pg1.get_capture(len(pkts))
5568 self.verify_capture_out(capture)
5569 pkts = self.create_stream_in(self.pg0, self.pg1)
5570 self.pg0.add_stream(pkts)
5571 self.pg_enable_capture(self.pg_interfaces)
5573 capture = self.pg1.get_capture(len(pkts))
5574 self.verify_capture_out(capture)
5576 # from external network back to local network host
5577 pkts = self.create_stream_out(self.pg1)
5578 self.pg1.add_stream(pkts)
5579 self.pg_enable_capture(self.pg_interfaces)
5581 capture = self.pg0.get_capture(len(pkts))
5582 self.verify_capture_in(capture, self.pg0)
5584 def test_output_feature_and_service2(self):
5585 """ NAT44 interface output feature and service host direct access """
5586 self.vapi.nat44_forwarding_enable_disable(enable=1)
5587 self.nat44_add_address(self.nat_addr)
5588 self.vapi.nat44_interface_add_del_output_feature(
5590 sw_if_index=self.pg1.sw_if_index)
5592 # session initiated from service host - translate
5593 pkts = self.create_stream_in(self.pg0, self.pg1)
5594 self.pg0.add_stream(pkts)
5595 self.pg_enable_capture(self.pg_interfaces)
5597 capture = self.pg1.get_capture(len(pkts))
5598 self.verify_capture_out(capture)
5600 pkts = self.create_stream_out(self.pg1)
5601 self.pg1.add_stream(pkts)
5602 self.pg_enable_capture(self.pg_interfaces)
5604 capture = self.pg0.get_capture(len(pkts))
5605 self.verify_capture_in(capture, self.pg0)
5607 # session initiated from remote host - do not translate
5608 self.tcp_port_in = 60303
5609 self.udp_port_in = 60304
5610 self.icmp_id_in = 60305
5611 pkts = self.create_stream_out(self.pg1,
5612 self.pg0.remote_ip4,
5613 use_inside_ports=True)
5614 self.pg1.add_stream(pkts)
5615 self.pg_enable_capture(self.pg_interfaces)
5617 capture = self.pg0.get_capture(len(pkts))
5618 self.verify_capture_in(capture, self.pg0)
5620 pkts = self.create_stream_in(self.pg0, self.pg1)
5621 self.pg0.add_stream(pkts)
5622 self.pg_enable_capture(self.pg_interfaces)
5624 capture = self.pg1.get_capture(len(pkts))
5625 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5628 def test_output_feature_and_service3(self):
5629 """ NAT44 interface output feature and DST NAT """
5630 external_addr = '1.2.3.4'
5634 self.vapi.nat44_forwarding_enable_disable(enable=1)
5635 self.nat44_add_address(self.nat_addr)
5636 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5637 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5638 local_port, external_port,
5639 proto=IP_PROTOS.tcp, flags=flags)
5640 flags = self.config_flags.NAT_IS_INSIDE
5641 self.vapi.nat44_interface_add_del_feature(
5642 sw_if_index=self.pg0.sw_if_index,
5644 self.vapi.nat44_interface_add_del_feature(
5645 sw_if_index=self.pg0.sw_if_index,
5646 flags=flags, is_add=1)
5647 self.vapi.nat44_interface_add_del_output_feature(
5649 sw_if_index=self.pg1.sw_if_index)
5651 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5652 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5653 TCP(sport=12345, dport=external_port))
5654 self.pg0.add_stream(p)
5655 self.pg_enable_capture(self.pg_interfaces)
5657 capture = self.pg1.get_capture(1)
5662 self.assertEqual(ip.src, self.pg0.remote_ip4)
5663 self.assertEqual(tcp.sport, 12345)
5664 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5665 self.assertEqual(tcp.dport, local_port)
5666 self.assert_packet_checksums_valid(p)
5668 self.logger.error(ppp("Unexpected or invalid packet:", p))
5671 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5672 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5673 TCP(sport=local_port, dport=12345))
5674 self.pg1.add_stream(p)
5675 self.pg_enable_capture(self.pg_interfaces)
5677 capture = self.pg0.get_capture(1)
5682 self.assertEqual(ip.src, external_addr)
5683 self.assertEqual(tcp.sport, external_port)
5684 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5685 self.assertEqual(tcp.dport, 12345)
5686 self.assert_packet_checksums_valid(p)
5688 self.logger.error(ppp("Unexpected or invalid packet:", p))
5691 def test_next_src_nat(self):
5692 """ On way back forward packet to nat44-in2out node. """
5693 twice_nat_addr = '10.0.1.3'
5696 post_twice_nat_port = 0
5698 self.vapi.nat44_forwarding_enable_disable(enable=1)
5699 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5700 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5701 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5702 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5703 local_port, external_port,
5704 proto=IP_PROTOS.tcp, vrf_id=1,
5706 self.vapi.nat44_interface_add_del_feature(
5707 sw_if_index=self.pg6.sw_if_index,
5710 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5711 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5712 TCP(sport=12345, dport=external_port))
5713 self.pg6.add_stream(p)
5714 self.pg_enable_capture(self.pg_interfaces)
5716 capture = self.pg6.get_capture(1)
5721 self.assertEqual(ip.src, twice_nat_addr)
5722 self.assertNotEqual(tcp.sport, 12345)
5723 post_twice_nat_port = tcp.sport
5724 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5725 self.assertEqual(tcp.dport, local_port)
5726 self.assert_packet_checksums_valid(p)
5728 self.logger.error(ppp("Unexpected or invalid packet:", p))
5731 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5732 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5733 TCP(sport=local_port, dport=post_twice_nat_port))
5734 self.pg6.add_stream(p)
5735 self.pg_enable_capture(self.pg_interfaces)
5737 capture = self.pg6.get_capture(1)
5742 self.assertEqual(ip.src, self.pg1.remote_ip4)
5743 self.assertEqual(tcp.sport, external_port)
5744 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5745 self.assertEqual(tcp.dport, 12345)
5746 self.assert_packet_checksums_valid(p)
5748 self.logger.error(ppp("Unexpected or invalid packet:", p))
5751 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5753 twice_nat_addr = '10.0.1.3'
5761 port_in1 = port_in + 1
5762 port_in2 = port_in + 2
5767 server1 = self.pg0.remote_hosts[0]
5768 server2 = self.pg0.remote_hosts[1]
5780 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5783 self.nat44_add_address(self.nat_addr)
5784 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5788 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5790 flags |= self.config_flags.NAT_IS_TWICE_NAT
5793 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5795 proto=IP_PROTOS.tcp,
5798 locals = [{'addr': server1.ip4,
5802 {'addr': server2.ip4,
5806 out_addr = self.nat_addr
5808 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5809 external_addr=out_addr,
5810 external_port=port_out,
5811 protocol=IP_PROTOS.tcp,
5812 local_num=len(locals),
5814 flags = self.config_flags.NAT_IS_INSIDE
5815 self.vapi.nat44_interface_add_del_feature(
5816 sw_if_index=pg0.sw_if_index,
5817 flags=flags, is_add=1)
5818 self.vapi.nat44_interface_add_del_feature(
5819 sw_if_index=pg1.sw_if_index,
5826 assert client_id is not None
5828 client = self.pg0.remote_hosts[0]
5829 elif client_id == 2:
5830 client = self.pg0.remote_hosts[1]
5832 client = pg1.remote_hosts[0]
5833 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5834 IP(src=client.ip4, dst=self.nat_addr) /
5835 TCP(sport=eh_port_out, dport=port_out))
5837 self.pg_enable_capture(self.pg_interfaces)
5839 capture = pg0.get_capture(1)
5845 if ip.dst == server1.ip4:
5851 self.assertEqual(ip.dst, server.ip4)
5853 self.assertIn(tcp.dport, [port_in1, port_in2])
5855 self.assertEqual(tcp.dport, port_in)
5857 self.assertEqual(ip.src, twice_nat_addr)
5858 self.assertNotEqual(tcp.sport, eh_port_out)
5860 self.assertEqual(ip.src, client.ip4)
5861 self.assertEqual(tcp.sport, eh_port_out)
5863 eh_port_in = tcp.sport
5864 saved_port_in = tcp.dport
5865 self.assert_packet_checksums_valid(p)
5867 self.logger.error(ppp("Unexpected or invalid packet:", p))
5870 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5871 IP(src=server.ip4, dst=eh_addr_in) /
5872 TCP(sport=saved_port_in, dport=eh_port_in))
5874 self.pg_enable_capture(self.pg_interfaces)
5876 capture = pg1.get_capture(1)
5881 self.assertEqual(ip.dst, client.ip4)
5882 self.assertEqual(ip.src, self.nat_addr)
5883 self.assertEqual(tcp.dport, eh_port_out)
5884 self.assertEqual(tcp.sport, port_out)
5885 self.assert_packet_checksums_valid(p)
5887 self.logger.error(ppp("Unexpected or invalid packet:", p))
5891 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5892 self.assertEqual(len(sessions), 1)
5893 self.assertTrue(sessions[0].flags &
5894 self.config_flags.NAT_IS_EXT_HOST_VALID)
5895 self.assertTrue(sessions[0].flags &
5896 self.config_flags.NAT_IS_TWICE_NAT)
5897 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5898 self.vapi.nat44_del_session(
5899 address=sessions[0].inside_ip_address,
5900 port=sessions[0].inside_port,
5901 protocol=sessions[0].protocol,
5902 flags=(self.config_flags.NAT_IS_INSIDE |
5903 self.config_flags.NAT_IS_EXT_HOST_VALID),
5904 ext_host_address=sessions[0].ext_host_nat_address,
5905 ext_host_port=sessions[0].ext_host_nat_port)
5906 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5907 self.assertEqual(len(sessions), 0)
5909 def test_twice_nat(self):
5911 self.twice_nat_common()
5913 def test_self_twice_nat_positive(self):
5914 """ Self Twice NAT44 (positive test) """
5915 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5917 def test_self_twice_nat_negative(self):
5918 """ Self Twice NAT44 (negative test) """
5919 self.twice_nat_common(self_twice_nat=True)
5921 def test_twice_nat_lb(self):
5922 """ Twice NAT44 local service load balancing """
5923 self.twice_nat_common(lb=True)
5925 def test_self_twice_nat_lb_positive(self):
5926 """ Self Twice NAT44 local service load balancing (positive test) """
5927 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5930 def test_self_twice_nat_lb_negative(self):
5931 """ Self Twice NAT44 local service load balancing (negative test) """
5932 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5935 def test_twice_nat_interface_addr(self):
5936 """ Acquire twice NAT44 addresses from interface """
5937 flags = self.config_flags.NAT_IS_TWICE_NAT
5938 self.vapi.nat44_add_del_interface_addr(
5940 sw_if_index=self.pg3.sw_if_index,
5943 # no address in NAT pool
5944 adresses = self.vapi.nat44_address_dump()
5945 self.assertEqual(0, len(adresses))
5947 # configure interface address and check NAT address pool
5948 self.pg3.config_ip4()
5949 adresses = self.vapi.nat44_address_dump()
5950 self.assertEqual(1, len(adresses))
5951 self.assertEqual(str(adresses[0].ip_address),
5953 self.assertEqual(adresses[0].flags, flags)
5955 # remove interface address and check NAT address pool
5956 self.pg3.unconfig_ip4()
5957 adresses = self.vapi.nat44_address_dump()
5958 self.assertEqual(0, len(adresses))
5960 def test_tcp_close(self):
5961 """ Close TCP session from inside network - output feature """
5962 self.vapi.nat44_forwarding_enable_disable(enable=1)
5963 self.nat44_add_address(self.pg1.local_ip4)
5964 twice_nat_addr = '10.0.1.3'
5965 service_ip = '192.168.16.150'
5966 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5967 flags = self.config_flags.NAT_IS_INSIDE
5968 self.vapi.nat44_interface_add_del_feature(
5969 sw_if_index=self.pg0.sw_if_index,
5971 self.vapi.nat44_interface_add_del_feature(
5972 sw_if_index=self.pg0.sw_if_index,
5973 flags=flags, is_add=1)
5974 self.vapi.nat44_interface_add_del_output_feature(
5976 sw_if_index=self.pg1.sw_if_index)
5977 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5978 self.config_flags.NAT_IS_TWICE_NAT)
5979 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5983 proto=IP_PROTOS.tcp,
5985 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5986 start_sessnum = len(sessions)
5988 # SYN packet out->in
5989 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5990 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5991 TCP(sport=33898, dport=80, flags="S"))
5992 self.pg1.add_stream(p)
5993 self.pg_enable_capture(self.pg_interfaces)
5995 capture = self.pg0.get_capture(1)
5997 tcp_port = p[TCP].sport
5999 # SYN + ACK packet in->out
6000 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6001 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6002 TCP(sport=80, dport=tcp_port, flags="SA"))
6003 self.pg0.add_stream(p)
6004 self.pg_enable_capture(self.pg_interfaces)
6006 self.pg1.get_capture(1)
6008 # ACK packet out->in
6009 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6010 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6011 TCP(sport=33898, dport=80, flags="A"))
6012 self.pg1.add_stream(p)
6013 self.pg_enable_capture(self.pg_interfaces)
6015 self.pg0.get_capture(1)
6017 # FIN packet in -> out
6018 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6019 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6020 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6021 self.pg0.add_stream(p)
6022 self.pg_enable_capture(self.pg_interfaces)
6024 self.pg1.get_capture(1)
6026 # FIN+ACK packet out -> in
6027 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6028 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6029 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6030 self.pg1.add_stream(p)
6031 self.pg_enable_capture(self.pg_interfaces)
6033 self.pg0.get_capture(1)
6035 # ACK packet in -> out
6036 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6037 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6038 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6039 self.pg0.add_stream(p)
6040 self.pg_enable_capture(self.pg_interfaces)
6042 self.pg1.get_capture(1)
6044 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6046 self.assertEqual(len(sessions) - start_sessnum, 0)
6048 def test_tcp_session_close_in(self):
6049 """ Close TCP session from inside network """
6050 self.tcp_port_out = 10505
6051 self.nat44_add_address(self.nat_addr)
6052 flags = self.config_flags.NAT_IS_TWICE_NAT
6053 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6057 proto=IP_PROTOS.tcp,
6059 flags = self.config_flags.NAT_IS_INSIDE
6060 self.vapi.nat44_interface_add_del_feature(
6061 sw_if_index=self.pg0.sw_if_index,
6062 flags=flags, is_add=1)
6063 self.vapi.nat44_interface_add_del_feature(
6064 sw_if_index=self.pg1.sw_if_index,
6067 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6068 start_sessnum = len(sessions)
6070 self.initiate_tcp_session(self.pg0, self.pg1)
6072 # FIN packet in -> out
6073 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6074 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6075 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6076 flags="FA", seq=100, ack=300))
6077 self.pg0.add_stream(p)
6078 self.pg_enable_capture(self.pg_interfaces)
6080 self.pg1.get_capture(1)
6084 # ACK packet out -> in
6085 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6086 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6087 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6088 flags="A", seq=300, ack=101))
6091 # FIN packet out -> in
6092 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6093 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6094 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6095 flags="FA", seq=300, ack=101))
6098 self.pg1.add_stream(pkts)
6099 self.pg_enable_capture(self.pg_interfaces)
6101 self.pg0.get_capture(2)
6103 # ACK packet in -> out
6104 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6105 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6106 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6107 flags="A", seq=101, ack=301))
6108 self.pg0.add_stream(p)
6109 self.pg_enable_capture(self.pg_interfaces)
6111 self.pg1.get_capture(1)
6113 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6115 self.assertEqual(len(sessions) - start_sessnum, 0)
6117 def test_tcp_session_close_out(self):
6118 """ Close TCP session from outside network """
6119 self.tcp_port_out = 10505
6120 self.nat44_add_address(self.nat_addr)
6121 flags = self.config_flags.NAT_IS_TWICE_NAT
6122 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6126 proto=IP_PROTOS.tcp,
6128 flags = self.config_flags.NAT_IS_INSIDE
6129 self.vapi.nat44_interface_add_del_feature(
6130 sw_if_index=self.pg0.sw_if_index,
6131 flags=flags, is_add=1)
6132 self.vapi.nat44_interface_add_del_feature(
6133 sw_if_index=self.pg1.sw_if_index,
6136 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6137 start_sessnum = len(sessions)
6139 self.initiate_tcp_session(self.pg0, self.pg1)
6141 # FIN packet out -> in
6142 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6143 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6144 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6145 flags="FA", seq=100, ack=300))
6146 self.pg1.add_stream(p)
6147 self.pg_enable_capture(self.pg_interfaces)
6149 self.pg0.get_capture(1)
6151 # FIN+ACK packet in -> out
6152 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6153 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6154 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6155 flags="FA", seq=300, ack=101))
6157 self.pg0.add_stream(p)
6158 self.pg_enable_capture(self.pg_interfaces)
6160 self.pg1.get_capture(1)
6162 # ACK packet out -> in
6163 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6164 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6165 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6166 flags="A", seq=101, ack=301))
6167 self.pg1.add_stream(p)
6168 self.pg_enable_capture(self.pg_interfaces)
6170 self.pg0.get_capture(1)
6172 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6174 self.assertEqual(len(sessions) - start_sessnum, 0)
6176 def test_tcp_session_close_simultaneous(self):
6177 """ Close TCP session from inside network """
6178 self.tcp_port_out = 10505
6179 self.nat44_add_address(self.nat_addr)
6180 flags = self.config_flags.NAT_IS_TWICE_NAT
6181 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6185 proto=IP_PROTOS.tcp,
6187 flags = self.config_flags.NAT_IS_INSIDE
6188 self.vapi.nat44_interface_add_del_feature(
6189 sw_if_index=self.pg0.sw_if_index,
6190 flags=flags, is_add=1)
6191 self.vapi.nat44_interface_add_del_feature(
6192 sw_if_index=self.pg1.sw_if_index,
6195 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6196 start_sessnum = len(sessions)
6198 self.initiate_tcp_session(self.pg0, self.pg1)
6200 # FIN packet in -> out
6201 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6202 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6203 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6204 flags="FA", seq=100, ack=300))
6205 self.pg0.add_stream(p)
6206 self.pg_enable_capture(self.pg_interfaces)
6208 self.pg1.get_capture(1)
6210 # FIN packet out -> in
6211 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6212 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6213 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6214 flags="FA", seq=300, ack=100))
6215 self.pg1.add_stream(p)
6216 self.pg_enable_capture(self.pg_interfaces)
6218 self.pg0.get_capture(1)
6220 # ACK packet in -> out
6221 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6222 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6223 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6224 flags="A", seq=101, ack=301))
6225 self.pg0.add_stream(p)
6226 self.pg_enable_capture(self.pg_interfaces)
6228 self.pg1.get_capture(1)
6230 # ACK packet out -> in
6231 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6232 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6233 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6234 flags="A", seq=301, ack=101))
6235 self.pg1.add_stream(p)
6236 self.pg_enable_capture(self.pg_interfaces)
6238 self.pg0.get_capture(1)
6240 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6242 self.assertEqual(len(sessions) - start_sessnum, 0)
6244 def test_one_armed_nat44_static(self):
6245 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6246 remote_host = self.pg4.remote_hosts[0]
6247 local_host = self.pg4.remote_hosts[1]
6252 self.vapi.nat44_forwarding_enable_disable(enable=1)
6253 self.nat44_add_address(self.nat_addr, twice_nat=1)
6254 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6255 self.config_flags.NAT_IS_TWICE_NAT)
6256 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6257 local_port, external_port,
6258 proto=IP_PROTOS.tcp, flags=flags)
6259 flags = self.config_flags.NAT_IS_INSIDE
6260 self.vapi.nat44_interface_add_del_feature(
6261 sw_if_index=self.pg4.sw_if_index,
6263 self.vapi.nat44_interface_add_del_feature(
6264 sw_if_index=self.pg4.sw_if_index,
6265 flags=flags, is_add=1)
6267 # from client to service
6268 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6269 IP(src=remote_host.ip4, dst=self.nat_addr) /
6270 TCP(sport=12345, dport=external_port))
6271 self.pg4.add_stream(p)
6272 self.pg_enable_capture(self.pg_interfaces)
6274 capture = self.pg4.get_capture(1)
6279 self.assertEqual(ip.dst, local_host.ip4)
6280 self.assertEqual(ip.src, self.nat_addr)
6281 self.assertEqual(tcp.dport, local_port)
6282 self.assertNotEqual(tcp.sport, 12345)
6283 eh_port_in = tcp.sport
6284 self.assert_packet_checksums_valid(p)
6286 self.logger.error(ppp("Unexpected or invalid packet:", p))
6289 # from service back to client
6290 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6291 IP(src=local_host.ip4, dst=self.nat_addr) /
6292 TCP(sport=local_port, dport=eh_port_in))
6293 self.pg4.add_stream(p)
6294 self.pg_enable_capture(self.pg_interfaces)
6296 capture = self.pg4.get_capture(1)
6301 self.assertEqual(ip.src, self.nat_addr)
6302 self.assertEqual(ip.dst, remote_host.ip4)
6303 self.assertEqual(tcp.sport, external_port)
6304 self.assertEqual(tcp.dport, 12345)
6305 self.assert_packet_checksums_valid(p)
6307 self.logger.error(ppp("Unexpected or invalid packet:", p))
6310 def test_static_with_port_out2(self):
6311 """ 1:1 NAPT asymmetrical rule """
6316 self.vapi.nat44_forwarding_enable_disable(enable=1)
6317 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6318 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6319 local_port, external_port,
6320 proto=IP_PROTOS.tcp, flags=flags)
6321 flags = self.config_flags.NAT_IS_INSIDE
6322 self.vapi.nat44_interface_add_del_feature(
6323 sw_if_index=self.pg0.sw_if_index,
6324 flags=flags, is_add=1)
6325 self.vapi.nat44_interface_add_del_feature(
6326 sw_if_index=self.pg1.sw_if_index,
6329 # from client to service
6330 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6331 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6332 TCP(sport=12345, dport=external_port))
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.dst, self.pg0.remote_ip4)
6342 self.assertEqual(tcp.dport, local_port)
6343 self.assert_packet_checksums_valid(p)
6345 self.logger.error(ppp("Unexpected or invalid packet:", p))
6349 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6350 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6351 ICMP(type=11) / capture[0][IP])
6352 self.pg0.add_stream(p)
6353 self.pg_enable_capture(self.pg_interfaces)
6355 capture = self.pg1.get_capture(1)
6358 self.assertEqual(p[IP].src, self.nat_addr)
6360 self.assertEqual(inner.dst, self.nat_addr)
6361 self.assertEqual(inner[TCPerror].dport, external_port)
6363 self.logger.error(ppp("Unexpected or invalid packet:", p))
6366 # from service back to client
6367 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6368 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6369 TCP(sport=local_port, dport=12345))
6370 self.pg0.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6373 capture = self.pg1.get_capture(1)
6378 self.assertEqual(ip.src, self.nat_addr)
6379 self.assertEqual(tcp.sport, external_port)
6380 self.assert_packet_checksums_valid(p)
6382 self.logger.error(ppp("Unexpected or invalid packet:", p))
6386 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6387 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6388 ICMP(type=11) / capture[0][IP])
6389 self.pg1.add_stream(p)
6390 self.pg_enable_capture(self.pg_interfaces)
6392 capture = self.pg0.get_capture(1)
6395 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6397 self.assertEqual(inner.src, self.pg0.remote_ip4)
6398 self.assertEqual(inner[TCPerror].sport, local_port)
6400 self.logger.error(ppp("Unexpected or invalid packet:", p))
6403 # from client to server (no translation)
6404 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6405 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6406 TCP(sport=12346, dport=local_port))
6407 self.pg1.add_stream(p)
6408 self.pg_enable_capture(self.pg_interfaces)
6410 capture = self.pg0.get_capture(1)
6415 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6416 self.assertEqual(tcp.dport, local_port)
6417 self.assert_packet_checksums_valid(p)
6419 self.logger.error(ppp("Unexpected or invalid packet:", p))
6422 # from service back to client (no translation)
6423 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6424 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6425 TCP(sport=local_port, dport=12346))
6426 self.pg0.add_stream(p)
6427 self.pg_enable_capture(self.pg_interfaces)
6429 capture = self.pg1.get_capture(1)
6434 self.assertEqual(ip.src, self.pg0.remote_ip4)
6435 self.assertEqual(tcp.sport, local_port)
6436 self.assert_packet_checksums_valid(p)
6438 self.logger.error(ppp("Unexpected or invalid packet:", p))
6441 def test_output_feature(self):
6442 """ NAT44 interface output feature (in2out postrouting) """
6443 self.vapi.nat44_forwarding_enable_disable(enable=1)
6444 self.nat44_add_address(self.nat_addr)
6445 self.vapi.nat44_interface_add_del_feature(
6446 sw_if_index=self.pg0.sw_if_index,
6448 self.vapi.nat44_interface_add_del_output_feature(
6450 sw_if_index=self.pg1.sw_if_index)
6453 pkts = self.create_stream_in(self.pg0, self.pg1)
6454 self.pg0.add_stream(pkts)
6455 self.pg_enable_capture(self.pg_interfaces)
6457 capture = self.pg1.get_capture(len(pkts))
6458 self.verify_capture_out(capture)
6461 pkts = self.create_stream_out(self.pg1)
6462 self.pg1.add_stream(pkts)
6463 self.pg_enable_capture(self.pg_interfaces)
6465 capture = self.pg0.get_capture(len(pkts))
6466 self.verify_capture_in(capture, self.pg0)
6468 def test_multiple_vrf(self):
6469 """ Multiple VRF setup """
6470 external_addr = '1.2.3.4'
6475 self.vapi.nat44_forwarding_enable_disable(enable=1)
6476 self.nat44_add_address(self.nat_addr)
6477 flags = self.config_flags.NAT_IS_INSIDE
6478 self.vapi.nat44_interface_add_del_feature(
6479 sw_if_index=self.pg0.sw_if_index,
6481 self.vapi.nat44_interface_add_del_feature(
6482 sw_if_index=self.pg0.sw_if_index,
6483 flags=flags, is_add=1)
6484 self.vapi.nat44_interface_add_del_output_feature(
6486 sw_if_index=self.pg1.sw_if_index)
6487 self.vapi.nat44_interface_add_del_feature(
6488 sw_if_index=self.pg5.sw_if_index,
6490 self.vapi.nat44_interface_add_del_feature(
6491 sw_if_index=self.pg5.sw_if_index,
6492 flags=flags, is_add=1)
6493 self.vapi.nat44_interface_add_del_feature(
6494 sw_if_index=self.pg6.sw_if_index,
6496 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6497 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6498 local_port, external_port, vrf_id=1,
6499 proto=IP_PROTOS.tcp, flags=flags)
6500 self.nat44_add_static_mapping(
6501 self.pg0.remote_ip4,
6502 external_sw_if_index=self.pg0.sw_if_index,
6503 local_port=local_port,
6505 external_port=external_port,
6506 proto=IP_PROTOS.tcp,
6510 # from client to service (both VRF1)
6511 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6512 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6513 TCP(sport=12345, dport=external_port))
6514 self.pg6.add_stream(p)
6515 self.pg_enable_capture(self.pg_interfaces)
6517 capture = self.pg5.get_capture(1)
6522 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6523 self.assertEqual(tcp.dport, local_port)
6524 self.assert_packet_checksums_valid(p)
6526 self.logger.error(ppp("Unexpected or invalid packet:", p))
6529 # from service back to client (both VRF1)
6530 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6531 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6532 TCP(sport=local_port, dport=12345))
6533 self.pg5.add_stream(p)
6534 self.pg_enable_capture(self.pg_interfaces)
6536 capture = self.pg6.get_capture(1)
6541 self.assertEqual(ip.src, external_addr)
6542 self.assertEqual(tcp.sport, external_port)
6543 self.assert_packet_checksums_valid(p)
6545 self.logger.error(ppp("Unexpected or invalid packet:", p))
6548 # dynamic NAT from VRF1 to VRF0 (output-feature)
6549 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6550 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6551 TCP(sport=2345, dport=22))
6552 self.pg5.add_stream(p)
6553 self.pg_enable_capture(self.pg_interfaces)
6555 capture = self.pg1.get_capture(1)
6560 self.assertEqual(ip.src, self.nat_addr)
6561 self.assertNotEqual(tcp.sport, 2345)
6562 self.assert_packet_checksums_valid(p)
6565 self.logger.error(ppp("Unexpected or invalid packet:", p))
6568 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6569 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6570 TCP(sport=22, dport=port))
6571 self.pg1.add_stream(p)
6572 self.pg_enable_capture(self.pg_interfaces)
6574 capture = self.pg5.get_capture(1)
6579 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6580 self.assertEqual(tcp.dport, 2345)
6581 self.assert_packet_checksums_valid(p)
6583 self.logger.error(ppp("Unexpected or invalid packet:", p))
6586 # from client VRF1 to service VRF0
6587 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6588 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6589 TCP(sport=12346, dport=external_port))
6590 self.pg6.add_stream(p)
6591 self.pg_enable_capture(self.pg_interfaces)
6593 capture = self.pg0.get_capture(1)
6598 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6599 self.assertEqual(tcp.dport, local_port)
6600 self.assert_packet_checksums_valid(p)
6602 self.logger.error(ppp("Unexpected or invalid packet:", p))
6605 # from service VRF0 back to client VRF1
6606 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6607 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6608 TCP(sport=local_port, dport=12346))
6609 self.pg0.add_stream(p)
6610 self.pg_enable_capture(self.pg_interfaces)
6612 capture = self.pg6.get_capture(1)
6617 self.assertEqual(ip.src, self.pg0.local_ip4)
6618 self.assertEqual(tcp.sport, external_port)
6619 self.assert_packet_checksums_valid(p)
6621 self.logger.error(ppp("Unexpected or invalid packet:", p))
6624 # from client VRF0 to service VRF1
6625 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6626 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6627 TCP(sport=12347, dport=external_port))
6628 self.pg0.add_stream(p)
6629 self.pg_enable_capture(self.pg_interfaces)
6631 capture = self.pg5.get_capture(1)
6636 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6637 self.assertEqual(tcp.dport, local_port)
6638 self.assert_packet_checksums_valid(p)
6640 self.logger.error(ppp("Unexpected or invalid packet:", p))
6643 # from service VRF1 back to client VRF0
6644 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6645 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6646 TCP(sport=local_port, dport=12347))
6647 self.pg5.add_stream(p)
6648 self.pg_enable_capture(self.pg_interfaces)
6650 capture = self.pg0.get_capture(1)
6655 self.assertEqual(ip.src, external_addr)
6656 self.assertEqual(tcp.sport, external_port)
6657 self.assert_packet_checksums_valid(p)
6659 self.logger.error(ppp("Unexpected or invalid packet:", p))
6662 # from client to server (both VRF1, no translation)
6663 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6664 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6665 TCP(sport=12348, dport=local_port))
6666 self.pg6.add_stream(p)
6667 self.pg_enable_capture(self.pg_interfaces)
6669 capture = self.pg5.get_capture(1)
6674 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6675 self.assertEqual(tcp.dport, local_port)
6676 self.assert_packet_checksums_valid(p)
6678 self.logger.error(ppp("Unexpected or invalid packet:", p))
6681 # from server back to client (both VRF1, no translation)
6682 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6683 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6684 TCP(sport=local_port, dport=12348))
6685 self.pg5.add_stream(p)
6686 self.pg_enable_capture(self.pg_interfaces)
6688 capture = self.pg6.get_capture(1)
6693 self.assertEqual(ip.src, self.pg5.remote_ip4)
6694 self.assertEqual(tcp.sport, local_port)
6695 self.assert_packet_checksums_valid(p)
6697 self.logger.error(ppp("Unexpected or invalid packet:", p))
6700 # from client VRF1 to server VRF0 (no translation)
6701 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6702 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6703 TCP(sport=local_port, dport=12349))
6704 self.pg0.add_stream(p)
6705 self.pg_enable_capture(self.pg_interfaces)
6707 capture = self.pg6.get_capture(1)
6712 self.assertEqual(ip.src, self.pg0.remote_ip4)
6713 self.assertEqual(tcp.sport, local_port)
6714 self.assert_packet_checksums_valid(p)
6716 self.logger.error(ppp("Unexpected or invalid packet:", p))
6719 # from server VRF0 back to client VRF1 (no translation)
6720 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6721 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6722 TCP(sport=local_port, dport=12349))
6723 self.pg0.add_stream(p)
6724 self.pg_enable_capture(self.pg_interfaces)
6726 capture = self.pg6.get_capture(1)
6731 self.assertEqual(ip.src, self.pg0.remote_ip4)
6732 self.assertEqual(tcp.sport, local_port)
6733 self.assert_packet_checksums_valid(p)
6735 self.logger.error(ppp("Unexpected or invalid packet:", p))
6738 # from client VRF0 to server VRF1 (no translation)
6739 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6740 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6741 TCP(sport=12344, dport=local_port))
6742 self.pg0.add_stream(p)
6743 self.pg_enable_capture(self.pg_interfaces)
6745 capture = self.pg5.get_capture(1)
6750 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6751 self.assertEqual(tcp.dport, local_port)
6752 self.assert_packet_checksums_valid(p)
6754 self.logger.error(ppp("Unexpected or invalid packet:", p))
6757 # from server VRF1 back to client VRF0 (no translation)
6758 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6759 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6760 TCP(sport=local_port, dport=12344))
6761 self.pg5.add_stream(p)
6762 self.pg_enable_capture(self.pg_interfaces)
6764 capture = self.pg0.get_capture(1)
6769 self.assertEqual(ip.src, self.pg5.remote_ip4)
6770 self.assertEqual(tcp.sport, local_port)
6771 self.assert_packet_checksums_valid(p)
6773 self.logger.error(ppp("Unexpected or invalid packet:", p))
6776 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6777 def test_session_timeout(self):
6778 """ NAT44 session timeouts """
6779 self.nat44_add_address(self.nat_addr)
6780 flags = self.config_flags.NAT_IS_INSIDE
6781 self.vapi.nat44_interface_add_del_feature(
6782 sw_if_index=self.pg0.sw_if_index,
6783 flags=flags, is_add=1)
6784 self.vapi.nat44_interface_add_del_feature(
6785 sw_if_index=self.pg1.sw_if_index,
6787 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6788 tcp_transitory=240, icmp=5)
6792 for i in range(0, max_sessions):
6793 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6794 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6795 IP(src=src, dst=self.pg1.remote_ip4) /
6796 ICMP(id=1025, type='echo-request'))
6798 self.pg0.add_stream(pkts)
6799 self.pg_enable_capture(self.pg_interfaces)
6801 self.pg1.get_capture(max_sessions)
6806 for i in range(0, max_sessions):
6807 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6808 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6809 IP(src=src, dst=self.pg1.remote_ip4) /
6810 ICMP(id=1026, type='echo-request'))
6812 self.pg0.add_stream(pkts)
6813 self.pg_enable_capture(self.pg_interfaces)
6815 self.pg1.get_capture(max_sessions)
6818 users = self.vapi.nat44_user_dump()
6820 nsessions = nsessions + user.nsessions
6821 self.assertLess(nsessions, 2 * max_sessions)
6823 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6824 def test_session_rst_timeout(self):
6825 """ NAT44 session RST timeouts """
6826 self.nat44_add_address(self.nat_addr)
6827 flags = self.config_flags.NAT_IS_INSIDE
6828 self.vapi.nat44_interface_add_del_feature(
6829 sw_if_index=self.pg0.sw_if_index,
6830 flags=flags, is_add=1)
6831 self.vapi.nat44_interface_add_del_feature(
6832 sw_if_index=self.pg1.sw_if_index,
6834 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6835 tcp_transitory=5, icmp=60)
6837 self.initiate_tcp_session(self.pg0, self.pg1)
6838 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6839 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6840 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6842 self.pg0.add_stream(p)
6843 self.pg_enable_capture(self.pg_interfaces)
6845 self.pg1.get_capture(1)
6849 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6850 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6851 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6853 self.pg0.add_stream(p)
6854 self.pg_enable_capture(self.pg_interfaces)
6856 self.pg1.get_capture(1)
6859 users = self.vapi.nat44_user_dump()
6860 self.assertEqual(len(users), 1)
6861 self.assertEqual(str(users[0].ip_address),
6862 self.pg0.remote_ip4)
6863 self.assertEqual(users[0].nsessions, 1)
6865 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6866 def test_session_limit_per_user(self):
6867 """ Maximum sessions per user limit """
6868 self.nat44_add_address(self.nat_addr)
6869 flags = self.config_flags.NAT_IS_INSIDE
6870 self.vapi.nat44_interface_add_del_feature(
6871 sw_if_index=self.pg0.sw_if_index,
6872 flags=flags, is_add=1)
6873 self.vapi.nat44_interface_add_del_feature(
6874 sw_if_index=self.pg1.sw_if_index,
6876 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
6877 src_address=self.pg2.local_ip4,
6879 template_interval=10)
6880 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6881 tcp_transitory=240, icmp=60)
6883 # get maximum number of translations per user
6884 nat44_config = self.vapi.nat_show_config()
6887 for port in range(0, nat44_config.max_translations_per_user):
6888 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6889 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6890 UDP(sport=1025 + port, dport=1025 + port))
6893 self.pg0.add_stream(pkts)
6894 self.pg_enable_capture(self.pg_interfaces)
6896 capture = self.pg1.get_capture(len(pkts))
6898 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6899 src_port=self.ipfix_src_port,
6902 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6903 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6904 UDP(sport=3001, dport=3002))
6905 self.pg0.add_stream(p)
6906 self.pg_enable_capture(self.pg_interfaces)
6908 capture = self.pg1.assert_nothing_captured()
6910 # verify IPFIX logging
6911 self.vapi.ipfix_flush()
6913 capture = self.pg2.get_capture(10)
6914 ipfix = IPFIXDecoder()
6915 # first load template
6917 self.assertTrue(p.haslayer(IPFIX))
6918 if p.haslayer(Template):
6919 ipfix.add_template(p.getlayer(Template))
6920 # verify events in data set
6922 if p.haslayer(Data):
6923 data = ipfix.decode_data_set(p.getlayer(Set))
6924 self.verify_ipfix_max_entries_per_user(
6926 nat44_config.max_translations_per_user,
6927 self.pg0.remote_ip4)
6930 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6931 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6932 UDP(sport=3001, dport=3002))
6933 self.pg0.add_stream(p)
6934 self.pg_enable_capture(self.pg_interfaces)
6936 self.pg1.get_capture(1)
6938 def test_syslog_sess(self):
6939 """ Test syslog session creation and deletion """
6940 self.vapi.syslog_set_filter(
6941 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6942 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6943 self.nat44_add_address(self.nat_addr)
6944 flags = self.config_flags.NAT_IS_INSIDE
6945 self.vapi.nat44_interface_add_del_feature(
6946 sw_if_index=self.pg0.sw_if_index,
6947 flags=flags, is_add=1)
6948 self.vapi.nat44_interface_add_del_feature(
6949 sw_if_index=self.pg1.sw_if_index,
6952 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6953 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6954 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6955 self.pg0.add_stream(p)
6956 self.pg_enable_capture(self.pg_interfaces)
6958 capture = self.pg1.get_capture(1)
6959 self.tcp_port_out = capture[0][TCP].sport
6960 capture = self.pg2.get_capture(1)
6961 self.verify_syslog_sess(capture[0][Raw].load)
6963 self.pg_enable_capture(self.pg_interfaces)
6965 self.nat44_add_address(self.nat_addr, is_add=0)
6966 capture = self.pg2.get_capture(1)
6967 self.verify_syslog_sess(capture[0][Raw].load, False)
6970 super(TestNAT44EndpointDependent, self).tearDown()
6971 if not self.vpp_dead:
6973 self.vapi.cli("clear logging")
6975 def show_commands_at_teardown(self):
6976 self.logger.info(self.vapi.cli("show nat44 addresses"))
6977 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6978 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6979 self.logger.info(self.vapi.cli("show nat44 interface address"))
6980 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6981 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6982 self.logger.info(self.vapi.cli("show nat timeouts"))
6985 class TestNAT44Out2InDPO(MethodHolder):
6986 """ NAT44 Test Cases using out2in DPO """
6989 def setUpConstants(cls):
6990 super(TestNAT44Out2InDPO, cls).setUpConstants()
6991 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6994 def setUpClass(cls):
6995 super(TestNAT44Out2InDPO, cls).setUpClass()
6996 cls.vapi.cli("set log class nat level debug")
6999 cls.tcp_port_in = 6303
7000 cls.tcp_port_out = 6303
7001 cls.udp_port_in = 6304
7002 cls.udp_port_out = 6304
7003 cls.icmp_id_in = 6305
7004 cls.icmp_id_out = 6305
7005 cls.nat_addr = '10.0.0.3'
7006 cls.dst_ip4 = '192.168.70.1'
7008 cls.create_pg_interfaces(range(2))
7011 cls.pg0.config_ip4()
7012 cls.pg0.resolve_arp()
7015 cls.pg1.config_ip6()
7016 cls.pg1.resolve_ndp()
7018 r1 = VppIpRoute(cls, "::", 0,
7019 [VppRoutePath(cls.pg1.remote_ip6,
7020 cls.pg1.sw_if_index)],
7025 super(TestNAT44Out2InDPO, cls).tearDownClass()
7029 def tearDownClass(cls):
7030 super(TestNAT44Out2InDPO, cls).tearDownClass()
7032 def configure_xlat(self):
7033 self.dst_ip6_pfx = '1:2:3::'
7034 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7036 self.dst_ip6_pfx_len = 96
7037 self.src_ip6_pfx = '4:5:6::'
7038 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7040 self.src_ip6_pfx_len = 96
7041 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7042 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7043 '\x00\x00\x00\x00', 0)
7045 @unittest.skip('Temporary disabled')
7046 def test_464xlat_ce(self):
7047 """ Test 464XLAT CE with NAT44 """
7049 nat_config = self.vapi.nat_show_config()
7050 self.assertEqual(1, nat_config.out2in_dpo)
7052 self.configure_xlat()
7054 flags = self.config_flags.NAT_IS_INSIDE
7055 self.vapi.nat44_interface_add_del_feature(
7056 sw_if_index=self.pg0.sw_if_index,
7057 flags=flags, is_add=1)
7058 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7059 last_ip_address=self.nat_addr_n,
7060 vrf_id=0xFFFFFFFF, is_add=1)
7062 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7063 self.dst_ip6_pfx_len)
7064 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7065 self.src_ip6_pfx_len)
7068 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7069 self.pg0.add_stream(pkts)
7070 self.pg_enable_capture(self.pg_interfaces)
7072 capture = self.pg1.get_capture(len(pkts))
7073 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7076 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7078 self.pg1.add_stream(pkts)
7079 self.pg_enable_capture(self.pg_interfaces)
7081 capture = self.pg0.get_capture(len(pkts))
7082 self.verify_capture_in(capture, self.pg0)
7084 self.vapi.nat44_interface_add_del_feature(
7085 sw_if_index=self.pg0.sw_if_index,
7087 self.vapi.nat44_add_del_address_range(
7088 first_ip_address=self.nat_addr_n,
7089 last_ip_address=self.nat_addr_n,
7092 @unittest.skip('Temporary disabled')
7093 def test_464xlat_ce_no_nat(self):
7094 """ Test 464XLAT CE without NAT44 """
7096 self.configure_xlat()
7098 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7099 self.dst_ip6_pfx_len)
7100 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7101 self.src_ip6_pfx_len)
7103 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7104 self.pg0.add_stream(pkts)
7105 self.pg_enable_capture(self.pg_interfaces)
7107 capture = self.pg1.get_capture(len(pkts))
7108 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7109 nat_ip=out_dst_ip6, same_port=True)
7111 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7112 self.pg1.add_stream(pkts)
7113 self.pg_enable_capture(self.pg_interfaces)
7115 capture = self.pg0.get_capture(len(pkts))
7116 self.verify_capture_in(capture, self.pg0)
7119 class TestDeterministicNAT(MethodHolder):
7120 """ Deterministic NAT Test Cases """
7123 def setUpConstants(cls):
7124 super(TestDeterministicNAT, cls).setUpConstants()
7125 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7128 def setUpClass(cls):
7129 super(TestDeterministicNAT, cls).setUpClass()
7130 cls.vapi.cli("set log class nat level debug")
7133 cls.tcp_port_in = 6303
7134 cls.tcp_external_port = 6303
7135 cls.udp_port_in = 6304
7136 cls.udp_external_port = 6304
7137 cls.icmp_id_in = 6305
7138 cls.nat_addr = '10.0.0.3'
7140 cls.create_pg_interfaces(range(3))
7141 cls.interfaces = list(cls.pg_interfaces)
7143 for i in cls.interfaces:
7148 cls.pg0.generate_remote_hosts(2)
7149 cls.pg0.configure_ipv4_neighbors()
7152 super(TestDeterministicNAT, cls).tearDownClass()
7156 def tearDownClass(cls):
7157 super(TestDeterministicNAT, cls).tearDownClass()
7159 def create_stream_in(self, in_if, out_if, ttl=64):
7161 Create packet stream for inside network
7163 :param in_if: Inside interface
7164 :param out_if: Outside interface
7165 :param ttl: TTL of generated packets
7169 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7170 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7171 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7175 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7176 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7177 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7181 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7182 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7183 ICMP(id=self.icmp_id_in, type='echo-request'))
7188 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7190 Create packet stream for outside network
7192 :param out_if: Outside interface
7193 :param dst_ip: Destination IP address (Default use global NAT address)
7194 :param ttl: TTL of generated packets
7197 dst_ip = self.nat_addr
7200 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7201 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7202 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7206 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7207 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7208 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7212 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7213 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7214 ICMP(id=self.icmp_external_id, type='echo-reply'))
7219 def verify_capture_out(self, capture, nat_ip=None):
7221 Verify captured packets on outside network
7223 :param capture: Captured packets
7224 :param nat_ip: Translated IP address (Default use global NAT address)
7225 :param same_port: Source port number is not translated (Default False)
7228 nat_ip = self.nat_addr
7229 for packet in capture:
7231 self.assertEqual(packet[IP].src, nat_ip)
7232 if packet.haslayer(TCP):
7233 self.tcp_port_out = packet[TCP].sport
7234 elif packet.haslayer(UDP):
7235 self.udp_port_out = packet[UDP].sport
7237 self.icmp_external_id = packet[ICMP].id
7239 self.logger.error(ppp("Unexpected or invalid packet "
7240 "(outside network):", packet))
7243 def test_deterministic_mode(self):
7244 """ NAT plugin run deterministic mode """
7245 in_addr = '172.16.255.0'
7246 out_addr = '172.17.255.50'
7247 in_addr_t = '172.16.255.20'
7251 nat_config = self.vapi.nat_show_config()
7252 self.assertEqual(1, nat_config.deterministic)
7254 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7255 in_plen=in_plen, out_addr=out_addr,
7258 rep1 = self.vapi.nat_det_forward(in_addr_t)
7259 self.assertEqual(str(rep1.out_addr), out_addr)
7260 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7262 self.assertEqual(str(rep2.in_addr), in_addr_t)
7264 deterministic_mappings = self.vapi.nat_det_map_dump()
7265 self.assertEqual(len(deterministic_mappings), 1)
7266 dsm = deterministic_mappings[0]
7267 self.assertEqual(in_addr, str(dsm.in_addr))
7268 self.assertEqual(in_plen, dsm.in_plen)
7269 self.assertEqual(out_addr, str(dsm.out_addr))
7270 self.assertEqual(out_plen, dsm.out_plen)
7272 self.clear_nat_det()
7273 deterministic_mappings = self.vapi.nat_det_map_dump()
7274 self.assertEqual(len(deterministic_mappings), 0)
7276 def test_set_timeouts(self):
7277 """ Set deterministic NAT timeouts """
7278 timeouts_before = self.vapi.nat_get_timeouts()
7280 self.vapi.nat_set_timeouts(
7281 udp=timeouts_before.udp + 10,
7282 tcp_established=timeouts_before.tcp_established + 10,
7283 tcp_transitory=timeouts_before.tcp_transitory + 10,
7284 icmp=timeouts_before.icmp + 10)
7286 timeouts_after = self.vapi.nat_get_timeouts()
7288 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7289 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7290 self.assertNotEqual(timeouts_before.tcp_established,
7291 timeouts_after.tcp_established)
7292 self.assertNotEqual(timeouts_before.tcp_transitory,
7293 timeouts_after.tcp_transitory)
7295 def test_det_in(self):
7296 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7298 nat_ip = "10.0.0.10"
7300 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7302 out_addr=socket.inet_aton(nat_ip),
7305 flags = self.config_flags.NAT_IS_INSIDE
7306 self.vapi.nat44_interface_add_del_feature(
7307 sw_if_index=self.pg0.sw_if_index,
7308 flags=flags, is_add=1)
7309 self.vapi.nat44_interface_add_del_feature(
7310 sw_if_index=self.pg1.sw_if_index,
7314 pkts = self.create_stream_in(self.pg0, self.pg1)
7315 self.pg0.add_stream(pkts)
7316 self.pg_enable_capture(self.pg_interfaces)
7318 capture = self.pg1.get_capture(len(pkts))
7319 self.verify_capture_out(capture, nat_ip)
7322 pkts = self.create_stream_out(self.pg1, nat_ip)
7323 self.pg1.add_stream(pkts)
7324 self.pg_enable_capture(self.pg_interfaces)
7326 capture = self.pg0.get_capture(len(pkts))
7327 self.verify_capture_in(capture, self.pg0)
7330 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7331 self.assertEqual(len(sessions), 3)
7335 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7336 self.assertEqual(s.in_port, self.tcp_port_in)
7337 self.assertEqual(s.out_port, self.tcp_port_out)
7338 self.assertEqual(s.ext_port, self.tcp_external_port)
7342 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7343 self.assertEqual(s.in_port, self.udp_port_in)
7344 self.assertEqual(s.out_port, self.udp_port_out)
7345 self.assertEqual(s.ext_port, self.udp_external_port)
7349 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7350 self.assertEqual(s.in_port, self.icmp_id_in)
7351 self.assertEqual(s.out_port, self.icmp_external_id)
7353 def test_multiple_users(self):
7354 """ Deterministic NAT multiple users """
7356 nat_ip = "10.0.0.10"
7358 external_port = 6303
7360 host0 = self.pg0.remote_hosts[0]
7361 host1 = self.pg0.remote_hosts[1]
7363 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7364 out_addr=socket.inet_aton(nat_ip),
7366 flags = self.config_flags.NAT_IS_INSIDE
7367 self.vapi.nat44_interface_add_del_feature(
7368 sw_if_index=self.pg0.sw_if_index,
7369 flags=flags, is_add=1)
7370 self.vapi.nat44_interface_add_del_feature(
7371 sw_if_index=self.pg1.sw_if_index,
7375 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7376 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7377 TCP(sport=port_in, dport=external_port))
7378 self.pg0.add_stream(p)
7379 self.pg_enable_capture(self.pg_interfaces)
7381 capture = self.pg1.get_capture(1)
7386 self.assertEqual(ip.src, nat_ip)
7387 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7388 self.assertEqual(tcp.dport, external_port)
7389 port_out0 = tcp.sport
7391 self.logger.error(ppp("Unexpected or invalid packet:", p))
7395 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7396 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7397 TCP(sport=port_in, dport=external_port))
7398 self.pg0.add_stream(p)
7399 self.pg_enable_capture(self.pg_interfaces)
7401 capture = self.pg1.get_capture(1)
7406 self.assertEqual(ip.src, nat_ip)
7407 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7408 self.assertEqual(tcp.dport, external_port)
7409 port_out1 = tcp.sport
7411 self.logger.error(ppp("Unexpected or invalid packet:", p))
7414 dms = self.vapi.nat_det_map_dump()
7415 self.assertEqual(1, len(dms))
7416 self.assertEqual(2, dms[0].ses_num)
7419 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7420 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7421 TCP(sport=external_port, dport=port_out0))
7422 self.pg1.add_stream(p)
7423 self.pg_enable_capture(self.pg_interfaces)
7425 capture = self.pg0.get_capture(1)
7430 self.assertEqual(ip.src, self.pg1.remote_ip4)
7431 self.assertEqual(ip.dst, host0.ip4)
7432 self.assertEqual(tcp.dport, port_in)
7433 self.assertEqual(tcp.sport, external_port)
7435 self.logger.error(ppp("Unexpected or invalid packet:", p))
7439 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7440 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7441 TCP(sport=external_port, dport=port_out1))
7442 self.pg1.add_stream(p)
7443 self.pg_enable_capture(self.pg_interfaces)
7445 capture = self.pg0.get_capture(1)
7450 self.assertEqual(ip.src, self.pg1.remote_ip4)
7451 self.assertEqual(ip.dst, host1.ip4)
7452 self.assertEqual(tcp.dport, port_in)
7453 self.assertEqual(tcp.sport, external_port)
7455 self.logger.error(ppp("Unexpected or invalid packet", p))
7458 # session close api test
7459 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7461 self.pg1.remote_ip4,
7463 dms = self.vapi.nat_det_map_dump()
7464 self.assertEqual(dms[0].ses_num, 1)
7466 self.vapi.nat_det_close_session_in(host0.ip4,
7468 self.pg1.remote_ip4,
7470 dms = self.vapi.nat_det_map_dump()
7471 self.assertEqual(dms[0].ses_num, 0)
7473 def test_tcp_session_close_detection_in(self):
7474 """ Deterministic NAT TCP session close from inside network """
7475 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7477 out_addr=socket.inet_aton(self.nat_addr),
7479 flags = self.config_flags.NAT_IS_INSIDE
7480 self.vapi.nat44_interface_add_del_feature(
7481 sw_if_index=self.pg0.sw_if_index,
7482 flags=flags, is_add=1)
7483 self.vapi.nat44_interface_add_del_feature(
7484 sw_if_index=self.pg1.sw_if_index,
7487 self.initiate_tcp_session(self.pg0, self.pg1)
7489 # close the session from inside
7491 # FIN packet in -> out
7492 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7493 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7494 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7496 self.pg0.add_stream(p)
7497 self.pg_enable_capture(self.pg_interfaces)
7499 self.pg1.get_capture(1)
7503 # ACK packet out -> in
7504 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7505 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7506 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7510 # FIN packet out -> in
7511 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7512 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7513 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7517 self.pg1.add_stream(pkts)
7518 self.pg_enable_capture(self.pg_interfaces)
7520 self.pg0.get_capture(2)
7522 # ACK packet in -> out
7523 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7524 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7525 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7527 self.pg0.add_stream(p)
7528 self.pg_enable_capture(self.pg_interfaces)
7530 self.pg1.get_capture(1)
7532 # Check if deterministic NAT44 closed the session
7533 dms = self.vapi.nat_det_map_dump()
7534 self.assertEqual(0, dms[0].ses_num)
7536 self.logger.error("TCP session termination failed")
7539 def test_tcp_session_close_detection_out(self):
7540 """ Deterministic NAT TCP session close from outside network """
7541 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7543 out_addr=socket.inet_aton(self.nat_addr),
7545 flags = self.config_flags.NAT_IS_INSIDE
7546 self.vapi.nat44_interface_add_del_feature(
7547 sw_if_index=self.pg0.sw_if_index,
7548 flags=flags, is_add=1)
7549 self.vapi.nat44_interface_add_del_feature(
7550 sw_if_index=self.pg1.sw_if_index,
7553 self.initiate_tcp_session(self.pg0, self.pg1)
7555 # close the session from outside
7557 # FIN packet out -> in
7558 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7559 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7560 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7562 self.pg1.add_stream(p)
7563 self.pg_enable_capture(self.pg_interfaces)
7565 self.pg0.get_capture(1)
7569 # ACK packet in -> out
7570 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7571 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7572 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7576 # ACK packet in -> out
7577 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7578 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7579 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7583 self.pg0.add_stream(pkts)
7584 self.pg_enable_capture(self.pg_interfaces)
7586 self.pg1.get_capture(2)
7588 # ACK packet out -> in
7589 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7590 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7591 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7593 self.pg1.add_stream(p)
7594 self.pg_enable_capture(self.pg_interfaces)
7596 self.pg0.get_capture(1)
7598 # Check if deterministic NAT44 closed the session
7599 dms = self.vapi.nat_det_map_dump()
7600 self.assertEqual(0, dms[0].ses_num)
7602 self.logger.error("TCP session termination failed")
7605 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7606 def test_session_timeout(self):
7607 """ Deterministic NAT session timeouts """
7608 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7610 out_addr=socket.inet_aton(self.nat_addr),
7612 flags = self.config_flags.NAT_IS_INSIDE
7613 self.vapi.nat44_interface_add_del_feature(
7614 sw_if_index=self.pg0.sw_if_index,
7615 flags=flags, is_add=1)
7616 self.vapi.nat44_interface_add_del_feature(
7617 sw_if_index=self.pg1.sw_if_index,
7620 self.initiate_tcp_session(self.pg0, self.pg1)
7621 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7623 pkts = self.create_stream_in(self.pg0, self.pg1)
7624 self.pg0.add_stream(pkts)
7625 self.pg_enable_capture(self.pg_interfaces)
7627 capture = self.pg1.get_capture(len(pkts))
7630 dms = self.vapi.nat_det_map_dump()
7631 self.assertEqual(0, dms[0].ses_num)
7633 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7634 def test_session_limit_per_user(self):
7635 """ Deterministic NAT maximum sessions per user limit """
7636 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7638 out_addr=socket.inet_aton(self.nat_addr),
7640 flags = self.config_flags.NAT_IS_INSIDE
7641 self.vapi.nat44_interface_add_del_feature(
7642 sw_if_index=self.pg0.sw_if_index,
7643 flags=flags, is_add=1)
7644 self.vapi.nat44_interface_add_del_feature(
7645 sw_if_index=self.pg1.sw_if_index,
7647 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7648 src_address=self.pg2.local_ip4,
7650 template_interval=10)
7651 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7655 for port in range(1025, 2025):
7656 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7657 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7658 UDP(sport=port, dport=port))
7661 self.pg0.add_stream(pkts)
7662 self.pg_enable_capture(self.pg_interfaces)
7664 capture = self.pg1.get_capture(len(pkts))
7666 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7667 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7668 UDP(sport=3001, dport=3002))
7669 self.pg0.add_stream(p)
7670 self.pg_enable_capture(self.pg_interfaces)
7672 capture = self.pg1.assert_nothing_captured()
7674 # verify ICMP error packet
7675 capture = self.pg0.get_capture(1)
7677 self.assertTrue(p.haslayer(ICMP))
7679 self.assertEqual(icmp.type, 3)
7680 self.assertEqual(icmp.code, 1)
7681 self.assertTrue(icmp.haslayer(IPerror))
7682 inner_ip = icmp[IPerror]
7683 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7684 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7686 dms = self.vapi.nat_det_map_dump()
7688 self.assertEqual(1000, dms[0].ses_num)
7690 # verify IPFIX logging
7691 self.vapi.ipfix_flush()
7693 capture = self.pg2.get_capture(2)
7694 ipfix = IPFIXDecoder()
7695 # first load template
7697 self.assertTrue(p.haslayer(IPFIX))
7698 if p.haslayer(Template):
7699 ipfix.add_template(p.getlayer(Template))
7700 # verify events in data set
7702 if p.haslayer(Data):
7703 data = ipfix.decode_data_set(p.getlayer(Set))
7704 self.verify_ipfix_max_entries_per_user(data,
7706 self.pg0.remote_ip4)
7708 def clear_nat_det(self):
7710 Clear deterministic NAT configuration.
7712 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7714 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7715 tcp_transitory=240, icmp=60)
7716 deterministic_mappings = self.vapi.nat_det_map_dump()
7717 for dsm in deterministic_mappings:
7718 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7719 in_plen=dsm.in_plen,
7720 out_addr=dsm.out_addr,
7721 out_plen=dsm.out_plen)
7723 interfaces = self.vapi.nat44_interface_dump()
7724 for intf in interfaces:
7725 self.vapi.nat44_interface_add_del_feature(
7726 sw_if_index=intf.sw_if_index,
7730 super(TestDeterministicNAT, self).tearDown()
7731 if not self.vpp_dead:
7732 self.clear_nat_det()
7734 def show_commands_at_teardown(self):
7735 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7736 self.logger.info(self.vapi.cli("show nat timeouts"))
7738 self.vapi.cli("show nat44 deterministic mappings"))
7740 self.vapi.cli("show nat44 deterministic sessions"))
7743 class TestNAT64(MethodHolder):
7744 """ NAT64 Test Cases """
7747 def setUpConstants(cls):
7748 super(TestNAT64, cls).setUpConstants()
7749 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7750 "nat64 st hash buckets 256", "}"])
7753 def setUpClass(cls):
7754 super(TestNAT64, cls).setUpClass()
7757 cls.tcp_port_in = 6303
7758 cls.tcp_port_out = 6303
7759 cls.udp_port_in = 6304
7760 cls.udp_port_out = 6304
7761 cls.icmp_id_in = 6305
7762 cls.icmp_id_out = 6305
7763 cls.tcp_external_port = 80
7764 cls.nat_addr = '10.0.0.3'
7765 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7767 cls.vrf1_nat_addr = '10.0.10.3'
7768 cls.ipfix_src_port = 4739
7769 cls.ipfix_domain_id = 1
7771 cls.create_pg_interfaces(range(6))
7772 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7773 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7774 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7776 cls.vapi.ip_table_add_del(is_add=1,
7777 table={'table_id': cls.vrf1_id,
7780 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7782 cls.pg0.generate_remote_hosts(2)
7784 for i in cls.ip6_interfaces:
7787 i.configure_ipv6_neighbors()
7789 for i in cls.ip4_interfaces:
7795 cls.pg3.config_ip4()
7796 cls.pg3.resolve_arp()
7797 cls.pg3.config_ip6()
7798 cls.pg3.configure_ipv6_neighbors()
7801 cls.pg5.config_ip6()
7804 super(TestNAT64, cls).tearDownClass()
7808 def tearDownClass(cls):
7809 super(TestNAT64, cls).tearDownClass()
7811 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7812 """ NAT64 inside interface handles Neighbor Advertisement """
7814 flags = self.config_flags.NAT_IS_INSIDE
7815 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7816 sw_if_index=self.pg5.sw_if_index)
7819 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7820 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7821 ICMPv6EchoRequest())
7823 self.pg5.add_stream(pkts)
7824 self.pg_enable_capture(self.pg_interfaces)
7827 # Wait for Neighbor Solicitation
7828 capture = self.pg5.get_capture(len(pkts))
7831 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7832 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7833 tgt = packet[ICMPv6ND_NS].tgt
7835 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7838 # Send Neighbor Advertisement
7839 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7840 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7841 ICMPv6ND_NA(tgt=tgt) /
7842 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7844 self.pg5.add_stream(pkts)
7845 self.pg_enable_capture(self.pg_interfaces)
7848 # Try to send ping again
7850 self.pg5.add_stream(pkts)
7851 self.pg_enable_capture(self.pg_interfaces)
7854 # Wait for ping reply
7855 capture = self.pg5.get_capture(len(pkts))
7858 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7859 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7860 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7862 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7865 def test_pool(self):
7866 """ Add/delete address to NAT64 pool """
7867 nat_addr = '1.2.3.4'
7869 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7871 vrf_id=0xFFFFFFFF, is_add=1)
7873 addresses = self.vapi.nat64_pool_addr_dump()
7874 self.assertEqual(len(addresses), 1)
7875 self.assertEqual(str(addresses[0].address), nat_addr)
7877 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7879 vrf_id=0xFFFFFFFF, is_add=0)
7881 addresses = self.vapi.nat64_pool_addr_dump()
7882 self.assertEqual(len(addresses), 0)
7884 def test_interface(self):
7885 """ Enable/disable NAT64 feature on the interface """
7886 flags = self.config_flags.NAT_IS_INSIDE
7887 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7888 sw_if_index=self.pg0.sw_if_index)
7889 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7890 sw_if_index=self.pg1.sw_if_index)
7892 interfaces = self.vapi.nat64_interface_dump()
7893 self.assertEqual(len(interfaces), 2)
7896 for intf in interfaces:
7897 if intf.sw_if_index == self.pg0.sw_if_index:
7898 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7900 elif intf.sw_if_index == self.pg1.sw_if_index:
7901 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7903 self.assertTrue(pg0_found)
7904 self.assertTrue(pg1_found)
7906 features = self.vapi.cli("show interface features pg0")
7907 self.assertIn('nat64-in2out', features)
7908 features = self.vapi.cli("show interface features pg1")
7909 self.assertIn('nat64-out2in', features)
7911 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7912 sw_if_index=self.pg0.sw_if_index)
7913 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7914 sw_if_index=self.pg1.sw_if_index)
7916 interfaces = self.vapi.nat64_interface_dump()
7917 self.assertEqual(len(interfaces), 0)
7919 def test_static_bib(self):
7920 """ Add/delete static BIB entry """
7921 in_addr = '2001:db8:85a3::8a2e:370:7334'
7922 out_addr = '10.1.1.3'
7925 proto = IP_PROTOS.tcp
7927 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7928 i_port=in_port, o_port=out_port,
7929 proto=proto, vrf_id=0, is_add=1)
7930 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7933 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7935 self.assertEqual(str(bibe.i_addr), in_addr)
7936 self.assertEqual(str(bibe.o_addr), out_addr)
7937 self.assertEqual(bibe.i_port, in_port)
7938 self.assertEqual(bibe.o_port, out_port)
7939 self.assertEqual(static_bib_num, 1)
7940 bibs = self.statistics.get_counter('/nat64/total-bibs')
7941 self.assertEqual(bibs[0][0], 1)
7943 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7944 i_port=in_port, o_port=out_port,
7945 proto=proto, vrf_id=0, is_add=0)
7946 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7949 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7951 self.assertEqual(static_bib_num, 0)
7952 bibs = self.statistics.get_counter('/nat64/total-bibs')
7953 self.assertEqual(bibs[0][0], 0)
7955 def test_set_timeouts(self):
7956 """ Set NAT64 timeouts """
7957 # verify default values
7958 timeouts = self.vapi.nat_get_timeouts()
7959 self.assertEqual(timeouts.udp, 300)
7960 self.assertEqual(timeouts.icmp, 60)
7961 self.assertEqual(timeouts.tcp_transitory, 240)
7962 self.assertEqual(timeouts.tcp_established, 7440)
7964 # set and verify custom values
7965 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7966 tcp_transitory=250, icmp=30)
7967 timeouts = self.vapi.nat_get_timeouts()
7968 self.assertEqual(timeouts.udp, 200)
7969 self.assertEqual(timeouts.icmp, 30)
7970 self.assertEqual(timeouts.tcp_transitory, 250)
7971 self.assertEqual(timeouts.tcp_established, 7450)
7973 def test_dynamic(self):
7974 """ NAT64 dynamic translation test """
7975 self.tcp_port_in = 6303
7976 self.udp_port_in = 6304
7977 self.icmp_id_in = 6305
7979 ses_num_start = self.nat64_get_ses_num()
7981 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7982 end_addr=self.nat_addr,
7985 flags = self.config_flags.NAT_IS_INSIDE
7986 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7987 sw_if_index=self.pg0.sw_if_index)
7988 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7989 sw_if_index=self.pg1.sw_if_index)
7992 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7993 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7994 icmpn = self.statistics.get_err_counter(
7995 '/err/nat64-in2out/ICMP packets')
7996 totaln = self.statistics.get_err_counter(
7997 '/err/nat64-in2out/good in2out packets processed')
7999 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8000 self.pg0.add_stream(pkts)
8001 self.pg_enable_capture(self.pg_interfaces)
8003 capture = self.pg1.get_capture(len(pkts))
8004 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8005 dst_ip=self.pg1.remote_ip4)
8007 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8008 self.assertEqual(err - tcpn, 1)
8009 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8010 self.assertEqual(err - udpn, 1)
8011 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8012 self.assertEqual(err - icmpn, 1)
8013 err = self.statistics.get_err_counter(
8014 '/err/nat64-in2out/good in2out packets processed')
8015 self.assertEqual(err - totaln, 3)
8018 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8019 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8020 icmpn = self.statistics.get_err_counter(
8021 '/err/nat64-out2in/ICMP packets')
8022 totaln = self.statistics.get_err_counter(
8023 '/err/nat64-out2in/good out2in packets processed')
8025 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8026 self.pg1.add_stream(pkts)
8027 self.pg_enable_capture(self.pg_interfaces)
8029 capture = self.pg0.get_capture(len(pkts))
8030 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8031 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8033 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8034 self.assertEqual(err - tcpn, 2)
8035 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8036 self.assertEqual(err - udpn, 1)
8037 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8038 self.assertEqual(err - icmpn, 1)
8039 err = self.statistics.get_err_counter(
8040 '/err/nat64-out2in/good out2in packets processed')
8041 self.assertEqual(err - totaln, 4)
8043 bibs = self.statistics.get_counter('/nat64/total-bibs')
8044 self.assertEqual(bibs[0][0], 3)
8045 sessions = self.statistics.get_counter('/nat64/total-sessions')
8046 self.assertEqual(sessions[0][0], 3)
8049 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8050 self.pg0.add_stream(pkts)
8051 self.pg_enable_capture(self.pg_interfaces)
8053 capture = self.pg1.get_capture(len(pkts))
8054 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8055 dst_ip=self.pg1.remote_ip4)
8058 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8059 self.pg1.add_stream(pkts)
8060 self.pg_enable_capture(self.pg_interfaces)
8062 capture = self.pg0.get_capture(len(pkts))
8063 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8065 ses_num_end = self.nat64_get_ses_num()
8067 self.assertEqual(ses_num_end - ses_num_start, 3)
8069 # tenant with specific VRF
8070 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8071 end_addr=self.vrf1_nat_addr,
8072 vrf_id=self.vrf1_id, is_add=1)
8073 flags = self.config_flags.NAT_IS_INSIDE
8074 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8075 sw_if_index=self.pg2.sw_if_index)
8077 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8078 self.pg2.add_stream(pkts)
8079 self.pg_enable_capture(self.pg_interfaces)
8081 capture = self.pg1.get_capture(len(pkts))
8082 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8083 dst_ip=self.pg1.remote_ip4)
8085 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8086 self.pg1.add_stream(pkts)
8087 self.pg_enable_capture(self.pg_interfaces)
8089 capture = self.pg2.get_capture(len(pkts))
8090 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8092 def test_static(self):
8093 """ NAT64 static translation test """
8094 self.tcp_port_in = 60303
8095 self.udp_port_in = 60304
8096 self.icmp_id_in = 60305
8097 self.tcp_port_out = 60303
8098 self.udp_port_out = 60304
8099 self.icmp_id_out = 60305
8101 ses_num_start = self.nat64_get_ses_num()
8103 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8104 end_addr=self.nat_addr,
8107 flags = self.config_flags.NAT_IS_INSIDE
8108 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8109 sw_if_index=self.pg0.sw_if_index)
8110 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8111 sw_if_index=self.pg1.sw_if_index)
8113 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8114 o_addr=self.nat_addr,
8115 i_port=self.tcp_port_in,
8116 o_port=self.tcp_port_out,
8117 proto=IP_PROTOS.tcp, vrf_id=0,
8119 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8120 o_addr=self.nat_addr,
8121 i_port=self.udp_port_in,
8122 o_port=self.udp_port_out,
8123 proto=IP_PROTOS.udp, vrf_id=0,
8125 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8126 o_addr=self.nat_addr,
8127 i_port=self.icmp_id_in,
8128 o_port=self.icmp_id_out,
8129 proto=IP_PROTOS.icmp, vrf_id=0,
8133 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8134 self.pg0.add_stream(pkts)
8135 self.pg_enable_capture(self.pg_interfaces)
8137 capture = self.pg1.get_capture(len(pkts))
8138 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8139 dst_ip=self.pg1.remote_ip4, same_port=True)
8142 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8143 self.pg1.add_stream(pkts)
8144 self.pg_enable_capture(self.pg_interfaces)
8146 capture = self.pg0.get_capture(len(pkts))
8147 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8148 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8150 ses_num_end = self.nat64_get_ses_num()
8152 self.assertEqual(ses_num_end - ses_num_start, 3)
8154 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8155 def test_session_timeout(self):
8156 """ NAT64 session timeout """
8157 self.icmp_id_in = 1234
8158 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8159 end_addr=self.nat_addr,
8162 flags = self.config_flags.NAT_IS_INSIDE
8163 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8164 sw_if_index=self.pg0.sw_if_index)
8165 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8166 sw_if_index=self.pg1.sw_if_index)
8167 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8171 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8172 self.pg0.add_stream(pkts)
8173 self.pg_enable_capture(self.pg_interfaces)
8175 capture = self.pg1.get_capture(len(pkts))
8177 ses_num_before_timeout = self.nat64_get_ses_num()
8181 # ICMP and TCP session after timeout
8182 ses_num_after_timeout = self.nat64_get_ses_num()
8183 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8185 def test_icmp_error(self):
8186 """ NAT64 ICMP Error message translation """
8187 self.tcp_port_in = 6303
8188 self.udp_port_in = 6304
8189 self.icmp_id_in = 6305
8191 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8192 end_addr=self.nat_addr,
8195 flags = self.config_flags.NAT_IS_INSIDE
8196 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8197 sw_if_index=self.pg0.sw_if_index)
8198 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8199 sw_if_index=self.pg1.sw_if_index)
8201 # send some packets to create sessions
8202 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8203 self.pg0.add_stream(pkts)
8204 self.pg_enable_capture(self.pg_interfaces)
8206 capture_ip4 = self.pg1.get_capture(len(pkts))
8207 self.verify_capture_out(capture_ip4,
8208 nat_ip=self.nat_addr,
8209 dst_ip=self.pg1.remote_ip4)
8211 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8212 self.pg1.add_stream(pkts)
8213 self.pg_enable_capture(self.pg_interfaces)
8215 capture_ip6 = self.pg0.get_capture(len(pkts))
8216 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8217 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8218 self.pg0.remote_ip6)
8221 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8222 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8223 ICMPv6DestUnreach(code=1) /
8224 packet[IPv6] for packet in capture_ip6]
8225 self.pg0.add_stream(pkts)
8226 self.pg_enable_capture(self.pg_interfaces)
8228 capture = self.pg1.get_capture(len(pkts))
8229 for packet in capture:
8231 self.assertEqual(packet[IP].src, self.nat_addr)
8232 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8233 self.assertEqual(packet[ICMP].type, 3)
8234 self.assertEqual(packet[ICMP].code, 13)
8235 inner = packet[IPerror]
8236 self.assertEqual(inner.src, self.pg1.remote_ip4)
8237 self.assertEqual(inner.dst, self.nat_addr)
8238 self.assert_packet_checksums_valid(packet)
8239 if inner.haslayer(TCPerror):
8240 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8241 elif inner.haslayer(UDPerror):
8242 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8244 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8246 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8250 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8251 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8252 ICMP(type=3, code=13) /
8253 packet[IP] for packet in capture_ip4]
8254 self.pg1.add_stream(pkts)
8255 self.pg_enable_capture(self.pg_interfaces)
8257 capture = self.pg0.get_capture(len(pkts))
8258 for packet in capture:
8260 self.assertEqual(packet[IPv6].src, ip.src)
8261 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8262 icmp = packet[ICMPv6DestUnreach]
8263 self.assertEqual(icmp.code, 1)
8264 inner = icmp[IPerror6]
8265 self.assertEqual(inner.src, self.pg0.remote_ip6)
8266 self.assertEqual(inner.dst, ip.src)
8267 self.assert_icmpv6_checksum_valid(packet)
8268 if inner.haslayer(TCPerror):
8269 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8270 elif inner.haslayer(UDPerror):
8271 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8273 self.assertEqual(inner[ICMPv6EchoRequest].id,
8276 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8279 def test_hairpinning(self):
8280 """ NAT64 hairpinning """
8282 client = self.pg0.remote_hosts[0]
8283 server = self.pg0.remote_hosts[1]
8284 server_tcp_in_port = 22
8285 server_tcp_out_port = 4022
8286 server_udp_in_port = 23
8287 server_udp_out_port = 4023
8288 client_tcp_in_port = 1234
8289 client_udp_in_port = 1235
8290 client_tcp_out_port = 0
8291 client_udp_out_port = 0
8292 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8293 nat_addr_ip6 = ip.src
8295 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8296 end_addr=self.nat_addr,
8299 flags = self.config_flags.NAT_IS_INSIDE
8300 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8301 sw_if_index=self.pg0.sw_if_index)
8302 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8303 sw_if_index=self.pg1.sw_if_index)
8305 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8306 o_addr=self.nat_addr,
8307 i_port=server_tcp_in_port,
8308 o_port=server_tcp_out_port,
8309 proto=IP_PROTOS.tcp, vrf_id=0,
8311 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8312 o_addr=self.nat_addr,
8313 i_port=server_udp_in_port,
8314 o_port=server_udp_out_port,
8315 proto=IP_PROTOS.udp, vrf_id=0,
8320 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8321 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8322 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8324 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8325 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8326 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8328 self.pg0.add_stream(pkts)
8329 self.pg_enable_capture(self.pg_interfaces)
8331 capture = self.pg0.get_capture(len(pkts))
8332 for packet in capture:
8334 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8335 self.assertEqual(packet[IPv6].dst, server.ip6)
8336 self.assert_packet_checksums_valid(packet)
8337 if packet.haslayer(TCP):
8338 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8339 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8340 client_tcp_out_port = packet[TCP].sport
8342 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8343 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8344 client_udp_out_port = packet[UDP].sport
8346 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8351 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8352 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8353 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8355 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8356 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8357 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8359 self.pg0.add_stream(pkts)
8360 self.pg_enable_capture(self.pg_interfaces)
8362 capture = self.pg0.get_capture(len(pkts))
8363 for packet in capture:
8365 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8366 self.assertEqual(packet[IPv6].dst, client.ip6)
8367 self.assert_packet_checksums_valid(packet)
8368 if packet.haslayer(TCP):
8369 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8370 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8372 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8373 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8375 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8380 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8381 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8382 ICMPv6DestUnreach(code=1) /
8383 packet[IPv6] for packet in capture]
8384 self.pg0.add_stream(pkts)
8385 self.pg_enable_capture(self.pg_interfaces)
8387 capture = self.pg0.get_capture(len(pkts))
8388 for packet in capture:
8390 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8391 self.assertEqual(packet[IPv6].dst, server.ip6)
8392 icmp = packet[ICMPv6DestUnreach]
8393 self.assertEqual(icmp.code, 1)
8394 inner = icmp[IPerror6]
8395 self.assertEqual(inner.src, server.ip6)
8396 self.assertEqual(inner.dst, nat_addr_ip6)
8397 self.assert_packet_checksums_valid(packet)
8398 if inner.haslayer(TCPerror):
8399 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8400 self.assertEqual(inner[TCPerror].dport,
8401 client_tcp_out_port)
8403 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8404 self.assertEqual(inner[UDPerror].dport,
8405 client_udp_out_port)
8407 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8410 def test_prefix(self):
8411 """ NAT64 Network-Specific Prefix """
8413 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8414 end_addr=self.nat_addr,
8417 flags = self.config_flags.NAT_IS_INSIDE
8418 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8419 sw_if_index=self.pg0.sw_if_index)
8420 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8421 sw_if_index=self.pg1.sw_if_index)
8422 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8423 end_addr=self.vrf1_nat_addr,
8424 vrf_id=self.vrf1_id, is_add=1)
8425 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8426 sw_if_index=self.pg2.sw_if_index)
8429 global_pref64 = "2001:db8::"
8430 global_pref64_len = 32
8431 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8432 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8435 prefix = self.vapi.nat64_prefix_dump()
8436 self.assertEqual(len(prefix), 1)
8437 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8438 self.assertEqual(prefix[0].vrf_id, 0)
8440 # Add tenant specific prefix
8441 vrf1_pref64 = "2001:db8:122:300::"
8442 vrf1_pref64_len = 56
8443 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8444 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8445 vrf_id=self.vrf1_id, is_add=1)
8447 prefix = self.vapi.nat64_prefix_dump()
8448 self.assertEqual(len(prefix), 2)
8451 pkts = self.create_stream_in_ip6(self.pg0,
8454 plen=global_pref64_len)
8455 self.pg0.add_stream(pkts)
8456 self.pg_enable_capture(self.pg_interfaces)
8458 capture = self.pg1.get_capture(len(pkts))
8459 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8460 dst_ip=self.pg1.remote_ip4)
8462 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8463 self.pg1.add_stream(pkts)
8464 self.pg_enable_capture(self.pg_interfaces)
8466 capture = self.pg0.get_capture(len(pkts))
8467 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8470 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8472 # Tenant specific prefix
8473 pkts = self.create_stream_in_ip6(self.pg2,
8476 plen=vrf1_pref64_len)
8477 self.pg2.add_stream(pkts)
8478 self.pg_enable_capture(self.pg_interfaces)
8480 capture = self.pg1.get_capture(len(pkts))
8481 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8482 dst_ip=self.pg1.remote_ip4)
8484 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8485 self.pg1.add_stream(pkts)
8486 self.pg_enable_capture(self.pg_interfaces)
8488 capture = self.pg2.get_capture(len(pkts))
8489 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8492 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8494 def test_unknown_proto(self):
8495 """ NAT64 translate packet with unknown protocol """
8497 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8498 end_addr=self.nat_addr,
8501 flags = self.config_flags.NAT_IS_INSIDE
8502 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8503 sw_if_index=self.pg0.sw_if_index)
8504 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8505 sw_if_index=self.pg1.sw_if_index)
8506 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8509 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8510 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8511 TCP(sport=self.tcp_port_in, dport=20))
8512 self.pg0.add_stream(p)
8513 self.pg_enable_capture(self.pg_interfaces)
8515 p = self.pg1.get_capture(1)
8517 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8518 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8520 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8521 TCP(sport=1234, dport=1234))
8522 self.pg0.add_stream(p)
8523 self.pg_enable_capture(self.pg_interfaces)
8525 p = self.pg1.get_capture(1)
8528 self.assertEqual(packet[IP].src, self.nat_addr)
8529 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8530 self.assertEqual(packet.haslayer(GRE), 1)
8531 self.assert_packet_checksums_valid(packet)
8533 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8537 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8538 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8540 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8541 TCP(sport=1234, dport=1234))
8542 self.pg1.add_stream(p)
8543 self.pg_enable_capture(self.pg_interfaces)
8545 p = self.pg0.get_capture(1)
8548 self.assertEqual(packet[IPv6].src, remote_ip6)
8549 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8550 self.assertEqual(packet[IPv6].nh, 47)
8552 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8555 def test_hairpinning_unknown_proto(self):
8556 """ NAT64 translate packet with unknown protocol - hairpinning """
8558 client = self.pg0.remote_hosts[0]
8559 server = self.pg0.remote_hosts[1]
8560 server_tcp_in_port = 22
8561 server_tcp_out_port = 4022
8562 client_tcp_in_port = 1234
8563 client_tcp_out_port = 1235
8564 server_nat_ip = "10.0.0.100"
8565 client_nat_ip = "10.0.0.110"
8566 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8567 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8569 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8570 end_addr=client_nat_ip,
8573 flags = self.config_flags.NAT_IS_INSIDE
8574 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8575 sw_if_index=self.pg0.sw_if_index)
8576 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8577 sw_if_index=self.pg1.sw_if_index)
8579 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8580 o_addr=server_nat_ip,
8581 i_port=server_tcp_in_port,
8582 o_port=server_tcp_out_port,
8583 proto=IP_PROTOS.tcp, vrf_id=0,
8586 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8587 o_addr=server_nat_ip, i_port=0,
8589 proto=IP_PROTOS.gre, vrf_id=0,
8592 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8593 o_addr=client_nat_ip,
8594 i_port=client_tcp_in_port,
8595 o_port=client_tcp_out_port,
8596 proto=IP_PROTOS.tcp, vrf_id=0,
8600 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8601 IPv6(src=client.ip6, dst=server_nat_ip6) /
8602 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8603 self.pg0.add_stream(p)
8604 self.pg_enable_capture(self.pg_interfaces)
8606 p = self.pg0.get_capture(1)
8608 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8609 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8611 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8612 TCP(sport=1234, dport=1234))
8613 self.pg0.add_stream(p)
8614 self.pg_enable_capture(self.pg_interfaces)
8616 p = self.pg0.get_capture(1)
8619 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8620 self.assertEqual(packet[IPv6].dst, server.ip6)
8621 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8623 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8627 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8628 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8630 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8631 TCP(sport=1234, dport=1234))
8632 self.pg0.add_stream(p)
8633 self.pg_enable_capture(self.pg_interfaces)
8635 p = self.pg0.get_capture(1)
8638 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8639 self.assertEqual(packet[IPv6].dst, client.ip6)
8640 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8642 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8645 def test_one_armed_nat64(self):
8646 """ One armed NAT64 """
8648 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8652 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8653 end_addr=self.nat_addr,
8656 flags = self.config_flags.NAT_IS_INSIDE
8657 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8658 sw_if_index=self.pg3.sw_if_index)
8659 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8660 sw_if_index=self.pg3.sw_if_index)
8663 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8664 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8665 TCP(sport=12345, dport=80))
8666 self.pg3.add_stream(p)
8667 self.pg_enable_capture(self.pg_interfaces)
8669 capture = self.pg3.get_capture(1)
8674 self.assertEqual(ip.src, self.nat_addr)
8675 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8676 self.assertNotEqual(tcp.sport, 12345)
8677 external_port = tcp.sport
8678 self.assertEqual(tcp.dport, 80)
8679 self.assert_packet_checksums_valid(p)
8681 self.logger.error(ppp("Unexpected or invalid packet:", p))
8685 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8686 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8687 TCP(sport=80, dport=external_port))
8688 self.pg3.add_stream(p)
8689 self.pg_enable_capture(self.pg_interfaces)
8691 capture = self.pg3.get_capture(1)
8696 self.assertEqual(ip.src, remote_host_ip6)
8697 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8698 self.assertEqual(tcp.sport, 80)
8699 self.assertEqual(tcp.dport, 12345)
8700 self.assert_packet_checksums_valid(p)
8702 self.logger.error(ppp("Unexpected or invalid packet:", p))
8705 def test_frag_in_order(self):
8706 """ NAT64 translate fragments arriving in order """
8707 self.tcp_port_in = random.randint(1025, 65535)
8709 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8710 end_addr=self.nat_addr,
8713 flags = self.config_flags.NAT_IS_INSIDE
8714 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8715 sw_if_index=self.pg0.sw_if_index)
8716 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8717 sw_if_index=self.pg1.sw_if_index)
8719 reass = self.vapi.nat_reass_dump()
8720 reass_n_start = len(reass)
8724 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8725 self.tcp_port_in, 20, data)
8726 self.pg0.add_stream(pkts)
8727 self.pg_enable_capture(self.pg_interfaces)
8729 frags = self.pg1.get_capture(len(pkts))
8730 p = self.reass_frags_and_verify(frags,
8732 self.pg1.remote_ip4)
8733 self.assertEqual(p[TCP].dport, 20)
8734 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8735 self.tcp_port_out = p[TCP].sport
8736 self.assertEqual(data, p[Raw].load)
8739 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8740 pkts = self.create_stream_frag(self.pg1,
8745 self.pg1.add_stream(pkts)
8746 self.pg_enable_capture(self.pg_interfaces)
8748 frags = self.pg0.get_capture(len(pkts))
8749 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8750 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8751 self.assertEqual(p[TCP].sport, 20)
8752 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8753 self.assertEqual(data, p[Raw].load)
8755 reass = self.vapi.nat_reass_dump()
8756 reass_n_end = len(reass)
8758 self.assertEqual(reass_n_end - reass_n_start, 2)
8760 def test_reass_hairpinning(self):
8761 """ NAT64 fragments hairpinning """
8763 server = self.pg0.remote_hosts[1]
8764 server_in_port = random.randint(1025, 65535)
8765 server_out_port = random.randint(1025, 65535)
8766 client_in_port = random.randint(1025, 65535)
8767 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8768 nat_addr_ip6 = ip.src
8770 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8771 end_addr=self.nat_addr,
8774 flags = self.config_flags.NAT_IS_INSIDE
8775 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8776 sw_if_index=self.pg0.sw_if_index)
8777 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8778 sw_if_index=self.pg1.sw_if_index)
8780 # add static BIB entry for server
8781 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8782 o_addr=self.nat_addr,
8783 i_port=server_in_port,
8784 o_port=server_out_port,
8785 proto=IP_PROTOS.tcp, vrf_id=0,
8788 # send packet from host to server
8789 pkts = self.create_stream_frag_ip6(self.pg0,
8794 self.pg0.add_stream(pkts)
8795 self.pg_enable_capture(self.pg_interfaces)
8797 frags = self.pg0.get_capture(len(pkts))
8798 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8799 self.assertNotEqual(p[TCP].sport, client_in_port)
8800 self.assertEqual(p[TCP].dport, server_in_port)
8801 self.assertEqual(data, p[Raw].load)
8803 def test_frag_out_of_order(self):
8804 """ NAT64 translate fragments arriving out of order """
8805 self.tcp_port_in = random.randint(1025, 65535)
8807 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8808 end_addr=self.nat_addr,
8811 flags = self.config_flags.NAT_IS_INSIDE
8812 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8813 sw_if_index=self.pg0.sw_if_index)
8814 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8815 sw_if_index=self.pg1.sw_if_index)
8819 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8820 self.tcp_port_in, 20, data)
8822 self.pg0.add_stream(pkts)
8823 self.pg_enable_capture(self.pg_interfaces)
8825 frags = self.pg1.get_capture(len(pkts))
8826 p = self.reass_frags_and_verify(frags,
8828 self.pg1.remote_ip4)
8829 self.assertEqual(p[TCP].dport, 20)
8830 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8831 self.tcp_port_out = p[TCP].sport
8832 self.assertEqual(data, p[Raw].load)
8835 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8836 pkts = self.create_stream_frag(self.pg1,
8842 self.pg1.add_stream(pkts)
8843 self.pg_enable_capture(self.pg_interfaces)
8845 frags = self.pg0.get_capture(len(pkts))
8846 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8847 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8848 self.assertEqual(p[TCP].sport, 20)
8849 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8850 self.assertEqual(data, p[Raw].load)
8852 def test_interface_addr(self):
8853 """ Acquire NAT64 pool addresses from interface """
8854 self.vapi.nat64_add_del_interface_addr(
8856 sw_if_index=self.pg4.sw_if_index)
8858 # no address in NAT64 pool
8859 addresses = self.vapi.nat44_address_dump()
8860 self.assertEqual(0, len(addresses))
8862 # configure interface address and check NAT64 address pool
8863 self.pg4.config_ip4()
8864 addresses = self.vapi.nat64_pool_addr_dump()
8865 self.assertEqual(len(addresses), 1)
8867 self.assertEqual(str(addresses[0].address),
8870 # remove interface address and check NAT64 address pool
8871 self.pg4.unconfig_ip4()
8872 addresses = self.vapi.nat64_pool_addr_dump()
8873 self.assertEqual(0, len(addresses))
8875 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8876 def test_ipfix_max_bibs_sessions(self):
8877 """ IPFIX logging maximum session and BIB entries exceeded """
8880 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8884 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8885 end_addr=self.nat_addr,
8888 flags = self.config_flags.NAT_IS_INSIDE
8889 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8890 sw_if_index=self.pg0.sw_if_index)
8891 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8892 sw_if_index=self.pg1.sw_if_index)
8896 for i in range(0, max_bibs):
8897 src = "fd01:aa::%x" % (i)
8898 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8899 IPv6(src=src, dst=remote_host_ip6) /
8900 TCP(sport=12345, dport=80))
8902 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8903 IPv6(src=src, dst=remote_host_ip6) /
8904 TCP(sport=12345, dport=22))
8906 self.pg0.add_stream(pkts)
8907 self.pg_enable_capture(self.pg_interfaces)
8909 self.pg1.get_capture(max_sessions)
8911 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8912 src_address=self.pg3.local_ip4,
8914 template_interval=10)
8915 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8916 src_port=self.ipfix_src_port,
8919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8920 IPv6(src=src, dst=remote_host_ip6) /
8921 TCP(sport=12345, dport=25))
8922 self.pg0.add_stream(p)
8923 self.pg_enable_capture(self.pg_interfaces)
8925 self.pg1.assert_nothing_captured()
8927 self.vapi.ipfix_flush()
8928 capture = self.pg3.get_capture(9)
8929 ipfix = IPFIXDecoder()
8930 # first load template
8932 self.assertTrue(p.haslayer(IPFIX))
8933 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8934 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8935 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8936 self.assertEqual(p[UDP].dport, 4739)
8937 self.assertEqual(p[IPFIX].observationDomainID,
8938 self.ipfix_domain_id)
8939 if p.haslayer(Template):
8940 ipfix.add_template(p.getlayer(Template))
8941 # verify events in data set
8943 if p.haslayer(Data):
8944 data = ipfix.decode_data_set(p.getlayer(Set))
8945 self.verify_ipfix_max_sessions(data, max_sessions)
8947 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8948 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8949 TCP(sport=12345, dport=80))
8950 self.pg0.add_stream(p)
8951 self.pg_enable_capture(self.pg_interfaces)
8953 self.pg1.assert_nothing_captured()
8955 self.vapi.ipfix_flush()
8956 capture = self.pg3.get_capture(1)
8957 # verify events in data set
8959 self.assertTrue(p.haslayer(IPFIX))
8960 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8961 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8962 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8963 self.assertEqual(p[UDP].dport, 4739)
8964 self.assertEqual(p[IPFIX].observationDomainID,
8965 self.ipfix_domain_id)
8966 if p.haslayer(Data):
8967 data = ipfix.decode_data_set(p.getlayer(Set))
8968 self.verify_ipfix_max_bibs(data, max_bibs)
8970 def test_ipfix_max_frags(self):
8971 """ IPFIX logging maximum fragments pending reassembly exceeded """
8972 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8973 end_addr=self.nat_addr,
8976 flags = self.config_flags.NAT_IS_INSIDE
8977 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8978 sw_if_index=self.pg0.sw_if_index)
8979 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8980 sw_if_index=self.pg1.sw_if_index)
8981 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8982 drop_frag=0, is_ip6=1)
8983 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8984 src_address=self.pg3.local_ip4,
8986 template_interval=10)
8987 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8988 src_port=self.ipfix_src_port,
8992 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8993 self.tcp_port_in, 20, data)
8995 self.pg0.add_stream(pkts)
8996 self.pg_enable_capture(self.pg_interfaces)
8998 self.pg1.assert_nothing_captured()
9000 self.vapi.ipfix_flush()
9001 capture = self.pg3.get_capture(9)
9002 ipfix = IPFIXDecoder()
9003 # first load template
9005 self.assertTrue(p.haslayer(IPFIX))
9006 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9007 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9008 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9009 self.assertEqual(p[UDP].dport, 4739)
9010 self.assertEqual(p[IPFIX].observationDomainID,
9011 self.ipfix_domain_id)
9012 if p.haslayer(Template):
9013 ipfix.add_template(p.getlayer(Template))
9014 # verify events in data set
9016 if p.haslayer(Data):
9017 data = ipfix.decode_data_set(p.getlayer(Set))
9018 self.verify_ipfix_max_fragments_ip6(data, 1,
9019 self.pg0.remote_ip6n)
9021 def test_ipfix_bib_ses(self):
9022 """ IPFIX logging NAT64 BIB/session create and delete events """
9023 self.tcp_port_in = random.randint(1025, 65535)
9024 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9028 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9029 end_addr=self.nat_addr,
9032 flags = self.config_flags.NAT_IS_INSIDE
9033 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9034 sw_if_index=self.pg0.sw_if_index)
9035 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9036 sw_if_index=self.pg1.sw_if_index)
9037 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9038 src_address=self.pg3.local_ip4,
9040 template_interval=10)
9041 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9042 src_port=self.ipfix_src_port,
9046 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9047 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9048 TCP(sport=self.tcp_port_in, dport=25))
9049 self.pg0.add_stream(p)
9050 self.pg_enable_capture(self.pg_interfaces)
9052 p = self.pg1.get_capture(1)
9053 self.tcp_port_out = p[0][TCP].sport
9054 self.vapi.ipfix_flush()
9055 capture = self.pg3.get_capture(10)
9056 ipfix = IPFIXDecoder()
9057 # first load template
9059 self.assertTrue(p.haslayer(IPFIX))
9060 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9061 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9062 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9063 self.assertEqual(p[UDP].dport, 4739)
9064 self.assertEqual(p[IPFIX].observationDomainID,
9065 self.ipfix_domain_id)
9066 if p.haslayer(Template):
9067 ipfix.add_template(p.getlayer(Template))
9068 # verify events in data set
9070 if p.haslayer(Data):
9071 data = ipfix.decode_data_set(p.getlayer(Set))
9072 if scapy.compat.orb(data[0][230]) == 10:
9073 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
9074 elif scapy.compat.orb(data[0][230]) == 6:
9075 self.verify_ipfix_nat64_ses(data,
9077 self.pg0.remote_ip6n,
9078 self.pg1.remote_ip4,
9081 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9084 self.pg_enable_capture(self.pg_interfaces)
9085 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9086 end_addr=self.nat_addr,
9089 self.vapi.ipfix_flush()
9090 capture = self.pg3.get_capture(2)
9091 # verify events in data set
9093 self.assertTrue(p.haslayer(IPFIX))
9094 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9095 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9096 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9097 self.assertEqual(p[UDP].dport, 4739)
9098 self.assertEqual(p[IPFIX].observationDomainID,
9099 self.ipfix_domain_id)
9100 if p.haslayer(Data):
9101 data = ipfix.decode_data_set(p.getlayer(Set))
9102 if scapy.compat.orb(data[0][230]) == 11:
9103 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9104 elif scapy.compat.orb(data[0][230]) == 7:
9105 self.verify_ipfix_nat64_ses(data,
9107 self.pg0.remote_ip6n,
9108 self.pg1.remote_ip4,
9111 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9113 def test_syslog_sess(self):
9114 """ Test syslog session creation and deletion """
9115 self.tcp_port_in = random.randint(1025, 65535)
9116 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9120 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9121 end_addr=self.nat_addr,
9124 flags = self.config_flags.NAT_IS_INSIDE
9125 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9126 sw_if_index=self.pg0.sw_if_index)
9127 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9128 sw_if_index=self.pg1.sw_if_index)
9129 self.vapi.syslog_set_filter(
9130 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9131 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9133 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9134 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9135 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9136 self.pg0.add_stream(p)
9137 self.pg_enable_capture(self.pg_interfaces)
9139 p = self.pg1.get_capture(1)
9140 self.tcp_port_out = p[0][TCP].sport
9141 capture = self.pg3.get_capture(1)
9142 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9144 self.pg_enable_capture(self.pg_interfaces)
9146 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9147 end_addr=self.nat_addr,
9150 capture = self.pg3.get_capture(1)
9151 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9153 def nat64_get_ses_num(self):
9155 Return number of active NAT64 sessions.
9157 st = self.vapi.nat64_st_dump(proto=255)
9160 def clear_nat64(self):
9162 Clear NAT64 configuration.
9164 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9165 src_port=self.ipfix_src_port,
9167 self.ipfix_src_port = 4739
9168 self.ipfix_domain_id = 1
9170 self.vapi.syslog_set_filter(
9171 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9173 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9174 tcp_transitory=240, icmp=60)
9176 interfaces = self.vapi.nat64_interface_dump()
9177 for intf in interfaces:
9178 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9179 sw_if_index=intf.sw_if_index)
9181 bib = self.vapi.nat64_bib_dump(proto=255)
9183 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9184 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9192 adresses = self.vapi.nat64_pool_addr_dump()
9193 for addr in adresses:
9194 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9195 end_addr=addr.address,
9199 prefixes = self.vapi.nat64_prefix_dump()
9200 for prefix in prefixes:
9201 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9202 vrf_id=prefix.vrf_id, is_add=0)
9204 bibs = self.statistics.get_counter('/nat64/total-bibs')
9205 self.assertEqual(bibs[0][0], 0)
9206 sessions = self.statistics.get_counter('/nat64/total-sessions')
9207 self.assertEqual(sessions[0][0], 0)
9210 super(TestNAT64, self).tearDown()
9211 if not self.vpp_dead:
9214 def show_commands_at_teardown(self):
9215 self.logger.info(self.vapi.cli("show nat64 pool"))
9216 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9217 self.logger.info(self.vapi.cli("show nat64 prefix"))
9218 self.logger.info(self.vapi.cli("show nat64 bib all"))
9219 self.logger.info(self.vapi.cli("show nat64 session table all"))
9220 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9223 class TestDSlite(MethodHolder):
9224 """ DS-Lite Test Cases """
9227 def setUpClass(cls):
9228 super(TestDSlite, cls).setUpClass()
9231 cls.nat_addr = '10.0.0.3'
9233 cls.create_pg_interfaces(range(3))
9235 cls.pg0.config_ip4()
9236 cls.pg0.resolve_arp()
9238 cls.pg1.config_ip6()
9239 cls.pg1.generate_remote_hosts(2)
9240 cls.pg1.configure_ipv6_neighbors()
9242 cls.pg2.config_ip4()
9243 cls.pg2.resolve_arp()
9246 super(TestDSlite, cls).tearDownClass()
9250 def tearDownClass(cls):
9251 super(TestDSlite, cls).tearDownClass()
9253 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9255 message = data.decode('utf-8')
9257 message = SyslogMessage.parse(message)
9258 except ParseError as e:
9259 self.logger.error(e)
9261 self.assertEqual(message.severity, SyslogSeverity.info)
9262 self.assertEqual(message.appname, 'NAT')
9263 self.assertEqual(message.msgid, 'APMADD')
9264 sd_params = message.sd.get('napmap')
9265 self.assertTrue(sd_params is not None)
9266 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9267 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9268 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9269 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9270 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9271 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9272 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9273 self.assertTrue(sd_params.get('SSUBIX') is not None)
9274 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9276 def test_dslite(self):
9277 """ Test DS-Lite """
9278 nat_config = self.vapi.nat_show_config()
9279 self.assertEqual(0, nat_config.dslite_ce)
9281 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9282 end_addr=self.nat_addr,
9284 aftr_ip4 = '192.0.0.1'
9285 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9286 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9287 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
9290 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9291 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9292 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9293 UDP(sport=20000, dport=10000))
9294 self.pg1.add_stream(p)
9295 self.pg_enable_capture(self.pg_interfaces)
9297 capture = self.pg0.get_capture(1)
9298 capture = capture[0]
9299 self.assertFalse(capture.haslayer(IPv6))
9300 self.assertEqual(capture[IP].src, self.nat_addr)
9301 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9302 self.assertNotEqual(capture[UDP].sport, 20000)
9303 self.assertEqual(capture[UDP].dport, 10000)
9304 self.assert_packet_checksums_valid(capture)
9305 out_port = capture[UDP].sport
9306 capture = self.pg2.get_capture(1)
9307 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9308 20000, self.nat_addr, out_port,
9309 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9311 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9312 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9313 UDP(sport=10000, dport=out_port))
9314 self.pg0.add_stream(p)
9315 self.pg_enable_capture(self.pg_interfaces)
9317 capture = self.pg1.get_capture(1)
9318 capture = capture[0]
9319 self.assertEqual(capture[IPv6].src, aftr_ip6)
9320 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9321 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9322 self.assertEqual(capture[IP].dst, '192.168.1.1')
9323 self.assertEqual(capture[UDP].sport, 10000)
9324 self.assertEqual(capture[UDP].dport, 20000)
9325 self.assert_packet_checksums_valid(capture)
9328 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9329 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9330 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9331 TCP(sport=20001, dport=10001))
9332 self.pg1.add_stream(p)
9333 self.pg_enable_capture(self.pg_interfaces)
9335 capture = self.pg0.get_capture(1)
9336 capture = capture[0]
9337 self.assertFalse(capture.haslayer(IPv6))
9338 self.assertEqual(capture[IP].src, self.nat_addr)
9339 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9340 self.assertNotEqual(capture[TCP].sport, 20001)
9341 self.assertEqual(capture[TCP].dport, 10001)
9342 self.assert_packet_checksums_valid(capture)
9343 out_port = capture[TCP].sport
9345 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9346 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9347 TCP(sport=10001, dport=out_port))
9348 self.pg0.add_stream(p)
9349 self.pg_enable_capture(self.pg_interfaces)
9351 capture = self.pg1.get_capture(1)
9352 capture = capture[0]
9353 self.assertEqual(capture[IPv6].src, aftr_ip6)
9354 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9355 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9356 self.assertEqual(capture[IP].dst, '192.168.1.1')
9357 self.assertEqual(capture[TCP].sport, 10001)
9358 self.assertEqual(capture[TCP].dport, 20001)
9359 self.assert_packet_checksums_valid(capture)
9362 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9363 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9364 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9365 ICMP(id=4000, type='echo-request'))
9366 self.pg1.add_stream(p)
9367 self.pg_enable_capture(self.pg_interfaces)
9369 capture = self.pg0.get_capture(1)
9370 capture = capture[0]
9371 self.assertFalse(capture.haslayer(IPv6))
9372 self.assertEqual(capture[IP].src, self.nat_addr)
9373 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9374 self.assertNotEqual(capture[ICMP].id, 4000)
9375 self.assert_packet_checksums_valid(capture)
9376 out_id = capture[ICMP].id
9378 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9379 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9380 ICMP(id=out_id, type='echo-reply'))
9381 self.pg0.add_stream(p)
9382 self.pg_enable_capture(self.pg_interfaces)
9384 capture = self.pg1.get_capture(1)
9385 capture = capture[0]
9386 self.assertEqual(capture[IPv6].src, aftr_ip6)
9387 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9388 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9389 self.assertEqual(capture[IP].dst, '192.168.1.1')
9390 self.assertEqual(capture[ICMP].id, 4000)
9391 self.assert_packet_checksums_valid(capture)
9393 # ping DS-Lite AFTR tunnel endpoint address
9394 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9395 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9396 ICMPv6EchoRequest())
9397 self.pg1.add_stream(p)
9398 self.pg_enable_capture(self.pg_interfaces)
9400 capture = self.pg1.get_capture(1)
9401 capture = capture[0]
9402 self.assertEqual(capture[IPv6].src, aftr_ip6)
9403 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9404 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9406 b4s = self.statistics.get_counter('/dslite/total-b4s')
9407 self.assertEqual(b4s[0][0], 2)
9408 sessions = self.statistics.get_counter('/dslite/total-sessions')
9409 self.assertEqual(sessions[0][0], 3)
9412 super(TestDSlite, self).tearDown()
9414 def show_commands_at_teardown(self):
9415 self.logger.info(self.vapi.cli("show dslite pool"))
9417 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9418 self.logger.info(self.vapi.cli("show dslite sessions"))
9421 class TestDSliteCE(MethodHolder):
9422 """ DS-Lite CE Test Cases """
9425 def setUpConstants(cls):
9426 super(TestDSliteCE, cls).setUpConstants()
9427 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9430 def setUpClass(cls):
9431 super(TestDSliteCE, cls).setUpClass()
9434 cls.create_pg_interfaces(range(2))
9436 cls.pg0.config_ip4()
9437 cls.pg0.resolve_arp()
9439 cls.pg1.config_ip6()
9440 cls.pg1.generate_remote_hosts(1)
9441 cls.pg1.configure_ipv6_neighbors()
9444 super(TestDSliteCE, cls).tearDownClass()
9448 def tearDownClass(cls):
9449 super(TestDSliteCE, cls).tearDownClass()
9451 def test_dslite_ce(self):
9452 """ Test DS-Lite CE """
9454 nat_config = self.vapi.nat_show_config()
9455 self.assertEqual(1, nat_config.dslite_ce)
9457 b4_ip4 = '192.0.0.2'
9458 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9459 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9461 aftr_ip4 = '192.0.0.1'
9462 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9463 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9464 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9466 r1 = VppIpRoute(self, aftr_ip6, 128,
9467 [VppRoutePath(self.pg1.remote_ip6,
9468 self.pg1.sw_if_index)])
9472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9473 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9474 UDP(sport=10000, dport=20000))
9475 self.pg0.add_stream(p)
9476 self.pg_enable_capture(self.pg_interfaces)
9478 capture = self.pg1.get_capture(1)
9479 capture = capture[0]
9480 self.assertEqual(capture[IPv6].src, b4_ip6)
9481 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9482 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9483 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9484 self.assertEqual(capture[UDP].sport, 10000)
9485 self.assertEqual(capture[UDP].dport, 20000)
9486 self.assert_packet_checksums_valid(capture)
9489 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9490 IPv6(dst=b4_ip6, src=aftr_ip6) /
9491 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9492 UDP(sport=20000, dport=10000))
9493 self.pg1.add_stream(p)
9494 self.pg_enable_capture(self.pg_interfaces)
9496 capture = self.pg0.get_capture(1)
9497 capture = capture[0]
9498 self.assertFalse(capture.haslayer(IPv6))
9499 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9500 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9501 self.assertEqual(capture[UDP].sport, 20000)
9502 self.assertEqual(capture[UDP].dport, 10000)
9503 self.assert_packet_checksums_valid(capture)
9505 # ping DS-Lite B4 tunnel endpoint address
9506 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9507 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9508 ICMPv6EchoRequest())
9509 self.pg1.add_stream(p)
9510 self.pg_enable_capture(self.pg_interfaces)
9512 capture = self.pg1.get_capture(1)
9513 capture = capture[0]
9514 self.assertEqual(capture[IPv6].src, b4_ip6)
9515 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9516 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9519 super(TestDSliteCE, self).tearDown()
9521 def show_commands_at_teardown(self):
9523 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9525 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9528 class TestNAT66(MethodHolder):
9529 """ NAT66 Test Cases """
9532 def setUpClass(cls):
9533 super(TestNAT66, cls).setUpClass()
9536 cls.nat_addr = 'fd01:ff::2'
9538 cls.create_pg_interfaces(range(2))
9539 cls.interfaces = list(cls.pg_interfaces)
9541 for i in cls.interfaces:
9544 i.configure_ipv6_neighbors()
9547 super(TestNAT66, cls).tearDownClass()
9551 def tearDownClass(cls):
9552 super(TestNAT66, cls).tearDownClass()
9554 def test_static(self):
9555 """ 1:1 NAT66 test """
9556 flags = self.config_flags.NAT_IS_INSIDE
9557 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9558 sw_if_index=self.pg0.sw_if_index)
9559 self.vapi.nat66_add_del_interface(is_add=1,
9560 sw_if_index=self.pg1.sw_if_index)
9561 self.vapi.nat66_add_del_static_mapping(
9562 local_ip_address=self.pg0.remote_ip6n,
9563 external_ip_address=self.nat_addr,
9568 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9569 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9572 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9573 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9576 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9577 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9578 ICMPv6EchoRequest())
9580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9581 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9582 GRE() / IP() / TCP())
9584 self.pg0.add_stream(pkts)
9585 self.pg_enable_capture(self.pg_interfaces)
9587 capture = self.pg1.get_capture(len(pkts))
9588 for packet in capture:
9590 self.assertEqual(packet[IPv6].src, self.nat_addr)
9591 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9592 self.assert_packet_checksums_valid(packet)
9594 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9599 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9600 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9603 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9604 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9607 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9608 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9611 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9612 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9613 GRE() / IP() / TCP())
9615 self.pg1.add_stream(pkts)
9616 self.pg_enable_capture(self.pg_interfaces)
9618 capture = self.pg0.get_capture(len(pkts))
9619 for packet in capture:
9621 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9622 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9623 self.assert_packet_checksums_valid(packet)
9625 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9628 sm = self.vapi.nat66_static_mapping_dump()
9629 self.assertEqual(len(sm), 1)
9630 self.assertEqual(sm[0].total_pkts, 8)
9632 def test_check_no_translate(self):
9633 """ NAT66 translate only when egress interface is outside interface """
9634 flags = self.config_flags.NAT_IS_INSIDE
9635 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9636 sw_if_index=self.pg0.sw_if_index)
9637 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9638 sw_if_index=self.pg1.sw_if_index)
9639 self.vapi.nat66_add_del_static_mapping(
9640 local_ip_address=self.pg0.remote_ip6n,
9641 external_ip_address=self.nat_addr,
9645 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9646 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9648 self.pg0.add_stream([p])
9649 self.pg_enable_capture(self.pg_interfaces)
9651 capture = self.pg1.get_capture(1)
9654 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9655 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9657 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9660 def clear_nat66(self):
9662 Clear NAT66 configuration.
9664 interfaces = self.vapi.nat66_interface_dump()
9665 for intf in interfaces:
9666 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9667 sw_if_index=intf.sw_if_index)
9669 static_mappings = self.vapi.nat66_static_mapping_dump()
9670 for sm in static_mappings:
9671 self.vapi.nat66_add_del_static_mapping(
9672 local_ip_address=sm.local_ip_address,
9673 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9677 super(TestNAT66, self).tearDown()
9680 def show_commands_at_teardown(self):
9681 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9682 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9685 if __name__ == '__main__':
9686 unittest.main(testRunner=VppTestRunner)