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(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_id=10)
1505 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1507 cls.pg4._local_ip4 = "172.16.255.1"
1508 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1509 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1510 cls.pg4.set_table_ip4(10)
1511 cls.pg5._local_ip4 = "172.17.255.3"
1512 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1513 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1514 cls.pg5.set_table_ip4(10)
1515 cls.pg6._local_ip4 = "172.16.255.1"
1516 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1517 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1518 cls.pg6.set_table_ip4(20)
1519 for i in cls.overlapping_interfaces:
1527 cls.pg9.generate_remote_hosts(2)
1528 cls.pg9.config_ip4()
1529 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1530 cls.vapi.sw_interface_add_del_address(
1531 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1534 cls.pg9.resolve_arp()
1535 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1536 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1537 cls.pg9.resolve_arp()
1540 super(TestNAT44, cls).tearDownClass()
1544 def tearDownClass(cls):
1545 super(TestNAT44, cls).tearDownClass()
1547 def test_dynamic(self):
1548 """ NAT44 dynamic translation test """
1549 self.nat44_add_address(self.nat_addr)
1550 flags = self.config_flags.NAT_IS_INSIDE
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg0.sw_if_index,
1553 flags=flags, is_add=1)
1554 self.vapi.nat44_interface_add_del_feature(
1555 sw_if_index=self.pg1.sw_if_index,
1559 tcpn = self.statistics.get_err_counter(
1560 '/err/nat44-in2out-slowpath/TCP packets')
1561 udpn = self.statistics.get_err_counter(
1562 '/err/nat44-in2out-slowpath/UDP packets')
1563 icmpn = self.statistics.get_err_counter(
1564 '/err/nat44-in2out-slowpath/ICMP packets')
1565 totaln = self.statistics.get_err_counter(
1566 '/err/nat44-in2out-slowpath/good in2out packets processed')
1568 pkts = self.create_stream_in(self.pg0, self.pg1)
1569 self.pg0.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1572 capture = self.pg1.get_capture(len(pkts))
1573 self.verify_capture_out(capture)
1575 err = self.statistics.get_err_counter(
1576 '/err/nat44-in2out-slowpath/TCP packets')
1577 self.assertEqual(err - tcpn, 1)
1578 err = self.statistics.get_err_counter(
1579 '/err/nat44-in2out-slowpath/UDP packets')
1580 self.assertEqual(err - udpn, 1)
1581 err = self.statistics.get_err_counter(
1582 '/err/nat44-in2out-slowpath/ICMP packets')
1583 self.assertEqual(err - icmpn, 1)
1584 err = self.statistics.get_err_counter(
1585 '/err/nat44-in2out-slowpath/good in2out packets processed')
1586 self.assertEqual(err - totaln, 3)
1589 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1590 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1591 icmpn = self.statistics.get_err_counter(
1592 '/err/nat44-out2in/ICMP packets')
1593 totaln = self.statistics.get_err_counter(
1594 '/err/nat44-out2in/good out2in packets processed')
1596 pkts = self.create_stream_out(self.pg1)
1597 self.pg1.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1600 capture = self.pg0.get_capture(len(pkts))
1601 self.verify_capture_in(capture, self.pg0)
1603 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1604 self.assertEqual(err - tcpn, 1)
1605 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1606 self.assertEqual(err - udpn, 1)
1607 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1608 self.assertEqual(err - icmpn, 1)
1609 err = self.statistics.get_err_counter(
1610 '/err/nat44-out2in/good out2in packets processed')
1611 self.assertEqual(err - totaln, 3)
1613 users = self.statistics.get_counter('/nat44/total-users')
1614 self.assertEqual(users[0][0], 1)
1615 sessions = self.statistics.get_counter('/nat44/total-sessions')
1616 self.assertEqual(sessions[0][0], 3)
1618 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1619 """ NAT44 handling of client packets with TTL=1 """
1621 self.nat44_add_address(self.nat_addr)
1622 flags = self.config_flags.NAT_IS_INSIDE
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg0.sw_if_index,
1625 flags=flags, is_add=1)
1626 self.vapi.nat44_interface_add_del_feature(
1627 sw_if_index=self.pg1.sw_if_index,
1630 # Client side - generate traffic
1631 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1632 self.pg0.add_stream(pkts)
1633 self.pg_enable_capture(self.pg_interfaces)
1636 # Client side - verify ICMP type 11 packets
1637 capture = self.pg0.get_capture(len(pkts))
1638 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1640 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1641 """ NAT44 handling of server packets with TTL=1 """
1643 self.nat44_add_address(self.nat_addr)
1644 flags = self.config_flags.NAT_IS_INSIDE
1645 self.vapi.nat44_interface_add_del_feature(
1646 sw_if_index=self.pg0.sw_if_index,
1647 flags=flags, is_add=1)
1648 self.vapi.nat44_interface_add_del_feature(
1649 sw_if_index=self.pg1.sw_if_index,
1652 # Client side - create sessions
1653 pkts = self.create_stream_in(self.pg0, self.pg1)
1654 self.pg0.add_stream(pkts)
1655 self.pg_enable_capture(self.pg_interfaces)
1658 # Server side - generate traffic
1659 capture = self.pg1.get_capture(len(pkts))
1660 self.verify_capture_out(capture)
1661 pkts = self.create_stream_out(self.pg1, ttl=1)
1662 self.pg1.add_stream(pkts)
1663 self.pg_enable_capture(self.pg_interfaces)
1666 # Server side - verify ICMP type 11 packets
1667 capture = self.pg1.get_capture(len(pkts))
1668 self.verify_capture_out_with_icmp_errors(capture,
1669 src_ip=self.pg1.local_ip4)
1671 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1672 """ NAT44 handling of error responses to client packets with TTL=2 """
1674 self.nat44_add_address(self.nat_addr)
1675 flags = self.config_flags.NAT_IS_INSIDE
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg0.sw_if_index,
1678 flags=flags, is_add=1)
1679 self.vapi.nat44_interface_add_del_feature(
1680 sw_if_index=self.pg1.sw_if_index,
1683 # Client side - generate traffic
1684 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1685 self.pg0.add_stream(pkts)
1686 self.pg_enable_capture(self.pg_interfaces)
1689 # Server side - simulate ICMP type 11 response
1690 capture = self.pg1.get_capture(len(pkts))
1691 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1692 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1693 ICMP(type=11) / packet[IP] for packet in capture]
1694 self.pg1.add_stream(pkts)
1695 self.pg_enable_capture(self.pg_interfaces)
1698 # Client side - verify ICMP type 11 packets
1699 capture = self.pg0.get_capture(len(pkts))
1700 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1702 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1703 """ NAT44 handling of error responses to server packets with TTL=2 """
1705 self.nat44_add_address(self.nat_addr)
1706 flags = self.config_flags.NAT_IS_INSIDE
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg0.sw_if_index,
1709 flags=flags, is_add=1)
1710 self.vapi.nat44_interface_add_del_feature(
1711 sw_if_index=self.pg1.sw_if_index,
1714 # Client side - create sessions
1715 pkts = self.create_stream_in(self.pg0, self.pg1)
1716 self.pg0.add_stream(pkts)
1717 self.pg_enable_capture(self.pg_interfaces)
1720 # Server side - generate traffic
1721 capture = self.pg1.get_capture(len(pkts))
1722 self.verify_capture_out(capture)
1723 pkts = self.create_stream_out(self.pg1, ttl=2)
1724 self.pg1.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1728 # Client side - simulate ICMP type 11 response
1729 capture = self.pg0.get_capture(len(pkts))
1730 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1731 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1732 ICMP(type=11) / packet[IP] for packet in capture]
1733 self.pg0.add_stream(pkts)
1734 self.pg_enable_capture(self.pg_interfaces)
1737 # Server side - verify ICMP type 11 packets
1738 capture = self.pg1.get_capture(len(pkts))
1739 self.verify_capture_out_with_icmp_errors(capture)
1741 def test_ping_out_interface_from_outside(self):
1742 """ Ping NAT44 out interface from outside network """
1744 self.nat44_add_address(self.nat_addr)
1745 flags = self.config_flags.NAT_IS_INSIDE
1746 self.vapi.nat44_interface_add_del_feature(
1747 sw_if_index=self.pg0.sw_if_index,
1748 flags=flags, is_add=1)
1749 self.vapi.nat44_interface_add_del_feature(
1750 sw_if_index=self.pg1.sw_if_index,
1753 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1754 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1755 ICMP(id=self.icmp_id_out, type='echo-request'))
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg1.get_capture(len(pkts))
1763 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1764 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1765 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1766 self.assertEqual(packet[ICMP].type, 0) # echo reply
1768 self.logger.error(ppp("Unexpected or invalid packet "
1769 "(outside network):", packet))
1772 def test_ping_internal_host_from_outside(self):
1773 """ Ping internal host from outside network """
1775 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1776 flags = self.config_flags.NAT_IS_INSIDE
1777 self.vapi.nat44_interface_add_del_feature(
1778 sw_if_index=self.pg0.sw_if_index,
1779 flags=flags, is_add=1)
1780 self.vapi.nat44_interface_add_del_feature(
1781 sw_if_index=self.pg1.sw_if_index,
1785 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1786 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1787 ICMP(id=self.icmp_id_out, type='echo-request'))
1788 self.pg1.add_stream(pkt)
1789 self.pg_enable_capture(self.pg_interfaces)
1791 capture = self.pg0.get_capture(1)
1792 self.verify_capture_in(capture, self.pg0)
1793 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1796 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1797 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1798 ICMP(id=self.icmp_id_in, type='echo-reply'))
1799 self.pg0.add_stream(pkt)
1800 self.pg_enable_capture(self.pg_interfaces)
1802 capture = self.pg1.get_capture(1)
1803 self.verify_capture_out(capture, same_port=True)
1804 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1806 def test_forwarding(self):
1807 """ NAT44 forwarding test """
1809 flags = self.config_flags.NAT_IS_INSIDE
1810 self.vapi.nat44_interface_add_del_feature(
1811 sw_if_index=self.pg0.sw_if_index,
1812 flags=flags, is_add=1)
1813 self.vapi.nat44_interface_add_del_feature(
1814 sw_if_index=self.pg1.sw_if_index,
1816 self.vapi.nat44_forwarding_enable_disable(enable=1)
1818 real_ip = self.pg0.remote_ip4n
1819 alias_ip = self.nat_addr
1820 flags = self.config_flags.NAT_IS_ADDR_ONLY
1821 self.vapi.nat44_add_del_static_mapping(is_add=1,
1822 local_ip_address=real_ip,
1823 external_ip_address=alias_ip,
1824 external_sw_if_index=0xFFFFFFFF,
1828 # static mapping match
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1837 pkts = self.create_stream_in(self.pg0, self.pg1)
1838 self.pg0.add_stream(pkts)
1839 self.pg_enable_capture(self.pg_interfaces)
1841 capture = self.pg1.get_capture(len(pkts))
1842 self.verify_capture_out(capture, same_port=True)
1844 # no static mapping match
1846 host0 = self.pg0.remote_hosts[0]
1847 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1849 pkts = self.create_stream_out(self.pg1,
1850 dst_ip=self.pg0.remote_ip4,
1851 use_inside_ports=True)
1852 self.pg1.add_stream(pkts)
1853 self.pg_enable_capture(self.pg_interfaces)
1855 capture = self.pg0.get_capture(len(pkts))
1856 self.verify_capture_in(capture, self.pg0)
1858 pkts = self.create_stream_in(self.pg0, self.pg1)
1859 self.pg0.add_stream(pkts)
1860 self.pg_enable_capture(self.pg_interfaces)
1862 capture = self.pg1.get_capture(len(pkts))
1863 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1866 self.pg0.remote_hosts[0] = host0
1869 self.vapi.nat44_forwarding_enable_disable(enable=0)
1870 flags = self.config_flags.NAT_IS_ADDR_ONLY
1871 self.vapi.nat44_add_del_static_mapping(
1873 local_ip_address=real_ip,
1874 external_ip_address=alias_ip,
1875 external_sw_if_index=0xFFFFFFFF,
1878 def test_static_in(self):
1879 """ 1:1 NAT initialized from inside network """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1887 flags = self.config_flags.NAT_IS_INSIDE
1888 self.vapi.nat44_interface_add_del_feature(
1889 sw_if_index=self.pg0.sw_if_index,
1890 flags=flags, is_add=1)
1891 self.vapi.nat44_interface_add_del_feature(
1892 sw_if_index=self.pg1.sw_if_index,
1894 sm = self.vapi.nat44_static_mapping_dump()
1895 self.assertEqual(len(sm), 1)
1896 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1897 self.assertEqual(sm[0].protocol, 0)
1898 self.assertEqual(sm[0].local_port, 0)
1899 self.assertEqual(sm[0].external_port, 0)
1902 pkts = self.create_stream_in(self.pg0, self.pg1)
1903 self.pg0.add_stream(pkts)
1904 self.pg_enable_capture(self.pg_interfaces)
1906 capture = self.pg1.get_capture(len(pkts))
1907 self.verify_capture_out(capture, nat_ip, True)
1910 pkts = self.create_stream_out(self.pg1, nat_ip)
1911 self.pg1.add_stream(pkts)
1912 self.pg_enable_capture(self.pg_interfaces)
1914 capture = self.pg0.get_capture(len(pkts))
1915 self.verify_capture_in(capture, self.pg0)
1917 def test_static_out(self):
1918 """ 1:1 NAT initialized from outside network """
1920 nat_ip = "10.0.0.20"
1921 self.tcp_port_out = 6303
1922 self.udp_port_out = 6304
1923 self.icmp_id_out = 6305
1926 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1927 flags = self.config_flags.NAT_IS_INSIDE
1928 self.vapi.nat44_interface_add_del_feature(
1929 sw_if_index=self.pg0.sw_if_index,
1930 flags=flags, is_add=1)
1931 self.vapi.nat44_interface_add_del_feature(
1932 sw_if_index=self.pg1.sw_if_index,
1934 sm = self.vapi.nat44_static_mapping_dump()
1935 self.assertEqual(len(sm), 1)
1936 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1939 pkts = self.create_stream_out(self.pg1, nat_ip)
1940 self.pg1.add_stream(pkts)
1941 self.pg_enable_capture(self.pg_interfaces)
1943 capture = self.pg0.get_capture(len(pkts))
1944 self.verify_capture_in(capture, self.pg0)
1947 pkts = self.create_stream_in(self.pg0, self.pg1)
1948 self.pg0.add_stream(pkts)
1949 self.pg_enable_capture(self.pg_interfaces)
1951 capture = self.pg1.get_capture(len(pkts))
1952 self.verify_capture_out(capture, nat_ip, True)
1954 def test_static_with_port_in(self):
1955 """ 1:1 NAPT initialized from inside network """
1957 self.tcp_port_out = 3606
1958 self.udp_port_out = 3607
1959 self.icmp_id_out = 3608
1961 self.nat44_add_address(self.nat_addr)
1962 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1963 self.tcp_port_in, self.tcp_port_out,
1964 proto=IP_PROTOS.tcp)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.udp_port_in, self.udp_port_out,
1967 proto=IP_PROTOS.udp)
1968 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1969 self.icmp_id_in, self.icmp_id_out,
1970 proto=IP_PROTOS.icmp)
1971 flags = self.config_flags.NAT_IS_INSIDE
1972 self.vapi.nat44_interface_add_del_feature(
1973 sw_if_index=self.pg0.sw_if_index,
1974 flags=flags, is_add=1)
1975 self.vapi.nat44_interface_add_del_feature(
1976 sw_if_index=self.pg1.sw_if_index,
1980 pkts = self.create_stream_in(self.pg0, self.pg1)
1981 self.pg0.add_stream(pkts)
1982 self.pg_enable_capture(self.pg_interfaces)
1984 capture = self.pg1.get_capture(len(pkts))
1985 self.verify_capture_out(capture)
1988 pkts = self.create_stream_out(self.pg1)
1989 self.pg1.add_stream(pkts)
1990 self.pg_enable_capture(self.pg_interfaces)
1992 capture = self.pg0.get_capture(len(pkts))
1993 self.verify_capture_in(capture, self.pg0)
1995 def test_static_with_port_out(self):
1996 """ 1:1 NAPT initialized from outside network """
1998 self.tcp_port_out = 30606
1999 self.udp_port_out = 30607
2000 self.icmp_id_out = 30608
2002 self.nat44_add_address(self.nat_addr)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2004 self.tcp_port_in, self.tcp_port_out,
2005 proto=IP_PROTOS.tcp)
2006 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2007 self.udp_port_in, self.udp_port_out,
2008 proto=IP_PROTOS.udp)
2009 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2010 self.icmp_id_in, self.icmp_id_out,
2011 proto=IP_PROTOS.icmp)
2012 flags = self.config_flags.NAT_IS_INSIDE
2013 self.vapi.nat44_interface_add_del_feature(
2014 sw_if_index=self.pg0.sw_if_index,
2015 flags=flags, is_add=1)
2016 self.vapi.nat44_interface_add_del_feature(
2017 sw_if_index=self.pg1.sw_if_index,
2021 pkts = self.create_stream_out(self.pg1)
2022 self.pg1.add_stream(pkts)
2023 self.pg_enable_capture(self.pg_interfaces)
2025 capture = self.pg0.get_capture(len(pkts))
2026 self.verify_capture_in(capture, self.pg0)
2029 pkts = self.create_stream_in(self.pg0, self.pg1)
2030 self.pg0.add_stream(pkts)
2031 self.pg_enable_capture(self.pg_interfaces)
2033 capture = self.pg1.get_capture(len(pkts))
2034 self.verify_capture_out(capture)
2036 def test_static_vrf_aware(self):
2037 """ 1:1 NAT VRF awareness """
2039 nat_ip1 = "10.0.0.30"
2040 nat_ip2 = "10.0.0.40"
2041 self.tcp_port_out = 6303
2042 self.udp_port_out = 6304
2043 self.icmp_id_out = 6305
2045 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2047 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2049 flags = self.config_flags.NAT_IS_INSIDE
2050 self.vapi.nat44_interface_add_del_feature(
2051 sw_if_index=self.pg3.sw_if_index,
2053 self.vapi.nat44_interface_add_del_feature(
2054 sw_if_index=self.pg0.sw_if_index,
2055 flags=flags, is_add=1)
2056 self.vapi.nat44_interface_add_del_feature(
2057 sw_if_index=self.pg4.sw_if_index,
2058 flags=flags, is_add=1)
2060 # inside interface VRF match NAT44 static mapping VRF
2061 pkts = self.create_stream_in(self.pg4, self.pg3)
2062 self.pg4.add_stream(pkts)
2063 self.pg_enable_capture(self.pg_interfaces)
2065 capture = self.pg3.get_capture(len(pkts))
2066 self.verify_capture_out(capture, nat_ip1, True)
2068 # inside interface VRF don't match NAT44 static mapping VRF (packets
2070 pkts = self.create_stream_in(self.pg0, self.pg3)
2071 self.pg0.add_stream(pkts)
2072 self.pg_enable_capture(self.pg_interfaces)
2074 self.pg3.assert_nothing_captured()
2076 def test_dynamic_to_static(self):
2077 """ Switch from dynamic translation to 1:1NAT """
2078 nat_ip = "10.0.0.10"
2079 self.tcp_port_out = 6303
2080 self.udp_port_out = 6304
2081 self.icmp_id_out = 6305
2083 self.nat44_add_address(self.nat_addr)
2084 flags = self.config_flags.NAT_IS_INSIDE
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg0.sw_if_index,
2087 flags=flags, is_add=1)
2088 self.vapi.nat44_interface_add_del_feature(
2089 sw_if_index=self.pg1.sw_if_index,
2093 pkts = self.create_stream_in(self.pg0, self.pg1)
2094 self.pg0.add_stream(pkts)
2095 self.pg_enable_capture(self.pg_interfaces)
2097 capture = self.pg1.get_capture(len(pkts))
2098 self.verify_capture_out(capture)
2101 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2102 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2103 self.assertEqual(len(sessions), 0)
2104 pkts = self.create_stream_in(self.pg0, self.pg1)
2105 self.pg0.add_stream(pkts)
2106 self.pg_enable_capture(self.pg_interfaces)
2108 capture = self.pg1.get_capture(len(pkts))
2109 self.verify_capture_out(capture, nat_ip, True)
2111 def test_identity_nat(self):
2112 """ Identity NAT """
2113 flags = self.config_flags.NAT_IS_ADDR_ONLY
2114 self.vapi.nat44_add_del_identity_mapping(
2115 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2116 flags=flags, is_add=1)
2117 flags = self.config_flags.NAT_IS_INSIDE
2118 self.vapi.nat44_interface_add_del_feature(
2119 sw_if_index=self.pg0.sw_if_index,
2120 flags=flags, is_add=1)
2121 self.vapi.nat44_interface_add_del_feature(
2122 sw_if_index=self.pg1.sw_if_index,
2125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2126 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2127 TCP(sport=12345, dport=56789))
2128 self.pg1.add_stream(p)
2129 self.pg_enable_capture(self.pg_interfaces)
2131 capture = self.pg0.get_capture(1)
2136 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2137 self.assertEqual(ip.src, self.pg1.remote_ip4)
2138 self.assertEqual(tcp.dport, 56789)
2139 self.assertEqual(tcp.sport, 12345)
2140 self.assert_packet_checksums_valid(p)
2142 self.logger.error(ppp("Unexpected or invalid packet:", p))
2145 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2146 self.assertEqual(len(sessions), 0)
2147 flags = self.config_flags.NAT_IS_ADDR_ONLY
2148 self.vapi.nat44_add_del_identity_mapping(
2149 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2150 flags=flags, vrf_id=1, is_add=1)
2151 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2152 self.assertEqual(len(identity_mappings), 2)
2154 def test_multiple_inside_interfaces(self):
2155 """ NAT44 multiple non-overlapping address space inside interfaces """
2157 self.nat44_add_address(self.nat_addr)
2158 flags = self.config_flags.NAT_IS_INSIDE
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg0.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg1.sw_if_index,
2164 flags=flags, is_add=1)
2165 self.vapi.nat44_interface_add_del_feature(
2166 sw_if_index=self.pg3.sw_if_index,
2169 # between two NAT44 inside interfaces (no translation)
2170 pkts = self.create_stream_in(self.pg0, self.pg1)
2171 self.pg0.add_stream(pkts)
2172 self.pg_enable_capture(self.pg_interfaces)
2174 capture = self.pg1.get_capture(len(pkts))
2175 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2177 # from NAT44 inside to interface without NAT44 feature (no translation)
2178 pkts = self.create_stream_in(self.pg0, self.pg2)
2179 self.pg0.add_stream(pkts)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg2.get_capture(len(pkts))
2183 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2185 # in2out 1st interface
2186 pkts = self.create_stream_in(self.pg0, self.pg3)
2187 self.pg0.add_stream(pkts)
2188 self.pg_enable_capture(self.pg_interfaces)
2190 capture = self.pg3.get_capture(len(pkts))
2191 self.verify_capture_out(capture)
2193 # out2in 1st interface
2194 pkts = self.create_stream_out(self.pg3)
2195 self.pg3.add_stream(pkts)
2196 self.pg_enable_capture(self.pg_interfaces)
2198 capture = self.pg0.get_capture(len(pkts))
2199 self.verify_capture_in(capture, self.pg0)
2201 # in2out 2nd interface
2202 pkts = self.create_stream_in(self.pg1, self.pg3)
2203 self.pg1.add_stream(pkts)
2204 self.pg_enable_capture(self.pg_interfaces)
2206 capture = self.pg3.get_capture(len(pkts))
2207 self.verify_capture_out(capture)
2209 # out2in 2nd interface
2210 pkts = self.create_stream_out(self.pg3)
2211 self.pg3.add_stream(pkts)
2212 self.pg_enable_capture(self.pg_interfaces)
2214 capture = self.pg1.get_capture(len(pkts))
2215 self.verify_capture_in(capture, self.pg1)
2217 def test_inside_overlapping_interfaces(self):
2218 """ NAT44 multiple inside interfaces with overlapping address space """
2220 static_nat_ip = "10.0.0.10"
2221 self.nat44_add_address(self.nat_addr)
2222 flags = self.config_flags.NAT_IS_INSIDE
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg3.sw_if_index,
2226 self.vapi.nat44_interface_add_del_feature(
2227 sw_if_index=self.pg4.sw_if_index,
2228 flags=flags, is_add=1)
2229 self.vapi.nat44_interface_add_del_feature(
2230 sw_if_index=self.pg5.sw_if_index,
2231 flags=flags, is_add=1)
2232 self.vapi.nat44_interface_add_del_feature(
2233 sw_if_index=self.pg6.sw_if_index,
2234 flags=flags, is_add=1)
2235 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2238 # between NAT44 inside interfaces with same VRF (no translation)
2239 pkts = self.create_stream_in(self.pg4, self.pg5)
2240 self.pg4.add_stream(pkts)
2241 self.pg_enable_capture(self.pg_interfaces)
2243 capture = self.pg5.get_capture(len(pkts))
2244 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2246 # between NAT44 inside interfaces with different VRF (hairpinning)
2247 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2248 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2249 TCP(sport=1234, dport=5678))
2250 self.pg4.add_stream(p)
2251 self.pg_enable_capture(self.pg_interfaces)
2253 capture = self.pg6.get_capture(1)
2258 self.assertEqual(ip.src, self.nat_addr)
2259 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2260 self.assertNotEqual(tcp.sport, 1234)
2261 self.assertEqual(tcp.dport, 5678)
2263 self.logger.error(ppp("Unexpected or invalid packet:", p))
2266 # in2out 1st interface
2267 pkts = self.create_stream_in(self.pg4, self.pg3)
2268 self.pg4.add_stream(pkts)
2269 self.pg_enable_capture(self.pg_interfaces)
2271 capture = self.pg3.get_capture(len(pkts))
2272 self.verify_capture_out(capture)
2274 # out2in 1st interface
2275 pkts = self.create_stream_out(self.pg3)
2276 self.pg3.add_stream(pkts)
2277 self.pg_enable_capture(self.pg_interfaces)
2279 capture = self.pg4.get_capture(len(pkts))
2280 self.verify_capture_in(capture, self.pg4)
2282 # in2out 2nd interface
2283 pkts = self.create_stream_in(self.pg5, self.pg3)
2284 self.pg5.add_stream(pkts)
2285 self.pg_enable_capture(self.pg_interfaces)
2287 capture = self.pg3.get_capture(len(pkts))
2288 self.verify_capture_out(capture)
2290 # out2in 2nd interface
2291 pkts = self.create_stream_out(self.pg3)
2292 self.pg3.add_stream(pkts)
2293 self.pg_enable_capture(self.pg_interfaces)
2295 capture = self.pg5.get_capture(len(pkts))
2296 self.verify_capture_in(capture, self.pg5)
2299 addresses = self.vapi.nat44_address_dump()
2300 self.assertEqual(len(addresses), 1)
2301 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2302 self.assertEqual(len(sessions), 3)
2303 for session in sessions:
2304 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2305 self.assertEqual(str(session.inside_ip_address),
2306 self.pg5.remote_ip4)
2307 self.assertEqual(session.outside_ip_address,
2308 addresses[0].ip_address)
2309 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2310 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2311 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2312 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2313 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2314 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2315 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2316 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2317 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2319 # in2out 3rd interface
2320 pkts = self.create_stream_in(self.pg6, self.pg3)
2321 self.pg6.add_stream(pkts)
2322 self.pg_enable_capture(self.pg_interfaces)
2324 capture = self.pg3.get_capture(len(pkts))
2325 self.verify_capture_out(capture, static_nat_ip, True)
2327 # out2in 3rd interface
2328 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2329 self.pg3.add_stream(pkts)
2330 self.pg_enable_capture(self.pg_interfaces)
2332 capture = self.pg6.get_capture(len(pkts))
2333 self.verify_capture_in(capture, self.pg6)
2335 # general user and session dump verifications
2336 users = self.vapi.nat44_user_dump()
2337 self.assertGreaterEqual(len(users), 3)
2338 addresses = self.vapi.nat44_address_dump()
2339 self.assertEqual(len(addresses), 1)
2341 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2343 for session in sessions:
2344 self.assertEqual(user.ip_address, session.inside_ip_address)
2345 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2346 self.assertTrue(session.protocol in
2347 [IP_PROTOS.tcp, IP_PROTOS.udp,
2349 self.assertFalse(session.flags &
2350 self.config_flags.NAT_IS_EXT_HOST_VALID)
2353 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2354 self.assertGreaterEqual(len(sessions), 4)
2355 for session in sessions:
2356 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2357 self.assertEqual(str(session.inside_ip_address),
2358 self.pg4.remote_ip4)
2359 self.assertEqual(session.outside_ip_address,
2360 addresses[0].ip_address)
2363 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2364 self.assertGreaterEqual(len(sessions), 3)
2365 for session in sessions:
2366 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2367 self.assertEqual(str(session.inside_ip_address),
2368 self.pg6.remote_ip4)
2369 self.assertEqual(str(session.outside_ip_address),
2371 self.assertTrue(session.inside_port in
2372 [self.tcp_port_in, self.udp_port_in,
2375 def test_hairpinning(self):
2376 """ NAT44 hairpinning - 1:1 NAPT """
2378 host = self.pg0.remote_hosts[0]
2379 server = self.pg0.remote_hosts[1]
2382 server_in_port = 5678
2383 server_out_port = 8765
2385 self.nat44_add_address(self.nat_addr)
2386 flags = self.config_flags.NAT_IS_INSIDE
2387 self.vapi.nat44_interface_add_del_feature(
2388 sw_if_index=self.pg0.sw_if_index,
2389 flags=flags, is_add=1)
2390 self.vapi.nat44_interface_add_del_feature(
2391 sw_if_index=self.pg1.sw_if_index,
2394 # add static mapping for server
2395 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2396 server_in_port, server_out_port,
2397 proto=IP_PROTOS.tcp)
2399 # send packet from host to server
2400 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2401 IP(src=host.ip4, dst=self.nat_addr) /
2402 TCP(sport=host_in_port, dport=server_out_port))
2403 self.pg0.add_stream(p)
2404 self.pg_enable_capture(self.pg_interfaces)
2406 capture = self.pg0.get_capture(1)
2411 self.assertEqual(ip.src, self.nat_addr)
2412 self.assertEqual(ip.dst, server.ip4)
2413 self.assertNotEqual(tcp.sport, host_in_port)
2414 self.assertEqual(tcp.dport, server_in_port)
2415 self.assert_packet_checksums_valid(p)
2416 host_out_port = tcp.sport
2418 self.logger.error(ppp("Unexpected or invalid packet:", p))
2421 # send reply from server to host
2422 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2423 IP(src=server.ip4, dst=self.nat_addr) /
2424 TCP(sport=server_in_port, dport=host_out_port))
2425 self.pg0.add_stream(p)
2426 self.pg_enable_capture(self.pg_interfaces)
2428 capture = self.pg0.get_capture(1)
2433 self.assertEqual(ip.src, self.nat_addr)
2434 self.assertEqual(ip.dst, host.ip4)
2435 self.assertEqual(tcp.sport, server_out_port)
2436 self.assertEqual(tcp.dport, host_in_port)
2437 self.assert_packet_checksums_valid(p)
2439 self.logger.error(ppp("Unexpected or invalid packet:", p))
2442 def test_hairpinning2(self):
2443 """ NAT44 hairpinning - 1:1 NAT"""
2445 server1_nat_ip = "10.0.0.10"
2446 server2_nat_ip = "10.0.0.11"
2447 host = self.pg0.remote_hosts[0]
2448 server1 = self.pg0.remote_hosts[1]
2449 server2 = self.pg0.remote_hosts[2]
2450 server_tcp_port = 22
2451 server_udp_port = 20
2453 self.nat44_add_address(self.nat_addr)
2454 flags = self.config_flags.NAT_IS_INSIDE
2455 self.vapi.nat44_interface_add_del_feature(
2456 sw_if_index=self.pg0.sw_if_index,
2457 flags=flags, is_add=1)
2458 self.vapi.nat44_interface_add_del_feature(
2459 sw_if_index=self.pg1.sw_if_index,
2462 # add static mapping for servers
2463 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2464 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2469 IP(src=host.ip4, dst=server1_nat_ip) /
2470 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2473 IP(src=host.ip4, dst=server1_nat_ip) /
2474 UDP(sport=self.udp_port_in, dport=server_udp_port))
2476 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2477 IP(src=host.ip4, dst=server1_nat_ip) /
2478 ICMP(id=self.icmp_id_in, type='echo-request'))
2480 self.pg0.add_stream(pkts)
2481 self.pg_enable_capture(self.pg_interfaces)
2483 capture = self.pg0.get_capture(len(pkts))
2484 for packet in capture:
2486 self.assertEqual(packet[IP].src, self.nat_addr)
2487 self.assertEqual(packet[IP].dst, server1.ip4)
2488 if packet.haslayer(TCP):
2489 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2490 self.assertEqual(packet[TCP].dport, server_tcp_port)
2491 self.tcp_port_out = packet[TCP].sport
2492 self.assert_packet_checksums_valid(packet)
2493 elif packet.haslayer(UDP):
2494 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2495 self.assertEqual(packet[UDP].dport, server_udp_port)
2496 self.udp_port_out = packet[UDP].sport
2498 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2499 self.icmp_id_out = packet[ICMP].id
2501 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2507 IP(src=server1.ip4, dst=self.nat_addr) /
2508 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2510 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2511 IP(src=server1.ip4, dst=self.nat_addr) /
2512 UDP(sport=server_udp_port, dport=self.udp_port_out))
2514 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2515 IP(src=server1.ip4, dst=self.nat_addr) /
2516 ICMP(id=self.icmp_id_out, type='echo-reply'))
2518 self.pg0.add_stream(pkts)
2519 self.pg_enable_capture(self.pg_interfaces)
2521 capture = self.pg0.get_capture(len(pkts))
2522 for packet in capture:
2524 self.assertEqual(packet[IP].src, server1_nat_ip)
2525 self.assertEqual(packet[IP].dst, host.ip4)
2526 if packet.haslayer(TCP):
2527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2528 self.assertEqual(packet[TCP].sport, server_tcp_port)
2529 self.assert_packet_checksums_valid(packet)
2530 elif packet.haslayer(UDP):
2531 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2532 self.assertEqual(packet[UDP].sport, server_udp_port)
2534 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2536 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2539 # server2 to server1
2541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2542 IP(src=server2.ip4, dst=server1_nat_ip) /
2543 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2545 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2546 IP(src=server2.ip4, dst=server1_nat_ip) /
2547 UDP(sport=self.udp_port_in, dport=server_udp_port))
2549 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2550 IP(src=server2.ip4, dst=server1_nat_ip) /
2551 ICMP(id=self.icmp_id_in, type='echo-request'))
2553 self.pg0.add_stream(pkts)
2554 self.pg_enable_capture(self.pg_interfaces)
2556 capture = self.pg0.get_capture(len(pkts))
2557 for packet in capture:
2559 self.assertEqual(packet[IP].src, server2_nat_ip)
2560 self.assertEqual(packet[IP].dst, server1.ip4)
2561 if packet.haslayer(TCP):
2562 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2563 self.assertEqual(packet[TCP].dport, server_tcp_port)
2564 self.tcp_port_out = packet[TCP].sport
2565 self.assert_packet_checksums_valid(packet)
2566 elif packet.haslayer(UDP):
2567 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2568 self.assertEqual(packet[UDP].dport, server_udp_port)
2569 self.udp_port_out = packet[UDP].sport
2571 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2572 self.icmp_id_out = packet[ICMP].id
2574 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2577 # server1 to server2
2579 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2580 IP(src=server1.ip4, dst=server2_nat_ip) /
2581 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2583 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2584 IP(src=server1.ip4, dst=server2_nat_ip) /
2585 UDP(sport=server_udp_port, dport=self.udp_port_out))
2587 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2588 IP(src=server1.ip4, dst=server2_nat_ip) /
2589 ICMP(id=self.icmp_id_out, type='echo-reply'))
2591 self.pg0.add_stream(pkts)
2592 self.pg_enable_capture(self.pg_interfaces)
2594 capture = self.pg0.get_capture(len(pkts))
2595 for packet in capture:
2597 self.assertEqual(packet[IP].src, server1_nat_ip)
2598 self.assertEqual(packet[IP].dst, server2.ip4)
2599 if packet.haslayer(TCP):
2600 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2601 self.assertEqual(packet[TCP].sport, server_tcp_port)
2602 self.assert_packet_checksums_valid(packet)
2603 elif packet.haslayer(UDP):
2604 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2605 self.assertEqual(packet[UDP].sport, server_udp_port)
2607 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2612 def test_max_translations_per_user(self):
2613 """ MAX translations per user - recycle the least recently used """
2615 self.nat44_add_address(self.nat_addr)
2616 flags = self.config_flags.NAT_IS_INSIDE
2617 self.vapi.nat44_interface_add_del_feature(
2618 sw_if_index=self.pg0.sw_if_index,
2619 flags=flags, is_add=1)
2620 self.vapi.nat44_interface_add_del_feature(
2621 sw_if_index=self.pg1.sw_if_index,
2624 # get maximum number of translations per user
2625 nat44_config = self.vapi.nat_show_config()
2627 # send more than maximum number of translations per user packets
2628 pkts_num = nat44_config.max_translations_per_user + 5
2630 for port in range(0, pkts_num):
2631 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2632 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2633 TCP(sport=1025 + port))
2635 self.pg0.add_stream(pkts)
2636 self.pg_enable_capture(self.pg_interfaces)
2639 # verify number of translated packet
2640 self.pg1.get_capture(pkts_num)
2642 users = self.vapi.nat44_user_dump()
2644 if user.ip_address == self.pg0.remote_ip4n:
2645 self.assertEqual(user.nsessions,
2646 nat44_config.max_translations_per_user)
2647 self.assertEqual(user.nstaticsessions, 0)
2650 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2652 proto=IP_PROTOS.tcp)
2653 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2654 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2655 TCP(sport=tcp_port))
2656 self.pg0.add_stream(p)
2657 self.pg_enable_capture(self.pg_interfaces)
2659 self.pg1.get_capture(1)
2660 users = self.vapi.nat44_user_dump()
2662 if user.ip_address == self.pg0.remote_ip4n:
2663 self.assertEqual(user.nsessions,
2664 nat44_config.max_translations_per_user - 1)
2665 self.assertEqual(user.nstaticsessions, 1)
2667 def test_interface_addr(self):
2668 """ Acquire NAT44 addresses from interface """
2669 self.vapi.nat44_add_del_interface_addr(
2671 sw_if_index=self.pg7.sw_if_index)
2673 # no address in NAT pool
2674 addresses = self.vapi.nat44_address_dump()
2675 self.assertEqual(0, len(addresses))
2677 # configure interface address and check NAT address pool
2678 self.pg7.config_ip4()
2679 addresses = self.vapi.nat44_address_dump()
2680 self.assertEqual(1, len(addresses))
2681 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2683 # remove interface address and check NAT address pool
2684 self.pg7.unconfig_ip4()
2685 addresses = self.vapi.nat44_address_dump()
2686 self.assertEqual(0, len(addresses))
2688 def test_interface_addr_static_mapping(self):
2689 """ Static mapping with addresses from interface """
2692 self.vapi.nat44_add_del_interface_addr(
2694 sw_if_index=self.pg7.sw_if_index)
2695 self.nat44_add_static_mapping(
2697 external_sw_if_index=self.pg7.sw_if_index,
2700 # static mappings with external interface
2701 static_mappings = self.vapi.nat44_static_mapping_dump()
2702 self.assertEqual(1, len(static_mappings))
2703 self.assertEqual(self.pg7.sw_if_index,
2704 static_mappings[0].external_sw_if_index)
2705 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2707 # configure interface address and check static mappings
2708 self.pg7.config_ip4()
2709 static_mappings = self.vapi.nat44_static_mapping_dump()
2710 self.assertEqual(2, len(static_mappings))
2712 for sm in static_mappings:
2713 if sm.external_sw_if_index == 0xFFFFFFFF:
2714 self.assertEqual(str(sm.external_ip_address),
2716 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2718 self.assertTrue(resolved)
2720 # remove interface address and check static mappings
2721 self.pg7.unconfig_ip4()
2722 static_mappings = self.vapi.nat44_static_mapping_dump()
2723 self.assertEqual(1, len(static_mappings))
2724 self.assertEqual(self.pg7.sw_if_index,
2725 static_mappings[0].external_sw_if_index)
2726 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2728 # configure interface address again and check static mappings
2729 self.pg7.config_ip4()
2730 static_mappings = self.vapi.nat44_static_mapping_dump()
2731 self.assertEqual(2, len(static_mappings))
2733 for sm in static_mappings:
2734 if sm.external_sw_if_index == 0xFFFFFFFF:
2735 self.assertEqual(str(sm.external_ip_address),
2737 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2739 self.assertTrue(resolved)
2741 # remove static mapping
2742 self.nat44_add_static_mapping(
2744 external_sw_if_index=self.pg7.sw_if_index,
2747 static_mappings = self.vapi.nat44_static_mapping_dump()
2748 self.assertEqual(0, len(static_mappings))
2750 def test_interface_addr_identity_nat(self):
2751 """ Identity NAT with addresses from interface """
2754 self.vapi.nat44_add_del_interface_addr(
2756 sw_if_index=self.pg7.sw_if_index)
2757 self.vapi.nat44_add_del_identity_mapping(
2759 sw_if_index=self.pg7.sw_if_index,
2761 protocol=IP_PROTOS.tcp,
2764 # identity mappings with external interface
2765 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2766 self.assertEqual(1, len(identity_mappings))
2767 self.assertEqual(self.pg7.sw_if_index,
2768 identity_mappings[0].sw_if_index)
2770 # configure interface address and check identity mappings
2771 self.pg7.config_ip4()
2772 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2774 self.assertEqual(2, len(identity_mappings))
2775 for sm in identity_mappings:
2776 if sm.sw_if_index == 0xFFFFFFFF:
2777 self.assertEqual(str(identity_mappings[0].ip_address),
2779 self.assertEqual(port, identity_mappings[0].port)
2780 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2782 self.assertTrue(resolved)
2784 # remove interface address and check identity mappings
2785 self.pg7.unconfig_ip4()
2786 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2787 self.assertEqual(1, len(identity_mappings))
2788 self.assertEqual(self.pg7.sw_if_index,
2789 identity_mappings[0].sw_if_index)
2791 def test_ipfix_nat44_sess(self):
2792 """ IPFIX logging NAT44 session created/deleted """
2793 self.ipfix_domain_id = 10
2794 self.ipfix_src_port = 20202
2795 collector_port = 30303
2796 bind_layers(UDP, IPFIX, dport=30303)
2797 self.nat44_add_address(self.nat_addr)
2798 flags = self.config_flags.NAT_IS_INSIDE
2799 self.vapi.nat44_interface_add_del_feature(
2800 sw_if_index=self.pg0.sw_if_index,
2801 flags=flags, is_add=1)
2802 self.vapi.nat44_interface_add_del_feature(
2803 sw_if_index=self.pg1.sw_if_index,
2805 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2806 src_address=self.pg3.local_ip4n,
2808 template_interval=10,
2809 collector_port=collector_port)
2810 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2811 src_port=self.ipfix_src_port,
2814 pkts = self.create_stream_in(self.pg0, self.pg1)
2815 self.pg0.add_stream(pkts)
2816 self.pg_enable_capture(self.pg_interfaces)
2818 capture = self.pg1.get_capture(len(pkts))
2819 self.verify_capture_out(capture)
2820 self.nat44_add_address(self.nat_addr, is_add=0)
2821 self.vapi.ipfix_flush()
2822 capture = self.pg3.get_capture(9)
2823 ipfix = IPFIXDecoder()
2824 # first load template
2826 self.assertTrue(p.haslayer(IPFIX))
2827 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2828 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2829 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2830 self.assertEqual(p[UDP].dport, collector_port)
2831 self.assertEqual(p[IPFIX].observationDomainID,
2832 self.ipfix_domain_id)
2833 if p.haslayer(Template):
2834 ipfix.add_template(p.getlayer(Template))
2835 # verify events in data set
2837 if p.haslayer(Data):
2838 data = ipfix.decode_data_set(p.getlayer(Set))
2839 self.verify_ipfix_nat44_ses(data)
2841 def test_ipfix_addr_exhausted(self):
2842 """ IPFIX logging NAT addresses exhausted """
2843 flags = self.config_flags.NAT_IS_INSIDE
2844 self.vapi.nat44_interface_add_del_feature(
2845 sw_if_index=self.pg0.sw_if_index,
2846 flags=flags, is_add=1)
2847 self.vapi.nat44_interface_add_del_feature(
2848 sw_if_index=self.pg1.sw_if_index,
2850 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2851 src_address=self.pg3.local_ip4n,
2853 template_interval=10)
2854 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2855 src_port=self.ipfix_src_port,
2858 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2859 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2861 self.pg0.add_stream(p)
2862 self.pg_enable_capture(self.pg_interfaces)
2864 self.pg1.assert_nothing_captured()
2866 self.vapi.ipfix_flush()
2867 capture = self.pg3.get_capture(9)
2868 ipfix = IPFIXDecoder()
2869 # first load template
2871 self.assertTrue(p.haslayer(IPFIX))
2872 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2873 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2874 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2875 self.assertEqual(p[UDP].dport, 4739)
2876 self.assertEqual(p[IPFIX].observationDomainID,
2877 self.ipfix_domain_id)
2878 if p.haslayer(Template):
2879 ipfix.add_template(p.getlayer(Template))
2880 # verify events in data set
2882 if p.haslayer(Data):
2883 data = ipfix.decode_data_set(p.getlayer(Set))
2884 self.verify_ipfix_addr_exhausted(data)
2886 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2887 def test_ipfix_max_sessions(self):
2888 """ IPFIX logging maximum session entries exceeded """
2889 self.nat44_add_address(self.nat_addr)
2890 flags = self.config_flags.NAT_IS_INSIDE
2891 self.vapi.nat44_interface_add_del_feature(
2892 sw_if_index=self.pg0.sw_if_index,
2893 flags=flags, is_add=1)
2894 self.vapi.nat44_interface_add_del_feature(
2895 sw_if_index=self.pg1.sw_if_index,
2898 nat44_config = self.vapi.nat_show_config()
2899 max_sessions = 10 * nat44_config.translation_buckets
2902 for i in range(0, max_sessions):
2903 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2904 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2905 IP(src=src, dst=self.pg1.remote_ip4) /
2908 self.pg0.add_stream(pkts)
2909 self.pg_enable_capture(self.pg_interfaces)
2912 self.pg1.get_capture(max_sessions)
2913 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2914 src_address=self.pg3.local_ip4n,
2916 template_interval=10)
2917 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2918 src_port=self.ipfix_src_port,
2921 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2922 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2924 self.pg0.add_stream(p)
2925 self.pg_enable_capture(self.pg_interfaces)
2927 self.pg1.assert_nothing_captured()
2929 self.vapi.ipfix_flush()
2930 capture = self.pg3.get_capture(9)
2931 ipfix = IPFIXDecoder()
2932 # first load template
2934 self.assertTrue(p.haslayer(IPFIX))
2935 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2936 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2937 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2938 self.assertEqual(p[UDP].dport, 4739)
2939 self.assertEqual(p[IPFIX].observationDomainID,
2940 self.ipfix_domain_id)
2941 if p.haslayer(Template):
2942 ipfix.add_template(p.getlayer(Template))
2943 # verify events in data set
2945 if p.haslayer(Data):
2946 data = ipfix.decode_data_set(p.getlayer(Set))
2947 self.verify_ipfix_max_sessions(data, max_sessions)
2949 def test_syslog_apmap(self):
2950 """ Test syslog address and port mapping creation and deletion """
2951 self.vapi.syslog_set_filter(
2952 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2953 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2954 self.nat44_add_address(self.nat_addr)
2955 flags = self.config_flags.NAT_IS_INSIDE
2956 self.vapi.nat44_interface_add_del_feature(
2957 sw_if_index=self.pg0.sw_if_index,
2958 flags=flags, is_add=1)
2959 self.vapi.nat44_interface_add_del_feature(
2960 sw_if_index=self.pg1.sw_if_index,
2963 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2964 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2965 TCP(sport=self.tcp_port_in, dport=20))
2966 self.pg0.add_stream(p)
2967 self.pg_enable_capture(self.pg_interfaces)
2969 capture = self.pg1.get_capture(1)
2970 self.tcp_port_out = capture[0][TCP].sport
2971 capture = self.pg3.get_capture(1)
2972 self.verify_syslog_apmap(capture[0][Raw].load)
2974 self.pg_enable_capture(self.pg_interfaces)
2976 self.nat44_add_address(self.nat_addr, is_add=0)
2977 capture = self.pg3.get_capture(1)
2978 self.verify_syslog_apmap(capture[0][Raw].load, False)
2980 def test_pool_addr_fib(self):
2981 """ NAT44 add pool addresses to FIB """
2982 static_addr = '10.0.0.10'
2983 self.nat44_add_address(self.nat_addr)
2984 flags = self.config_flags.NAT_IS_INSIDE
2985 self.vapi.nat44_interface_add_del_feature(
2986 sw_if_index=self.pg0.sw_if_index,
2987 flags=flags, is_add=1)
2988 self.vapi.nat44_interface_add_del_feature(
2989 sw_if_index=self.pg1.sw_if_index,
2991 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2994 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2995 ARP(op=ARP.who_has, pdst=self.nat_addr,
2996 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2997 self.pg1.add_stream(p)
2998 self.pg_enable_capture(self.pg_interfaces)
3000 capture = self.pg1.get_capture(1)
3001 self.assertTrue(capture[0].haslayer(ARP))
3002 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3005 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3006 ARP(op=ARP.who_has, pdst=static_addr,
3007 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 capture = self.pg1.get_capture(1)
3012 self.assertTrue(capture[0].haslayer(ARP))
3013 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3015 # send ARP to non-NAT44 interface
3016 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3017 ARP(op=ARP.who_has, pdst=self.nat_addr,
3018 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3019 self.pg2.add_stream(p)
3020 self.pg_enable_capture(self.pg_interfaces)
3022 self.pg1.assert_nothing_captured()
3024 # remove addresses and verify
3025 self.nat44_add_address(self.nat_addr, is_add=0)
3026 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3029 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3030 ARP(op=ARP.who_has, pdst=self.nat_addr,
3031 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3032 self.pg1.add_stream(p)
3033 self.pg_enable_capture(self.pg_interfaces)
3035 self.pg1.assert_nothing_captured()
3037 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3038 ARP(op=ARP.who_has, pdst=static_addr,
3039 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3040 self.pg1.add_stream(p)
3041 self.pg_enable_capture(self.pg_interfaces)
3043 self.pg1.assert_nothing_captured()
3045 def test_vrf_mode(self):
3046 """ NAT44 tenant VRF aware address pool mode """
3050 nat_ip1 = "10.0.0.10"
3051 nat_ip2 = "10.0.0.11"
3053 self.pg0.unconfig_ip4()
3054 self.pg1.unconfig_ip4()
3055 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3056 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3057 self.pg0.set_table_ip4(vrf_id1)
3058 self.pg1.set_table_ip4(vrf_id2)
3059 self.pg0.config_ip4()
3060 self.pg1.config_ip4()
3061 self.pg0.resolve_arp()
3062 self.pg1.resolve_arp()
3064 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3065 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3066 flags = self.config_flags.NAT_IS_INSIDE
3067 self.vapi.nat44_interface_add_del_feature(
3068 sw_if_index=self.pg0.sw_if_index,
3069 flags=flags, is_add=1)
3070 self.vapi.nat44_interface_add_del_feature(
3071 sw_if_index=self.pg1.sw_if_index,
3072 flags=flags, is_add=1)
3073 self.vapi.nat44_interface_add_del_feature(
3074 sw_if_index=self.pg2.sw_if_index,
3079 pkts = self.create_stream_in(self.pg0, self.pg2)
3080 self.pg0.add_stream(pkts)
3081 self.pg_enable_capture(self.pg_interfaces)
3083 capture = self.pg2.get_capture(len(pkts))
3084 self.verify_capture_out(capture, nat_ip1)
3087 pkts = self.create_stream_in(self.pg1, self.pg2)
3088 self.pg1.add_stream(pkts)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 capture = self.pg2.get_capture(len(pkts))
3092 self.verify_capture_out(capture, nat_ip2)
3095 self.pg0.unconfig_ip4()
3096 self.pg1.unconfig_ip4()
3097 self.pg0.set_table_ip4(0)
3098 self.pg1.set_table_ip4(0)
3099 self.pg0.config_ip4()
3100 self.pg1.config_ip4()
3101 self.pg0.resolve_arp()
3102 self.pg1.resolve_arp()
3103 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3104 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3106 def test_vrf_feature_independent(self):
3107 """ NAT44 tenant VRF independent address pool mode """
3109 nat_ip1 = "10.0.0.10"
3110 nat_ip2 = "10.0.0.11"
3112 self.nat44_add_address(nat_ip1)
3113 self.nat44_add_address(nat_ip2, vrf_id=99)
3114 flags = self.config_flags.NAT_IS_INSIDE
3115 self.vapi.nat44_interface_add_del_feature(
3116 sw_if_index=self.pg0.sw_if_index,
3117 flags=flags, is_add=1)
3118 self.vapi.nat44_interface_add_del_feature(
3119 sw_if_index=self.pg1.sw_if_index,
3120 flags=flags, is_add=1)
3121 self.vapi.nat44_interface_add_del_feature(
3122 sw_if_index=self.pg2.sw_if_index,
3126 pkts = self.create_stream_in(self.pg0, self.pg2)
3127 self.pg0.add_stream(pkts)
3128 self.pg_enable_capture(self.pg_interfaces)
3130 capture = self.pg2.get_capture(len(pkts))
3131 self.verify_capture_out(capture, nat_ip1)
3134 pkts = self.create_stream_in(self.pg1, self.pg2)
3135 self.pg1.add_stream(pkts)
3136 self.pg_enable_capture(self.pg_interfaces)
3138 capture = self.pg2.get_capture(len(pkts))
3139 self.verify_capture_out(capture, nat_ip1)
3141 def create_routes_and_neigbors(self):
3142 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3143 [VppRoutePath(self.pg7.remote_ip4,
3144 self.pg7.sw_if_index)])
3145 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3146 [VppRoutePath(self.pg8.remote_ip4,
3147 self.pg8.sw_if_index)])
3151 n1 = VppNeighbor(self,
3152 self.pg7.sw_if_index,
3153 self.pg7.remote_mac,
3154 self.pg7.remote_ip4,
3156 n2 = VppNeighbor(self,
3157 self.pg8.sw_if_index,
3158 self.pg8.remote_mac,
3159 self.pg8.remote_ip4,
3164 def test_dynamic_ipless_interfaces(self):
3165 """ NAT44 interfaces without configured IP address """
3166 self.create_routes_and_neigbors()
3167 self.nat44_add_address(self.nat_addr)
3168 flags = self.config_flags.NAT_IS_INSIDE
3169 self.vapi.nat44_interface_add_del_feature(
3170 sw_if_index=self.pg7.sw_if_index,
3171 flags=flags, is_add=1)
3172 self.vapi.nat44_interface_add_del_feature(
3173 sw_if_index=self.pg8.sw_if_index,
3177 pkts = self.create_stream_in(self.pg7, self.pg8)
3178 self.pg7.add_stream(pkts)
3179 self.pg_enable_capture(self.pg_interfaces)
3181 capture = self.pg8.get_capture(len(pkts))
3182 self.verify_capture_out(capture)
3185 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3186 self.pg8.add_stream(pkts)
3187 self.pg_enable_capture(self.pg_interfaces)
3189 capture = self.pg7.get_capture(len(pkts))
3190 self.verify_capture_in(capture, self.pg7)
3192 def test_static_ipless_interfaces(self):
3193 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3195 self.create_routes_and_neigbors()
3196 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3197 flags = self.config_flags.NAT_IS_INSIDE
3198 self.vapi.nat44_interface_add_del_feature(
3199 sw_if_index=self.pg7.sw_if_index,
3200 flags=flags, is_add=1)
3201 self.vapi.nat44_interface_add_del_feature(
3202 sw_if_index=self.pg8.sw_if_index,
3206 pkts = self.create_stream_out(self.pg8)
3207 self.pg8.add_stream(pkts)
3208 self.pg_enable_capture(self.pg_interfaces)
3210 capture = self.pg7.get_capture(len(pkts))
3211 self.verify_capture_in(capture, self.pg7)
3214 pkts = self.create_stream_in(self.pg7, self.pg8)
3215 self.pg7.add_stream(pkts)
3216 self.pg_enable_capture(self.pg_interfaces)
3218 capture = self.pg8.get_capture(len(pkts))
3219 self.verify_capture_out(capture, self.nat_addr, True)
3221 def test_static_with_port_ipless_interfaces(self):
3222 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3224 self.tcp_port_out = 30606
3225 self.udp_port_out = 30607
3226 self.icmp_id_out = 30608
3228 self.create_routes_and_neigbors()
3229 self.nat44_add_address(self.nat_addr)
3230 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3231 self.tcp_port_in, self.tcp_port_out,
3232 proto=IP_PROTOS.tcp)
3233 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3234 self.udp_port_in, self.udp_port_out,
3235 proto=IP_PROTOS.udp)
3236 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3237 self.icmp_id_in, self.icmp_id_out,
3238 proto=IP_PROTOS.icmp)
3239 flags = self.config_flags.NAT_IS_INSIDE
3240 self.vapi.nat44_interface_add_del_feature(
3241 sw_if_index=self.pg7.sw_if_index,
3242 flags=flags, is_add=1)
3243 self.vapi.nat44_interface_add_del_feature(
3244 sw_if_index=self.pg8.sw_if_index,
3248 pkts = self.create_stream_out(self.pg8)
3249 self.pg8.add_stream(pkts)
3250 self.pg_enable_capture(self.pg_interfaces)
3252 capture = self.pg7.get_capture(len(pkts))
3253 self.verify_capture_in(capture, self.pg7)
3256 pkts = self.create_stream_in(self.pg7, self.pg8)
3257 self.pg7.add_stream(pkts)
3258 self.pg_enable_capture(self.pg_interfaces)
3260 capture = self.pg8.get_capture(len(pkts))
3261 self.verify_capture_out(capture)
3263 def test_static_unknown_proto(self):
3264 """ 1:1 NAT translate packet with unknown protocol """
3265 nat_ip = "10.0.0.10"
3266 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3267 flags = self.config_flags.NAT_IS_INSIDE
3268 self.vapi.nat44_interface_add_del_feature(
3269 sw_if_index=self.pg0.sw_if_index,
3270 flags=flags, is_add=1)
3271 self.vapi.nat44_interface_add_del_feature(
3272 sw_if_index=self.pg1.sw_if_index,
3276 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3277 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3279 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3280 TCP(sport=1234, dport=1234))
3281 self.pg0.add_stream(p)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 p = self.pg1.get_capture(1)
3287 self.assertEqual(packet[IP].src, nat_ip)
3288 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3289 self.assertEqual(packet.haslayer(GRE), 1)
3290 self.assert_packet_checksums_valid(packet)
3292 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3296 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3297 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3299 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3300 TCP(sport=1234, dport=1234))
3301 self.pg1.add_stream(p)
3302 self.pg_enable_capture(self.pg_interfaces)
3304 p = self.pg0.get_capture(1)
3307 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3308 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3309 self.assertEqual(packet.haslayer(GRE), 1)
3310 self.assert_packet_checksums_valid(packet)
3312 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3315 def test_hairpinning_static_unknown_proto(self):
3316 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3318 host = self.pg0.remote_hosts[0]
3319 server = self.pg0.remote_hosts[1]
3321 host_nat_ip = "10.0.0.10"
3322 server_nat_ip = "10.0.0.11"
3324 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3325 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3326 flags = self.config_flags.NAT_IS_INSIDE
3327 self.vapi.nat44_interface_add_del_feature(
3328 sw_if_index=self.pg0.sw_if_index,
3329 flags=flags, is_add=1)
3330 self.vapi.nat44_interface_add_del_feature(
3331 sw_if_index=self.pg1.sw_if_index,
3335 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3336 IP(src=host.ip4, dst=server_nat_ip) /
3338 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3339 TCP(sport=1234, dport=1234))
3340 self.pg0.add_stream(p)
3341 self.pg_enable_capture(self.pg_interfaces)
3343 p = self.pg0.get_capture(1)
3346 self.assertEqual(packet[IP].src, host_nat_ip)
3347 self.assertEqual(packet[IP].dst, server.ip4)
3348 self.assertEqual(packet.haslayer(GRE), 1)
3349 self.assert_packet_checksums_valid(packet)
3351 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3355 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3356 IP(src=server.ip4, dst=host_nat_ip) /
3358 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3359 TCP(sport=1234, dport=1234))
3360 self.pg0.add_stream(p)
3361 self.pg_enable_capture(self.pg_interfaces)
3363 p = self.pg0.get_capture(1)
3366 self.assertEqual(packet[IP].src, server_nat_ip)
3367 self.assertEqual(packet[IP].dst, host.ip4)
3368 self.assertEqual(packet.haslayer(GRE), 1)
3369 self.assert_packet_checksums_valid(packet)
3371 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3374 def test_output_feature(self):
3375 """ NAT44 interface output feature (in2out postrouting) """
3376 self.nat44_add_address(self.nat_addr)
3377 flags = self.config_flags.NAT_IS_INSIDE
3378 self.vapi.nat44_interface_add_del_output_feature(
3379 is_add=1, flags=flags,
3380 sw_if_index=self.pg0.sw_if_index)
3381 self.vapi.nat44_interface_add_del_output_feature(
3382 is_add=1, flags=flags,
3383 sw_if_index=self.pg1.sw_if_index)
3384 self.vapi.nat44_interface_add_del_output_feature(
3386 sw_if_index=self.pg3.sw_if_index)
3389 pkts = self.create_stream_in(self.pg0, self.pg3)
3390 self.pg0.add_stream(pkts)
3391 self.pg_enable_capture(self.pg_interfaces)
3393 capture = self.pg3.get_capture(len(pkts))
3394 self.verify_capture_out(capture)
3397 pkts = self.create_stream_out(self.pg3)
3398 self.pg3.add_stream(pkts)
3399 self.pg_enable_capture(self.pg_interfaces)
3401 capture = self.pg0.get_capture(len(pkts))
3402 self.verify_capture_in(capture, self.pg0)
3404 # from non-NAT interface to NAT inside interface
3405 pkts = self.create_stream_in(self.pg2, self.pg0)
3406 self.pg2.add_stream(pkts)
3407 self.pg_enable_capture(self.pg_interfaces)
3409 capture = self.pg0.get_capture(len(pkts))
3410 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3412 def test_output_feature_vrf_aware(self):
3413 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3414 nat_ip_vrf10 = "10.0.0.10"
3415 nat_ip_vrf20 = "10.0.0.20"
3417 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3418 [VppRoutePath(self.pg3.remote_ip4,
3419 self.pg3.sw_if_index)],
3421 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3422 [VppRoutePath(self.pg3.remote_ip4,
3423 self.pg3.sw_if_index)],
3428 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3429 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3430 flags = self.config_flags.NAT_IS_INSIDE
3431 self.vapi.nat44_interface_add_del_output_feature(
3432 is_add=1, flags=flags,
3433 sw_if_index=self.pg4.sw_if_index)
3434 self.vapi.nat44_interface_add_del_output_feature(
3435 is_add=1, flags=flags,
3436 sw_if_index=self.pg6.sw_if_index)
3437 self.vapi.nat44_interface_add_del_output_feature(
3439 sw_if_index=self.pg3.sw_if_index)
3442 pkts = self.create_stream_in(self.pg4, self.pg3)
3443 self.pg4.add_stream(pkts)
3444 self.pg_enable_capture(self.pg_interfaces)
3446 capture = self.pg3.get_capture(len(pkts))
3447 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3450 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3451 self.pg3.add_stream(pkts)
3452 self.pg_enable_capture(self.pg_interfaces)
3454 capture = self.pg4.get_capture(len(pkts))
3455 self.verify_capture_in(capture, self.pg4)
3458 pkts = self.create_stream_in(self.pg6, self.pg3)
3459 self.pg6.add_stream(pkts)
3460 self.pg_enable_capture(self.pg_interfaces)
3462 capture = self.pg3.get_capture(len(pkts))
3463 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3466 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3467 self.pg3.add_stream(pkts)
3468 self.pg_enable_capture(self.pg_interfaces)
3470 capture = self.pg6.get_capture(len(pkts))
3471 self.verify_capture_in(capture, self.pg6)
3473 def test_output_feature_hairpinning(self):
3474 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3475 host = self.pg0.remote_hosts[0]
3476 server = self.pg0.remote_hosts[1]
3479 server_in_port = 5678
3480 server_out_port = 8765
3482 self.nat44_add_address(self.nat_addr)
3483 flags = self.config_flags.NAT_IS_INSIDE
3484 self.vapi.nat44_interface_add_del_output_feature(
3485 is_add=1, flags=flags,
3486 sw_if_index=self.pg0.sw_if_index)
3487 self.vapi.nat44_interface_add_del_output_feature(
3489 sw_if_index=self.pg1.sw_if_index)
3491 # add static mapping for server
3492 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3493 server_in_port, server_out_port,
3494 proto=IP_PROTOS.tcp)
3496 # send packet from host to server
3497 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3498 IP(src=host.ip4, dst=self.nat_addr) /
3499 TCP(sport=host_in_port, dport=server_out_port))
3500 self.pg0.add_stream(p)
3501 self.pg_enable_capture(self.pg_interfaces)
3503 capture = self.pg0.get_capture(1)
3508 self.assertEqual(ip.src, self.nat_addr)
3509 self.assertEqual(ip.dst, server.ip4)
3510 self.assertNotEqual(tcp.sport, host_in_port)
3511 self.assertEqual(tcp.dport, server_in_port)
3512 self.assert_packet_checksums_valid(p)
3513 host_out_port = tcp.sport
3515 self.logger.error(ppp("Unexpected or invalid packet:", p))
3518 # send reply from server to host
3519 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3520 IP(src=server.ip4, dst=self.nat_addr) /
3521 TCP(sport=server_in_port, dport=host_out_port))
3522 self.pg0.add_stream(p)
3523 self.pg_enable_capture(self.pg_interfaces)
3525 capture = self.pg0.get_capture(1)
3530 self.assertEqual(ip.src, self.nat_addr)
3531 self.assertEqual(ip.dst, host.ip4)
3532 self.assertEqual(tcp.sport, server_out_port)
3533 self.assertEqual(tcp.dport, host_in_port)
3534 self.assert_packet_checksums_valid(p)
3536 self.logger.error(ppp("Unexpected or invalid packet:", p))
3539 def test_one_armed_nat44(self):
3540 """ One armed NAT44 """
3541 remote_host = self.pg9.remote_hosts[0]
3542 local_host = self.pg9.remote_hosts[1]
3545 self.nat44_add_address(self.nat_addr)
3546 flags = self.config_flags.NAT_IS_INSIDE
3547 self.vapi.nat44_interface_add_del_feature(
3548 sw_if_index=self.pg9.sw_if_index,
3550 self.vapi.nat44_interface_add_del_feature(
3551 sw_if_index=self.pg9.sw_if_index,
3552 flags=flags, is_add=1)
3555 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3556 IP(src=local_host.ip4, dst=remote_host.ip4) /
3557 TCP(sport=12345, dport=80))
3558 self.pg9.add_stream(p)
3559 self.pg_enable_capture(self.pg_interfaces)
3561 capture = self.pg9.get_capture(1)
3566 self.assertEqual(ip.src, self.nat_addr)
3567 self.assertEqual(ip.dst, remote_host.ip4)
3568 self.assertNotEqual(tcp.sport, 12345)
3569 external_port = tcp.sport
3570 self.assertEqual(tcp.dport, 80)
3571 self.assert_packet_checksums_valid(p)
3573 self.logger.error(ppp("Unexpected or invalid packet:", p))
3577 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3578 IP(src=remote_host.ip4, dst=self.nat_addr) /
3579 TCP(sport=80, dport=external_port))
3580 self.pg9.add_stream(p)
3581 self.pg_enable_capture(self.pg_interfaces)
3583 capture = self.pg9.get_capture(1)
3588 self.assertEqual(ip.src, remote_host.ip4)
3589 self.assertEqual(ip.dst, local_host.ip4)
3590 self.assertEqual(tcp.sport, 80)
3591 self.assertEqual(tcp.dport, 12345)
3592 self.assert_packet_checksums_valid(p)
3594 self.logger.error(ppp("Unexpected or invalid packet:", p))
3597 err = self.statistics.get_err_counter(
3598 '/err/nat44-classify/next in2out')
3599 self.assertEqual(err, 1)
3600 err = self.statistics.get_err_counter(
3601 '/err/nat44-classify/next out2in')
3602 self.assertEqual(err, 1)
3604 def test_del_session(self):
3605 """ Delete NAT44 session """
3606 self.nat44_add_address(self.nat_addr)
3607 flags = self.config_flags.NAT_IS_INSIDE
3608 self.vapi.nat44_interface_add_del_feature(
3609 sw_if_index=self.pg0.sw_if_index,
3610 flags=flags, is_add=1)
3611 self.vapi.nat44_interface_add_del_feature(
3612 sw_if_index=self.pg1.sw_if_index,
3615 pkts = self.create_stream_in(self.pg0, self.pg1)
3616 self.pg0.add_stream(pkts)
3617 self.pg_enable_capture(self.pg_interfaces)
3619 self.pg1.get_capture(len(pkts))
3621 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3622 nsessions = len(sessions)
3624 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3625 port=sessions[0].inside_port,
3626 protocol=sessions[0].protocol,
3627 flags=self.config_flags.NAT_IS_INSIDE)
3628 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3629 port=sessions[1].outside_port,
3630 protocol=sessions[1].protocol)
3632 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3633 self.assertEqual(nsessions - len(sessions), 2)
3635 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3636 port=sessions[0].inside_port,
3637 protocol=sessions[0].protocol,
3638 flags=self.config_flags.NAT_IS_INSIDE)
3640 self.verify_no_nat44_user()
3642 def test_set_get_reass(self):
3643 """ NAT44 set/get virtual fragmentation reassembly """
3644 reas_cfg1 = self.vapi.nat_get_reass()
3646 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3647 max_reass=reas_cfg1.ip4_max_reass * 2,
3648 max_frag=reas_cfg1.ip4_max_frag * 2,
3651 reas_cfg2 = self.vapi.nat_get_reass()
3653 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3654 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3655 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3657 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3659 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3661 def test_frag_in_order(self):
3662 """ NAT44 translate fragments arriving in order """
3664 self.nat44_add_address(self.nat_addr)
3665 flags = self.config_flags.NAT_IS_INSIDE
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg0.sw_if_index,
3668 flags=flags, is_add=1)
3669 self.vapi.nat44_interface_add_del_feature(
3670 sw_if_index=self.pg1.sw_if_index,
3673 reas_cfg1 = self.vapi.nat_get_reass()
3674 # this test was intermittently failing in some cases
3675 # until we temporarily bump the reassembly timeouts
3676 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
3679 self.frag_in_order(proto=IP_PROTOS.tcp)
3680 self.frag_in_order(proto=IP_PROTOS.udp)
3681 self.frag_in_order(proto=IP_PROTOS.icmp)
3683 # restore the reassembly timeouts
3684 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
3685 max_reass=reas_cfg1.ip4_max_reass,
3686 max_frag=reas_cfg1.ip4_max_frag,
3687 drop_frag=reas_cfg1.ip4_drop_frag)
3689 def test_frag_forwarding(self):
3690 """ NAT44 forwarding fragment test """
3691 self.vapi.nat44_add_del_interface_addr(
3693 sw_if_index=self.pg1.sw_if_index)
3694 flags = self.config_flags.NAT_IS_INSIDE
3695 self.vapi.nat44_interface_add_del_feature(
3696 sw_if_index=self.pg0.sw_if_index,
3697 flags=flags, is_add=1)
3698 self.vapi.nat44_interface_add_del_feature(
3699 sw_if_index=self.pg1.sw_if_index,
3701 self.vapi.nat44_forwarding_enable_disable(enable=1)
3703 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3704 pkts = self.create_stream_frag(self.pg1,
3705 self.pg0.remote_ip4,
3709 proto=IP_PROTOS.udp)
3710 self.pg1.add_stream(pkts)
3711 self.pg_enable_capture(self.pg_interfaces)
3713 frags = self.pg0.get_capture(len(pkts))
3714 p = self.reass_frags_and_verify(frags,
3715 self.pg1.remote_ip4,
3716 self.pg0.remote_ip4)
3717 self.assertEqual(p[UDP].sport, 4789)
3718 self.assertEqual(p[UDP].dport, 4789)
3719 self.assertEqual(data, p[Raw].load)
3721 def test_reass_hairpinning(self):
3722 """ NAT44 fragments hairpinning """
3724 self.server = self.pg0.remote_hosts[1]
3725 self.host_in_port = random.randint(1025, 65535)
3726 self.server_in_port = random.randint(1025, 65535)
3727 self.server_out_port = random.randint(1025, 65535)
3729 self.nat44_add_address(self.nat_addr)
3730 flags = self.config_flags.NAT_IS_INSIDE
3731 self.vapi.nat44_interface_add_del_feature(
3732 sw_if_index=self.pg0.sw_if_index,
3733 flags=flags, is_add=1)
3734 self.vapi.nat44_interface_add_del_feature(
3735 sw_if_index=self.pg1.sw_if_index,
3737 # add static mapping for server
3738 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3739 self.server_in_port,
3740 self.server_out_port,
3741 proto=IP_PROTOS.tcp)
3742 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3743 self.server_in_port,
3744 self.server_out_port,
3745 proto=IP_PROTOS.udp)
3746 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3748 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3749 self.reass_hairpinning(proto=IP_PROTOS.udp)
3750 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3752 def test_frag_out_of_order(self):
3753 """ NAT44 translate fragments arriving out of order """
3755 self.nat44_add_address(self.nat_addr)
3756 flags = self.config_flags.NAT_IS_INSIDE
3757 self.vapi.nat44_interface_add_del_feature(
3758 sw_if_index=self.pg0.sw_if_index,
3759 flags=flags, is_add=1)
3760 self.vapi.nat44_interface_add_del_feature(
3761 sw_if_index=self.pg1.sw_if_index,
3764 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3765 self.frag_out_of_order(proto=IP_PROTOS.udp)
3766 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3768 def test_port_restricted(self):
3769 """ Port restricted NAT44 (MAP-E CE) """
3770 self.nat44_add_address(self.nat_addr)
3771 flags = self.config_flags.NAT_IS_INSIDE
3772 self.vapi.nat44_interface_add_del_feature(
3773 sw_if_index=self.pg0.sw_if_index,
3774 flags=flags, is_add=1)
3775 self.vapi.nat44_interface_add_del_feature(
3776 sw_if_index=self.pg1.sw_if_index,
3778 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3783 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3784 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3785 TCP(sport=4567, dport=22))
3786 self.pg0.add_stream(p)
3787 self.pg_enable_capture(self.pg_interfaces)
3789 capture = self.pg1.get_capture(1)
3794 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3795 self.assertEqual(ip.src, self.nat_addr)
3796 self.assertEqual(tcp.dport, 22)
3797 self.assertNotEqual(tcp.sport, 4567)
3798 self.assertEqual((tcp.sport >> 6) & 63, 10)
3799 self.assert_packet_checksums_valid(p)
3801 self.logger.error(ppp("Unexpected or invalid packet:", p))
3804 def test_port_range(self):
3805 """ External address port range """
3806 self.nat44_add_address(self.nat_addr)
3807 flags = self.config_flags.NAT_IS_INSIDE
3808 self.vapi.nat44_interface_add_del_feature(
3809 sw_if_index=self.pg0.sw_if_index,
3810 flags=flags, is_add=1)
3811 self.vapi.nat44_interface_add_del_feature(
3812 sw_if_index=self.pg1.sw_if_index,
3814 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3819 for port in range(0, 5):
3820 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3821 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3822 TCP(sport=1125 + port))
3824 self.pg0.add_stream(pkts)
3825 self.pg_enable_capture(self.pg_interfaces)
3827 capture = self.pg1.get_capture(3)
3830 self.assertGreaterEqual(tcp.sport, 1025)
3831 self.assertLessEqual(tcp.sport, 1027)
3833 def test_ipfix_max_frags(self):
3834 """ IPFIX logging maximum fragments pending reassembly exceeded """
3835 self.nat44_add_address(self.nat_addr)
3836 flags = self.config_flags.NAT_IS_INSIDE
3837 self.vapi.nat44_interface_add_del_feature(
3838 sw_if_index=self.pg0.sw_if_index,
3839 flags=flags, is_add=1)
3840 self.vapi.nat44_interface_add_del_feature(
3841 sw_if_index=self.pg1.sw_if_index,
3843 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3845 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3846 src_address=self.pg3.local_ip4n,
3848 template_interval=10)
3849 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3850 src_port=self.ipfix_src_port,
3853 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3854 self.tcp_port_in = random.randint(1025, 65535)
3855 pkts = self.create_stream_frag(self.pg0,
3856 self.pg1.remote_ip4,
3861 self.pg0.add_stream(pkts)
3862 self.pg_enable_capture(self.pg_interfaces)
3864 self.pg1.assert_nothing_captured()
3866 self.vapi.ipfix_flush()
3867 capture = self.pg3.get_capture(9)
3868 ipfix = IPFIXDecoder()
3869 # first load template
3871 self.assertTrue(p.haslayer(IPFIX))
3872 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3873 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3874 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3875 self.assertEqual(p[UDP].dport, 4739)
3876 self.assertEqual(p[IPFIX].observationDomainID,
3877 self.ipfix_domain_id)
3878 if p.haslayer(Template):
3879 ipfix.add_template(p.getlayer(Template))
3880 # verify events in data set
3882 if p.haslayer(Data):
3883 data = ipfix.decode_data_set(p.getlayer(Set))
3884 self.verify_ipfix_max_fragments_ip4(data, 1,
3885 self.pg0.remote_ip4n)
3887 def test_multiple_outside_vrf(self):
3888 """ Multiple outside VRF """
3892 self.pg1.unconfig_ip4()
3893 self.pg2.unconfig_ip4()
3894 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3895 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3896 self.pg1.set_table_ip4(vrf_id1)
3897 self.pg2.set_table_ip4(vrf_id2)
3898 self.pg1.config_ip4()
3899 self.pg2.config_ip4()
3900 self.pg1.resolve_arp()
3901 self.pg2.resolve_arp()
3903 self.nat44_add_address(self.nat_addr)
3904 flags = self.config_flags.NAT_IS_INSIDE
3905 self.vapi.nat44_interface_add_del_feature(
3906 sw_if_index=self.pg0.sw_if_index,
3907 flags=flags, is_add=1)
3908 self.vapi.nat44_interface_add_del_feature(
3909 sw_if_index=self.pg1.sw_if_index,
3911 self.vapi.nat44_interface_add_del_feature(
3912 sw_if_index=self.pg2.sw_if_index,
3917 pkts = self.create_stream_in(self.pg0, self.pg1)
3918 self.pg0.add_stream(pkts)
3919 self.pg_enable_capture(self.pg_interfaces)
3921 capture = self.pg1.get_capture(len(pkts))
3922 self.verify_capture_out(capture, self.nat_addr)
3924 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3925 self.pg1.add_stream(pkts)
3926 self.pg_enable_capture(self.pg_interfaces)
3928 capture = self.pg0.get_capture(len(pkts))
3929 self.verify_capture_in(capture, self.pg0)
3931 self.tcp_port_in = 60303
3932 self.udp_port_in = 60304
3933 self.icmp_id_in = 60305
3936 pkts = self.create_stream_in(self.pg0, self.pg2)
3937 self.pg0.add_stream(pkts)
3938 self.pg_enable_capture(self.pg_interfaces)
3940 capture = self.pg2.get_capture(len(pkts))
3941 self.verify_capture_out(capture, self.nat_addr)
3943 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3944 self.pg2.add_stream(pkts)
3945 self.pg_enable_capture(self.pg_interfaces)
3947 capture = self.pg0.get_capture(len(pkts))
3948 self.verify_capture_in(capture, self.pg0)
3951 self.nat44_add_address(self.nat_addr, is_add=0)
3952 self.pg1.unconfig_ip4()
3953 self.pg2.unconfig_ip4()
3954 self.pg1.set_table_ip4(0)
3955 self.pg2.set_table_ip4(0)
3956 self.pg1.config_ip4()
3957 self.pg2.config_ip4()
3958 self.pg1.resolve_arp()
3959 self.pg2.resolve_arp()
3961 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3962 def test_session_timeout(self):
3963 """ NAT44 session timeouts """
3964 self.nat44_add_address(self.nat_addr)
3965 flags = self.config_flags.NAT_IS_INSIDE
3966 self.vapi.nat44_interface_add_del_feature(
3967 sw_if_index=self.pg0.sw_if_index,
3968 flags=flags, is_add=1)
3969 self.vapi.nat44_interface_add_del_feature(
3970 sw_if_index=self.pg1.sw_if_index,
3972 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3973 tcp_transitory=240, icmp=60)
3977 for i in range(0, max_sessions):
3978 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3979 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3980 IP(src=src, dst=self.pg1.remote_ip4) /
3981 UDP(sport=1025, dport=53))
3983 self.pg0.add_stream(pkts)
3984 self.pg_enable_capture(self.pg_interfaces)
3986 self.pg1.get_capture(max_sessions)
3991 for i in range(0, max_sessions):
3992 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3993 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3994 IP(src=src, dst=self.pg1.remote_ip4) /
3995 UDP(sport=1026, dport=53))
3997 self.pg0.add_stream(pkts)
3998 self.pg_enable_capture(self.pg_interfaces)
4000 self.pg1.get_capture(max_sessions)
4003 users = self.vapi.nat44_user_dump()
4005 nsessions = nsessions + user.nsessions
4006 self.assertLess(nsessions, 2 * max_sessions)
4008 def test_mss_clamping(self):
4009 """ TCP MSS clamping """
4010 self.nat44_add_address(self.nat_addr)
4011 flags = self.config_flags.NAT_IS_INSIDE
4012 self.vapi.nat44_interface_add_del_feature(
4013 sw_if_index=self.pg0.sw_if_index,
4014 flags=flags, is_add=1)
4015 self.vapi.nat44_interface_add_del_feature(
4016 sw_if_index=self.pg1.sw_if_index,
4019 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4020 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4021 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4022 flags="S", options=[('MSS', 1400)]))
4024 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4025 self.pg0.add_stream(p)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 capture = self.pg1.get_capture(1)
4029 # Negotiated MSS value greater than configured - changed
4030 self.verify_mss_value(capture[0], 1000)
4032 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4033 self.pg0.add_stream(p)
4034 self.pg_enable_capture(self.pg_interfaces)
4036 capture = self.pg1.get_capture(1)
4037 # MSS clamping disabled - negotiated MSS unchanged
4038 self.verify_mss_value(capture[0], 1400)
4040 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4041 self.pg0.add_stream(p)
4042 self.pg_enable_capture(self.pg_interfaces)
4044 capture = self.pg1.get_capture(1)
4045 # Negotiated MSS value smaller than configured - unchanged
4046 self.verify_mss_value(capture[0], 1400)
4048 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4049 def test_ha_send(self):
4050 """ Send HA session synchronization events (active) """
4051 self.nat44_add_address(self.nat_addr)
4052 flags = self.config_flags.NAT_IS_INSIDE
4053 self.vapi.nat44_interface_add_del_feature(
4054 sw_if_index=self.pg0.sw_if_index,
4055 flags=flags, is_add=1)
4056 self.vapi.nat44_interface_add_del_feature(
4057 sw_if_index=self.pg1.sw_if_index,
4059 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4062 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4063 port=12346, session_refresh_interval=10)
4064 bind_layers(UDP, HANATStateSync, sport=12345)
4067 pkts = self.create_stream_in(self.pg0, self.pg1)
4068 self.pg0.add_stream(pkts)
4069 self.pg_enable_capture(self.pg_interfaces)
4071 capture = self.pg1.get_capture(len(pkts))
4072 self.verify_capture_out(capture)
4073 # active send HA events
4074 self.vapi.nat_ha_flush()
4075 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4076 self.assertEqual(stats[0][0], 3)
4077 capture = self.pg3.get_capture(1)
4079 self.assert_packet_checksums_valid(p)
4083 hanat = p[HANATStateSync]
4085 self.logger.error(ppp("Invalid packet:", p))
4088 self.assertEqual(ip.src, self.pg3.local_ip4)
4089 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4090 self.assertEqual(udp.sport, 12345)
4091 self.assertEqual(udp.dport, 12346)
4092 self.assertEqual(hanat.version, 1)
4093 self.assertEqual(hanat.thread_index, 0)
4094 self.assertEqual(hanat.count, 3)
4095 seq = hanat.sequence_number
4096 for event in hanat.events:
4097 self.assertEqual(event.event_type, 1)
4098 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4099 self.assertEqual(event.out_addr, self.nat_addr)
4100 self.assertEqual(event.fib_index, 0)
4102 # ACK received events
4103 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4104 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4105 UDP(sport=12346, dport=12345) /
4106 HANATStateSync(sequence_number=seq, flags='ACK'))
4107 self.pg3.add_stream(ack)
4109 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4110 self.assertEqual(stats[0][0], 1)
4112 # delete one session
4113 self.pg_enable_capture(self.pg_interfaces)
4114 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4115 port=self.tcp_port_in,
4116 protocol=IP_PROTOS.tcp,
4117 flags=self.config_flags.NAT_IS_INSIDE)
4118 self.vapi.nat_ha_flush()
4119 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4120 self.assertEqual(stats[0][0], 1)
4121 capture = self.pg3.get_capture(1)
4124 hanat = p[HANATStateSync]
4126 self.logger.error(ppp("Invalid packet:", p))
4129 self.assertGreater(hanat.sequence_number, seq)
4131 # do not send ACK, active retry send HA event again
4132 self.pg_enable_capture(self.pg_interfaces)
4134 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4135 self.assertEqual(stats[0][0], 3)
4136 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4137 self.assertEqual(stats[0][0], 1)
4138 capture = self.pg3.get_capture(3)
4139 for packet in capture:
4140 self.assertEqual(packet, p)
4142 # session counters refresh
4143 pkts = self.create_stream_out(self.pg1)
4144 self.pg1.add_stream(pkts)
4145 self.pg_enable_capture(self.pg_interfaces)
4147 self.pg0.get_capture(2)
4148 self.vapi.nat_ha_flush()
4149 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4150 self.assertEqual(stats[0][0], 2)
4151 capture = self.pg3.get_capture(1)
4153 self.assert_packet_checksums_valid(p)
4157 hanat = p[HANATStateSync]
4159 self.logger.error(ppp("Invalid packet:", p))
4162 self.assertEqual(ip.src, self.pg3.local_ip4)
4163 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4164 self.assertEqual(udp.sport, 12345)
4165 self.assertEqual(udp.dport, 12346)
4166 self.assertEqual(hanat.version, 1)
4167 self.assertEqual(hanat.count, 2)
4168 seq = hanat.sequence_number
4169 for event in hanat.events:
4170 self.assertEqual(event.event_type, 3)
4171 self.assertEqual(event.out_addr, self.nat_addr)
4172 self.assertEqual(event.fib_index, 0)
4173 self.assertEqual(event.total_pkts, 2)
4174 self.assertGreater(event.total_bytes, 0)
4176 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4177 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4178 UDP(sport=12346, dport=12345) /
4179 HANATStateSync(sequence_number=seq, flags='ACK'))
4180 self.pg3.add_stream(ack)
4182 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4183 self.assertEqual(stats[0][0], 2)
4185 def test_ha_recv(self):
4186 """ Receive HA session synchronization events (passive) """
4187 self.nat44_add_address(self.nat_addr)
4188 flags = self.config_flags.NAT_IS_INSIDE
4189 self.vapi.nat44_interface_add_del_feature(
4190 sw_if_index=self.pg0.sw_if_index,
4191 flags=flags, is_add=1)
4192 self.vapi.nat44_interface_add_del_feature(
4193 sw_if_index=self.pg1.sw_if_index,
4195 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4198 bind_layers(UDP, HANATStateSync, sport=12345)
4200 self.tcp_port_out = random.randint(1025, 65535)
4201 self.udp_port_out = random.randint(1025, 65535)
4203 # send HA session add events to failover/passive
4204 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4205 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4206 UDP(sport=12346, dport=12345) /
4207 HANATStateSync(sequence_number=1, events=[
4208 Event(event_type='add', protocol='tcp',
4209 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4210 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4211 eh_addr=self.pg1.remote_ip4,
4212 ehn_addr=self.pg1.remote_ip4,
4213 eh_port=self.tcp_external_port,
4214 ehn_port=self.tcp_external_port, fib_index=0),
4215 Event(event_type='add', protocol='udp',
4216 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4217 in_port=self.udp_port_in, out_port=self.udp_port_out,
4218 eh_addr=self.pg1.remote_ip4,
4219 ehn_addr=self.pg1.remote_ip4,
4220 eh_port=self.udp_external_port,
4221 ehn_port=self.udp_external_port, fib_index=0)]))
4223 self.pg3.add_stream(p)
4224 self.pg_enable_capture(self.pg_interfaces)
4227 capture = self.pg3.get_capture(1)
4230 hanat = p[HANATStateSync]
4232 self.logger.error(ppp("Invalid packet:", p))
4235 self.assertEqual(hanat.sequence_number, 1)
4236 self.assertEqual(hanat.flags, 'ACK')
4237 self.assertEqual(hanat.version, 1)
4238 self.assertEqual(hanat.thread_index, 0)
4239 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4240 self.assertEqual(stats[0][0], 1)
4241 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4242 self.assertEqual(stats[0][0], 2)
4243 users = self.statistics.get_counter('/nat44/total-users')
4244 self.assertEqual(users[0][0], 1)
4245 sessions = self.statistics.get_counter('/nat44/total-sessions')
4246 self.assertEqual(sessions[0][0], 2)
4247 users = self.vapi.nat44_user_dump()
4248 self.assertEqual(len(users), 1)
4249 self.assertEqual(str(users[0].ip_address),
4250 self.pg0.remote_ip4)
4251 # there should be 2 sessions created by HA
4252 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4254 self.assertEqual(len(sessions), 2)
4255 for session in sessions:
4256 self.assertEqual(str(session.inside_ip_address),
4257 self.pg0.remote_ip4)
4258 self.assertEqual(str(session.outside_ip_address),
4260 self.assertIn(session.inside_port,
4261 [self.tcp_port_in, self.udp_port_in])
4262 self.assertIn(session.outside_port,
4263 [self.tcp_port_out, self.udp_port_out])
4264 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4266 # send HA session delete event to failover/passive
4267 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4268 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4269 UDP(sport=12346, dport=12345) /
4270 HANATStateSync(sequence_number=2, events=[
4271 Event(event_type='del', protocol='udp',
4272 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4273 in_port=self.udp_port_in, out_port=self.udp_port_out,
4274 eh_addr=self.pg1.remote_ip4,
4275 ehn_addr=self.pg1.remote_ip4,
4276 eh_port=self.udp_external_port,
4277 ehn_port=self.udp_external_port, fib_index=0)]))
4279 self.pg3.add_stream(p)
4280 self.pg_enable_capture(self.pg_interfaces)
4283 capture = self.pg3.get_capture(1)
4286 hanat = p[HANATStateSync]
4288 self.logger.error(ppp("Invalid packet:", p))
4291 self.assertEqual(hanat.sequence_number, 2)
4292 self.assertEqual(hanat.flags, 'ACK')
4293 self.assertEqual(hanat.version, 1)
4294 users = self.vapi.nat44_user_dump()
4295 self.assertEqual(len(users), 1)
4296 self.assertEqual(str(users[0].ip_address),
4297 self.pg0.remote_ip4)
4298 # now we should have only 1 session, 1 deleted by HA
4299 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4301 self.assertEqual(len(sessions), 1)
4302 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4303 self.assertEqual(stats[0][0], 1)
4305 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4306 self.assertEqual(stats, 2)
4308 # send HA session refresh event to failover/passive
4309 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4310 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4311 UDP(sport=12346, dport=12345) /
4312 HANATStateSync(sequence_number=3, events=[
4313 Event(event_type='refresh', protocol='tcp',
4314 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4315 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4316 eh_addr=self.pg1.remote_ip4,
4317 ehn_addr=self.pg1.remote_ip4,
4318 eh_port=self.tcp_external_port,
4319 ehn_port=self.tcp_external_port, fib_index=0,
4320 total_bytes=1024, total_pkts=2)]))
4321 self.pg3.add_stream(p)
4322 self.pg_enable_capture(self.pg_interfaces)
4325 capture = self.pg3.get_capture(1)
4328 hanat = p[HANATStateSync]
4330 self.logger.error(ppp("Invalid packet:", p))
4333 self.assertEqual(hanat.sequence_number, 3)
4334 self.assertEqual(hanat.flags, 'ACK')
4335 self.assertEqual(hanat.version, 1)
4336 users = self.vapi.nat44_user_dump()
4337 self.assertEqual(len(users), 1)
4338 self.assertEqual(str(users[0].ip_address),
4339 self.pg0.remote_ip4)
4340 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4342 self.assertEqual(len(sessions), 1)
4343 session = sessions[0]
4344 self.assertEqual(session.total_bytes, 1024)
4345 self.assertEqual(session.total_pkts, 2)
4346 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4347 self.assertEqual(stats[0][0], 1)
4349 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4350 self.assertEqual(stats, 3)
4352 # send packet to test session created by HA
4353 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4354 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4355 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4356 self.pg1.add_stream(p)
4357 self.pg_enable_capture(self.pg_interfaces)
4359 capture = self.pg0.get_capture(1)
4365 self.logger.error(ppp("Invalid packet:", p))
4368 self.assertEqual(ip.src, self.pg1.remote_ip4)
4369 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4370 self.assertEqual(tcp.sport, self.tcp_external_port)
4371 self.assertEqual(tcp.dport, self.tcp_port_in)
4374 super(TestNAT44, self).tearDown()
4376 self.vapi.cli("clear logging")
4378 def show_commands_at_teardown(self):
4379 self.logger.info(self.vapi.cli("show nat44 addresses"))
4380 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4381 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4382 self.logger.info(self.vapi.cli("show nat44 interface address"))
4383 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4384 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4385 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4386 self.logger.info(self.vapi.cli("show nat timeouts"))
4388 self.vapi.cli("show nat addr-port-assignment-alg"))
4389 self.logger.info(self.vapi.cli("show nat ha"))
4392 class TestNAT44EndpointDependent(MethodHolder):
4393 """ Endpoint-Dependent mapping and filtering test cases """
4396 def setUpConstants(cls):
4397 super(TestNAT44EndpointDependent, cls).setUpConstants()
4398 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4401 def setUpClass(cls):
4402 super(TestNAT44EndpointDependent, cls).setUpClass()
4403 cls.vapi.cli("set log class nat level debug")
4405 cls.tcp_port_in = 6303
4406 cls.tcp_port_out = 6303
4407 cls.udp_port_in = 6304
4408 cls.udp_port_out = 6304
4409 cls.icmp_id_in = 6305
4410 cls.icmp_id_out = 6305
4411 cls.nat_addr = '10.0.0.3'
4412 cls.ipfix_src_port = 4739
4413 cls.ipfix_domain_id = 1
4414 cls.tcp_external_port = 80
4416 cls.create_pg_interfaces(range(7))
4417 cls.interfaces = list(cls.pg_interfaces[0:3])
4419 for i in cls.interfaces:
4424 cls.pg0.generate_remote_hosts(3)
4425 cls.pg0.configure_ipv4_neighbors()
4429 cls.pg4.generate_remote_hosts(2)
4430 cls.pg4.config_ip4()
4431 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4432 cls.vapi.sw_interface_add_del_address(
4433 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4436 cls.pg4.resolve_arp()
4437 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4438 cls.pg4.resolve_arp()
4440 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4441 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4443 cls.pg5._local_ip4 = "10.1.1.1"
4444 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4446 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4447 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4448 socket.AF_INET, cls.pg5.remote_ip4)
4449 cls.pg5.set_table_ip4(1)
4450 cls.pg5.config_ip4()
4452 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4453 [VppRoutePath("0.0.0.0",
4454 cls.pg5.sw_if_index)],
4459 cls.pg6._local_ip4 = "10.1.2.1"
4460 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4462 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4463 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4464 socket.AF_INET, cls.pg6.remote_ip4)
4465 cls.pg6.set_table_ip4(1)
4466 cls.pg6.config_ip4()
4469 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4470 [VppRoutePath("0.0.0.0",
4471 cls.pg6.sw_if_index)],
4474 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4475 [VppRoutePath("0.0.0.0",
4480 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4481 [VppRoutePath("0.0.0.0", 0xffffffff,
4485 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4486 [VppRoutePath(cls.pg1.local_ip4,
4487 cls.pg1.sw_if_index)],
4494 cls.pg5.resolve_arp()
4495 cls.pg6.resolve_arp()
4498 super(TestNAT44EndpointDependent, cls).tearDownClass()
4502 def tearDownClass(cls):
4503 super(TestNAT44EndpointDependent, cls).tearDownClass()
4505 def test_frag_in_order(self):
4506 """ NAT44 translate fragments arriving in order """
4507 self.nat44_add_address(self.nat_addr)
4508 flags = self.config_flags.NAT_IS_INSIDE
4509 self.vapi.nat44_interface_add_del_feature(
4510 sw_if_index=self.pg0.sw_if_index,
4511 flags=flags, is_add=1)
4512 self.vapi.nat44_interface_add_del_feature(
4513 sw_if_index=self.pg1.sw_if_index,
4515 self.frag_in_order(proto=IP_PROTOS.tcp)
4516 self.frag_in_order(proto=IP_PROTOS.udp)
4517 self.frag_in_order(proto=IP_PROTOS.icmp)
4519 def test_frag_in_order_dont_translate(self):
4520 """ NAT44 don't translate fragments arriving in order """
4521 flags = self.config_flags.NAT_IS_INSIDE
4522 self.vapi.nat44_interface_add_del_feature(
4523 sw_if_index=self.pg0.sw_if_index,
4524 flags=flags, is_add=1)
4525 self.vapi.nat44_interface_add_del_feature(
4526 sw_if_index=self.pg1.sw_if_index,
4528 self.vapi.nat44_forwarding_enable_disable(enable=True)
4529 reas_cfg1 = self.vapi.nat_get_reass()
4530 # this test was intermittently failing in some cases
4531 # until we temporarily bump the reassembly timeouts
4532 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4534 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4535 # restore the reassembly timeouts
4536 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4537 max_reass=reas_cfg1.ip4_max_reass,
4538 max_frag=reas_cfg1.ip4_max_frag,
4539 drop_frag=reas_cfg1.ip4_drop_frag)
4541 def test_frag_out_of_order(self):
4542 """ NAT44 translate fragments arriving out of order """
4543 self.nat44_add_address(self.nat_addr)
4544 flags = self.config_flags.NAT_IS_INSIDE
4545 self.vapi.nat44_interface_add_del_feature(
4546 sw_if_index=self.pg0.sw_if_index,
4547 flags=flags, is_add=1)
4548 self.vapi.nat44_interface_add_del_feature(
4549 sw_if_index=self.pg1.sw_if_index,
4551 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4552 self.frag_out_of_order(proto=IP_PROTOS.udp)
4553 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4555 def test_frag_out_of_order_dont_translate(self):
4556 """ NAT44 don't translate fragments arriving out of order """
4557 flags = self.config_flags.NAT_IS_INSIDE
4558 self.vapi.nat44_interface_add_del_feature(
4559 sw_if_index=self.pg0.sw_if_index,
4560 flags=flags, is_add=1)
4561 self.vapi.nat44_interface_add_del_feature(
4562 sw_if_index=self.pg1.sw_if_index,
4564 self.vapi.nat44_forwarding_enable_disable(enable=True)
4565 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4567 def test_frag_in_order_in_plus_out(self):
4568 """ in+out interface fragments in order """
4569 flags = self.config_flags.NAT_IS_INSIDE
4570 self.vapi.nat44_interface_add_del_feature(
4571 sw_if_index=self.pg0.sw_if_index,
4573 self.vapi.nat44_interface_add_del_feature(
4574 sw_if_index=self.pg0.sw_if_index,
4575 flags=flags, is_add=1)
4576 self.vapi.nat44_interface_add_del_feature(
4577 sw_if_index=self.pg1.sw_if_index,
4579 self.vapi.nat44_interface_add_del_feature(
4580 sw_if_index=self.pg1.sw_if_index,
4581 flags=flags, is_add=1)
4583 self.server = self.pg1.remote_hosts[0]
4585 self.server_in_addr = self.server.ip4
4586 self.server_out_addr = '11.11.11.11'
4587 self.server_in_port = random.randint(1025, 65535)
4588 self.server_out_port = random.randint(1025, 65535)
4590 self.nat44_add_address(self.server_out_addr)
4592 # add static mappings for server
4593 self.nat44_add_static_mapping(self.server_in_addr,
4594 self.server_out_addr,
4595 self.server_in_port,
4596 self.server_out_port,
4597 proto=IP_PROTOS.tcp)
4598 self.nat44_add_static_mapping(self.server_in_addr,
4599 self.server_out_addr,
4600 self.server_in_port,
4601 self.server_out_port,
4602 proto=IP_PROTOS.udp)
4603 self.nat44_add_static_mapping(self.server_in_addr,
4604 self.server_out_addr,
4605 proto=IP_PROTOS.icmp)
4607 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4610 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4611 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4612 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4614 def test_frag_out_of_order_in_plus_out(self):
4615 """ in+out interface fragments out of order """
4616 flags = self.config_flags.NAT_IS_INSIDE
4617 self.vapi.nat44_interface_add_del_feature(
4618 sw_if_index=self.pg0.sw_if_index,
4620 self.vapi.nat44_interface_add_del_feature(
4621 sw_if_index=self.pg0.sw_if_index,
4622 flags=flags, is_add=1)
4623 self.vapi.nat44_interface_add_del_feature(
4624 sw_if_index=self.pg1.sw_if_index,
4626 self.vapi.nat44_interface_add_del_feature(
4627 sw_if_index=self.pg1.sw_if_index,
4628 flags=flags, is_add=1)
4630 self.server = self.pg1.remote_hosts[0]
4632 self.server_in_addr = self.server.ip4
4633 self.server_out_addr = '11.11.11.11'
4634 self.server_in_port = random.randint(1025, 65535)
4635 self.server_out_port = random.randint(1025, 65535)
4637 self.nat44_add_address(self.server_out_addr)
4639 # add static mappings for server
4640 self.nat44_add_static_mapping(self.server_in_addr,
4641 self.server_out_addr,
4642 self.server_in_port,
4643 self.server_out_port,
4644 proto=IP_PROTOS.tcp)
4645 self.nat44_add_static_mapping(self.server_in_addr,
4646 self.server_out_addr,
4647 self.server_in_port,
4648 self.server_out_port,
4649 proto=IP_PROTOS.udp)
4650 self.nat44_add_static_mapping(self.server_in_addr,
4651 self.server_out_addr,
4652 proto=IP_PROTOS.icmp)
4654 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4657 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4658 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4659 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4661 def test_reass_hairpinning(self):
4662 """ NAT44 fragments hairpinning """
4663 self.server = self.pg0.remote_hosts[1]
4664 self.host_in_port = random.randint(1025, 65535)
4665 self.server_in_port = random.randint(1025, 65535)
4666 self.server_out_port = random.randint(1025, 65535)
4668 self.nat44_add_address(self.nat_addr)
4669 flags = self.config_flags.NAT_IS_INSIDE
4670 self.vapi.nat44_interface_add_del_feature(
4671 sw_if_index=self.pg0.sw_if_index,
4672 flags=flags, is_add=1)
4673 self.vapi.nat44_interface_add_del_feature(
4674 sw_if_index=self.pg1.sw_if_index,
4676 # add static mapping for server
4677 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4678 self.server_in_port,
4679 self.server_out_port,
4680 proto=IP_PROTOS.tcp)
4681 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4682 self.server_in_port,
4683 self.server_out_port,
4684 proto=IP_PROTOS.udp)
4685 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4687 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4688 self.reass_hairpinning(proto=IP_PROTOS.udp)
4689 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4691 def test_dynamic(self):
4692 """ NAT44 dynamic translation test """
4694 self.nat44_add_address(self.nat_addr)
4695 flags = self.config_flags.NAT_IS_INSIDE
4696 self.vapi.nat44_interface_add_del_feature(
4697 sw_if_index=self.pg0.sw_if_index,
4698 flags=flags, is_add=1)
4699 self.vapi.nat44_interface_add_del_feature(
4700 sw_if_index=self.pg1.sw_if_index,
4703 nat_config = self.vapi.nat_show_config()
4704 self.assertEqual(1, nat_config.endpoint_dependent)
4707 tcpn = self.statistics.get_err_counter(
4708 '/err/nat44-ed-in2out-slowpath/TCP packets')
4709 udpn = self.statistics.get_err_counter(
4710 '/err/nat44-ed-in2out-slowpath/UDP packets')
4711 icmpn = self.statistics.get_err_counter(
4712 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4713 totaln = self.statistics.get_err_counter(
4714 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4716 pkts = self.create_stream_in(self.pg0, self.pg1)
4717 self.pg0.add_stream(pkts)
4718 self.pg_enable_capture(self.pg_interfaces)
4720 capture = self.pg1.get_capture(len(pkts))
4721 self.verify_capture_out(capture)
4723 err = self.statistics.get_err_counter(
4724 '/err/nat44-ed-in2out-slowpath/TCP packets')
4725 self.assertEqual(err - tcpn, 1)
4726 err = self.statistics.get_err_counter(
4727 '/err/nat44-ed-in2out-slowpath/UDP packets')
4728 self.assertEqual(err - udpn, 1)
4729 err = self.statistics.get_err_counter(
4730 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4731 self.assertEqual(err - icmpn, 1)
4732 err = self.statistics.get_err_counter(
4733 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4734 self.assertEqual(err - totaln, 3)
4737 tcpn = self.statistics.get_err_counter(
4738 '/err/nat44-ed-out2in/TCP packets')
4739 udpn = self.statistics.get_err_counter(
4740 '/err/nat44-ed-out2in/UDP packets')
4741 icmpn = self.statistics.get_err_counter(
4742 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4743 totaln = self.statistics.get_err_counter(
4744 '/err/nat44-ed-out2in/good out2in packets processed')
4746 pkts = self.create_stream_out(self.pg1)
4747 self.pg1.add_stream(pkts)
4748 self.pg_enable_capture(self.pg_interfaces)
4750 capture = self.pg0.get_capture(len(pkts))
4751 self.verify_capture_in(capture, self.pg0)
4753 err = self.statistics.get_err_counter(
4754 '/err/nat44-ed-out2in/TCP packets')
4755 self.assertEqual(err - tcpn, 1)
4756 err = self.statistics.get_err_counter(
4757 '/err/nat44-ed-out2in/UDP packets')
4758 self.assertEqual(err - udpn, 1)
4759 err = self.statistics.get_err_counter(
4760 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4761 self.assertEqual(err - icmpn, 1)
4762 err = self.statistics.get_err_counter(
4763 '/err/nat44-ed-out2in/good out2in packets processed')
4764 self.assertEqual(err - totaln, 2)
4766 users = self.statistics.get_counter('/nat44/total-users')
4767 self.assertEqual(users[0][0], 1)
4768 sessions = self.statistics.get_counter('/nat44/total-sessions')
4769 self.assertEqual(sessions[0][0], 3)
4771 def test_forwarding(self):
4772 """ NAT44 forwarding test """
4774 flags = self.config_flags.NAT_IS_INSIDE
4775 self.vapi.nat44_interface_add_del_feature(
4776 sw_if_index=self.pg0.sw_if_index,
4777 flags=flags, is_add=1)
4778 self.vapi.nat44_interface_add_del_feature(
4779 sw_if_index=self.pg1.sw_if_index,
4781 self.vapi.nat44_forwarding_enable_disable(enable=1)
4783 real_ip = self.pg0.remote_ip4
4784 alias_ip = self.nat_addr
4785 flags = self.config_flags.NAT_IS_ADDR_ONLY
4786 self.vapi.nat44_add_del_static_mapping(is_add=1,
4787 local_ip_address=real_ip,
4788 external_ip_address=alias_ip,
4789 external_sw_if_index=0xFFFFFFFF,
4793 # in2out - static mapping match
4795 pkts = self.create_stream_out(self.pg1)
4796 self.pg1.add_stream(pkts)
4797 self.pg_enable_capture(self.pg_interfaces)
4799 capture = self.pg0.get_capture(len(pkts))
4800 self.verify_capture_in(capture, self.pg0)
4802 pkts = self.create_stream_in(self.pg0, self.pg1)
4803 self.pg0.add_stream(pkts)
4804 self.pg_enable_capture(self.pg_interfaces)
4806 capture = self.pg1.get_capture(len(pkts))
4807 self.verify_capture_out(capture, same_port=True)
4809 # in2out - no static mapping match
4811 host0 = self.pg0.remote_hosts[0]
4812 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4814 pkts = self.create_stream_out(self.pg1,
4815 dst_ip=self.pg0.remote_ip4,
4816 use_inside_ports=True)
4817 self.pg1.add_stream(pkts)
4818 self.pg_enable_capture(self.pg_interfaces)
4820 capture = self.pg0.get_capture(len(pkts))
4821 self.verify_capture_in(capture, self.pg0)
4823 pkts = self.create_stream_in(self.pg0, self.pg1)
4824 self.pg0.add_stream(pkts)
4825 self.pg_enable_capture(self.pg_interfaces)
4827 capture = self.pg1.get_capture(len(pkts))
4828 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4831 self.pg0.remote_hosts[0] = host0
4833 user = self.pg0.remote_hosts[1]
4834 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4835 self.assertEqual(len(sessions), 3)
4836 self.assertTrue(sessions[0].flags &
4837 self.config_flags.NAT_IS_EXT_HOST_VALID)
4838 self.vapi.nat44_del_session(
4839 address=sessions[0].inside_ip_address,
4840 port=sessions[0].inside_port,
4841 protocol=sessions[0].protocol,
4842 flags=(self.config_flags.NAT_IS_INSIDE |
4843 self.config_flags.NAT_IS_EXT_HOST_VALID),
4844 ext_host_address=sessions[0].ext_host_address,
4845 ext_host_port=sessions[0].ext_host_port)
4846 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4847 self.assertEqual(len(sessions), 2)
4850 self.vapi.nat44_forwarding_enable_disable(enable=0)
4851 flags = self.config_flags.NAT_IS_ADDR_ONLY
4852 self.vapi.nat44_add_del_static_mapping(
4854 local_ip_address=real_ip,
4855 external_ip_address=alias_ip,
4856 external_sw_if_index=0xFFFFFFFF,
4859 def test_static_lb(self):
4860 """ NAT44 local service load balancing """
4861 external_addr_n = self.nat_addr
4864 server1 = self.pg0.remote_hosts[0]
4865 server2 = self.pg0.remote_hosts[1]
4867 locals = [{'addr': server1.ip4n,
4871 {'addr': server2.ip4n,
4876 self.nat44_add_address(self.nat_addr)
4877 self.vapi.nat44_add_del_lb_static_mapping(
4879 external_addr=external_addr_n,
4880 external_port=external_port,
4881 protocol=IP_PROTOS.tcp,
4882 local_num=len(locals),
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,
4892 # from client to service
4893 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4894 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4895 TCP(sport=12345, dport=external_port))
4896 self.pg1.add_stream(p)
4897 self.pg_enable_capture(self.pg_interfaces)
4899 capture = self.pg0.get_capture(1)
4905 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4906 if ip.dst == server1.ip4:
4910 self.assertEqual(tcp.dport, local_port)
4911 self.assert_packet_checksums_valid(p)
4913 self.logger.error(ppp("Unexpected or invalid packet:", p))
4916 # from service back to client
4917 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4918 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4919 TCP(sport=local_port, dport=12345))
4920 self.pg0.add_stream(p)
4921 self.pg_enable_capture(self.pg_interfaces)
4923 capture = self.pg1.get_capture(1)
4928 self.assertEqual(ip.src, self.nat_addr)
4929 self.assertEqual(tcp.sport, external_port)
4930 self.assert_packet_checksums_valid(p)
4932 self.logger.error(ppp("Unexpected or invalid packet:", p))
4935 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4936 self.assertEqual(len(sessions), 1)
4937 self.assertTrue(sessions[0].flags &
4938 self.config_flags.NAT_IS_EXT_HOST_VALID)
4939 self.vapi.nat44_del_session(
4940 address=sessions[0].inside_ip_address,
4941 port=sessions[0].inside_port,
4942 protocol=sessions[0].protocol,
4943 flags=(self.config_flags.NAT_IS_INSIDE |
4944 self.config_flags.NAT_IS_EXT_HOST_VALID),
4945 ext_host_address=sessions[0].ext_host_address,
4946 ext_host_port=sessions[0].ext_host_port)
4947 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4948 self.assertEqual(len(sessions), 0)
4950 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4951 def test_static_lb_multi_clients(self):
4952 """ NAT44 local service load balancing - multiple clients"""
4954 external_addr = self.nat_addr
4957 server1 = self.pg0.remote_hosts[0]
4958 server2 = self.pg0.remote_hosts[1]
4959 server3 = self.pg0.remote_hosts[2]
4961 locals = [{'addr': server1.ip4n,
4965 {'addr': server2.ip4n,
4970 self.nat44_add_address(self.nat_addr)
4971 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4972 external_addr=external_addr,
4973 external_port=external_port,
4974 protocol=IP_PROTOS.tcp,
4975 local_num=len(locals),
4977 flags = self.config_flags.NAT_IS_INSIDE
4978 self.vapi.nat44_interface_add_del_feature(
4979 sw_if_index=self.pg0.sw_if_index,
4980 flags=flags, is_add=1)
4981 self.vapi.nat44_interface_add_del_feature(
4982 sw_if_index=self.pg1.sw_if_index,
4987 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4989 for client in clients:
4990 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4991 IP(src=client, dst=self.nat_addr) /
4992 TCP(sport=12345, dport=external_port))
4994 self.pg1.add_stream(pkts)
4995 self.pg_enable_capture(self.pg_interfaces)
4997 capture = self.pg0.get_capture(len(pkts))
4999 if p[IP].dst == server1.ip4:
5003 self.assertGreater(server1_n, server2_n)
5006 'addr': server3.ip4n,
5013 self.vapi.nat44_lb_static_mapping_add_del_local(
5015 external_addr=external_addr,
5016 external_port=external_port,
5018 protocol=IP_PROTOS.tcp)
5022 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5024 for client in clients:
5025 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5026 IP(src=client, dst=self.nat_addr) /
5027 TCP(sport=12346, dport=external_port))
5029 self.assertGreater(len(pkts), 0)
5030 self.pg1.add_stream(pkts)
5031 self.pg_enable_capture(self.pg_interfaces)
5033 capture = self.pg0.get_capture(len(pkts))
5035 if p[IP].dst == server1.ip4:
5037 elif p[IP].dst == server2.ip4:
5041 self.assertGreater(server1_n, 0)
5042 self.assertGreater(server2_n, 0)
5043 self.assertGreater(server3_n, 0)
5046 'addr': server2.ip4n,
5052 # remove one back-end
5053 self.vapi.nat44_lb_static_mapping_add_del_local(
5055 external_addr=external_addr,
5056 external_port=external_port,
5058 protocol=IP_PROTOS.tcp)
5062 self.pg1.add_stream(pkts)
5063 self.pg_enable_capture(self.pg_interfaces)
5065 capture = self.pg0.get_capture(len(pkts))
5067 if p[IP].dst == server1.ip4:
5069 elif p[IP].dst == server2.ip4:
5073 self.assertGreater(server1_n, 0)
5074 self.assertEqual(server2_n, 0)
5075 self.assertGreater(server3_n, 0)
5077 def test_static_lb_2(self):
5078 """ NAT44 local service load balancing (asymmetrical rule) """
5079 external_addr = self.nat_addr
5082 server1 = self.pg0.remote_hosts[0]
5083 server2 = self.pg0.remote_hosts[1]
5085 locals = [{'addr': server1.ip4n,
5089 {'addr': server2.ip4n,
5094 self.vapi.nat44_forwarding_enable_disable(enable=1)
5095 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5096 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5097 external_addr=external_addr,
5098 external_port=external_port,
5099 protocol=IP_PROTOS.tcp,
5100 local_num=len(locals),
5102 flags = self.config_flags.NAT_IS_INSIDE
5103 self.vapi.nat44_interface_add_del_feature(
5104 sw_if_index=self.pg0.sw_if_index,
5105 flags=flags, is_add=1)
5106 self.vapi.nat44_interface_add_del_feature(
5107 sw_if_index=self.pg1.sw_if_index,
5110 # from client to service
5111 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5112 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5113 TCP(sport=12345, dport=external_port))
5114 self.pg1.add_stream(p)
5115 self.pg_enable_capture(self.pg_interfaces)
5117 capture = self.pg0.get_capture(1)
5123 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5124 if ip.dst == server1.ip4:
5128 self.assertEqual(tcp.dport, local_port)
5129 self.assert_packet_checksums_valid(p)
5131 self.logger.error(ppp("Unexpected or invalid packet:", p))
5134 # from service back to client
5135 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5136 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5137 TCP(sport=local_port, dport=12345))
5138 self.pg0.add_stream(p)
5139 self.pg_enable_capture(self.pg_interfaces)
5141 capture = self.pg1.get_capture(1)
5146 self.assertEqual(ip.src, self.nat_addr)
5147 self.assertEqual(tcp.sport, external_port)
5148 self.assert_packet_checksums_valid(p)
5150 self.logger.error(ppp("Unexpected or invalid packet:", p))
5153 # from client to server (no translation)
5154 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5155 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5156 TCP(sport=12346, dport=local_port))
5157 self.pg1.add_stream(p)
5158 self.pg_enable_capture(self.pg_interfaces)
5160 capture = self.pg0.get_capture(1)
5166 self.assertEqual(ip.dst, server1.ip4)
5167 self.assertEqual(tcp.dport, local_port)
5168 self.assert_packet_checksums_valid(p)
5170 self.logger.error(ppp("Unexpected or invalid packet:", p))
5173 # from service back to client (no translation)
5174 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5175 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5176 TCP(sport=local_port, dport=12346))
5177 self.pg0.add_stream(p)
5178 self.pg_enable_capture(self.pg_interfaces)
5180 capture = self.pg1.get_capture(1)
5185 self.assertEqual(ip.src, server1.ip4)
5186 self.assertEqual(tcp.sport, local_port)
5187 self.assert_packet_checksums_valid(p)
5189 self.logger.error(ppp("Unexpected or invalid packet:", p))
5192 def test_lb_affinity(self):
5193 """ NAT44 local service load balancing affinity """
5194 external_addr = self.nat_addr
5197 server1 = self.pg0.remote_hosts[0]
5198 server2 = self.pg0.remote_hosts[1]
5200 locals = [{'addr': server1.ip4n,
5204 {'addr': server2.ip4n,
5209 self.nat44_add_address(self.nat_addr)
5210 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5211 external_addr=external_addr,
5212 external_port=external_port,
5213 protocol=IP_PROTOS.tcp,
5215 local_num=len(locals),
5217 flags = self.config_flags.NAT_IS_INSIDE
5218 self.vapi.nat44_interface_add_del_feature(
5219 sw_if_index=self.pg0.sw_if_index,
5220 flags=flags, is_add=1)
5221 self.vapi.nat44_interface_add_del_feature(
5222 sw_if_index=self.pg1.sw_if_index,
5225 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5226 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5227 TCP(sport=1025, dport=external_port))
5228 self.pg1.add_stream(p)
5229 self.pg_enable_capture(self.pg_interfaces)
5231 capture = self.pg0.get_capture(1)
5232 backend = capture[0][IP].dst
5234 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5235 self.assertEqual(len(sessions), 1)
5236 self.assertTrue(sessions[0].flags &
5237 self.config_flags.NAT_IS_EXT_HOST_VALID)
5238 self.vapi.nat44_del_session(
5239 address=sessions[0].inside_ip_address,
5240 port=sessions[0].inside_port,
5241 protocol=sessions[0].protocol,
5242 flags=(self.config_flags.NAT_IS_INSIDE |
5243 self.config_flags.NAT_IS_EXT_HOST_VALID),
5244 ext_host_address=sessions[0].ext_host_address,
5245 ext_host_port=sessions[0].ext_host_port)
5248 for port in range(1030, 1100):
5249 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5250 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5251 TCP(sport=port, dport=external_port))
5253 self.pg1.add_stream(pkts)
5254 self.pg_enable_capture(self.pg_interfaces)
5256 capture = self.pg0.get_capture(len(pkts))
5258 self.assertEqual(p[IP].dst, backend)
5260 def test_unknown_proto(self):
5261 """ NAT44 translate packet with unknown protocol """
5262 self.nat44_add_address(self.nat_addr)
5263 flags = self.config_flags.NAT_IS_INSIDE
5264 self.vapi.nat44_interface_add_del_feature(
5265 sw_if_index=self.pg0.sw_if_index,
5266 flags=flags, is_add=1)
5267 self.vapi.nat44_interface_add_del_feature(
5268 sw_if_index=self.pg1.sw_if_index,
5272 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5273 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5274 TCP(sport=self.tcp_port_in, dport=20))
5275 self.pg0.add_stream(p)
5276 self.pg_enable_capture(self.pg_interfaces)
5278 p = self.pg1.get_capture(1)
5280 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5281 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5283 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5284 TCP(sport=1234, dport=1234))
5285 self.pg0.add_stream(p)
5286 self.pg_enable_capture(self.pg_interfaces)
5288 p = self.pg1.get_capture(1)
5291 self.assertEqual(packet[IP].src, self.nat_addr)
5292 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5293 self.assertEqual(packet.haslayer(GRE), 1)
5294 self.assert_packet_checksums_valid(packet)
5296 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5300 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5301 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5303 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5304 TCP(sport=1234, dport=1234))
5305 self.pg1.add_stream(p)
5306 self.pg_enable_capture(self.pg_interfaces)
5308 p = self.pg0.get_capture(1)
5311 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5312 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5313 self.assertEqual(packet.haslayer(GRE), 1)
5314 self.assert_packet_checksums_valid(packet)
5316 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5319 def test_hairpinning_unknown_proto(self):
5320 """ NAT44 translate packet with unknown protocol - hairpinning """
5321 host = self.pg0.remote_hosts[0]
5322 server = self.pg0.remote_hosts[1]
5324 server_out_port = 8765
5325 server_nat_ip = "10.0.0.11"
5327 self.nat44_add_address(self.nat_addr)
5328 flags = self.config_flags.NAT_IS_INSIDE
5329 self.vapi.nat44_interface_add_del_feature(
5330 sw_if_index=self.pg0.sw_if_index,
5331 flags=flags, is_add=1)
5332 self.vapi.nat44_interface_add_del_feature(
5333 sw_if_index=self.pg1.sw_if_index,
5336 # add static mapping for server
5337 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5340 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5341 IP(src=host.ip4, dst=server_nat_ip) /
5342 TCP(sport=host_in_port, dport=server_out_port))
5343 self.pg0.add_stream(p)
5344 self.pg_enable_capture(self.pg_interfaces)
5346 self.pg0.get_capture(1)
5348 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5349 IP(src=host.ip4, dst=server_nat_ip) /
5351 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5352 TCP(sport=1234, dport=1234))
5353 self.pg0.add_stream(p)
5354 self.pg_enable_capture(self.pg_interfaces)
5356 p = self.pg0.get_capture(1)
5359 self.assertEqual(packet[IP].src, self.nat_addr)
5360 self.assertEqual(packet[IP].dst, server.ip4)
5361 self.assertEqual(packet.haslayer(GRE), 1)
5362 self.assert_packet_checksums_valid(packet)
5364 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5368 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5369 IP(src=server.ip4, dst=self.nat_addr) /
5371 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5372 TCP(sport=1234, dport=1234))
5373 self.pg0.add_stream(p)
5374 self.pg_enable_capture(self.pg_interfaces)
5376 p = self.pg0.get_capture(1)
5379 self.assertEqual(packet[IP].src, server_nat_ip)
5380 self.assertEqual(packet[IP].dst, host.ip4)
5381 self.assertEqual(packet.haslayer(GRE), 1)
5382 self.assert_packet_checksums_valid(packet)
5384 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5387 def test_output_feature_and_service(self):
5388 """ NAT44 interface output feature and services """
5389 external_addr = '1.2.3.4'
5393 self.vapi.nat44_forwarding_enable_disable(enable=1)
5394 self.nat44_add_address(self.nat_addr)
5395 flags = self.config_flags.NAT_IS_ADDR_ONLY
5396 self.vapi.nat44_add_del_identity_mapping(
5397 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5398 flags=flags, is_add=1)
5399 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5400 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5401 local_port, external_port,
5402 proto=IP_PROTOS.tcp, flags=flags)
5403 flags = self.config_flags.NAT_IS_INSIDE
5404 self.vapi.nat44_interface_add_del_feature(
5405 sw_if_index=self.pg0.sw_if_index,
5407 self.vapi.nat44_interface_add_del_feature(
5408 sw_if_index=self.pg0.sw_if_index,
5409 flags=flags, is_add=1)
5410 self.vapi.nat44_interface_add_del_output_feature(
5412 sw_if_index=self.pg1.sw_if_index)
5414 # from client to service
5415 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5416 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5417 TCP(sport=12345, dport=external_port))
5418 self.pg1.add_stream(p)
5419 self.pg_enable_capture(self.pg_interfaces)
5421 capture = self.pg0.get_capture(1)
5426 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5427 self.assertEqual(tcp.dport, local_port)
5428 self.assert_packet_checksums_valid(p)
5430 self.logger.error(ppp("Unexpected or invalid packet:", p))
5433 # from service back to client
5434 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5435 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5436 TCP(sport=local_port, dport=12345))
5437 self.pg0.add_stream(p)
5438 self.pg_enable_capture(self.pg_interfaces)
5440 capture = self.pg1.get_capture(1)
5445 self.assertEqual(ip.src, external_addr)
5446 self.assertEqual(tcp.sport, external_port)
5447 self.assert_packet_checksums_valid(p)
5449 self.logger.error(ppp("Unexpected or invalid packet:", p))
5452 # from local network host to external network
5453 pkts = self.create_stream_in(self.pg0, self.pg1)
5454 self.pg0.add_stream(pkts)
5455 self.pg_enable_capture(self.pg_interfaces)
5457 capture = self.pg1.get_capture(len(pkts))
5458 self.verify_capture_out(capture)
5459 pkts = self.create_stream_in(self.pg0, self.pg1)
5460 self.pg0.add_stream(pkts)
5461 self.pg_enable_capture(self.pg_interfaces)
5463 capture = self.pg1.get_capture(len(pkts))
5464 self.verify_capture_out(capture)
5466 # from external network back to local network host
5467 pkts = self.create_stream_out(self.pg1)
5468 self.pg1.add_stream(pkts)
5469 self.pg_enable_capture(self.pg_interfaces)
5471 capture = self.pg0.get_capture(len(pkts))
5472 self.verify_capture_in(capture, self.pg0)
5474 def test_output_feature_and_service2(self):
5475 """ NAT44 interface output feature and service host direct access """
5476 self.vapi.nat44_forwarding_enable_disable(enable=1)
5477 self.nat44_add_address(self.nat_addr)
5478 self.vapi.nat44_interface_add_del_output_feature(
5480 sw_if_index=self.pg1.sw_if_index)
5482 # session initiated from service host - translate
5483 pkts = self.create_stream_in(self.pg0, self.pg1)
5484 self.pg0.add_stream(pkts)
5485 self.pg_enable_capture(self.pg_interfaces)
5487 capture = self.pg1.get_capture(len(pkts))
5488 self.verify_capture_out(capture)
5490 pkts = self.create_stream_out(self.pg1)
5491 self.pg1.add_stream(pkts)
5492 self.pg_enable_capture(self.pg_interfaces)
5494 capture = self.pg0.get_capture(len(pkts))
5495 self.verify_capture_in(capture, self.pg0)
5497 # session initiated from remote host - do not translate
5498 self.tcp_port_in = 60303
5499 self.udp_port_in = 60304
5500 self.icmp_id_in = 60305
5501 pkts = self.create_stream_out(self.pg1,
5502 self.pg0.remote_ip4,
5503 use_inside_ports=True)
5504 self.pg1.add_stream(pkts)
5505 self.pg_enable_capture(self.pg_interfaces)
5507 capture = self.pg0.get_capture(len(pkts))
5508 self.verify_capture_in(capture, self.pg0)
5510 pkts = self.create_stream_in(self.pg0, self.pg1)
5511 self.pg0.add_stream(pkts)
5512 self.pg_enable_capture(self.pg_interfaces)
5514 capture = self.pg1.get_capture(len(pkts))
5515 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5518 def test_output_feature_and_service3(self):
5519 """ NAT44 interface output feature and DST NAT """
5520 external_addr = '1.2.3.4'
5524 self.vapi.nat44_forwarding_enable_disable(enable=1)
5525 self.nat44_add_address(self.nat_addr)
5526 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5527 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5528 local_port, external_port,
5529 proto=IP_PROTOS.tcp, flags=flags)
5530 flags = self.config_flags.NAT_IS_INSIDE
5531 self.vapi.nat44_interface_add_del_feature(
5532 sw_if_index=self.pg0.sw_if_index,
5534 self.vapi.nat44_interface_add_del_feature(
5535 sw_if_index=self.pg0.sw_if_index,
5536 flags=flags, is_add=1)
5537 self.vapi.nat44_interface_add_del_output_feature(
5539 sw_if_index=self.pg1.sw_if_index)
5541 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5542 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5543 TCP(sport=12345, dport=external_port))
5544 self.pg0.add_stream(p)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 capture = self.pg1.get_capture(1)
5552 self.assertEqual(ip.src, self.pg0.remote_ip4)
5553 self.assertEqual(tcp.sport, 12345)
5554 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5555 self.assertEqual(tcp.dport, local_port)
5556 self.assert_packet_checksums_valid(p)
5558 self.logger.error(ppp("Unexpected or invalid packet:", p))
5561 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5562 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5563 TCP(sport=local_port, dport=12345))
5564 self.pg1.add_stream(p)
5565 self.pg_enable_capture(self.pg_interfaces)
5567 capture = self.pg0.get_capture(1)
5572 self.assertEqual(ip.src, external_addr)
5573 self.assertEqual(tcp.sport, external_port)
5574 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5575 self.assertEqual(tcp.dport, 12345)
5576 self.assert_packet_checksums_valid(p)
5578 self.logger.error(ppp("Unexpected or invalid packet:", p))
5581 def test_next_src_nat(self):
5582 """ On way back forward packet to nat44-in2out node. """
5583 twice_nat_addr = '10.0.1.3'
5586 post_twice_nat_port = 0
5588 self.vapi.nat44_forwarding_enable_disable(enable=1)
5589 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5590 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5591 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5592 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5593 local_port, external_port,
5594 proto=IP_PROTOS.tcp, vrf_id=1,
5596 self.vapi.nat44_interface_add_del_feature(
5597 sw_if_index=self.pg6.sw_if_index,
5600 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5601 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5602 TCP(sport=12345, dport=external_port))
5603 self.pg6.add_stream(p)
5604 self.pg_enable_capture(self.pg_interfaces)
5606 capture = self.pg6.get_capture(1)
5611 self.assertEqual(ip.src, twice_nat_addr)
5612 self.assertNotEqual(tcp.sport, 12345)
5613 post_twice_nat_port = tcp.sport
5614 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5615 self.assertEqual(tcp.dport, local_port)
5616 self.assert_packet_checksums_valid(p)
5618 self.logger.error(ppp("Unexpected or invalid packet:", p))
5621 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5622 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5623 TCP(sport=local_port, dport=post_twice_nat_port))
5624 self.pg6.add_stream(p)
5625 self.pg_enable_capture(self.pg_interfaces)
5627 capture = self.pg6.get_capture(1)
5632 self.assertEqual(ip.src, self.pg1.remote_ip4)
5633 self.assertEqual(tcp.sport, external_port)
5634 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5635 self.assertEqual(tcp.dport, 12345)
5636 self.assert_packet_checksums_valid(p)
5638 self.logger.error(ppp("Unexpected or invalid packet:", p))
5641 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5643 twice_nat_addr = '10.0.1.3'
5651 port_in1 = port_in + 1
5652 port_in2 = port_in + 2
5657 server1 = self.pg0.remote_hosts[0]
5658 server2 = self.pg0.remote_hosts[1]
5670 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5673 self.nat44_add_address(self.nat_addr)
5674 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5678 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5680 flags |= self.config_flags.NAT_IS_TWICE_NAT
5683 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5685 proto=IP_PROTOS.tcp,
5688 locals = [{'addr': server1.ip4n,
5692 {'addr': server2.ip4n,
5696 out_addr = self.nat_addr
5698 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5699 external_addr=out_addr,
5700 external_port=port_out,
5701 protocol=IP_PROTOS.tcp,
5702 local_num=len(locals),
5704 flags = self.config_flags.NAT_IS_INSIDE
5705 self.vapi.nat44_interface_add_del_feature(
5706 sw_if_index=pg0.sw_if_index,
5707 flags=flags, is_add=1)
5708 self.vapi.nat44_interface_add_del_feature(
5709 sw_if_index=pg1.sw_if_index,
5716 assert client_id is not None
5718 client = self.pg0.remote_hosts[0]
5719 elif client_id == 2:
5720 client = self.pg0.remote_hosts[1]
5722 client = pg1.remote_hosts[0]
5723 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5724 IP(src=client.ip4, dst=self.nat_addr) /
5725 TCP(sport=eh_port_out, dport=port_out))
5727 self.pg_enable_capture(self.pg_interfaces)
5729 capture = pg0.get_capture(1)
5735 if ip.dst == server1.ip4:
5741 self.assertEqual(ip.dst, server.ip4)
5743 self.assertIn(tcp.dport, [port_in1, port_in2])
5745 self.assertEqual(tcp.dport, port_in)
5747 self.assertEqual(ip.src, twice_nat_addr)
5748 self.assertNotEqual(tcp.sport, eh_port_out)
5750 self.assertEqual(ip.src, client.ip4)
5751 self.assertEqual(tcp.sport, eh_port_out)
5753 eh_port_in = tcp.sport
5754 saved_port_in = tcp.dport
5755 self.assert_packet_checksums_valid(p)
5757 self.logger.error(ppp("Unexpected or invalid packet:", p))
5760 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5761 IP(src=server.ip4, dst=eh_addr_in) /
5762 TCP(sport=saved_port_in, dport=eh_port_in))
5764 self.pg_enable_capture(self.pg_interfaces)
5766 capture = pg1.get_capture(1)
5771 self.assertEqual(ip.dst, client.ip4)
5772 self.assertEqual(ip.src, self.nat_addr)
5773 self.assertEqual(tcp.dport, eh_port_out)
5774 self.assertEqual(tcp.sport, port_out)
5775 self.assert_packet_checksums_valid(p)
5777 self.logger.error(ppp("Unexpected or invalid packet:", p))
5781 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5782 self.assertEqual(len(sessions), 1)
5783 self.assertTrue(sessions[0].flags &
5784 self.config_flags.NAT_IS_EXT_HOST_VALID)
5785 self.assertTrue(sessions[0].flags &
5786 self.config_flags.NAT_IS_TWICE_NAT)
5787 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5788 self.vapi.nat44_del_session(
5789 address=sessions[0].inside_ip_address,
5790 port=sessions[0].inside_port,
5791 protocol=sessions[0].protocol,
5792 flags=(self.config_flags.NAT_IS_INSIDE |
5793 self.config_flags.NAT_IS_EXT_HOST_VALID),
5794 ext_host_address=sessions[0].ext_host_nat_address,
5795 ext_host_port=sessions[0].ext_host_nat_port)
5796 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5797 self.assertEqual(len(sessions), 0)
5799 def test_twice_nat(self):
5801 self.twice_nat_common()
5803 def test_self_twice_nat_positive(self):
5804 """ Self Twice NAT44 (positive test) """
5805 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5807 def test_self_twice_nat_negative(self):
5808 """ Self Twice NAT44 (negative test) """
5809 self.twice_nat_common(self_twice_nat=True)
5811 def test_twice_nat_lb(self):
5812 """ Twice NAT44 local service load balancing """
5813 self.twice_nat_common(lb=True)
5815 def test_self_twice_nat_lb_positive(self):
5816 """ Self Twice NAT44 local service load balancing (positive test) """
5817 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5820 def test_self_twice_nat_lb_negative(self):
5821 """ Self Twice NAT44 local service load balancing (negative test) """
5822 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5825 def test_twice_nat_interface_addr(self):
5826 """ Acquire twice NAT44 addresses from interface """
5827 flags = self.config_flags.NAT_IS_TWICE_NAT
5828 self.vapi.nat44_add_del_interface_addr(
5830 sw_if_index=self.pg3.sw_if_index,
5833 # no address in NAT pool
5834 adresses = self.vapi.nat44_address_dump()
5835 self.assertEqual(0, len(adresses))
5837 # configure interface address and check NAT address pool
5838 self.pg3.config_ip4()
5839 adresses = self.vapi.nat44_address_dump()
5840 self.assertEqual(1, len(adresses))
5841 self.assertEqual(str(adresses[0].ip_address),
5843 self.assertEqual(adresses[0].flags, flags)
5845 # remove interface address and check NAT address pool
5846 self.pg3.unconfig_ip4()
5847 adresses = self.vapi.nat44_address_dump()
5848 self.assertEqual(0, len(adresses))
5850 def test_tcp_close(self):
5851 """ Close TCP session from inside network - output feature """
5852 self.vapi.nat44_forwarding_enable_disable(enable=1)
5853 self.nat44_add_address(self.pg1.local_ip4)
5854 twice_nat_addr = '10.0.1.3'
5855 service_ip = '192.168.16.150'
5856 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5857 flags = self.config_flags.NAT_IS_INSIDE
5858 self.vapi.nat44_interface_add_del_feature(
5859 sw_if_index=self.pg0.sw_if_index,
5861 self.vapi.nat44_interface_add_del_feature(
5862 sw_if_index=self.pg0.sw_if_index,
5863 flags=flags, is_add=1)
5864 self.vapi.nat44_interface_add_del_output_feature(
5866 sw_if_index=self.pg1.sw_if_index)
5867 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5868 self.config_flags.NAT_IS_TWICE_NAT)
5869 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5873 proto=IP_PROTOS.tcp,
5875 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5876 start_sessnum = len(sessions)
5878 # SYN packet out->in
5879 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5880 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5881 TCP(sport=33898, dport=80, flags="S"))
5882 self.pg1.add_stream(p)
5883 self.pg_enable_capture(self.pg_interfaces)
5885 capture = self.pg0.get_capture(1)
5887 tcp_port = p[TCP].sport
5889 # SYN + ACK packet in->out
5890 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5891 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5892 TCP(sport=80, dport=tcp_port, flags="SA"))
5893 self.pg0.add_stream(p)
5894 self.pg_enable_capture(self.pg_interfaces)
5896 self.pg1.get_capture(1)
5898 # ACK packet out->in
5899 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5900 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5901 TCP(sport=33898, dport=80, flags="A"))
5902 self.pg1.add_stream(p)
5903 self.pg_enable_capture(self.pg_interfaces)
5905 self.pg0.get_capture(1)
5907 # FIN packet in -> out
5908 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5909 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5910 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5911 self.pg0.add_stream(p)
5912 self.pg_enable_capture(self.pg_interfaces)
5914 self.pg1.get_capture(1)
5916 # FIN+ACK packet out -> in
5917 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5918 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5919 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5920 self.pg1.add_stream(p)
5921 self.pg_enable_capture(self.pg_interfaces)
5923 self.pg0.get_capture(1)
5925 # ACK packet in -> out
5926 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5927 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5928 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5929 self.pg0.add_stream(p)
5930 self.pg_enable_capture(self.pg_interfaces)
5932 self.pg1.get_capture(1)
5934 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5936 self.assertEqual(len(sessions) - start_sessnum, 0)
5938 def test_tcp_session_close_in(self):
5939 """ Close TCP session from inside network """
5940 self.tcp_port_out = 10505
5941 self.nat44_add_address(self.nat_addr)
5942 flags = self.config_flags.NAT_IS_TWICE_NAT
5943 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5947 proto=IP_PROTOS.tcp,
5949 flags = self.config_flags.NAT_IS_INSIDE
5950 self.vapi.nat44_interface_add_del_feature(
5951 sw_if_index=self.pg0.sw_if_index,
5952 flags=flags, is_add=1)
5953 self.vapi.nat44_interface_add_del_feature(
5954 sw_if_index=self.pg1.sw_if_index,
5957 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5958 start_sessnum = len(sessions)
5960 self.initiate_tcp_session(self.pg0, self.pg1)
5962 # FIN packet in -> out
5963 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5964 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5965 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5966 flags="FA", seq=100, ack=300))
5967 self.pg0.add_stream(p)
5968 self.pg_enable_capture(self.pg_interfaces)
5970 self.pg1.get_capture(1)
5974 # ACK packet out -> in
5975 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5976 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5977 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5978 flags="A", seq=300, ack=101))
5981 # FIN packet out -> in
5982 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5983 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5984 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5985 flags="FA", seq=300, ack=101))
5988 self.pg1.add_stream(pkts)
5989 self.pg_enable_capture(self.pg_interfaces)
5991 self.pg0.get_capture(2)
5993 # ACK packet in -> out
5994 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5995 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5996 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5997 flags="A", seq=101, ack=301))
5998 self.pg0.add_stream(p)
5999 self.pg_enable_capture(self.pg_interfaces)
6001 self.pg1.get_capture(1)
6003 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6005 self.assertEqual(len(sessions) - start_sessnum, 0)
6007 def test_tcp_session_close_out(self):
6008 """ Close TCP session from outside network """
6009 self.tcp_port_out = 10505
6010 self.nat44_add_address(self.nat_addr)
6011 flags = self.config_flags.NAT_IS_TWICE_NAT
6012 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6016 proto=IP_PROTOS.tcp,
6018 flags = self.config_flags.NAT_IS_INSIDE
6019 self.vapi.nat44_interface_add_del_feature(
6020 sw_if_index=self.pg0.sw_if_index,
6021 flags=flags, is_add=1)
6022 self.vapi.nat44_interface_add_del_feature(
6023 sw_if_index=self.pg1.sw_if_index,
6026 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6027 start_sessnum = len(sessions)
6029 self.initiate_tcp_session(self.pg0, self.pg1)
6031 # FIN packet out -> in
6032 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6033 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6034 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6035 flags="FA", seq=100, ack=300))
6036 self.pg1.add_stream(p)
6037 self.pg_enable_capture(self.pg_interfaces)
6039 self.pg0.get_capture(1)
6041 # FIN+ACK packet in -> out
6042 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6043 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6044 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6045 flags="FA", seq=300, ack=101))
6047 self.pg0.add_stream(p)
6048 self.pg_enable_capture(self.pg_interfaces)
6050 self.pg1.get_capture(1)
6052 # ACK packet out -> in
6053 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6054 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6055 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6056 flags="A", seq=101, ack=301))
6057 self.pg1.add_stream(p)
6058 self.pg_enable_capture(self.pg_interfaces)
6060 self.pg0.get_capture(1)
6062 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6064 self.assertEqual(len(sessions) - start_sessnum, 0)
6066 def test_tcp_session_close_simultaneous(self):
6067 """ Close TCP session from inside network """
6068 self.tcp_port_out = 10505
6069 self.nat44_add_address(self.nat_addr)
6070 flags = self.config_flags.NAT_IS_TWICE_NAT
6071 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6075 proto=IP_PROTOS.tcp,
6077 flags = self.config_flags.NAT_IS_INSIDE
6078 self.vapi.nat44_interface_add_del_feature(
6079 sw_if_index=self.pg0.sw_if_index,
6080 flags=flags, is_add=1)
6081 self.vapi.nat44_interface_add_del_feature(
6082 sw_if_index=self.pg1.sw_if_index,
6085 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6086 start_sessnum = len(sessions)
6088 self.initiate_tcp_session(self.pg0, self.pg1)
6090 # FIN packet in -> out
6091 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6092 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6093 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6094 flags="FA", seq=100, ack=300))
6095 self.pg0.add_stream(p)
6096 self.pg_enable_capture(self.pg_interfaces)
6098 self.pg1.get_capture(1)
6100 # FIN packet out -> in
6101 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6102 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6103 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6104 flags="FA", seq=300, ack=100))
6105 self.pg1.add_stream(p)
6106 self.pg_enable_capture(self.pg_interfaces)
6108 self.pg0.get_capture(1)
6110 # ACK packet in -> out
6111 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6112 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6113 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6114 flags="A", seq=101, ack=301))
6115 self.pg0.add_stream(p)
6116 self.pg_enable_capture(self.pg_interfaces)
6118 self.pg1.get_capture(1)
6120 # ACK packet out -> in
6121 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6122 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6123 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6124 flags="A", seq=301, ack=101))
6125 self.pg1.add_stream(p)
6126 self.pg_enable_capture(self.pg_interfaces)
6128 self.pg0.get_capture(1)
6130 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6132 self.assertEqual(len(sessions) - start_sessnum, 0)
6134 def test_one_armed_nat44_static(self):
6135 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6136 remote_host = self.pg4.remote_hosts[0]
6137 local_host = self.pg4.remote_hosts[1]
6142 self.vapi.nat44_forwarding_enable_disable(enable=1)
6143 self.nat44_add_address(self.nat_addr, twice_nat=1)
6144 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6145 self.config_flags.NAT_IS_TWICE_NAT)
6146 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6147 local_port, external_port,
6148 proto=IP_PROTOS.tcp, flags=flags)
6149 flags = self.config_flags.NAT_IS_INSIDE
6150 self.vapi.nat44_interface_add_del_feature(
6151 sw_if_index=self.pg4.sw_if_index,
6153 self.vapi.nat44_interface_add_del_feature(
6154 sw_if_index=self.pg4.sw_if_index,
6155 flags=flags, is_add=1)
6157 # from client to service
6158 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6159 IP(src=remote_host.ip4, dst=self.nat_addr) /
6160 TCP(sport=12345, dport=external_port))
6161 self.pg4.add_stream(p)
6162 self.pg_enable_capture(self.pg_interfaces)
6164 capture = self.pg4.get_capture(1)
6169 self.assertEqual(ip.dst, local_host.ip4)
6170 self.assertEqual(ip.src, self.nat_addr)
6171 self.assertEqual(tcp.dport, local_port)
6172 self.assertNotEqual(tcp.sport, 12345)
6173 eh_port_in = tcp.sport
6174 self.assert_packet_checksums_valid(p)
6176 self.logger.error(ppp("Unexpected or invalid packet:", p))
6179 # from service back to client
6180 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6181 IP(src=local_host.ip4, dst=self.nat_addr) /
6182 TCP(sport=local_port, dport=eh_port_in))
6183 self.pg4.add_stream(p)
6184 self.pg_enable_capture(self.pg_interfaces)
6186 capture = self.pg4.get_capture(1)
6191 self.assertEqual(ip.src, self.nat_addr)
6192 self.assertEqual(ip.dst, remote_host.ip4)
6193 self.assertEqual(tcp.sport, external_port)
6194 self.assertEqual(tcp.dport, 12345)
6195 self.assert_packet_checksums_valid(p)
6197 self.logger.error(ppp("Unexpected or invalid packet:", p))
6200 def test_static_with_port_out2(self):
6201 """ 1:1 NAPT asymmetrical rule """
6206 self.vapi.nat44_forwarding_enable_disable(enable=1)
6207 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6208 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6209 local_port, external_port,
6210 proto=IP_PROTOS.tcp, flags=flags)
6211 flags = self.config_flags.NAT_IS_INSIDE
6212 self.vapi.nat44_interface_add_del_feature(
6213 sw_if_index=self.pg0.sw_if_index,
6214 flags=flags, is_add=1)
6215 self.vapi.nat44_interface_add_del_feature(
6216 sw_if_index=self.pg1.sw_if_index,
6219 # from client to service
6220 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6221 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6222 TCP(sport=12345, dport=external_port))
6223 self.pg1.add_stream(p)
6224 self.pg_enable_capture(self.pg_interfaces)
6226 capture = self.pg0.get_capture(1)
6231 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6232 self.assertEqual(tcp.dport, local_port)
6233 self.assert_packet_checksums_valid(p)
6235 self.logger.error(ppp("Unexpected or invalid packet:", p))
6239 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6240 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6241 ICMP(type=11) / capture[0][IP])
6242 self.pg0.add_stream(p)
6243 self.pg_enable_capture(self.pg_interfaces)
6245 capture = self.pg1.get_capture(1)
6248 self.assertEqual(p[IP].src, self.nat_addr)
6250 self.assertEqual(inner.dst, self.nat_addr)
6251 self.assertEqual(inner[TCPerror].dport, external_port)
6253 self.logger.error(ppp("Unexpected or invalid packet:", p))
6256 # from service back to client
6257 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6258 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6259 TCP(sport=local_port, dport=12345))
6260 self.pg0.add_stream(p)
6261 self.pg_enable_capture(self.pg_interfaces)
6263 capture = self.pg1.get_capture(1)
6268 self.assertEqual(ip.src, self.nat_addr)
6269 self.assertEqual(tcp.sport, external_port)
6270 self.assert_packet_checksums_valid(p)
6272 self.logger.error(ppp("Unexpected or invalid packet:", p))
6276 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6277 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6278 ICMP(type=11) / capture[0][IP])
6279 self.pg1.add_stream(p)
6280 self.pg_enable_capture(self.pg_interfaces)
6282 capture = self.pg0.get_capture(1)
6285 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6287 self.assertEqual(inner.src, self.pg0.remote_ip4)
6288 self.assertEqual(inner[TCPerror].sport, local_port)
6290 self.logger.error(ppp("Unexpected or invalid packet:", p))
6293 # from client to server (no translation)
6294 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6295 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6296 TCP(sport=12346, dport=local_port))
6297 self.pg1.add_stream(p)
6298 self.pg_enable_capture(self.pg_interfaces)
6300 capture = self.pg0.get_capture(1)
6305 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6306 self.assertEqual(tcp.dport, local_port)
6307 self.assert_packet_checksums_valid(p)
6309 self.logger.error(ppp("Unexpected or invalid packet:", p))
6312 # from service back to client (no translation)
6313 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6314 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6315 TCP(sport=local_port, dport=12346))
6316 self.pg0.add_stream(p)
6317 self.pg_enable_capture(self.pg_interfaces)
6319 capture = self.pg1.get_capture(1)
6324 self.assertEqual(ip.src, self.pg0.remote_ip4)
6325 self.assertEqual(tcp.sport, local_port)
6326 self.assert_packet_checksums_valid(p)
6328 self.logger.error(ppp("Unexpected or invalid packet:", p))
6331 def test_output_feature(self):
6332 """ NAT44 interface output feature (in2out postrouting) """
6333 self.vapi.nat44_forwarding_enable_disable(enable=1)
6334 self.nat44_add_address(self.nat_addr)
6335 self.vapi.nat44_interface_add_del_feature(
6336 sw_if_index=self.pg0.sw_if_index,
6338 self.vapi.nat44_interface_add_del_output_feature(
6340 sw_if_index=self.pg1.sw_if_index)
6343 pkts = self.create_stream_in(self.pg0, self.pg1)
6344 self.pg0.add_stream(pkts)
6345 self.pg_enable_capture(self.pg_interfaces)
6347 capture = self.pg1.get_capture(len(pkts))
6348 self.verify_capture_out(capture)
6351 pkts = self.create_stream_out(self.pg1)
6352 self.pg1.add_stream(pkts)
6353 self.pg_enable_capture(self.pg_interfaces)
6355 capture = self.pg0.get_capture(len(pkts))
6356 self.verify_capture_in(capture, self.pg0)
6358 def test_multiple_vrf(self):
6359 """ Multiple VRF setup """
6360 external_addr = '1.2.3.4'
6365 self.vapi.nat44_forwarding_enable_disable(enable=1)
6366 self.nat44_add_address(self.nat_addr)
6367 flags = self.config_flags.NAT_IS_INSIDE
6368 self.vapi.nat44_interface_add_del_feature(
6369 sw_if_index=self.pg0.sw_if_index,
6371 self.vapi.nat44_interface_add_del_feature(
6372 sw_if_index=self.pg0.sw_if_index,
6373 flags=flags, is_add=1)
6374 self.vapi.nat44_interface_add_del_output_feature(
6376 sw_if_index=self.pg1.sw_if_index)
6377 self.vapi.nat44_interface_add_del_feature(
6378 sw_if_index=self.pg5.sw_if_index,
6380 self.vapi.nat44_interface_add_del_feature(
6381 sw_if_index=self.pg5.sw_if_index,
6382 flags=flags, is_add=1)
6383 self.vapi.nat44_interface_add_del_feature(
6384 sw_if_index=self.pg6.sw_if_index,
6386 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6387 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6388 local_port, external_port, vrf_id=1,
6389 proto=IP_PROTOS.tcp, flags=flags)
6390 self.nat44_add_static_mapping(
6391 self.pg0.remote_ip4,
6392 external_sw_if_index=self.pg0.sw_if_index,
6393 local_port=local_port,
6395 external_port=external_port,
6396 proto=IP_PROTOS.tcp,
6400 # from client to service (both VRF1)
6401 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6402 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6403 TCP(sport=12345, dport=external_port))
6404 self.pg6.add_stream(p)
6405 self.pg_enable_capture(self.pg_interfaces)
6407 capture = self.pg5.get_capture(1)
6412 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6413 self.assertEqual(tcp.dport, local_port)
6414 self.assert_packet_checksums_valid(p)
6416 self.logger.error(ppp("Unexpected or invalid packet:", p))
6419 # from service back to client (both VRF1)
6420 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6421 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6422 TCP(sport=local_port, dport=12345))
6423 self.pg5.add_stream(p)
6424 self.pg_enable_capture(self.pg_interfaces)
6426 capture = self.pg6.get_capture(1)
6431 self.assertEqual(ip.src, external_addr)
6432 self.assertEqual(tcp.sport, external_port)
6433 self.assert_packet_checksums_valid(p)
6435 self.logger.error(ppp("Unexpected or invalid packet:", p))
6438 # dynamic NAT from VRF1 to VRF0 (output-feature)
6439 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6440 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6441 TCP(sport=2345, dport=22))
6442 self.pg5.add_stream(p)
6443 self.pg_enable_capture(self.pg_interfaces)
6445 capture = self.pg1.get_capture(1)
6450 self.assertEqual(ip.src, self.nat_addr)
6451 self.assertNotEqual(tcp.sport, 2345)
6452 self.assert_packet_checksums_valid(p)
6455 self.logger.error(ppp("Unexpected or invalid packet:", p))
6458 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6459 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6460 TCP(sport=22, dport=port))
6461 self.pg1.add_stream(p)
6462 self.pg_enable_capture(self.pg_interfaces)
6464 capture = self.pg5.get_capture(1)
6469 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6470 self.assertEqual(tcp.dport, 2345)
6471 self.assert_packet_checksums_valid(p)
6473 self.logger.error(ppp("Unexpected or invalid packet:", p))
6476 # from client VRF1 to service VRF0
6477 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6478 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6479 TCP(sport=12346, dport=external_port))
6480 self.pg6.add_stream(p)
6481 self.pg_enable_capture(self.pg_interfaces)
6483 capture = self.pg0.get_capture(1)
6488 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6489 self.assertEqual(tcp.dport, local_port)
6490 self.assert_packet_checksums_valid(p)
6492 self.logger.error(ppp("Unexpected or invalid packet:", p))
6495 # from service VRF0 back to client VRF1
6496 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6497 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6498 TCP(sport=local_port, dport=12346))
6499 self.pg0.add_stream(p)
6500 self.pg_enable_capture(self.pg_interfaces)
6502 capture = self.pg6.get_capture(1)
6507 self.assertEqual(ip.src, self.pg0.local_ip4)
6508 self.assertEqual(tcp.sport, external_port)
6509 self.assert_packet_checksums_valid(p)
6511 self.logger.error(ppp("Unexpected or invalid packet:", p))
6514 # from client VRF0 to service VRF1
6515 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6516 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6517 TCP(sport=12347, dport=external_port))
6518 self.pg0.add_stream(p)
6519 self.pg_enable_capture(self.pg_interfaces)
6521 capture = self.pg5.get_capture(1)
6526 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6527 self.assertEqual(tcp.dport, local_port)
6528 self.assert_packet_checksums_valid(p)
6530 self.logger.error(ppp("Unexpected or invalid packet:", p))
6533 # from service VRF1 back to client VRF0
6534 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6535 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6536 TCP(sport=local_port, dport=12347))
6537 self.pg5.add_stream(p)
6538 self.pg_enable_capture(self.pg_interfaces)
6540 capture = self.pg0.get_capture(1)
6545 self.assertEqual(ip.src, external_addr)
6546 self.assertEqual(tcp.sport, external_port)
6547 self.assert_packet_checksums_valid(p)
6549 self.logger.error(ppp("Unexpected or invalid packet:", p))
6552 # from client to server (both VRF1, no translation)
6553 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6554 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6555 TCP(sport=12348, dport=local_port))
6556 self.pg6.add_stream(p)
6557 self.pg_enable_capture(self.pg_interfaces)
6559 capture = self.pg5.get_capture(1)
6564 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6565 self.assertEqual(tcp.dport, local_port)
6566 self.assert_packet_checksums_valid(p)
6568 self.logger.error(ppp("Unexpected or invalid packet:", p))
6571 # from server back to client (both VRF1, no translation)
6572 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6573 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6574 TCP(sport=local_port, dport=12348))
6575 self.pg5.add_stream(p)
6576 self.pg_enable_capture(self.pg_interfaces)
6578 capture = self.pg6.get_capture(1)
6583 self.assertEqual(ip.src, self.pg5.remote_ip4)
6584 self.assertEqual(tcp.sport, local_port)
6585 self.assert_packet_checksums_valid(p)
6587 self.logger.error(ppp("Unexpected or invalid packet:", p))
6590 # from client VRF1 to server VRF0 (no translation)
6591 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6592 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6593 TCP(sport=local_port, dport=12349))
6594 self.pg0.add_stream(p)
6595 self.pg_enable_capture(self.pg_interfaces)
6597 capture = self.pg6.get_capture(1)
6602 self.assertEqual(ip.src, self.pg0.remote_ip4)
6603 self.assertEqual(tcp.sport, local_port)
6604 self.assert_packet_checksums_valid(p)
6606 self.logger.error(ppp("Unexpected or invalid packet:", p))
6609 # from server VRF0 back to client VRF1 (no translation)
6610 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6611 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6612 TCP(sport=local_port, dport=12349))
6613 self.pg0.add_stream(p)
6614 self.pg_enable_capture(self.pg_interfaces)
6616 capture = self.pg6.get_capture(1)
6621 self.assertEqual(ip.src, self.pg0.remote_ip4)
6622 self.assertEqual(tcp.sport, local_port)
6623 self.assert_packet_checksums_valid(p)
6625 self.logger.error(ppp("Unexpected or invalid packet:", p))
6628 # from client VRF0 to server VRF1 (no translation)
6629 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6630 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6631 TCP(sport=12344, dport=local_port))
6632 self.pg0.add_stream(p)
6633 self.pg_enable_capture(self.pg_interfaces)
6635 capture = self.pg5.get_capture(1)
6640 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6641 self.assertEqual(tcp.dport, local_port)
6642 self.assert_packet_checksums_valid(p)
6644 self.logger.error(ppp("Unexpected or invalid packet:", p))
6647 # from server VRF1 back to client VRF0 (no translation)
6648 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6649 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6650 TCP(sport=local_port, dport=12344))
6651 self.pg5.add_stream(p)
6652 self.pg_enable_capture(self.pg_interfaces)
6654 capture = self.pg0.get_capture(1)
6659 self.assertEqual(ip.src, self.pg5.remote_ip4)
6660 self.assertEqual(tcp.sport, local_port)
6661 self.assert_packet_checksums_valid(p)
6663 self.logger.error(ppp("Unexpected or invalid packet:", p))
6666 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6667 def test_session_timeout(self):
6668 """ NAT44 session timeouts """
6669 self.nat44_add_address(self.nat_addr)
6670 flags = self.config_flags.NAT_IS_INSIDE
6671 self.vapi.nat44_interface_add_del_feature(
6672 sw_if_index=self.pg0.sw_if_index,
6673 flags=flags, is_add=1)
6674 self.vapi.nat44_interface_add_del_feature(
6675 sw_if_index=self.pg1.sw_if_index,
6677 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6678 tcp_transitory=240, icmp=5)
6682 for i in range(0, max_sessions):
6683 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6684 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6685 IP(src=src, dst=self.pg1.remote_ip4) /
6686 ICMP(id=1025, type='echo-request'))
6688 self.pg0.add_stream(pkts)
6689 self.pg_enable_capture(self.pg_interfaces)
6691 self.pg1.get_capture(max_sessions)
6696 for i in range(0, max_sessions):
6697 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6698 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6699 IP(src=src, dst=self.pg1.remote_ip4) /
6700 ICMP(id=1026, type='echo-request'))
6702 self.pg0.add_stream(pkts)
6703 self.pg_enable_capture(self.pg_interfaces)
6705 self.pg1.get_capture(max_sessions)
6708 users = self.vapi.nat44_user_dump()
6710 nsessions = nsessions + user.nsessions
6711 self.assertLess(nsessions, 2 * max_sessions)
6713 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6714 def test_session_rst_timeout(self):
6715 """ NAT44 session RST timeouts """
6716 self.nat44_add_address(self.nat_addr)
6717 flags = self.config_flags.NAT_IS_INSIDE
6718 self.vapi.nat44_interface_add_del_feature(
6719 sw_if_index=self.pg0.sw_if_index,
6720 flags=flags, is_add=1)
6721 self.vapi.nat44_interface_add_del_feature(
6722 sw_if_index=self.pg1.sw_if_index,
6724 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6725 tcp_transitory=5, icmp=60)
6727 self.initiate_tcp_session(self.pg0, self.pg1)
6728 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6729 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6730 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6732 self.pg0.add_stream(p)
6733 self.pg_enable_capture(self.pg_interfaces)
6735 self.pg1.get_capture(1)
6739 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6740 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6741 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6743 self.pg0.add_stream(p)
6744 self.pg_enable_capture(self.pg_interfaces)
6746 self.pg1.get_capture(1)
6749 users = self.vapi.nat44_user_dump()
6750 self.assertEqual(len(users), 1)
6751 self.assertEqual(str(users[0].ip_address),
6752 self.pg0.remote_ip4)
6753 self.assertEqual(users[0].nsessions, 1)
6755 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6756 def test_session_limit_per_user(self):
6757 """ Maximum sessions per user limit """
6758 self.nat44_add_address(self.nat_addr)
6759 flags = self.config_flags.NAT_IS_INSIDE
6760 self.vapi.nat44_interface_add_del_feature(
6761 sw_if_index=self.pg0.sw_if_index,
6762 flags=flags, is_add=1)
6763 self.vapi.nat44_interface_add_del_feature(
6764 sw_if_index=self.pg1.sw_if_index,
6766 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6767 src_address=self.pg2.local_ip4n,
6769 template_interval=10)
6770 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6771 tcp_transitory=240, icmp=60)
6773 # get maximum number of translations per user
6774 nat44_config = self.vapi.nat_show_config()
6777 for port in range(0, nat44_config.max_translations_per_user):
6778 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6779 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6780 UDP(sport=1025 + port, dport=1025 + port))
6783 self.pg0.add_stream(pkts)
6784 self.pg_enable_capture(self.pg_interfaces)
6786 capture = self.pg1.get_capture(len(pkts))
6788 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6789 src_port=self.ipfix_src_port,
6792 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6793 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6794 UDP(sport=3001, dport=3002))
6795 self.pg0.add_stream(p)
6796 self.pg_enable_capture(self.pg_interfaces)
6798 capture = self.pg1.assert_nothing_captured()
6800 # verify IPFIX logging
6801 self.vapi.ipfix_flush()
6803 capture = self.pg2.get_capture(10)
6804 ipfix = IPFIXDecoder()
6805 # first load template
6807 self.assertTrue(p.haslayer(IPFIX))
6808 if p.haslayer(Template):
6809 ipfix.add_template(p.getlayer(Template))
6810 # verify events in data set
6812 if p.haslayer(Data):
6813 data = ipfix.decode_data_set(p.getlayer(Set))
6814 self.verify_ipfix_max_entries_per_user(
6816 nat44_config.max_translations_per_user,
6817 self.pg0.remote_ip4n)
6820 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6821 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6822 UDP(sport=3001, dport=3002))
6823 self.pg0.add_stream(p)
6824 self.pg_enable_capture(self.pg_interfaces)
6826 self.pg1.get_capture(1)
6828 def test_syslog_sess(self):
6829 """ Test syslog session creation and deletion """
6830 self.vapi.syslog_set_filter(
6831 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6832 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6833 self.nat44_add_address(self.nat_addr)
6834 flags = self.config_flags.NAT_IS_INSIDE
6835 self.vapi.nat44_interface_add_del_feature(
6836 sw_if_index=self.pg0.sw_if_index,
6837 flags=flags, is_add=1)
6838 self.vapi.nat44_interface_add_del_feature(
6839 sw_if_index=self.pg1.sw_if_index,
6842 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6843 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6844 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6845 self.pg0.add_stream(p)
6846 self.pg_enable_capture(self.pg_interfaces)
6848 capture = self.pg1.get_capture(1)
6849 self.tcp_port_out = capture[0][TCP].sport
6850 capture = self.pg2.get_capture(1)
6851 self.verify_syslog_sess(capture[0][Raw].load)
6853 self.pg_enable_capture(self.pg_interfaces)
6855 self.nat44_add_address(self.nat_addr, is_add=0)
6856 capture = self.pg2.get_capture(1)
6857 self.verify_syslog_sess(capture[0][Raw].load, False)
6860 super(TestNAT44EndpointDependent, self).tearDown()
6861 if not self.vpp_dead:
6863 self.vapi.cli("clear logging")
6865 def show_commands_at_teardown(self):
6866 self.logger.info(self.vapi.cli("show nat44 addresses"))
6867 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6868 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6869 self.logger.info(self.vapi.cli("show nat44 interface address"))
6870 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6871 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6872 self.logger.info(self.vapi.cli("show nat timeouts"))
6875 class TestNAT44Out2InDPO(MethodHolder):
6876 """ NAT44 Test Cases using out2in DPO """
6879 def setUpConstants(cls):
6880 super(TestNAT44Out2InDPO, cls).setUpConstants()
6881 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6884 def setUpClass(cls):
6885 super(TestNAT44Out2InDPO, cls).setUpClass()
6886 cls.vapi.cli("set log class nat level debug")
6889 cls.tcp_port_in = 6303
6890 cls.tcp_port_out = 6303
6891 cls.udp_port_in = 6304
6892 cls.udp_port_out = 6304
6893 cls.icmp_id_in = 6305
6894 cls.icmp_id_out = 6305
6895 cls.nat_addr = '10.0.0.3'
6896 cls.dst_ip4 = '192.168.70.1'
6898 cls.create_pg_interfaces(range(2))
6901 cls.pg0.config_ip4()
6902 cls.pg0.resolve_arp()
6905 cls.pg1.config_ip6()
6906 cls.pg1.resolve_ndp()
6908 r1 = VppIpRoute(cls, "::", 0,
6909 [VppRoutePath(cls.pg1.remote_ip6,
6910 cls.pg1.sw_if_index)],
6915 super(TestNAT44Out2InDPO, cls).tearDownClass()
6919 def tearDownClass(cls):
6920 super(TestNAT44Out2InDPO, cls).tearDownClass()
6922 def configure_xlat(self):
6923 self.dst_ip6_pfx = '1:2:3::'
6924 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6926 self.dst_ip6_pfx_len = 96
6927 self.src_ip6_pfx = '4:5:6::'
6928 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6930 self.src_ip6_pfx_len = 96
6931 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6932 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6933 '\x00\x00\x00\x00', 0)
6935 @unittest.skip('Temporary disabled')
6936 def test_464xlat_ce(self):
6937 """ Test 464XLAT CE with NAT44 """
6939 nat_config = self.vapi.nat_show_config()
6940 self.assertEqual(1, nat_config.out2in_dpo)
6942 self.configure_xlat()
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_add_del_address_range(first_ip_address=self.nat_addr_n,
6949 last_ip_address=self.nat_addr_n,
6950 vrf_id=0xFFFFFFFF, is_add=1)
6952 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6953 self.dst_ip6_pfx_len)
6954 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6955 self.src_ip6_pfx_len)
6958 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6959 self.pg0.add_stream(pkts)
6960 self.pg_enable_capture(self.pg_interfaces)
6962 capture = self.pg1.get_capture(len(pkts))
6963 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6966 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6968 self.pg1.add_stream(pkts)
6969 self.pg_enable_capture(self.pg_interfaces)
6971 capture = self.pg0.get_capture(len(pkts))
6972 self.verify_capture_in(capture, self.pg0)
6974 self.vapi.nat44_interface_add_del_feature(
6975 sw_if_index=self.pg0.sw_if_index,
6977 self.vapi.nat44_add_del_address_range(
6978 first_ip_address=self.nat_addr_n,
6979 last_ip_address=self.nat_addr_n,
6982 @unittest.skip('Temporary disabled')
6983 def test_464xlat_ce_no_nat(self):
6984 """ Test 464XLAT CE without NAT44 """
6986 self.configure_xlat()
6988 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6989 self.dst_ip6_pfx_len)
6990 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6991 self.src_ip6_pfx_len)
6993 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6994 self.pg0.add_stream(pkts)
6995 self.pg_enable_capture(self.pg_interfaces)
6997 capture = self.pg1.get_capture(len(pkts))
6998 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6999 nat_ip=out_dst_ip6, same_port=True)
7001 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7002 self.pg1.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 capture = self.pg0.get_capture(len(pkts))
7006 self.verify_capture_in(capture, self.pg0)
7009 class TestDeterministicNAT(MethodHolder):
7010 """ Deterministic NAT Test Cases """
7013 def setUpConstants(cls):
7014 super(TestDeterministicNAT, cls).setUpConstants()
7015 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7018 def setUpClass(cls):
7019 super(TestDeterministicNAT, cls).setUpClass()
7020 cls.vapi.cli("set log class nat level debug")
7023 cls.tcp_port_in = 6303
7024 cls.tcp_external_port = 6303
7025 cls.udp_port_in = 6304
7026 cls.udp_external_port = 6304
7027 cls.icmp_id_in = 6305
7028 cls.nat_addr = '10.0.0.3'
7030 cls.create_pg_interfaces(range(3))
7031 cls.interfaces = list(cls.pg_interfaces)
7033 for i in cls.interfaces:
7038 cls.pg0.generate_remote_hosts(2)
7039 cls.pg0.configure_ipv4_neighbors()
7042 super(TestDeterministicNAT, cls).tearDownClass()
7046 def tearDownClass(cls):
7047 super(TestDeterministicNAT, cls).tearDownClass()
7049 def create_stream_in(self, in_if, out_if, ttl=64):
7051 Create packet stream for inside network
7053 :param in_if: Inside interface
7054 :param out_if: Outside interface
7055 :param ttl: TTL of generated packets
7059 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7060 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7061 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7065 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7066 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7067 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7071 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7072 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7073 ICMP(id=self.icmp_id_in, type='echo-request'))
7078 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7080 Create packet stream for outside network
7082 :param out_if: Outside interface
7083 :param dst_ip: Destination IP address (Default use global NAT address)
7084 :param ttl: TTL of generated packets
7087 dst_ip = self.nat_addr
7090 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7091 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7092 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7096 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7097 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7098 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7102 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7103 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7104 ICMP(id=self.icmp_external_id, type='echo-reply'))
7109 def verify_capture_out(self, capture, nat_ip=None):
7111 Verify captured packets on outside network
7113 :param capture: Captured packets
7114 :param nat_ip: Translated IP address (Default use global NAT address)
7115 :param same_port: Source port number is not translated (Default False)
7118 nat_ip = self.nat_addr
7119 for packet in capture:
7121 self.assertEqual(packet[IP].src, nat_ip)
7122 if packet.haslayer(TCP):
7123 self.tcp_port_out = packet[TCP].sport
7124 elif packet.haslayer(UDP):
7125 self.udp_port_out = packet[UDP].sport
7127 self.icmp_external_id = packet[ICMP].id
7129 self.logger.error(ppp("Unexpected or invalid packet "
7130 "(outside network):", packet))
7133 def test_deterministic_mode(self):
7134 """ NAT plugin run deterministic mode """
7135 in_addr = '172.16.255.0'
7136 out_addr = '172.17.255.50'
7137 in_addr_t = '172.16.255.20'
7141 nat_config = self.vapi.nat_show_config()
7142 self.assertEqual(1, nat_config.deterministic)
7144 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7145 in_plen=in_plen, out_addr=out_addr,
7148 rep1 = self.vapi.nat_det_forward(in_addr_t)
7149 self.assertEqual(str(rep1.out_addr), out_addr)
7150 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7152 self.assertEqual(str(rep2.in_addr), in_addr_t)
7154 deterministic_mappings = self.vapi.nat_det_map_dump()
7155 self.assertEqual(len(deterministic_mappings), 1)
7156 dsm = deterministic_mappings[0]
7157 self.assertEqual(in_addr, str(dsm.in_addr))
7158 self.assertEqual(in_plen, dsm.in_plen)
7159 self.assertEqual(out_addr, str(dsm.out_addr))
7160 self.assertEqual(out_plen, dsm.out_plen)
7162 self.clear_nat_det()
7163 deterministic_mappings = self.vapi.nat_det_map_dump()
7164 self.assertEqual(len(deterministic_mappings), 0)
7166 def test_set_timeouts(self):
7167 """ Set deterministic NAT timeouts """
7168 timeouts_before = self.vapi.nat_get_timeouts()
7170 self.vapi.nat_set_timeouts(
7171 udp=timeouts_before.udp + 10,
7172 tcp_established=timeouts_before.tcp_established + 10,
7173 tcp_transitory=timeouts_before.tcp_transitory + 10,
7174 icmp=timeouts_before.icmp + 10)
7176 timeouts_after = self.vapi.nat_get_timeouts()
7178 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7179 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7180 self.assertNotEqual(timeouts_before.tcp_established,
7181 timeouts_after.tcp_established)
7182 self.assertNotEqual(timeouts_before.tcp_transitory,
7183 timeouts_after.tcp_transitory)
7185 def test_det_in(self):
7186 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7188 nat_ip = "10.0.0.10"
7190 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7192 out_addr=socket.inet_aton(nat_ip),
7195 flags = self.config_flags.NAT_IS_INSIDE
7196 self.vapi.nat44_interface_add_del_feature(
7197 sw_if_index=self.pg0.sw_if_index,
7198 flags=flags, is_add=1)
7199 self.vapi.nat44_interface_add_del_feature(
7200 sw_if_index=self.pg1.sw_if_index,
7204 pkts = self.create_stream_in(self.pg0, self.pg1)
7205 self.pg0.add_stream(pkts)
7206 self.pg_enable_capture(self.pg_interfaces)
7208 capture = self.pg1.get_capture(len(pkts))
7209 self.verify_capture_out(capture, nat_ip)
7212 pkts = self.create_stream_out(self.pg1, nat_ip)
7213 self.pg1.add_stream(pkts)
7214 self.pg_enable_capture(self.pg_interfaces)
7216 capture = self.pg0.get_capture(len(pkts))
7217 self.verify_capture_in(capture, self.pg0)
7220 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7221 self.assertEqual(len(sessions), 3)
7225 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7226 self.assertEqual(s.in_port, self.tcp_port_in)
7227 self.assertEqual(s.out_port, self.tcp_port_out)
7228 self.assertEqual(s.ext_port, self.tcp_external_port)
7232 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7233 self.assertEqual(s.in_port, self.udp_port_in)
7234 self.assertEqual(s.out_port, self.udp_port_out)
7235 self.assertEqual(s.ext_port, self.udp_external_port)
7239 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7240 self.assertEqual(s.in_port, self.icmp_id_in)
7241 self.assertEqual(s.out_port, self.icmp_external_id)
7243 def test_multiple_users(self):
7244 """ Deterministic NAT multiple users """
7246 nat_ip = "10.0.0.10"
7248 external_port = 6303
7250 host0 = self.pg0.remote_hosts[0]
7251 host1 = self.pg0.remote_hosts[1]
7253 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7254 out_addr=socket.inet_aton(nat_ip),
7256 flags = self.config_flags.NAT_IS_INSIDE
7257 self.vapi.nat44_interface_add_del_feature(
7258 sw_if_index=self.pg0.sw_if_index,
7259 flags=flags, is_add=1)
7260 self.vapi.nat44_interface_add_del_feature(
7261 sw_if_index=self.pg1.sw_if_index,
7265 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7266 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7267 TCP(sport=port_in, dport=external_port))
7268 self.pg0.add_stream(p)
7269 self.pg_enable_capture(self.pg_interfaces)
7271 capture = self.pg1.get_capture(1)
7276 self.assertEqual(ip.src, nat_ip)
7277 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7278 self.assertEqual(tcp.dport, external_port)
7279 port_out0 = tcp.sport
7281 self.logger.error(ppp("Unexpected or invalid packet:", p))
7285 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7286 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7287 TCP(sport=port_in, dport=external_port))
7288 self.pg0.add_stream(p)
7289 self.pg_enable_capture(self.pg_interfaces)
7291 capture = self.pg1.get_capture(1)
7296 self.assertEqual(ip.src, nat_ip)
7297 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7298 self.assertEqual(tcp.dport, external_port)
7299 port_out1 = tcp.sport
7301 self.logger.error(ppp("Unexpected or invalid packet:", p))
7304 dms = self.vapi.nat_det_map_dump()
7305 self.assertEqual(1, len(dms))
7306 self.assertEqual(2, dms[0].ses_num)
7309 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7310 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7311 TCP(sport=external_port, dport=port_out0))
7312 self.pg1.add_stream(p)
7313 self.pg_enable_capture(self.pg_interfaces)
7315 capture = self.pg0.get_capture(1)
7320 self.assertEqual(ip.src, self.pg1.remote_ip4)
7321 self.assertEqual(ip.dst, host0.ip4)
7322 self.assertEqual(tcp.dport, port_in)
7323 self.assertEqual(tcp.sport, external_port)
7325 self.logger.error(ppp("Unexpected or invalid packet:", p))
7329 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7330 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7331 TCP(sport=external_port, dport=port_out1))
7332 self.pg1.add_stream(p)
7333 self.pg_enable_capture(self.pg_interfaces)
7335 capture = self.pg0.get_capture(1)
7340 self.assertEqual(ip.src, self.pg1.remote_ip4)
7341 self.assertEqual(ip.dst, host1.ip4)
7342 self.assertEqual(tcp.dport, port_in)
7343 self.assertEqual(tcp.sport, external_port)
7345 self.logger.error(ppp("Unexpected or invalid packet", p))
7348 # session close api test
7349 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7351 self.pg1.remote_ip4n,
7353 dms = self.vapi.nat_det_map_dump()
7354 self.assertEqual(dms[0].ses_num, 1)
7356 self.vapi.nat_det_close_session_in(host0.ip4n,
7358 self.pg1.remote_ip4n,
7360 dms = self.vapi.nat_det_map_dump()
7361 self.assertEqual(dms[0].ses_num, 0)
7363 def test_tcp_session_close_detection_in(self):
7364 """ Deterministic NAT TCP session close from inside network """
7365 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7367 out_addr=socket.inet_aton(self.nat_addr),
7369 flags = self.config_flags.NAT_IS_INSIDE
7370 self.vapi.nat44_interface_add_del_feature(
7371 sw_if_index=self.pg0.sw_if_index,
7372 flags=flags, is_add=1)
7373 self.vapi.nat44_interface_add_del_feature(
7374 sw_if_index=self.pg1.sw_if_index,
7377 self.initiate_tcp_session(self.pg0, self.pg1)
7379 # close the session from inside
7381 # FIN packet in -> out
7382 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7383 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7384 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7386 self.pg0.add_stream(p)
7387 self.pg_enable_capture(self.pg_interfaces)
7389 self.pg1.get_capture(1)
7393 # ACK packet out -> in
7394 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7395 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7396 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7400 # FIN packet out -> in
7401 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7402 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7403 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7407 self.pg1.add_stream(pkts)
7408 self.pg_enable_capture(self.pg_interfaces)
7410 self.pg0.get_capture(2)
7412 # ACK packet in -> out
7413 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7414 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7415 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7417 self.pg0.add_stream(p)
7418 self.pg_enable_capture(self.pg_interfaces)
7420 self.pg1.get_capture(1)
7422 # Check if deterministic NAT44 closed the session
7423 dms = self.vapi.nat_det_map_dump()
7424 self.assertEqual(0, dms[0].ses_num)
7426 self.logger.error("TCP session termination failed")
7429 def test_tcp_session_close_detection_out(self):
7430 """ Deterministic NAT TCP session close from outside network """
7431 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7433 out_addr=socket.inet_aton(self.nat_addr),
7435 flags = self.config_flags.NAT_IS_INSIDE
7436 self.vapi.nat44_interface_add_del_feature(
7437 sw_if_index=self.pg0.sw_if_index,
7438 flags=flags, is_add=1)
7439 self.vapi.nat44_interface_add_del_feature(
7440 sw_if_index=self.pg1.sw_if_index,
7443 self.initiate_tcp_session(self.pg0, self.pg1)
7445 # close the session from outside
7447 # FIN packet out -> in
7448 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7449 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7450 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7452 self.pg1.add_stream(p)
7453 self.pg_enable_capture(self.pg_interfaces)
7455 self.pg0.get_capture(1)
7459 # ACK packet in -> out
7460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7462 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7466 # ACK packet in -> out
7467 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7468 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7469 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7473 self.pg0.add_stream(pkts)
7474 self.pg_enable_capture(self.pg_interfaces)
7476 self.pg1.get_capture(2)
7478 # ACK packet out -> in
7479 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7480 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7481 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7483 self.pg1.add_stream(p)
7484 self.pg_enable_capture(self.pg_interfaces)
7486 self.pg0.get_capture(1)
7488 # Check if deterministic NAT44 closed the session
7489 dms = self.vapi.nat_det_map_dump()
7490 self.assertEqual(0, dms[0].ses_num)
7492 self.logger.error("TCP session termination failed")
7495 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7496 def test_session_timeout(self):
7497 """ Deterministic NAT session timeouts """
7498 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7500 out_addr=socket.inet_aton(self.nat_addr),
7502 flags = self.config_flags.NAT_IS_INSIDE
7503 self.vapi.nat44_interface_add_del_feature(
7504 sw_if_index=self.pg0.sw_if_index,
7505 flags=flags, is_add=1)
7506 self.vapi.nat44_interface_add_del_feature(
7507 sw_if_index=self.pg1.sw_if_index,
7510 self.initiate_tcp_session(self.pg0, self.pg1)
7511 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7513 pkts = self.create_stream_in(self.pg0, self.pg1)
7514 self.pg0.add_stream(pkts)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 capture = self.pg1.get_capture(len(pkts))
7520 dms = self.vapi.nat_det_map_dump()
7521 self.assertEqual(0, dms[0].ses_num)
7523 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7524 def test_session_limit_per_user(self):
7525 """ Deterministic NAT maximum sessions per user limit """
7526 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7528 out_addr=socket.inet_aton(self.nat_addr),
7530 flags = self.config_flags.NAT_IS_INSIDE
7531 self.vapi.nat44_interface_add_del_feature(
7532 sw_if_index=self.pg0.sw_if_index,
7533 flags=flags, is_add=1)
7534 self.vapi.nat44_interface_add_del_feature(
7535 sw_if_index=self.pg1.sw_if_index,
7537 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7538 src_address=self.pg2.local_ip4n,
7540 template_interval=10)
7541 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7545 for port in range(1025, 2025):
7546 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7547 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7548 UDP(sport=port, dport=port))
7551 self.pg0.add_stream(pkts)
7552 self.pg_enable_capture(self.pg_interfaces)
7554 capture = self.pg1.get_capture(len(pkts))
7556 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7557 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7558 UDP(sport=3001, dport=3002))
7559 self.pg0.add_stream(p)
7560 self.pg_enable_capture(self.pg_interfaces)
7562 capture = self.pg1.assert_nothing_captured()
7564 # verify ICMP error packet
7565 capture = self.pg0.get_capture(1)
7567 self.assertTrue(p.haslayer(ICMP))
7569 self.assertEqual(icmp.type, 3)
7570 self.assertEqual(icmp.code, 1)
7571 self.assertTrue(icmp.haslayer(IPerror))
7572 inner_ip = icmp[IPerror]
7573 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7574 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7576 dms = self.vapi.nat_det_map_dump()
7578 self.assertEqual(1000, dms[0].ses_num)
7580 # verify IPFIX logging
7581 self.vapi.ipfix_flush()
7583 capture = self.pg2.get_capture(2)
7584 ipfix = IPFIXDecoder()
7585 # first load template
7587 self.assertTrue(p.haslayer(IPFIX))
7588 if p.haslayer(Template):
7589 ipfix.add_template(p.getlayer(Template))
7590 # verify events in data set
7592 if p.haslayer(Data):
7593 data = ipfix.decode_data_set(p.getlayer(Set))
7594 self.verify_ipfix_max_entries_per_user(data,
7596 self.pg0.remote_ip4n)
7598 def clear_nat_det(self):
7600 Clear deterministic NAT configuration.
7602 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7604 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7605 tcp_transitory=240, icmp=60)
7606 deterministic_mappings = self.vapi.nat_det_map_dump()
7607 for dsm in deterministic_mappings:
7608 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7609 in_plen=dsm.in_plen,
7610 out_addr=dsm.out_addr,
7611 out_plen=dsm.out_plen)
7613 interfaces = self.vapi.nat44_interface_dump()
7614 for intf in interfaces:
7615 self.vapi.nat44_interface_add_del_feature(
7616 sw_if_index=intf.sw_if_index,
7620 super(TestDeterministicNAT, self).tearDown()
7621 if not self.vpp_dead:
7622 self.clear_nat_det()
7624 def show_commands_at_teardown(self):
7625 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7626 self.logger.info(self.vapi.cli("show nat timeouts"))
7628 self.vapi.cli("show nat44 deterministic mappings"))
7630 self.vapi.cli("show nat44 deterministic sessions"))
7633 class TestNAT64(MethodHolder):
7634 """ NAT64 Test Cases """
7637 def setUpConstants(cls):
7638 super(TestNAT64, cls).setUpConstants()
7639 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7640 "nat64 st hash buckets 256", "}"])
7643 def setUpClass(cls):
7644 super(TestNAT64, cls).setUpClass()
7647 cls.tcp_port_in = 6303
7648 cls.tcp_port_out = 6303
7649 cls.udp_port_in = 6304
7650 cls.udp_port_out = 6304
7651 cls.icmp_id_in = 6305
7652 cls.icmp_id_out = 6305
7653 cls.tcp_external_port = 80
7654 cls.nat_addr = '10.0.0.3'
7655 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7657 cls.vrf1_nat_addr = '10.0.10.3'
7658 cls.ipfix_src_port = 4739
7659 cls.ipfix_domain_id = 1
7661 cls.create_pg_interfaces(range(6))
7662 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7663 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7664 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7666 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7667 table_id=cls.vrf1_id)
7669 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7671 cls.pg0.generate_remote_hosts(2)
7673 for i in cls.ip6_interfaces:
7676 i.configure_ipv6_neighbors()
7678 for i in cls.ip4_interfaces:
7684 cls.pg3.config_ip4()
7685 cls.pg3.resolve_arp()
7686 cls.pg3.config_ip6()
7687 cls.pg3.configure_ipv6_neighbors()
7690 cls.pg5.config_ip6()
7693 super(TestNAT64, cls).tearDownClass()
7697 def tearDownClass(cls):
7698 super(TestNAT64, cls).tearDownClass()
7700 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7701 """ NAT64 inside interface handles Neighbor Advertisement """
7703 flags = self.config_flags.NAT_IS_INSIDE
7704 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7705 sw_if_index=self.pg5.sw_if_index)
7708 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7709 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7710 ICMPv6EchoRequest())
7712 self.pg5.add_stream(pkts)
7713 self.pg_enable_capture(self.pg_interfaces)
7716 # Wait for Neighbor Solicitation
7717 capture = self.pg5.get_capture(len(pkts))
7720 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7721 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7722 tgt = packet[ICMPv6ND_NS].tgt
7724 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7727 # Send Neighbor Advertisement
7728 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7729 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7730 ICMPv6ND_NA(tgt=tgt) /
7731 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7733 self.pg5.add_stream(pkts)
7734 self.pg_enable_capture(self.pg_interfaces)
7737 # Try to send ping again
7739 self.pg5.add_stream(pkts)
7740 self.pg_enable_capture(self.pg_interfaces)
7743 # Wait for ping reply
7744 capture = self.pg5.get_capture(len(pkts))
7747 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7748 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7749 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7751 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7754 def test_pool(self):
7755 """ Add/delete address to NAT64 pool """
7756 nat_addr = '1.2.3.4'
7758 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7760 vrf_id=0xFFFFFFFF, is_add=1)
7762 addresses = self.vapi.nat64_pool_addr_dump()
7763 self.assertEqual(len(addresses), 1)
7764 self.assertEqual(str(addresses[0].address), nat_addr)
7766 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7768 vrf_id=0xFFFFFFFF, is_add=0)
7770 addresses = self.vapi.nat64_pool_addr_dump()
7771 self.assertEqual(len(addresses), 0)
7773 def test_interface(self):
7774 """ Enable/disable NAT64 feature on the interface """
7775 flags = self.config_flags.NAT_IS_INSIDE
7776 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7777 sw_if_index=self.pg0.sw_if_index)
7778 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7779 sw_if_index=self.pg1.sw_if_index)
7781 interfaces = self.vapi.nat64_interface_dump()
7782 self.assertEqual(len(interfaces), 2)
7785 for intf in interfaces:
7786 if intf.sw_if_index == self.pg0.sw_if_index:
7787 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7789 elif intf.sw_if_index == self.pg1.sw_if_index:
7790 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7792 self.assertTrue(pg0_found)
7793 self.assertTrue(pg1_found)
7795 features = self.vapi.cli("show interface features pg0")
7796 self.assertIn('nat64-in2out', features)
7797 features = self.vapi.cli("show interface features pg1")
7798 self.assertIn('nat64-out2in', features)
7800 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7801 sw_if_index=self.pg0.sw_if_index)
7802 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7803 sw_if_index=self.pg1.sw_if_index)
7805 interfaces = self.vapi.nat64_interface_dump()
7806 self.assertEqual(len(interfaces), 0)
7808 def test_static_bib(self):
7809 """ Add/delete static BIB entry """
7810 in_addr = '2001:db8:85a3::8a2e:370:7334'
7811 out_addr = '10.1.1.3'
7814 proto = IP_PROTOS.tcp
7816 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7817 i_port=in_port, o_port=out_port,
7818 proto=proto, vrf_id=0, is_add=1)
7819 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7822 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7824 self.assertEqual(str(bibe.i_addr), in_addr)
7825 self.assertEqual(str(bibe.o_addr), out_addr)
7826 self.assertEqual(bibe.i_port, in_port)
7827 self.assertEqual(bibe.o_port, out_port)
7828 self.assertEqual(static_bib_num, 1)
7829 bibs = self.statistics.get_counter('/nat64/total-bibs')
7830 self.assertEqual(bibs[0][0], 1)
7832 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7833 i_port=in_port, o_port=out_port,
7834 proto=proto, vrf_id=0, is_add=0)
7835 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7838 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7840 self.assertEqual(static_bib_num, 0)
7841 bibs = self.statistics.get_counter('/nat64/total-bibs')
7842 self.assertEqual(bibs[0][0], 0)
7844 def test_set_timeouts(self):
7845 """ Set NAT64 timeouts """
7846 # verify default values
7847 timeouts = self.vapi.nat_get_timeouts()
7848 self.assertEqual(timeouts.udp, 300)
7849 self.assertEqual(timeouts.icmp, 60)
7850 self.assertEqual(timeouts.tcp_transitory, 240)
7851 self.assertEqual(timeouts.tcp_established, 7440)
7853 # set and verify custom values
7854 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7855 tcp_transitory=250, icmp=30)
7856 timeouts = self.vapi.nat_get_timeouts()
7857 self.assertEqual(timeouts.udp, 200)
7858 self.assertEqual(timeouts.icmp, 30)
7859 self.assertEqual(timeouts.tcp_transitory, 250)
7860 self.assertEqual(timeouts.tcp_established, 7450)
7862 def test_dynamic(self):
7863 """ NAT64 dynamic translation test """
7864 self.tcp_port_in = 6303
7865 self.udp_port_in = 6304
7866 self.icmp_id_in = 6305
7868 ses_num_start = self.nat64_get_ses_num()
7870 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7871 end_addr=self.nat_addr,
7874 flags = self.config_flags.NAT_IS_INSIDE
7875 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7876 sw_if_index=self.pg0.sw_if_index)
7877 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7878 sw_if_index=self.pg1.sw_if_index)
7881 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7882 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7883 icmpn = self.statistics.get_err_counter(
7884 '/err/nat64-in2out/ICMP packets')
7885 totaln = self.statistics.get_err_counter(
7886 '/err/nat64-in2out/good in2out packets processed')
7888 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7889 self.pg0.add_stream(pkts)
7890 self.pg_enable_capture(self.pg_interfaces)
7892 capture = self.pg1.get_capture(len(pkts))
7893 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7894 dst_ip=self.pg1.remote_ip4)
7896 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7897 self.assertEqual(err - tcpn, 1)
7898 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7899 self.assertEqual(err - udpn, 1)
7900 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7901 self.assertEqual(err - icmpn, 1)
7902 err = self.statistics.get_err_counter(
7903 '/err/nat64-in2out/good in2out packets processed')
7904 self.assertEqual(err - totaln, 3)
7907 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7908 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7909 icmpn = self.statistics.get_err_counter(
7910 '/err/nat64-out2in/ICMP packets')
7911 totaln = self.statistics.get_err_counter(
7912 '/err/nat64-out2in/good out2in packets processed')
7914 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7915 self.pg1.add_stream(pkts)
7916 self.pg_enable_capture(self.pg_interfaces)
7918 capture = self.pg0.get_capture(len(pkts))
7919 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7920 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7922 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7923 self.assertEqual(err - tcpn, 1)
7924 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7925 self.assertEqual(err - udpn, 1)
7926 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7927 self.assertEqual(err - icmpn, 1)
7928 err = self.statistics.get_err_counter(
7929 '/err/nat64-out2in/good out2in packets processed')
7930 self.assertEqual(err - totaln, 3)
7932 bibs = self.statistics.get_counter('/nat64/total-bibs')
7933 self.assertEqual(bibs[0][0], 3)
7934 sessions = self.statistics.get_counter('/nat64/total-sessions')
7935 self.assertEqual(sessions[0][0], 3)
7938 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7939 self.pg0.add_stream(pkts)
7940 self.pg_enable_capture(self.pg_interfaces)
7942 capture = self.pg1.get_capture(len(pkts))
7943 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7944 dst_ip=self.pg1.remote_ip4)
7947 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7948 self.pg1.add_stream(pkts)
7949 self.pg_enable_capture(self.pg_interfaces)
7951 capture = self.pg0.get_capture(len(pkts))
7952 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7954 ses_num_end = self.nat64_get_ses_num()
7956 self.assertEqual(ses_num_end - ses_num_start, 3)
7958 # tenant with specific VRF
7959 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7960 end_addr=self.vrf1_nat_addr,
7961 vrf_id=self.vrf1_id, is_add=1)
7962 flags = self.config_flags.NAT_IS_INSIDE
7963 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7964 sw_if_index=self.pg2.sw_if_index)
7966 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7967 self.pg2.add_stream(pkts)
7968 self.pg_enable_capture(self.pg_interfaces)
7970 capture = self.pg1.get_capture(len(pkts))
7971 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7972 dst_ip=self.pg1.remote_ip4)
7974 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7975 self.pg1.add_stream(pkts)
7976 self.pg_enable_capture(self.pg_interfaces)
7978 capture = self.pg2.get_capture(len(pkts))
7979 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7981 def test_static(self):
7982 """ NAT64 static translation test """
7983 self.tcp_port_in = 60303
7984 self.udp_port_in = 60304
7985 self.icmp_id_in = 60305
7986 self.tcp_port_out = 60303
7987 self.udp_port_out = 60304
7988 self.icmp_id_out = 60305
7990 ses_num_start = self.nat64_get_ses_num()
7992 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7993 end_addr=self.nat_addr,
7996 flags = self.config_flags.NAT_IS_INSIDE
7997 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7998 sw_if_index=self.pg0.sw_if_index)
7999 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8000 sw_if_index=self.pg1.sw_if_index)
8002 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8003 o_addr=self.nat_addr,
8004 i_port=self.tcp_port_in,
8005 o_port=self.tcp_port_out,
8006 proto=IP_PROTOS.tcp, vrf_id=0,
8008 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8009 o_addr=self.nat_addr,
8010 i_port=self.udp_port_in,
8011 o_port=self.udp_port_out,
8012 proto=IP_PROTOS.udp, vrf_id=0,
8014 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8015 o_addr=self.nat_addr,
8016 i_port=self.icmp_id_in,
8017 o_port=self.icmp_id_out,
8018 proto=IP_PROTOS.icmp, vrf_id=0,
8022 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8023 self.pg0.add_stream(pkts)
8024 self.pg_enable_capture(self.pg_interfaces)
8026 capture = self.pg1.get_capture(len(pkts))
8027 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8028 dst_ip=self.pg1.remote_ip4, same_port=True)
8031 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8032 self.pg1.add_stream(pkts)
8033 self.pg_enable_capture(self.pg_interfaces)
8035 capture = self.pg0.get_capture(len(pkts))
8036 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8037 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8039 ses_num_end = self.nat64_get_ses_num()
8041 self.assertEqual(ses_num_end - ses_num_start, 3)
8043 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8044 def test_session_timeout(self):
8045 """ NAT64 session timeout """
8046 self.icmp_id_in = 1234
8047 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8048 end_addr=self.nat_addr,
8051 flags = self.config_flags.NAT_IS_INSIDE
8052 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8053 sw_if_index=self.pg0.sw_if_index)
8054 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8055 sw_if_index=self.pg1.sw_if_index)
8056 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8060 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8061 self.pg0.add_stream(pkts)
8062 self.pg_enable_capture(self.pg_interfaces)
8064 capture = self.pg1.get_capture(len(pkts))
8066 ses_num_before_timeout = self.nat64_get_ses_num()
8070 # ICMP and TCP session after timeout
8071 ses_num_after_timeout = self.nat64_get_ses_num()
8072 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8074 def test_icmp_error(self):
8075 """ NAT64 ICMP Error message translation """
8076 self.tcp_port_in = 6303
8077 self.udp_port_in = 6304
8078 self.icmp_id_in = 6305
8080 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8081 end_addr=self.nat_addr,
8084 flags = self.config_flags.NAT_IS_INSIDE
8085 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8086 sw_if_index=self.pg0.sw_if_index)
8087 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8088 sw_if_index=self.pg1.sw_if_index)
8090 # send some packets to create sessions
8091 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8092 self.pg0.add_stream(pkts)
8093 self.pg_enable_capture(self.pg_interfaces)
8095 capture_ip4 = self.pg1.get_capture(len(pkts))
8096 self.verify_capture_out(capture_ip4,
8097 nat_ip=self.nat_addr,
8098 dst_ip=self.pg1.remote_ip4)
8100 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8101 self.pg1.add_stream(pkts)
8102 self.pg_enable_capture(self.pg_interfaces)
8104 capture_ip6 = self.pg0.get_capture(len(pkts))
8105 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8106 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8107 self.pg0.remote_ip6)
8110 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8111 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8112 ICMPv6DestUnreach(code=1) /
8113 packet[IPv6] for packet in capture_ip6]
8114 self.pg0.add_stream(pkts)
8115 self.pg_enable_capture(self.pg_interfaces)
8117 capture = self.pg1.get_capture(len(pkts))
8118 for packet in capture:
8120 self.assertEqual(packet[IP].src, self.nat_addr)
8121 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8122 self.assertEqual(packet[ICMP].type, 3)
8123 self.assertEqual(packet[ICMP].code, 13)
8124 inner = packet[IPerror]
8125 self.assertEqual(inner.src, self.pg1.remote_ip4)
8126 self.assertEqual(inner.dst, self.nat_addr)
8127 self.assert_packet_checksums_valid(packet)
8128 if inner.haslayer(TCPerror):
8129 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8130 elif inner.haslayer(UDPerror):
8131 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8133 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8135 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8139 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8140 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8141 ICMP(type=3, code=13) /
8142 packet[IP] for packet in capture_ip4]
8143 self.pg1.add_stream(pkts)
8144 self.pg_enable_capture(self.pg_interfaces)
8146 capture = self.pg0.get_capture(len(pkts))
8147 for packet in capture:
8149 self.assertEqual(packet[IPv6].src, ip.src)
8150 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8151 icmp = packet[ICMPv6DestUnreach]
8152 self.assertEqual(icmp.code, 1)
8153 inner = icmp[IPerror6]
8154 self.assertEqual(inner.src, self.pg0.remote_ip6)
8155 self.assertEqual(inner.dst, ip.src)
8156 self.assert_icmpv6_checksum_valid(packet)
8157 if inner.haslayer(TCPerror):
8158 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8159 elif inner.haslayer(UDPerror):
8160 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8162 self.assertEqual(inner[ICMPv6EchoRequest].id,
8165 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8168 def test_hairpinning(self):
8169 """ NAT64 hairpinning """
8171 client = self.pg0.remote_hosts[0]
8172 server = self.pg0.remote_hosts[1]
8173 server_tcp_in_port = 22
8174 server_tcp_out_port = 4022
8175 server_udp_in_port = 23
8176 server_udp_out_port = 4023
8177 client_tcp_in_port = 1234
8178 client_udp_in_port = 1235
8179 client_tcp_out_port = 0
8180 client_udp_out_port = 0
8181 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8182 nat_addr_ip6 = ip.src
8184 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8185 end_addr=self.nat_addr,
8188 flags = self.config_flags.NAT_IS_INSIDE
8189 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8190 sw_if_index=self.pg0.sw_if_index)
8191 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8192 sw_if_index=self.pg1.sw_if_index)
8194 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8195 o_addr=self.nat_addr,
8196 i_port=server_tcp_in_port,
8197 o_port=server_tcp_out_port,
8198 proto=IP_PROTOS.tcp, vrf_id=0,
8200 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8201 o_addr=self.nat_addr,
8202 i_port=server_udp_in_port,
8203 o_port=server_udp_out_port,
8204 proto=IP_PROTOS.udp, vrf_id=0,
8209 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8210 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8211 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8213 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8214 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8215 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8217 self.pg0.add_stream(pkts)
8218 self.pg_enable_capture(self.pg_interfaces)
8220 capture = self.pg0.get_capture(len(pkts))
8221 for packet in capture:
8223 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8224 self.assertEqual(packet[IPv6].dst, server.ip6)
8225 self.assert_packet_checksums_valid(packet)
8226 if packet.haslayer(TCP):
8227 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8228 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8229 client_tcp_out_port = packet[TCP].sport
8231 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8232 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8233 client_udp_out_port = packet[UDP].sport
8235 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8240 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8241 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8242 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8244 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8245 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8246 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8248 self.pg0.add_stream(pkts)
8249 self.pg_enable_capture(self.pg_interfaces)
8251 capture = self.pg0.get_capture(len(pkts))
8252 for packet in capture:
8254 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8255 self.assertEqual(packet[IPv6].dst, client.ip6)
8256 self.assert_packet_checksums_valid(packet)
8257 if packet.haslayer(TCP):
8258 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8259 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8261 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8262 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8264 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8269 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8270 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8271 ICMPv6DestUnreach(code=1) /
8272 packet[IPv6] for packet in capture]
8273 self.pg0.add_stream(pkts)
8274 self.pg_enable_capture(self.pg_interfaces)
8276 capture = self.pg0.get_capture(len(pkts))
8277 for packet in capture:
8279 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8280 self.assertEqual(packet[IPv6].dst, server.ip6)
8281 icmp = packet[ICMPv6DestUnreach]
8282 self.assertEqual(icmp.code, 1)
8283 inner = icmp[IPerror6]
8284 self.assertEqual(inner.src, server.ip6)
8285 self.assertEqual(inner.dst, nat_addr_ip6)
8286 self.assert_packet_checksums_valid(packet)
8287 if inner.haslayer(TCPerror):
8288 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8289 self.assertEqual(inner[TCPerror].dport,
8290 client_tcp_out_port)
8292 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8293 self.assertEqual(inner[UDPerror].dport,
8294 client_udp_out_port)
8296 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8299 def test_prefix(self):
8300 """ NAT64 Network-Specific Prefix """
8302 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8303 end_addr=self.nat_addr,
8306 flags = self.config_flags.NAT_IS_INSIDE
8307 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8308 sw_if_index=self.pg0.sw_if_index)
8309 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8310 sw_if_index=self.pg1.sw_if_index)
8311 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8312 end_addr=self.vrf1_nat_addr,
8313 vrf_id=self.vrf1_id, is_add=1)
8314 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8315 sw_if_index=self.pg2.sw_if_index)
8318 global_pref64 = "2001:db8::"
8319 global_pref64_len = 32
8320 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8321 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8324 prefix = self.vapi.nat64_prefix_dump()
8325 self.assertEqual(len(prefix), 1)
8326 self.assertEqual(prefix[0].prefix,
8327 IPv6Network(unicode(global_pref64_str)))
8328 self.assertEqual(prefix[0].vrf_id, 0)
8330 # Add tenant specific prefix
8331 vrf1_pref64 = "2001:db8:122:300::"
8332 vrf1_pref64_len = 56
8333 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8334 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8335 vrf_id=self.vrf1_id, is_add=1)
8337 prefix = self.vapi.nat64_prefix_dump()
8338 self.assertEqual(len(prefix), 2)
8341 pkts = self.create_stream_in_ip6(self.pg0,
8344 plen=global_pref64_len)
8345 self.pg0.add_stream(pkts)
8346 self.pg_enable_capture(self.pg_interfaces)
8348 capture = self.pg1.get_capture(len(pkts))
8349 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8350 dst_ip=self.pg1.remote_ip4)
8352 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8353 self.pg1.add_stream(pkts)
8354 self.pg_enable_capture(self.pg_interfaces)
8356 capture = self.pg0.get_capture(len(pkts))
8357 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8360 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8362 # Tenant specific prefix
8363 pkts = self.create_stream_in_ip6(self.pg2,
8366 plen=vrf1_pref64_len)
8367 self.pg2.add_stream(pkts)
8368 self.pg_enable_capture(self.pg_interfaces)
8370 capture = self.pg1.get_capture(len(pkts))
8371 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8372 dst_ip=self.pg1.remote_ip4)
8374 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8375 self.pg1.add_stream(pkts)
8376 self.pg_enable_capture(self.pg_interfaces)
8378 capture = self.pg2.get_capture(len(pkts))
8379 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8382 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8384 def test_unknown_proto(self):
8385 """ NAT64 translate packet with unknown protocol """
8387 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8388 end_addr=self.nat_addr,
8391 flags = self.config_flags.NAT_IS_INSIDE
8392 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8393 sw_if_index=self.pg0.sw_if_index)
8394 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8395 sw_if_index=self.pg1.sw_if_index)
8396 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8399 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8400 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8401 TCP(sport=self.tcp_port_in, dport=20))
8402 self.pg0.add_stream(p)
8403 self.pg_enable_capture(self.pg_interfaces)
8405 p = self.pg1.get_capture(1)
8407 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8408 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8410 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8411 TCP(sport=1234, dport=1234))
8412 self.pg0.add_stream(p)
8413 self.pg_enable_capture(self.pg_interfaces)
8415 p = self.pg1.get_capture(1)
8418 self.assertEqual(packet[IP].src, self.nat_addr)
8419 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8420 self.assertEqual(packet.haslayer(GRE), 1)
8421 self.assert_packet_checksums_valid(packet)
8423 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8427 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8430 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8431 TCP(sport=1234, dport=1234))
8432 self.pg1.add_stream(p)
8433 self.pg_enable_capture(self.pg_interfaces)
8435 p = self.pg0.get_capture(1)
8438 self.assertEqual(packet[IPv6].src, remote_ip6)
8439 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8440 self.assertEqual(packet[IPv6].nh, 47)
8442 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8445 def test_hairpinning_unknown_proto(self):
8446 """ NAT64 translate packet with unknown protocol - hairpinning """
8448 client = self.pg0.remote_hosts[0]
8449 server = self.pg0.remote_hosts[1]
8450 server_tcp_in_port = 22
8451 server_tcp_out_port = 4022
8452 client_tcp_in_port = 1234
8453 client_tcp_out_port = 1235
8454 server_nat_ip = "10.0.0.100"
8455 client_nat_ip = "10.0.0.110"
8456 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8457 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8459 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8460 end_addr=client_nat_ip,
8463 flags = self.config_flags.NAT_IS_INSIDE
8464 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8465 sw_if_index=self.pg0.sw_if_index)
8466 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8467 sw_if_index=self.pg1.sw_if_index)
8469 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8470 o_addr=server_nat_ip,
8471 i_port=server_tcp_in_port,
8472 o_port=server_tcp_out_port,
8473 proto=IP_PROTOS.tcp, vrf_id=0,
8476 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8477 o_addr=server_nat_ip, i_port=0,
8479 proto=IP_PROTOS.gre, vrf_id=0,
8482 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8483 o_addr=client_nat_ip,
8484 i_port=client_tcp_in_port,
8485 o_port=client_tcp_out_port,
8486 proto=IP_PROTOS.tcp, vrf_id=0,
8490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8491 IPv6(src=client.ip6, dst=server_nat_ip6) /
8492 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8493 self.pg0.add_stream(p)
8494 self.pg_enable_capture(self.pg_interfaces)
8496 p = self.pg0.get_capture(1)
8498 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8499 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8501 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8502 TCP(sport=1234, dport=1234))
8503 self.pg0.add_stream(p)
8504 self.pg_enable_capture(self.pg_interfaces)
8506 p = self.pg0.get_capture(1)
8509 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8510 self.assertEqual(packet[IPv6].dst, server.ip6)
8511 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8513 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8517 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8518 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8520 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8521 TCP(sport=1234, dport=1234))
8522 self.pg0.add_stream(p)
8523 self.pg_enable_capture(self.pg_interfaces)
8525 p = self.pg0.get_capture(1)
8528 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8529 self.assertEqual(packet[IPv6].dst, client.ip6)
8530 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8532 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8535 def test_one_armed_nat64(self):
8536 """ One armed NAT64 """
8538 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8542 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8543 end_addr=self.nat_addr,
8546 flags = self.config_flags.NAT_IS_INSIDE
8547 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8548 sw_if_index=self.pg3.sw_if_index)
8549 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8550 sw_if_index=self.pg3.sw_if_index)
8553 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8554 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8555 TCP(sport=12345, dport=80))
8556 self.pg3.add_stream(p)
8557 self.pg_enable_capture(self.pg_interfaces)
8559 capture = self.pg3.get_capture(1)
8564 self.assertEqual(ip.src, self.nat_addr)
8565 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8566 self.assertNotEqual(tcp.sport, 12345)
8567 external_port = tcp.sport
8568 self.assertEqual(tcp.dport, 80)
8569 self.assert_packet_checksums_valid(p)
8571 self.logger.error(ppp("Unexpected or invalid packet:", p))
8575 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8576 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8577 TCP(sport=80, dport=external_port))
8578 self.pg3.add_stream(p)
8579 self.pg_enable_capture(self.pg_interfaces)
8581 capture = self.pg3.get_capture(1)
8586 self.assertEqual(ip.src, remote_host_ip6)
8587 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8588 self.assertEqual(tcp.sport, 80)
8589 self.assertEqual(tcp.dport, 12345)
8590 self.assert_packet_checksums_valid(p)
8592 self.logger.error(ppp("Unexpected or invalid packet:", p))
8595 def test_frag_in_order(self):
8596 """ NAT64 translate fragments arriving in order """
8597 self.tcp_port_in = random.randint(1025, 65535)
8599 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8600 end_addr=self.nat_addr,
8603 flags = self.config_flags.NAT_IS_INSIDE
8604 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8605 sw_if_index=self.pg0.sw_if_index)
8606 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8607 sw_if_index=self.pg1.sw_if_index)
8609 reass = self.vapi.nat_reass_dump()
8610 reass_n_start = len(reass)
8614 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8615 self.tcp_port_in, 20, data)
8616 self.pg0.add_stream(pkts)
8617 self.pg_enable_capture(self.pg_interfaces)
8619 frags = self.pg1.get_capture(len(pkts))
8620 p = self.reass_frags_and_verify(frags,
8622 self.pg1.remote_ip4)
8623 self.assertEqual(p[TCP].dport, 20)
8624 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8625 self.tcp_port_out = p[TCP].sport
8626 self.assertEqual(data, p[Raw].load)
8629 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8630 pkts = self.create_stream_frag(self.pg1,
8635 self.pg1.add_stream(pkts)
8636 self.pg_enable_capture(self.pg_interfaces)
8638 frags = self.pg0.get_capture(len(pkts))
8639 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8640 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8641 self.assertEqual(p[TCP].sport, 20)
8642 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8643 self.assertEqual(data, p[Raw].load)
8645 reass = self.vapi.nat_reass_dump()
8646 reass_n_end = len(reass)
8648 self.assertEqual(reass_n_end - reass_n_start, 2)
8650 def test_reass_hairpinning(self):
8651 """ NAT64 fragments hairpinning """
8653 server = self.pg0.remote_hosts[1]
8654 server_in_port = random.randint(1025, 65535)
8655 server_out_port = random.randint(1025, 65535)
8656 client_in_port = random.randint(1025, 65535)
8657 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8658 nat_addr_ip6 = ip.src
8660 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8661 end_addr=self.nat_addr,
8664 flags = self.config_flags.NAT_IS_INSIDE
8665 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8666 sw_if_index=self.pg0.sw_if_index)
8667 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8668 sw_if_index=self.pg1.sw_if_index)
8670 # add static BIB entry for server
8671 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8672 o_addr=self.nat_addr,
8673 i_port=server_in_port,
8674 o_port=server_out_port,
8675 proto=IP_PROTOS.tcp, vrf_id=0,
8678 # send packet from host to server
8679 pkts = self.create_stream_frag_ip6(self.pg0,
8684 self.pg0.add_stream(pkts)
8685 self.pg_enable_capture(self.pg_interfaces)
8687 frags = self.pg0.get_capture(len(pkts))
8688 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8689 self.assertNotEqual(p[TCP].sport, client_in_port)
8690 self.assertEqual(p[TCP].dport, server_in_port)
8691 self.assertEqual(data, p[Raw].load)
8693 def test_frag_out_of_order(self):
8694 """ NAT64 translate fragments arriving out of order """
8695 self.tcp_port_in = random.randint(1025, 65535)
8697 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8698 end_addr=self.nat_addr,
8701 flags = self.config_flags.NAT_IS_INSIDE
8702 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8703 sw_if_index=self.pg0.sw_if_index)
8704 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8705 sw_if_index=self.pg1.sw_if_index)
8709 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8710 self.tcp_port_in, 20, data)
8712 self.pg0.add_stream(pkts)
8713 self.pg_enable_capture(self.pg_interfaces)
8715 frags = self.pg1.get_capture(len(pkts))
8716 p = self.reass_frags_and_verify(frags,
8718 self.pg1.remote_ip4)
8719 self.assertEqual(p[TCP].dport, 20)
8720 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8721 self.tcp_port_out = p[TCP].sport
8722 self.assertEqual(data, p[Raw].load)
8725 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8726 pkts = self.create_stream_frag(self.pg1,
8732 self.pg1.add_stream(pkts)
8733 self.pg_enable_capture(self.pg_interfaces)
8735 frags = self.pg0.get_capture(len(pkts))
8736 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8737 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8738 self.assertEqual(p[TCP].sport, 20)
8739 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8740 self.assertEqual(data, p[Raw].load)
8742 def test_interface_addr(self):
8743 """ Acquire NAT64 pool addresses from interface """
8744 self.vapi.nat64_add_del_interface_addr(
8746 sw_if_index=self.pg4.sw_if_index)
8748 # no address in NAT64 pool
8749 addresses = self.vapi.nat44_address_dump()
8750 self.assertEqual(0, len(addresses))
8752 # configure interface address and check NAT64 address pool
8753 self.pg4.config_ip4()
8754 addresses = self.vapi.nat64_pool_addr_dump()
8755 self.assertEqual(len(addresses), 1)
8757 self.assertEqual(str(addresses[0].address),
8760 # remove interface address and check NAT64 address pool
8761 self.pg4.unconfig_ip4()
8762 addresses = self.vapi.nat64_pool_addr_dump()
8763 self.assertEqual(0, len(addresses))
8765 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8766 def test_ipfix_max_bibs_sessions(self):
8767 """ IPFIX logging maximum session and BIB entries exceeded """
8770 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8774 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8775 end_addr=self.nat_addr,
8778 flags = self.config_flags.NAT_IS_INSIDE
8779 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8780 sw_if_index=self.pg0.sw_if_index)
8781 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8782 sw_if_index=self.pg1.sw_if_index)
8786 for i in range(0, max_bibs):
8787 src = "fd01:aa::%x" % (i)
8788 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8789 IPv6(src=src, dst=remote_host_ip6) /
8790 TCP(sport=12345, dport=80))
8792 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8793 IPv6(src=src, dst=remote_host_ip6) /
8794 TCP(sport=12345, dport=22))
8796 self.pg0.add_stream(pkts)
8797 self.pg_enable_capture(self.pg_interfaces)
8799 self.pg1.get_capture(max_sessions)
8801 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8802 src_address=self.pg3.local_ip4n,
8804 template_interval=10)
8805 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8806 src_port=self.ipfix_src_port,
8809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8810 IPv6(src=src, dst=remote_host_ip6) /
8811 TCP(sport=12345, dport=25))
8812 self.pg0.add_stream(p)
8813 self.pg_enable_capture(self.pg_interfaces)
8815 self.pg1.assert_nothing_captured()
8817 self.vapi.ipfix_flush()
8818 capture = self.pg3.get_capture(9)
8819 ipfix = IPFIXDecoder()
8820 # first load template
8822 self.assertTrue(p.haslayer(IPFIX))
8823 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8824 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8825 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8826 self.assertEqual(p[UDP].dport, 4739)
8827 self.assertEqual(p[IPFIX].observationDomainID,
8828 self.ipfix_domain_id)
8829 if p.haslayer(Template):
8830 ipfix.add_template(p.getlayer(Template))
8831 # verify events in data set
8833 if p.haslayer(Data):
8834 data = ipfix.decode_data_set(p.getlayer(Set))
8835 self.verify_ipfix_max_sessions(data, max_sessions)
8837 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8838 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8839 TCP(sport=12345, dport=80))
8840 self.pg0.add_stream(p)
8841 self.pg_enable_capture(self.pg_interfaces)
8843 self.pg1.assert_nothing_captured()
8845 self.vapi.ipfix_flush()
8846 capture = self.pg3.get_capture(1)
8847 # verify events in data set
8849 self.assertTrue(p.haslayer(IPFIX))
8850 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8851 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8852 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8853 self.assertEqual(p[UDP].dport, 4739)
8854 self.assertEqual(p[IPFIX].observationDomainID,
8855 self.ipfix_domain_id)
8856 if p.haslayer(Data):
8857 data = ipfix.decode_data_set(p.getlayer(Set))
8858 self.verify_ipfix_max_bibs(data, max_bibs)
8860 def test_ipfix_max_frags(self):
8861 """ IPFIX logging maximum fragments pending reassembly exceeded """
8862 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8863 end_addr=self.nat_addr,
8866 flags = self.config_flags.NAT_IS_INSIDE
8867 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8868 sw_if_index=self.pg0.sw_if_index)
8869 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8870 sw_if_index=self.pg1.sw_if_index)
8871 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8872 drop_frag=0, is_ip6=1)
8873 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8874 src_address=self.pg3.local_ip4n,
8876 template_interval=10)
8877 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8878 src_port=self.ipfix_src_port,
8882 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8883 self.tcp_port_in, 20, data)
8885 self.pg0.add_stream(pkts)
8886 self.pg_enable_capture(self.pg_interfaces)
8888 self.pg1.assert_nothing_captured()
8890 self.vapi.ipfix_flush()
8891 capture = self.pg3.get_capture(9)
8892 ipfix = IPFIXDecoder()
8893 # first load template
8895 self.assertTrue(p.haslayer(IPFIX))
8896 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8897 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8898 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8899 self.assertEqual(p[UDP].dport, 4739)
8900 self.assertEqual(p[IPFIX].observationDomainID,
8901 self.ipfix_domain_id)
8902 if p.haslayer(Template):
8903 ipfix.add_template(p.getlayer(Template))
8904 # verify events in data set
8906 if p.haslayer(Data):
8907 data = ipfix.decode_data_set(p.getlayer(Set))
8908 self.verify_ipfix_max_fragments_ip6(data, 1,
8909 self.pg0.remote_ip6n)
8911 def test_ipfix_bib_ses(self):
8912 """ IPFIX logging NAT64 BIB/session create and delete events """
8913 self.tcp_port_in = random.randint(1025, 65535)
8914 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8918 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8919 end_addr=self.nat_addr,
8922 flags = self.config_flags.NAT_IS_INSIDE
8923 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8924 sw_if_index=self.pg0.sw_if_index)
8925 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8926 sw_if_index=self.pg1.sw_if_index)
8927 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8928 src_address=self.pg3.local_ip4n,
8930 template_interval=10)
8931 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8932 src_port=self.ipfix_src_port,
8936 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8937 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8938 TCP(sport=self.tcp_port_in, dport=25))
8939 self.pg0.add_stream(p)
8940 self.pg_enable_capture(self.pg_interfaces)
8942 p = self.pg1.get_capture(1)
8943 self.tcp_port_out = p[0][TCP].sport
8944 self.vapi.ipfix_flush()
8945 capture = self.pg3.get_capture(10)
8946 ipfix = IPFIXDecoder()
8947 # first load template
8949 self.assertTrue(p.haslayer(IPFIX))
8950 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8951 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8952 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8953 self.assertEqual(p[UDP].dport, 4739)
8954 self.assertEqual(p[IPFIX].observationDomainID,
8955 self.ipfix_domain_id)
8956 if p.haslayer(Template):
8957 ipfix.add_template(p.getlayer(Template))
8958 # verify events in data set
8960 if p.haslayer(Data):
8961 data = ipfix.decode_data_set(p.getlayer(Set))
8962 if scapy.compat.orb(data[0][230]) == 10:
8963 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8964 elif scapy.compat.orb(data[0][230]) == 6:
8965 self.verify_ipfix_nat64_ses(data,
8967 self.pg0.remote_ip6n,
8968 self.pg1.remote_ip4,
8971 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8974 self.pg_enable_capture(self.pg_interfaces)
8975 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8976 end_addr=self.nat_addr,
8979 self.vapi.ipfix_flush()
8980 capture = self.pg3.get_capture(2)
8981 # verify events in data set
8983 self.assertTrue(p.haslayer(IPFIX))
8984 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8985 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8986 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8987 self.assertEqual(p[UDP].dport, 4739)
8988 self.assertEqual(p[IPFIX].observationDomainID,
8989 self.ipfix_domain_id)
8990 if p.haslayer(Data):
8991 data = ipfix.decode_data_set(p.getlayer(Set))
8992 if scapy.compat.orb(data[0][230]) == 11:
8993 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8994 elif scapy.compat.orb(data[0][230]) == 7:
8995 self.verify_ipfix_nat64_ses(data,
8997 self.pg0.remote_ip6n,
8998 self.pg1.remote_ip4,
9001 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9003 def test_syslog_sess(self):
9004 """ Test syslog session creation and deletion """
9005 self.tcp_port_in = random.randint(1025, 65535)
9006 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9010 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9011 end_addr=self.nat_addr,
9014 flags = self.config_flags.NAT_IS_INSIDE
9015 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9016 sw_if_index=self.pg0.sw_if_index)
9017 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9018 sw_if_index=self.pg1.sw_if_index)
9019 self.vapi.syslog_set_filter(
9020 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9021 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9023 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9024 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9025 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9026 self.pg0.add_stream(p)
9027 self.pg_enable_capture(self.pg_interfaces)
9029 p = self.pg1.get_capture(1)
9030 self.tcp_port_out = p[0][TCP].sport
9031 capture = self.pg3.get_capture(1)
9032 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9034 self.pg_enable_capture(self.pg_interfaces)
9036 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9037 end_addr=self.nat_addr,
9040 capture = self.pg3.get_capture(1)
9041 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9043 def nat64_get_ses_num(self):
9045 Return number of active NAT64 sessions.
9047 st = self.vapi.nat64_st_dump(proto=255)
9050 def clear_nat64(self):
9052 Clear NAT64 configuration.
9054 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9055 src_port=self.ipfix_src_port,
9057 self.ipfix_src_port = 4739
9058 self.ipfix_domain_id = 1
9060 self.vapi.syslog_set_filter(
9061 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9063 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9064 tcp_transitory=240, icmp=60)
9066 interfaces = self.vapi.nat64_interface_dump()
9067 for intf in interfaces:
9068 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9069 sw_if_index=intf.sw_if_index)
9071 bib = self.vapi.nat64_bib_dump(proto=255)
9073 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9074 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9082 adresses = self.vapi.nat64_pool_addr_dump()
9083 for addr in adresses:
9084 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9085 end_addr=addr.address,
9089 prefixes = self.vapi.nat64_prefix_dump()
9090 for prefix in prefixes:
9091 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9092 vrf_id=prefix.vrf_id, is_add=0)
9094 bibs = self.statistics.get_counter('/nat64/total-bibs')
9095 self.assertEqual(bibs[0][0], 0)
9096 sessions = self.statistics.get_counter('/nat64/total-sessions')
9097 self.assertEqual(sessions[0][0], 0)
9100 super(TestNAT64, self).tearDown()
9101 if not self.vpp_dead:
9104 def show_commands_at_teardown(self):
9105 self.logger.info(self.vapi.cli("show nat64 pool"))
9106 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9107 self.logger.info(self.vapi.cli("show nat64 prefix"))
9108 self.logger.info(self.vapi.cli("show nat64 bib all"))
9109 self.logger.info(self.vapi.cli("show nat64 session table all"))
9110 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9113 class TestDSlite(MethodHolder):
9114 """ DS-Lite Test Cases """
9117 def setUpClass(cls):
9118 super(TestDSlite, cls).setUpClass()
9121 cls.nat_addr = '10.0.0.3'
9123 cls.create_pg_interfaces(range(3))
9125 cls.pg0.config_ip4()
9126 cls.pg0.resolve_arp()
9128 cls.pg1.config_ip6()
9129 cls.pg1.generate_remote_hosts(2)
9130 cls.pg1.configure_ipv6_neighbors()
9132 cls.pg2.config_ip4()
9133 cls.pg2.resolve_arp()
9136 super(TestDSlite, cls).tearDownClass()
9140 def tearDownClass(cls):
9141 super(TestDSlite, cls).tearDownClass()
9143 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9145 message = data.decode('utf-8')
9147 message = SyslogMessage.parse(message)
9148 except ParseError as e:
9149 self.logger.error(e)
9151 self.assertEqual(message.severity, SyslogSeverity.info)
9152 self.assertEqual(message.appname, 'NAT')
9153 self.assertEqual(message.msgid, 'APMADD')
9154 sd_params = message.sd.get('napmap')
9155 self.assertTrue(sd_params is not None)
9156 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9157 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9158 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9159 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9160 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9161 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9162 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9163 self.assertTrue(sd_params.get('SSUBIX') is not None)
9164 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9166 def test_dslite(self):
9167 """ Test DS-Lite """
9168 nat_config = self.vapi.nat_show_config()
9169 self.assertEqual(0, nat_config.dslite_ce)
9171 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9172 end_addr=self.nat_addr,
9174 aftr_ip4 = '192.0.0.1'
9175 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9176 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9177 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9180 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9181 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9182 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9183 UDP(sport=20000, dport=10000))
9184 self.pg1.add_stream(p)
9185 self.pg_enable_capture(self.pg_interfaces)
9187 capture = self.pg0.get_capture(1)
9188 capture = capture[0]
9189 self.assertFalse(capture.haslayer(IPv6))
9190 self.assertEqual(capture[IP].src, self.nat_addr)
9191 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9192 self.assertNotEqual(capture[UDP].sport, 20000)
9193 self.assertEqual(capture[UDP].dport, 10000)
9194 self.assert_packet_checksums_valid(capture)
9195 out_port = capture[UDP].sport
9196 capture = self.pg2.get_capture(1)
9197 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9198 20000, self.nat_addr, out_port,
9199 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9201 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9202 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9203 UDP(sport=10000, dport=out_port))
9204 self.pg0.add_stream(p)
9205 self.pg_enable_capture(self.pg_interfaces)
9207 capture = self.pg1.get_capture(1)
9208 capture = capture[0]
9209 self.assertEqual(capture[IPv6].src, aftr_ip6)
9210 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9211 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9212 self.assertEqual(capture[IP].dst, '192.168.1.1')
9213 self.assertEqual(capture[UDP].sport, 10000)
9214 self.assertEqual(capture[UDP].dport, 20000)
9215 self.assert_packet_checksums_valid(capture)
9218 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9219 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9220 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9221 TCP(sport=20001, dport=10001))
9222 self.pg1.add_stream(p)
9223 self.pg_enable_capture(self.pg_interfaces)
9225 capture = self.pg0.get_capture(1)
9226 capture = capture[0]
9227 self.assertFalse(capture.haslayer(IPv6))
9228 self.assertEqual(capture[IP].src, self.nat_addr)
9229 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9230 self.assertNotEqual(capture[TCP].sport, 20001)
9231 self.assertEqual(capture[TCP].dport, 10001)
9232 self.assert_packet_checksums_valid(capture)
9233 out_port = capture[TCP].sport
9235 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9236 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9237 TCP(sport=10001, dport=out_port))
9238 self.pg0.add_stream(p)
9239 self.pg_enable_capture(self.pg_interfaces)
9241 capture = self.pg1.get_capture(1)
9242 capture = capture[0]
9243 self.assertEqual(capture[IPv6].src, aftr_ip6)
9244 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9245 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9246 self.assertEqual(capture[IP].dst, '192.168.1.1')
9247 self.assertEqual(capture[TCP].sport, 10001)
9248 self.assertEqual(capture[TCP].dport, 20001)
9249 self.assert_packet_checksums_valid(capture)
9252 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9253 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9254 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9255 ICMP(id=4000, type='echo-request'))
9256 self.pg1.add_stream(p)
9257 self.pg_enable_capture(self.pg_interfaces)
9259 capture = self.pg0.get_capture(1)
9260 capture = capture[0]
9261 self.assertFalse(capture.haslayer(IPv6))
9262 self.assertEqual(capture[IP].src, self.nat_addr)
9263 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9264 self.assertNotEqual(capture[ICMP].id, 4000)
9265 self.assert_packet_checksums_valid(capture)
9266 out_id = capture[ICMP].id
9268 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9269 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9270 ICMP(id=out_id, type='echo-reply'))
9271 self.pg0.add_stream(p)
9272 self.pg_enable_capture(self.pg_interfaces)
9274 capture = self.pg1.get_capture(1)
9275 capture = capture[0]
9276 self.assertEqual(capture[IPv6].src, aftr_ip6)
9277 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9278 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9279 self.assertEqual(capture[IP].dst, '192.168.1.1')
9280 self.assertEqual(capture[ICMP].id, 4000)
9281 self.assert_packet_checksums_valid(capture)
9283 # ping DS-Lite AFTR tunnel endpoint address
9284 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9285 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9286 ICMPv6EchoRequest())
9287 self.pg1.add_stream(p)
9288 self.pg_enable_capture(self.pg_interfaces)
9290 capture = self.pg1.get_capture(1)
9291 capture = capture[0]
9292 self.assertEqual(capture[IPv6].src, aftr_ip6)
9293 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9294 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9296 b4s = self.statistics.get_counter('/dslite/total-b4s')
9297 self.assertEqual(b4s[0][0], 2)
9298 sessions = self.statistics.get_counter('/dslite/total-sessions')
9299 self.assertEqual(sessions[0][0], 3)
9302 super(TestDSlite, self).tearDown()
9304 def show_commands_at_teardown(self):
9305 self.logger.info(self.vapi.cli("show dslite pool"))
9307 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9308 self.logger.info(self.vapi.cli("show dslite sessions"))
9311 class TestDSliteCE(MethodHolder):
9312 """ DS-Lite CE Test Cases """
9315 def setUpConstants(cls):
9316 super(TestDSliteCE, cls).setUpConstants()
9317 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9320 def setUpClass(cls):
9321 super(TestDSliteCE, cls).setUpClass()
9324 cls.create_pg_interfaces(range(2))
9326 cls.pg0.config_ip4()
9327 cls.pg0.resolve_arp()
9329 cls.pg1.config_ip6()
9330 cls.pg1.generate_remote_hosts(1)
9331 cls.pg1.configure_ipv6_neighbors()
9334 super(TestDSliteCE, cls).tearDownClass()
9338 def tearDownClass(cls):
9339 super(TestDSliteCE, cls).tearDownClass()
9341 def test_dslite_ce(self):
9342 """ Test DS-Lite CE """
9344 nat_config = self.vapi.nat_show_config()
9345 self.assertEqual(1, nat_config.dslite_ce)
9347 b4_ip4 = '192.0.0.2'
9348 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9349 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9351 aftr_ip4 = '192.0.0.1'
9352 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9353 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9354 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9356 r1 = VppIpRoute(self, aftr_ip6, 128,
9357 [VppRoutePath(self.pg1.remote_ip6,
9358 self.pg1.sw_if_index)])
9362 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9363 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9364 UDP(sport=10000, dport=20000))
9365 self.pg0.add_stream(p)
9366 self.pg_enable_capture(self.pg_interfaces)
9368 capture = self.pg1.get_capture(1)
9369 capture = capture[0]
9370 self.assertEqual(capture[IPv6].src, b4_ip6)
9371 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9372 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9373 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9374 self.assertEqual(capture[UDP].sport, 10000)
9375 self.assertEqual(capture[UDP].dport, 20000)
9376 self.assert_packet_checksums_valid(capture)
9379 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9380 IPv6(dst=b4_ip6, src=aftr_ip6) /
9381 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9382 UDP(sport=20000, dport=10000))
9383 self.pg1.add_stream(p)
9384 self.pg_enable_capture(self.pg_interfaces)
9386 capture = self.pg0.get_capture(1)
9387 capture = capture[0]
9388 self.assertFalse(capture.haslayer(IPv6))
9389 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9390 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9391 self.assertEqual(capture[UDP].sport, 20000)
9392 self.assertEqual(capture[UDP].dport, 10000)
9393 self.assert_packet_checksums_valid(capture)
9395 # ping DS-Lite B4 tunnel endpoint address
9396 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9397 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9398 ICMPv6EchoRequest())
9399 self.pg1.add_stream(p)
9400 self.pg_enable_capture(self.pg_interfaces)
9402 capture = self.pg1.get_capture(1)
9403 capture = capture[0]
9404 self.assertEqual(capture[IPv6].src, b4_ip6)
9405 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9406 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9409 super(TestDSliteCE, self).tearDown()
9411 def show_commands_at_teardown(self):
9413 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9415 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9418 class TestNAT66(MethodHolder):
9419 """ NAT66 Test Cases """
9422 def setUpClass(cls):
9423 super(TestNAT66, cls).setUpClass()
9426 cls.nat_addr = 'fd01:ff::2'
9428 cls.create_pg_interfaces(range(2))
9429 cls.interfaces = list(cls.pg_interfaces)
9431 for i in cls.interfaces:
9434 i.configure_ipv6_neighbors()
9437 super(TestNAT66, cls).tearDownClass()
9441 def tearDownClass(cls):
9442 super(TestNAT66, cls).tearDownClass()
9444 def test_static(self):
9445 """ 1:1 NAT66 test """
9446 flags = self.config_flags.NAT_IS_INSIDE
9447 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9448 sw_if_index=self.pg0.sw_if_index)
9449 self.vapi.nat66_add_del_interface(is_add=1,
9450 sw_if_index=self.pg1.sw_if_index)
9451 self.vapi.nat66_add_del_static_mapping(
9452 local_ip_address=self.pg0.remote_ip6n,
9453 external_ip_address=self.nat_addr,
9458 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9459 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9462 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9463 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9466 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9467 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9468 ICMPv6EchoRequest())
9470 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9471 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9472 GRE() / IP() / TCP())
9474 self.pg0.add_stream(pkts)
9475 self.pg_enable_capture(self.pg_interfaces)
9477 capture = self.pg1.get_capture(len(pkts))
9478 for packet in capture:
9480 self.assertEqual(packet[IPv6].src, self.nat_addr)
9481 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9482 self.assert_packet_checksums_valid(packet)
9484 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9489 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9490 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9493 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9494 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9497 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9498 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9501 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9502 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9503 GRE() / IP() / TCP())
9505 self.pg1.add_stream(pkts)
9506 self.pg_enable_capture(self.pg_interfaces)
9508 capture = self.pg0.get_capture(len(pkts))
9509 for packet in capture:
9511 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9512 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9513 self.assert_packet_checksums_valid(packet)
9515 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9518 sm = self.vapi.nat66_static_mapping_dump()
9519 self.assertEqual(len(sm), 1)
9520 self.assertEqual(sm[0].total_pkts, 8)
9522 def test_check_no_translate(self):
9523 """ NAT66 translate only when egress interface is outside interface """
9524 flags = self.config_flags.NAT_IS_INSIDE
9525 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9526 sw_if_index=self.pg0.sw_if_index)
9527 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9528 sw_if_index=self.pg1.sw_if_index)
9529 self.vapi.nat66_add_del_static_mapping(
9530 local_ip_address=self.pg0.remote_ip6n,
9531 external_ip_address=self.nat_addr,
9535 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9536 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9538 self.pg0.add_stream([p])
9539 self.pg_enable_capture(self.pg_interfaces)
9541 capture = self.pg1.get_capture(1)
9544 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9545 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9547 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9550 def clear_nat66(self):
9552 Clear NAT66 configuration.
9554 interfaces = self.vapi.nat66_interface_dump()
9555 for intf in interfaces:
9556 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9557 sw_if_index=intf.sw_if_index)
9559 static_mappings = self.vapi.nat66_static_mapping_dump()
9560 for sm in static_mappings:
9561 self.vapi.nat66_add_del_static_mapping(
9562 local_ip_address=sm.local_ip_address,
9563 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9567 super(TestNAT66, self).tearDown()
9570 def show_commands_at_teardown(self):
9571 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9572 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9575 if __name__ == '__main__':
9576 unittest.main(testRunner=VppTestRunner)