8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
33 from ipaddress import IPv6Network
36 # NAT HA protocol event data
39 fields_desc = [ByteEnumField("event_type", None,
40 {1: "add", 2: "del", 3: "refresh"}),
41 ByteEnumField("protocol", None,
42 {0: "udp", 1: "tcp", 2: "icmp"}),
43 ShortField("flags", 0),
44 IPField("in_addr", None),
45 IPField("out_addr", None),
46 ShortField("in_port", None),
47 ShortField("out_port", None),
48 IPField("eh_addr", None),
49 IPField("ehn_addr", None),
50 ShortField("eh_port", None),
51 ShortField("ehn_port", None),
52 IntField("fib_index", None),
53 IntField("total_pkts", 0),
54 LongField("total_bytes", 0)]
56 def extract_padding(self, s):
60 # NAT HA protocol header
61 class HANATStateSync(Packet):
62 name = "HA NAT state sync"
63 fields_desc = [XByteField("version", 1),
64 FlagsField("flags", 0, 8, ['ACK']),
65 FieldLenField("count", None, count_of="events"),
66 IntField("sequence_number", 1),
67 IntField("thread_index", 0),
68 PacketListField("events", [], Event,
69 count_from=lambda pkt: pkt.count)]
72 class MethodHolder(VppTestCase):
73 """ NAT create capture and verify method holder """
76 def config_flags(self):
77 return VppEnum.vl_api_nat_config_flags_t
80 def SYSLOG_SEVERITY(self):
81 return VppEnum.vl_api_syslog_severity_t
83 def clear_nat44(self):
85 Clear NAT44 configuration.
87 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
88 if self.pg7.has_ip4_config:
89 self.pg7.unconfig_ip4()
91 self.vapi.nat44_forwarding_enable_disable(enable=0)
93 interfaces = self.vapi.nat44_interface_addr_dump()
94 for intf in interfaces:
95 self.vapi.nat44_add_del_interface_addr(
97 sw_if_index=intf.sw_if_index,
100 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
101 src_port=self.ipfix_src_port,
103 self.ipfix_src_port = 4739
104 self.ipfix_domain_id = 1
106 self.vapi.syslog_set_filter(
107 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
109 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
111 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
112 session_refresh_interval=10)
114 interfaces = self.vapi.nat44_interface_dump()
115 for intf in interfaces:
116 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
117 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
118 self.vapi.nat44_interface_add_del_feature(
119 sw_if_index=intf.sw_if_index)
120 self.vapi.nat44_interface_add_del_feature(
121 sw_if_index=intf.sw_if_index,
124 interfaces = self.vapi.nat44_interface_output_feature_dump()
125 for intf in interfaces:
126 self.vapi.nat44_interface_add_del_output_feature(
129 sw_if_index=intf.sw_if_index)
130 static_mappings = self.vapi.nat44_static_mapping_dump()
131 for sm in static_mappings:
132 self.vapi.nat44_add_del_static_mapping(
134 local_ip_address=sm.local_ip_address,
135 external_ip_address=sm.external_ip_address,
136 external_sw_if_index=sm.external_sw_if_index,
137 local_port=sm.local_port,
138 external_port=sm.external_port,
140 protocol=sm.protocol,
141 flags=sm.flags, tag=sm.tag)
143 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
144 for lb_sm in lb_static_mappings:
145 self.vapi.nat44_add_del_lb_static_mapping(
148 external_addr=lb_sm.external_addr,
149 external_port=lb_sm.external_port,
150 protocol=lb_sm.protocol,
151 local_num=0, locals=[],
154 identity_mappings = self.vapi.nat44_identity_mapping_dump()
155 for id_m in identity_mappings:
156 self.vapi.nat44_add_del_identity_mapping(
157 ip_address=id_m.ip_address,
158 sw_if_index=id_m.sw_if_index,
162 protocol=id_m.protocol)
164 addresses = self.vapi.nat44_address_dump()
165 for addr in addresses:
166 self.vapi.nat44_add_del_address_range(
167 first_ip_address=addr.ip_address,
168 last_ip_address=addr.ip_address,
169 vrf_id=0xFFFFFFFF, flags=addr.flags)
171 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
173 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
174 drop_frag=0, is_ip6=1)
175 self.verify_no_nat44_user()
176 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
177 tcp_transitory=240, icmp=60)
178 self.vapi.nat_set_addr_and_port_alloc_alg()
179 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
181 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
182 local_port=0, external_port=0, vrf_id=0,
183 is_add=1, external_sw_if_index=0xFFFFFFFF,
184 proto=0, tag="", flags=0):
186 Add/delete NAT44 static mapping
188 :param local_ip: Local IP address
189 :param external_ip: External IP address
190 :param local_port: Local port number (Optional)
191 :param external_port: External port number (Optional)
192 :param vrf_id: VRF ID (Default 0)
193 :param is_add: 1 if add, 0 if delete (Default add)
194 :param external_sw_if_index: External interface instead of IP address
195 :param proto: IP protocol (Mandatory if port specified)
196 :param tag: Opaque string tag
197 :param flags: NAT configuration flags
200 if not (local_port and external_port):
201 flags |= self.config_flags.NAT_IS_ADDR_ONLY
203 self.vapi.nat44_add_del_static_mapping(
205 local_ip_address=local_ip,
206 external_ip_address=external_ip,
207 external_sw_if_index=external_sw_if_index,
208 local_port=local_port,
209 external_port=external_port,
210 vrf_id=vrf_id, protocol=proto,
214 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
216 Add/delete NAT44 address
218 :param ip: IP address
219 :param is_add: 1 if add, 0 if delete (Default add)
220 :param twice_nat: twice NAT address for external hosts
222 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
223 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
229 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
231 Create packet stream for inside network
233 :param in_if: Inside interface
234 :param out_if: Outside interface
235 :param dst_ip: Destination address
236 :param ttl: TTL of generated packets
239 dst_ip = out_if.remote_ip4
243 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
244 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
245 TCP(sport=self.tcp_port_in, dport=20))
249 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
250 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
251 UDP(sport=self.udp_port_in, dport=20))
255 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
256 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
257 ICMP(id=self.icmp_id_in, type='echo-request'))
262 def compose_ip6(self, ip4, pref, plen):
264 Compose IPv4-embedded IPv6 addresses
266 :param ip4: IPv4 address
267 :param pref: IPv6 prefix
268 :param plen: IPv6 prefix length
269 :returns: IPv4-embedded IPv6 addresses
271 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
272 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
287 pref_n[10] = ip4_n[3]
291 pref_n[10] = ip4_n[2]
292 pref_n[11] = ip4_n[3]
295 pref_n[10] = ip4_n[1]
296 pref_n[11] = ip4_n[2]
297 pref_n[12] = ip4_n[3]
299 pref_n[12] = ip4_n[0]
300 pref_n[13] = ip4_n[1]
301 pref_n[14] = ip4_n[2]
302 pref_n[15] = ip4_n[3]
303 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
304 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
306 def extract_ip4(self, ip6, plen):
308 Extract IPv4 address embedded in IPv6 addresses
310 :param ip6: IPv6 address
311 :param plen: IPv6 prefix length
312 :returns: extracted IPv4 address
314 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
346 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
348 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
350 Create IPv6 packet stream for inside network
352 :param in_if: Inside interface
353 :param out_if: Outside interface
354 :param ttl: Hop Limit of generated packets
355 :param pref: NAT64 prefix
356 :param plen: NAT64 prefix length
360 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
362 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
365 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
366 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
367 TCP(sport=self.tcp_port_in, dport=20))
371 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
372 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
373 UDP(sport=self.udp_port_in, dport=20))
377 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
378 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
379 ICMPv6EchoRequest(id=self.icmp_id_in))
384 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
385 use_inside_ports=False):
387 Create packet stream for outside network
389 :param out_if: Outside interface
390 :param dst_ip: Destination IP address (Default use global NAT address)
391 :param ttl: TTL of generated packets
392 :param use_inside_ports: Use inside NAT ports as destination ports
393 instead of outside ports
396 dst_ip = self.nat_addr
397 if not use_inside_ports:
398 tcp_port = self.tcp_port_out
399 udp_port = self.udp_port_out
400 icmp_id = self.icmp_id_out
402 tcp_port = self.tcp_port_in
403 udp_port = self.udp_port_in
404 icmp_id = self.icmp_id_in
407 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
408 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
409 TCP(dport=tcp_port, sport=20))
413 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
414 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
415 UDP(dport=udp_port, sport=20))
419 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
420 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
421 ICMP(id=icmp_id, type='echo-reply'))
426 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
428 Create packet stream for outside network
430 :param out_if: Outside interface
431 :param dst_ip: Destination IP address (Default use global NAT address)
432 :param hl: HL of generated packets
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
438 TCP(dport=self.tcp_port_out, sport=20))
442 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
443 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
444 UDP(dport=self.udp_port_out, sport=20))
448 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
449 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
450 ICMPv6EchoReply(id=self.icmp_id_out))
455 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
456 dst_ip=None, is_ip6=False):
458 Verify captured packets on outside network
460 :param capture: Captured packets
461 :param nat_ip: Translated IP address (Default use global NAT address)
462 :param same_port: Source port number is not translated (Default False)
463 :param dst_ip: Destination IP address (Default do not verify)
464 :param is_ip6: If L3 protocol is IPv6 (Default False)
468 ICMP46 = ICMPv6EchoRequest
473 nat_ip = self.nat_addr
474 for packet in capture:
477 self.assert_packet_checksums_valid(packet)
478 self.assertEqual(packet[IP46].src, nat_ip)
479 if dst_ip is not None:
480 self.assertEqual(packet[IP46].dst, dst_ip)
481 if packet.haslayer(TCP):
483 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
486 packet[TCP].sport, self.tcp_port_in)
487 self.tcp_port_out = packet[TCP].sport
488 self.assert_packet_checksums_valid(packet)
489 elif packet.haslayer(UDP):
491 self.assertEqual(packet[UDP].sport, self.udp_port_in)
494 packet[UDP].sport, self.udp_port_in)
495 self.udp_port_out = packet[UDP].sport
498 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
500 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
501 self.icmp_id_out = packet[ICMP46].id
502 self.assert_packet_checksums_valid(packet)
504 self.logger.error(ppp("Unexpected or invalid packet "
505 "(outside network):", packet))
508 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
511 Verify captured packets on outside network
513 :param capture: Captured packets
514 :param nat_ip: Translated IP address
515 :param same_port: Source port number is not translated (Default False)
516 :param dst_ip: Destination IP address (Default do not verify)
518 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
521 def verify_capture_in(self, capture, in_if):
523 Verify captured packets on inside network
525 :param capture: Captured packets
526 :param in_if: Inside interface
528 for packet in capture:
530 self.assert_packet_checksums_valid(packet)
531 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
532 if packet.haslayer(TCP):
533 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
534 elif packet.haslayer(UDP):
535 self.assertEqual(packet[UDP].dport, self.udp_port_in)
537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
539 self.logger.error(ppp("Unexpected or invalid packet "
540 "(inside network):", packet))
543 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
545 Verify captured IPv6 packets on inside network
547 :param capture: Captured packets
548 :param src_ip: Source IP
549 :param dst_ip: Destination IP address
551 for packet in capture:
553 self.assertEqual(packet[IPv6].src, src_ip)
554 self.assertEqual(packet[IPv6].dst, dst_ip)
555 self.assert_packet_checksums_valid(packet)
556 if packet.haslayer(TCP):
557 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
558 elif packet.haslayer(UDP):
559 self.assertEqual(packet[UDP].dport, self.udp_port_in)
561 self.assertEqual(packet[ICMPv6EchoReply].id,
564 self.logger.error(ppp("Unexpected or invalid packet "
565 "(inside network):", packet))
568 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
570 Verify captured packet that don't have to be translated
572 :param capture: Captured packets
573 :param ingress_if: Ingress interface
574 :param egress_if: Egress interface
576 for packet in capture:
578 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
579 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
580 if packet.haslayer(TCP):
581 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
582 elif packet.haslayer(UDP):
583 self.assertEqual(packet[UDP].sport, self.udp_port_in)
585 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(inside network):", packet))
591 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
594 Verify captured packets with ICMP errors on outside network
596 :param capture: Captured packets
597 :param src_ip: Translated IP address or IP address of VPP
598 (Default use global NAT address)
599 :param icmp_type: Type of error ICMP packet
600 we are expecting (Default 11)
603 src_ip = self.nat_addr
604 for packet in capture:
606 self.assertEqual(packet[IP].src, src_ip)
607 self.assertEqual(packet.haslayer(ICMP), 1)
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].dport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].dport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(outside network):", packet))
625 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
627 Verify captured packets with ICMP errors on inside network
629 :param capture: Captured packets
630 :param in_if: Inside interface
631 :param icmp_type: Type of error ICMP packet
632 we are expecting (Default 11)
634 for packet in capture:
636 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
637 self.assertEqual(packet.haslayer(ICMP), 1)
639 self.assertEqual(icmp.type, icmp_type)
640 self.assertTrue(icmp.haslayer(IPerror))
641 inner_ip = icmp[IPerror]
642 if inner_ip.haslayer(TCPerror):
643 self.assertEqual(inner_ip[TCPerror].sport,
645 elif inner_ip.haslayer(UDPerror):
646 self.assertEqual(inner_ip[UDPerror].sport,
649 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
651 self.logger.error(ppp("Unexpected or invalid packet "
652 "(inside network):", packet))
655 def create_stream_frag(self, src_if, dst, sport, dport, data,
656 proto=IP_PROTOS.tcp, echo_reply=False):
658 Create fragmented packet stream
660 :param src_if: Source interface
661 :param dst: Destination IPv4 address
662 :param sport: Source port
663 :param dport: Destination port
664 :param data: Payload data
665 :param proto: protocol (TCP, UDP, ICMP)
666 :param echo_reply: use echo_reply if protocol is ICMP
669 if proto == IP_PROTOS.tcp:
670 p = (IP(src=src_if.remote_ip4, dst=dst) /
671 TCP(sport=sport, dport=dport) /
673 p = p.__class__(scapy.compat.raw(p))
674 chksum = p[TCP].chksum
675 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
676 elif proto == IP_PROTOS.udp:
677 proto_header = UDP(sport=sport, dport=dport)
678 elif proto == IP_PROTOS.icmp:
680 proto_header = ICMP(id=sport, type='echo-request')
682 proto_header = ICMP(id=sport, type='echo-reply')
684 raise Exception("Unsupported protocol")
685 id = random.randint(0, 65535)
687 if proto == IP_PROTOS.tcp:
690 raw = Raw(data[0:16])
691 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
692 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
696 if proto == IP_PROTOS.tcp:
697 raw = Raw(data[4:20])
699 raw = Raw(data[16:32])
700 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
701 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
705 if proto == IP_PROTOS.tcp:
709 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
710 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
716 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
717 pref=None, plen=0, frag_size=128):
719 Create fragmented packet stream
721 :param src_if: Source interface
722 :param dst: Destination IPv4 address
723 :param sport: Source TCP port
724 :param dport: Destination TCP port
725 :param data: Payload data
726 :param pref: NAT64 prefix
727 :param plen: NAT64 prefix length
728 :param fragsize: size of fragments
732 dst_ip6 = ''.join(['64:ff9b::', dst])
734 dst_ip6 = self.compose_ip6(dst, pref, plen)
736 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
737 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
738 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
739 TCP(sport=sport, dport=dport) /
742 return fragment6(p, frag_size)
744 def reass_frags_and_verify(self, frags, src, dst):
746 Reassemble and verify fragmented packet
748 :param frags: Captured fragments
749 :param src: Source IPv4 address to verify
750 :param dst: Destination IPv4 address to verify
752 :returns: Reassembled IPv4 packet
756 self.assertEqual(p[IP].src, src)
757 self.assertEqual(p[IP].dst, dst)
758 self.assert_ip_checksum_valid(p)
759 buffer.seek(p[IP].frag * 8)
760 buffer.write(bytes(p[IP].payload))
761 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
762 proto=frags[0][IP].proto)
763 if ip.proto == IP_PROTOS.tcp:
764 p = (ip / TCP(buffer.getvalue()))
765 self.assert_tcp_checksum_valid(p)
766 elif ip.proto == IP_PROTOS.udp:
767 p = (ip / UDP(buffer.getvalue()[:8]) /
768 Raw(buffer.getvalue()[8:]))
769 elif ip.proto == IP_PROTOS.icmp:
770 p = (ip / ICMP(buffer.getvalue()))
773 def reass_frags_and_verify_ip6(self, frags, src, dst):
775 Reassemble and verify fragmented packet
777 :param frags: Captured fragments
778 :param src: Source IPv6 address to verify
779 :param dst: Destination IPv6 address to verify
781 :returns: Reassembled IPv6 packet
785 self.assertEqual(p[IPv6].src, src)
786 self.assertEqual(p[IPv6].dst, dst)
787 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
788 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
789 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
790 nh=frags[0][IPv6ExtHdrFragment].nh)
791 if ip.nh == IP_PROTOS.tcp:
792 p = (ip / TCP(buffer.getvalue()))
793 elif ip.nh == IP_PROTOS.udp:
794 p = (ip / UDP(buffer.getvalue()))
795 self.assert_packet_checksums_valid(p)
798 def initiate_tcp_session(self, in_if, out_if):
800 Initiates TCP session
802 :param in_if: Inside interface
803 :param out_if: Outside interface
807 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
808 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
809 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
812 self.pg_enable_capture(self.pg_interfaces)
814 capture = out_if.get_capture(1)
816 self.tcp_port_out = p[TCP].sport
818 # SYN + ACK packet out->in
819 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
820 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
821 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
824 self.pg_enable_capture(self.pg_interfaces)
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 out_if.get_capture(1)
839 self.logger.error("TCP 3 way handshake failed")
842 def verify_ipfix_nat44_ses(self, data):
844 Verify IPFIX NAT44 session create/delete event
846 :param data: Decoded IPFIX data records
848 nat44_ses_create_num = 0
849 nat44_ses_delete_num = 0
850 self.assertEqual(6, len(data))
853 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
854 if scapy.compat.orb(record[230]) == 4:
855 nat44_ses_create_num += 1
857 nat44_ses_delete_num += 1
859 self.assertEqual(self.pg0.remote_ip4n, record[8])
860 # postNATSourceIPv4Address
861 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
864 self.assertEqual(struct.pack("!I", 0), record[234])
865 # protocolIdentifier/sourceTransportPort
866 # /postNAPTSourceTransportPort
867 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
868 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
869 self.assertEqual(struct.pack("!H", self.icmp_id_out),
871 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
872 self.assertEqual(struct.pack("!H", self.tcp_port_in),
874 self.assertEqual(struct.pack("!H", self.tcp_port_out),
876 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.udp_port_in),
879 self.assertEqual(struct.pack("!H", self.udp_port_out),
882 self.fail("Invalid protocol")
883 self.assertEqual(3, nat44_ses_create_num)
884 self.assertEqual(3, nat44_ses_delete_num)
886 def verify_ipfix_addr_exhausted(self, data):
888 Verify IPFIX NAT addresses event
890 :param data: Decoded IPFIX data records
892 self.assertEqual(1, len(data))
895 self.assertEqual(scapy.compat.orb(record[230]), 3)
897 self.assertEqual(struct.pack("!I", 0), record[283])
899 def verify_ipfix_max_sessions(self, data, limit):
901 Verify IPFIX maximum session entries exceeded event
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum session entries that can be created.
906 self.assertEqual(1, len(data))
909 self.assertEqual(scapy.compat.orb(record[230]), 13)
910 # natQuotaExceededEvent
911 self.assertEqual(struct.pack("I", 1), record[466])
913 self.assertEqual(struct.pack("I", limit), record[471])
915 def verify_ipfix_max_bibs(self, data, limit):
917 Verify IPFIX maximum BIB entries exceeded event
919 :param data: Decoded IPFIX data records
920 :param limit: Number of maximum BIB entries that can be created.
922 self.assertEqual(1, len(data))
925 self.assertEqual(scapy.compat.orb(record[230]), 13)
926 # natQuotaExceededEvent
927 self.assertEqual(struct.pack("I", 2), record[466])
929 self.assertEqual(struct.pack("I", limit), record[472])
931 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
933 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
935 :param data: Decoded IPFIX data records
936 :param limit: Number of maximum fragments pending reassembly
937 :param src_addr: IPv6 source address
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 5), record[466])
945 # maxFragmentsPendingReassembly
946 self.assertEqual(struct.pack("I", limit), record[475])
948 self.assertEqual(src_addr, record[27])
950 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
952 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
954 :param data: Decoded IPFIX data records
955 :param limit: Number of maximum fragments pending reassembly
956 :param src_addr: IPv4 source address
958 self.assertEqual(1, len(data))
961 self.assertEqual(scapy.compat.orb(record[230]), 13)
962 # natQuotaExceededEvent
963 self.assertEqual(struct.pack("I", 5), record[466])
964 # maxFragmentsPendingReassembly
965 self.assertEqual(struct.pack("I", limit), record[475])
967 self.assertEqual(src_addr, record[8])
969 def verify_ipfix_bib(self, data, is_create, src_addr):
971 Verify IPFIX NAT64 BIB create and delete events
973 :param data: Decoded IPFIX data records
974 :param is_create: Create event if nonzero value otherwise delete event
975 :param src_addr: IPv6 source address
977 self.assertEqual(1, len(data))
981 self.assertEqual(scapy.compat.orb(record[230]), 10)
983 self.assertEqual(scapy.compat.orb(record[230]), 11)
985 self.assertEqual(src_addr, record[27])
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
997 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1000 Verify IPFIX NAT64 session create and delete events
1002 :param data: Decoded IPFIX data records
1003 :param is_create: Create event if nonzero value otherwise delete event
1004 :param src_addr: IPv6 source address
1005 :param dst_addr: IPv4 destination address
1006 :param dst_port: destination TCP port
1008 self.assertEqual(1, len(data))
1012 self.assertEqual(scapy.compat.orb(record[230]), 6)
1014 self.assertEqual(scapy.compat.orb(record[230]), 7)
1016 self.assertEqual(src_addr, record[27])
1017 # destinationIPv6Address
1018 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1019 self.compose_ip6(dst_addr,
1023 # postNATSourceIPv4Address
1024 self.assertEqual(self.nat_addr_n, record[225])
1025 # postNATDestinationIPv4Address
1026 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1028 # protocolIdentifier
1029 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1031 self.assertEqual(struct.pack("!I", 0), record[234])
1032 # sourceTransportPort
1033 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1034 # postNAPTSourceTransportPort
1035 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1036 # destinationTransportPort
1037 self.assertEqual(struct.pack("!H", dst_port), record[11])
1038 # postNAPTDestinationTransportPort
1039 self.assertEqual(struct.pack("!H", dst_port), record[228])
1041 def verify_no_nat44_user(self):
1042 """ Verify that there is no NAT44 user """
1043 users = self.vapi.nat44_user_dump()
1044 self.assertEqual(len(users), 0)
1045 users = self.statistics.get_counter('/nat44/total-users')
1046 self.assertEqual(users[0][0], 0)
1047 sessions = self.statistics.get_counter('/nat44/total-sessions')
1048 self.assertEqual(sessions[0][0], 0)
1050 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1052 Verify IPFIX maximum entries per user exceeded event
1054 :param data: Decoded IPFIX data records
1055 :param limit: Number of maximum entries per user
1056 :param src_addr: IPv4 source address
1058 self.assertEqual(1, len(data))
1061 self.assertEqual(scapy.compat.orb(record[230]), 13)
1062 # natQuotaExceededEvent
1063 self.assertEqual(struct.pack("I", 3), record[466])
1065 self.assertEqual(struct.pack("I", limit), record[473])
1067 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1069 def verify_syslog_apmap(self, data, is_add=True):
1070 message = data.decode('utf-8')
1072 message = SyslogMessage.parse(message)
1073 except ParseError as e:
1074 self.logger.error(e)
1077 self.assertEqual(message.severity, SyslogSeverity.info)
1078 self.assertEqual(message.appname, 'NAT')
1079 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1080 sd_params = message.sd.get('napmap')
1081 self.assertTrue(sd_params is not None)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1085 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1086 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1087 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1088 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1089 self.assertTrue(sd_params.get('SSUBIX') is not None)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1092 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1093 message = data.decode('utf-8')
1095 message = SyslogMessage.parse(message)
1096 except ParseError as e:
1097 self.logger.error(e)
1100 self.assertEqual(message.severity, SyslogSeverity.info)
1101 self.assertEqual(message.appname, 'NAT')
1102 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1103 sd_params = message.sd.get('nsess')
1104 self.assertTrue(sd_params is not None)
1106 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1107 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1109 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1110 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1113 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1114 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1115 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1116 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1117 self.assertEqual(sd_params.get('SVLAN'), '0')
1118 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1119 self.assertEqual(sd_params.get('XDPORT'),
1120 "%d" % self.tcp_external_port)
1122 def verify_mss_value(self, pkt, mss):
1124 Verify TCP MSS value
1129 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1130 raise TypeError("Not a TCP/IP packet")
1132 for option in pkt[TCP].options:
1133 if option[0] == 'MSS':
1134 self.assertEqual(option[1], mss)
1135 self.assert_tcp_checksum_valid(pkt)
1138 def proto2layer(proto):
1139 if proto == IP_PROTOS.tcp:
1141 elif proto == IP_PROTOS.udp:
1143 elif proto == IP_PROTOS.icmp:
1146 raise Exception("Unsupported protocol")
1148 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1149 layer = self.proto2layer(proto)
1151 if proto == IP_PROTOS.tcp:
1152 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1154 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1155 self.port_in = random.randint(1025, 65535)
1157 reass = self.vapi.nat_reass_dump()
1158 reass_n_start = len(reass)
1161 pkts = self.create_stream_frag(self.pg0,
1162 self.pg1.remote_ip4,
1167 self.pg0.add_stream(pkts)
1168 self.pg_enable_capture(self.pg_interfaces)
1170 frags = self.pg1.get_capture(len(pkts))
1171 if not dont_translate:
1172 p = self.reass_frags_and_verify(frags,
1174 self.pg1.remote_ip4)
1176 p = self.reass_frags_and_verify(frags,
1177 self.pg0.remote_ip4,
1178 self.pg1.remote_ip4)
1179 if proto != IP_PROTOS.icmp:
1180 if not dont_translate:
1181 self.assertEqual(p[layer].dport, 20)
1182 self.assertNotEqual(p[layer].sport, self.port_in)
1184 self.assertEqual(p[layer].sport, self.port_in)
1186 if not dont_translate:
1187 self.assertNotEqual(p[layer].id, self.port_in)
1189 self.assertEqual(p[layer].id, self.port_in)
1190 self.assertEqual(data, p[Raw].load)
1193 if not dont_translate:
1194 dst_addr = self.nat_addr
1196 dst_addr = self.pg0.remote_ip4
1197 if proto != IP_PROTOS.icmp:
1199 dport = p[layer].sport
1203 pkts = self.create_stream_frag(self.pg1,
1210 self.pg1.add_stream(pkts)
1211 self.pg_enable_capture(self.pg_interfaces)
1213 frags = self.pg0.get_capture(len(pkts))
1214 p = self.reass_frags_and_verify(frags,
1215 self.pg1.remote_ip4,
1216 self.pg0.remote_ip4)
1217 if proto != IP_PROTOS.icmp:
1218 self.assertEqual(p[layer].sport, 20)
1219 self.assertEqual(p[layer].dport, self.port_in)
1221 self.assertEqual(p[layer].id, self.port_in)
1222 self.assertEqual(data, p[Raw].load)
1224 reass = self.vapi.nat_reass_dump()
1225 reass_n_end = len(reass)
1227 self.assertEqual(reass_n_end - reass_n_start, 2)
1229 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1230 layer = self.proto2layer(proto)
1232 if proto == IP_PROTOS.tcp:
1233 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1235 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1236 self.port_in = random.randint(1025, 65535)
1239 reass = self.vapi.nat_reass_dump()
1240 reass_n_start = len(reass)
1243 pkts = self.create_stream_frag(self.pg0,
1244 self.server_out_addr,
1246 self.server_out_port,
1249 self.pg0.add_stream(pkts)
1250 self.pg_enable_capture(self.pg_interfaces)
1252 frags = self.pg1.get_capture(len(pkts))
1253 p = self.reass_frags_and_verify(frags,
1254 self.pg0.remote_ip4,
1255 self.server_in_addr)
1256 if proto != IP_PROTOS.icmp:
1257 self.assertEqual(p[layer].sport, self.port_in)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1260 self.assertEqual(p[layer].id, self.port_in)
1261 self.assertEqual(data, p[Raw].load)
1264 if proto != IP_PROTOS.icmp:
1265 pkts = self.create_stream_frag(self.pg1,
1266 self.pg0.remote_ip4,
1267 self.server_in_port,
1272 pkts = self.create_stream_frag(self.pg1,
1273 self.pg0.remote_ip4,
1279 self.pg1.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg0.get_capture(len(pkts))
1283 p = self.reass_frags_and_verify(frags,
1284 self.server_out_addr,
1285 self.pg0.remote_ip4)
1286 if proto != IP_PROTOS.icmp:
1287 self.assertEqual(p[layer].sport, self.server_out_port)
1288 self.assertEqual(p[layer].dport, self.port_in)
1290 self.assertEqual(p[layer].id, self.port_in)
1291 self.assertEqual(data, p[Raw].load)
1293 reass = self.vapi.nat_reass_dump()
1294 reass_n_end = len(reass)
1296 self.assertEqual(reass_n_end - reass_n_start, 2)
1298 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1299 layer = self.proto2layer(proto)
1301 if proto == IP_PROTOS.tcp:
1302 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1304 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1306 # send packet from host to server
1307 pkts = self.create_stream_frag(self.pg0,
1310 self.server_out_port,
1313 self.pg0.add_stream(pkts)
1314 self.pg_enable_capture(self.pg_interfaces)
1316 frags = self.pg0.get_capture(len(pkts))
1317 p = self.reass_frags_and_verify(frags,
1320 if proto != IP_PROTOS.icmp:
1321 self.assertNotEqual(p[layer].sport, self.host_in_port)
1322 self.assertEqual(p[layer].dport, self.server_in_port)
1324 self.assertNotEqual(p[layer].id, self.host_in_port)
1325 self.assertEqual(data, p[Raw].load)
1327 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1328 layer = self.proto2layer(proto)
1330 if proto == IP_PROTOS.tcp:
1331 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1333 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1334 self.port_in = random.randint(1025, 65535)
1338 pkts = self.create_stream_frag(self.pg0,
1339 self.pg1.remote_ip4,
1345 self.pg0.add_stream(pkts)
1346 self.pg_enable_capture(self.pg_interfaces)
1348 frags = self.pg1.get_capture(len(pkts))
1349 if not dont_translate:
1350 p = self.reass_frags_and_verify(frags,
1352 self.pg1.remote_ip4)
1354 p = self.reass_frags_and_verify(frags,
1355 self.pg0.remote_ip4,
1356 self.pg1.remote_ip4)
1357 if proto != IP_PROTOS.icmp:
1358 if not dont_translate:
1359 self.assertEqual(p[layer].dport, 20)
1360 self.assertNotEqual(p[layer].sport, self.port_in)
1362 self.assertEqual(p[layer].sport, self.port_in)
1364 if not dont_translate:
1365 self.assertNotEqual(p[layer].id, self.port_in)
1367 self.assertEqual(p[layer].id, self.port_in)
1368 self.assertEqual(data, p[Raw].load)
1371 if not dont_translate:
1372 dst_addr = self.nat_addr
1374 dst_addr = self.pg0.remote_ip4
1375 if proto != IP_PROTOS.icmp:
1377 dport = p[layer].sport
1381 pkts = self.create_stream_frag(self.pg1,
1389 self.pg1.add_stream(pkts)
1390 self.pg_enable_capture(self.pg_interfaces)
1392 frags = self.pg0.get_capture(len(pkts))
1393 p = self.reass_frags_and_verify(frags,
1394 self.pg1.remote_ip4,
1395 self.pg0.remote_ip4)
1396 if proto != IP_PROTOS.icmp:
1397 self.assertEqual(p[layer].sport, 20)
1398 self.assertEqual(p[layer].dport, self.port_in)
1400 self.assertEqual(p[layer].id, self.port_in)
1401 self.assertEqual(data, p[Raw].load)
1403 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1404 layer = self.proto2layer(proto)
1406 if proto == IP_PROTOS.tcp:
1407 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1409 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1410 self.port_in = random.randint(1025, 65535)
1414 pkts = self.create_stream_frag(self.pg0,
1415 self.server_out_addr,
1417 self.server_out_port,
1421 self.pg0.add_stream(pkts)
1422 self.pg_enable_capture(self.pg_interfaces)
1424 frags = self.pg1.get_capture(len(pkts))
1425 p = self.reass_frags_and_verify(frags,
1426 self.pg0.remote_ip4,
1427 self.server_in_addr)
1428 if proto != IP_PROTOS.icmp:
1429 self.assertEqual(p[layer].dport, self.server_in_port)
1430 self.assertEqual(p[layer].sport, self.port_in)
1431 self.assertEqual(p[layer].dport, self.server_in_port)
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1437 if proto != IP_PROTOS.icmp:
1438 pkts = self.create_stream_frag(self.pg1,
1439 self.pg0.remote_ip4,
1440 self.server_in_port,
1445 pkts = self.create_stream_frag(self.pg1,
1446 self.pg0.remote_ip4,
1453 self.pg1.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1456 frags = self.pg0.get_capture(len(pkts))
1457 p = self.reass_frags_and_verify(frags,
1458 self.server_out_addr,
1459 self.pg0.remote_ip4)
1460 if proto != IP_PROTOS.icmp:
1461 self.assertEqual(p[layer].sport, self.server_out_port)
1462 self.assertEqual(p[layer].dport, self.port_in)
1464 self.assertEqual(p[layer].id, self.port_in)
1465 self.assertEqual(data, p[Raw].load)
1468 class TestNAT44(MethodHolder):
1469 """ NAT44 Test Cases """
1472 def setUpClass(cls):
1473 super(TestNAT44, cls).setUpClass()
1474 cls.vapi.cli("set log class nat level debug")
1477 cls.tcp_port_in = 6303
1478 cls.tcp_port_out = 6303
1479 cls.udp_port_in = 6304
1480 cls.udp_port_out = 6304
1481 cls.icmp_id_in = 6305
1482 cls.icmp_id_out = 6305
1483 cls.nat_addr = '10.0.0.3'
1484 cls.ipfix_src_port = 4739
1485 cls.ipfix_domain_id = 1
1486 cls.tcp_external_port = 80
1487 cls.udp_external_port = 69
1489 cls.create_pg_interfaces(range(10))
1490 cls.interfaces = list(cls.pg_interfaces[0:4])
1492 for i in cls.interfaces:
1497 cls.pg0.generate_remote_hosts(3)
1498 cls.pg0.configure_ipv4_neighbors()
1500 cls.pg1.generate_remote_hosts(1)
1501 cls.pg1.configure_ipv4_neighbors()
1503 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1504 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1505 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1507 cls.pg4._local_ip4 = "172.16.255.1"
1508 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1509 cls.pg4.set_table_ip4(10)
1510 cls.pg5._local_ip4 = "172.17.255.3"
1511 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1512 cls.pg5.set_table_ip4(10)
1513 cls.pg6._local_ip4 = "172.16.255.1"
1514 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1515 cls.pg6.set_table_ip4(20)
1516 for i in cls.overlapping_interfaces:
1524 cls.pg9.generate_remote_hosts(2)
1525 cls.pg9.config_ip4()
1526 cls.vapi.sw_interface_add_del_address(
1527 sw_if_index=cls.pg9.sw_if_index,
1528 prefix="10.0.0.1/24")
1531 cls.pg9.resolve_arp()
1532 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1533 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1534 cls.pg9.resolve_arp()
1537 super(TestNAT44, cls).tearDownClass()
1541 def tearDownClass(cls):
1542 super(TestNAT44, cls).tearDownClass()
1544 def test_dynamic(self):
1545 """ NAT44 dynamic translation test """
1546 self.nat44_add_address(self.nat_addr)
1547 flags = self.config_flags.NAT_IS_INSIDE
1548 self.vapi.nat44_interface_add_del_feature(
1549 sw_if_index=self.pg0.sw_if_index,
1550 flags=flags, is_add=1)
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg1.sw_if_index,
1556 tcpn = self.statistics.get_err_counter(
1557 '/err/nat44-in2out-slowpath/TCP packets')
1558 udpn = self.statistics.get_err_counter(
1559 '/err/nat44-in2out-slowpath/UDP packets')
1560 icmpn = self.statistics.get_err_counter(
1561 '/err/nat44-in2out-slowpath/ICMP packets')
1562 totaln = self.statistics.get_err_counter(
1563 '/err/nat44-in2out-slowpath/good in2out packets processed')
1565 pkts = self.create_stream_in(self.pg0, self.pg1)
1566 self.pg0.add_stream(pkts)
1567 self.pg_enable_capture(self.pg_interfaces)
1569 capture = self.pg1.get_capture(len(pkts))
1570 self.verify_capture_out(capture)
1572 err = self.statistics.get_err_counter(
1573 '/err/nat44-in2out-slowpath/TCP packets')
1574 self.assertEqual(err - tcpn, 2)
1575 err = self.statistics.get_err_counter(
1576 '/err/nat44-in2out-slowpath/UDP packets')
1577 self.assertEqual(err - udpn, 1)
1578 err = self.statistics.get_err_counter(
1579 '/err/nat44-in2out-slowpath/ICMP packets')
1580 self.assertEqual(err - icmpn, 1)
1581 err = self.statistics.get_err_counter(
1582 '/err/nat44-in2out-slowpath/good in2out packets processed')
1583 self.assertEqual(err - totaln, 4)
1586 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1587 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1588 icmpn = self.statistics.get_err_counter(
1589 '/err/nat44-out2in/ICMP packets')
1590 totaln = self.statistics.get_err_counter(
1591 '/err/nat44-out2in/good out2in packets processed')
1593 pkts = self.create_stream_out(self.pg1)
1594 self.pg1.add_stream(pkts)
1595 self.pg_enable_capture(self.pg_interfaces)
1597 capture = self.pg0.get_capture(len(pkts))
1598 self.verify_capture_in(capture, self.pg0)
1600 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1601 self.assertEqual(err - tcpn, 2)
1602 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1603 self.assertEqual(err - udpn, 1)
1604 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1605 self.assertEqual(err - icmpn, 1)
1606 err = self.statistics.get_err_counter(
1607 '/err/nat44-out2in/good out2in packets processed')
1608 self.assertEqual(err - totaln, 4)
1610 users = self.statistics.get_counter('/nat44/total-users')
1611 self.assertEqual(users[0][0], 1)
1612 sessions = self.statistics.get_counter('/nat44/total-sessions')
1613 self.assertEqual(sessions[0][0], 3)
1615 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1616 """ NAT44 handling of client packets with TTL=1 """
1618 self.nat44_add_address(self.nat_addr)
1619 flags = self.config_flags.NAT_IS_INSIDE
1620 self.vapi.nat44_interface_add_del_feature(
1621 sw_if_index=self.pg0.sw_if_index,
1622 flags=flags, is_add=1)
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg1.sw_if_index,
1627 # Client side - generate traffic
1628 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1629 self.pg0.add_stream(pkts)
1630 self.pg_enable_capture(self.pg_interfaces)
1633 # Client side - verify ICMP type 11 packets
1634 capture = self.pg0.get_capture(len(pkts))
1635 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1637 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1638 """ NAT44 handling of server packets with TTL=1 """
1640 self.nat44_add_address(self.nat_addr)
1641 flags = self.config_flags.NAT_IS_INSIDE
1642 self.vapi.nat44_interface_add_del_feature(
1643 sw_if_index=self.pg0.sw_if_index,
1644 flags=flags, is_add=1)
1645 self.vapi.nat44_interface_add_del_feature(
1646 sw_if_index=self.pg1.sw_if_index,
1649 # Client side - create sessions
1650 pkts = self.create_stream_in(self.pg0, self.pg1)
1651 self.pg0.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1655 # Server side - generate traffic
1656 capture = self.pg1.get_capture(len(pkts))
1657 self.verify_capture_out(capture)
1658 pkts = self.create_stream_out(self.pg1, ttl=1)
1659 self.pg1.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1663 # Server side - verify ICMP type 11 packets
1664 capture = self.pg1.get_capture(len(pkts))
1665 self.verify_capture_out_with_icmp_errors(capture,
1666 src_ip=self.pg1.local_ip4)
1668 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1669 """ NAT44 handling of error responses to client packets with TTL=2 """
1671 self.nat44_add_address(self.nat_addr)
1672 flags = self.config_flags.NAT_IS_INSIDE
1673 self.vapi.nat44_interface_add_del_feature(
1674 sw_if_index=self.pg0.sw_if_index,
1675 flags=flags, is_add=1)
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg1.sw_if_index,
1680 # Client side - generate traffic
1681 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1682 self.pg0.add_stream(pkts)
1683 self.pg_enable_capture(self.pg_interfaces)
1686 # Server side - simulate ICMP type 11 response
1687 capture = self.pg1.get_capture(len(pkts))
1688 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1689 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1690 ICMP(type=11) / packet[IP] for packet in capture]
1691 self.pg1.add_stream(pkts)
1692 self.pg_enable_capture(self.pg_interfaces)
1695 # Client side - verify ICMP type 11 packets
1696 capture = self.pg0.get_capture(len(pkts))
1697 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1699 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1700 """ NAT44 handling of error responses to server packets with TTL=2 """
1702 self.nat44_add_address(self.nat_addr)
1703 flags = self.config_flags.NAT_IS_INSIDE
1704 self.vapi.nat44_interface_add_del_feature(
1705 sw_if_index=self.pg0.sw_if_index,
1706 flags=flags, is_add=1)
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg1.sw_if_index,
1711 # Client side - create sessions
1712 pkts = self.create_stream_in(self.pg0, self.pg1)
1713 self.pg0.add_stream(pkts)
1714 self.pg_enable_capture(self.pg_interfaces)
1717 # Server side - generate traffic
1718 capture = self.pg1.get_capture(len(pkts))
1719 self.verify_capture_out(capture)
1720 pkts = self.create_stream_out(self.pg1, ttl=2)
1721 self.pg1.add_stream(pkts)
1722 self.pg_enable_capture(self.pg_interfaces)
1725 # Client side - simulate ICMP type 11 response
1726 capture = self.pg0.get_capture(len(pkts))
1727 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1728 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1729 ICMP(type=11) / packet[IP] for packet in capture]
1730 self.pg0.add_stream(pkts)
1731 self.pg_enable_capture(self.pg_interfaces)
1734 # Server side - verify ICMP type 11 packets
1735 capture = self.pg1.get_capture(len(pkts))
1736 self.verify_capture_out_with_icmp_errors(capture)
1738 def test_ping_out_interface_from_outside(self):
1739 """ Ping NAT44 out interface from outside network """
1741 self.nat44_add_address(self.nat_addr)
1742 flags = self.config_flags.NAT_IS_INSIDE
1743 self.vapi.nat44_interface_add_del_feature(
1744 sw_if_index=self.pg0.sw_if_index,
1745 flags=flags, is_add=1)
1746 self.vapi.nat44_interface_add_del_feature(
1747 sw_if_index=self.pg1.sw_if_index,
1750 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1751 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1752 ICMP(id=self.icmp_id_out, type='echo-request'))
1754 self.pg1.add_stream(pkts)
1755 self.pg_enable_capture(self.pg_interfaces)
1757 capture = self.pg1.get_capture(len(pkts))
1760 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1761 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1762 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1763 self.assertEqual(packet[ICMP].type, 0) # echo reply
1765 self.logger.error(ppp("Unexpected or invalid packet "
1766 "(outside network):", packet))
1769 def test_ping_internal_host_from_outside(self):
1770 """ Ping internal host from outside network """
1772 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1773 flags = self.config_flags.NAT_IS_INSIDE
1774 self.vapi.nat44_interface_add_del_feature(
1775 sw_if_index=self.pg0.sw_if_index,
1776 flags=flags, is_add=1)
1777 self.vapi.nat44_interface_add_del_feature(
1778 sw_if_index=self.pg1.sw_if_index,
1782 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1783 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1784 ICMP(id=self.icmp_id_out, type='echo-request'))
1785 self.pg1.add_stream(pkt)
1786 self.pg_enable_capture(self.pg_interfaces)
1788 capture = self.pg0.get_capture(1)
1789 self.verify_capture_in(capture, self.pg0)
1790 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1793 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1794 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1795 ICMP(id=self.icmp_id_in, type='echo-reply'))
1796 self.pg0.add_stream(pkt)
1797 self.pg_enable_capture(self.pg_interfaces)
1799 capture = self.pg1.get_capture(1)
1800 self.verify_capture_out(capture, same_port=True)
1801 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1803 def test_forwarding(self):
1804 """ NAT44 forwarding test """
1806 flags = self.config_flags.NAT_IS_INSIDE
1807 self.vapi.nat44_interface_add_del_feature(
1808 sw_if_index=self.pg0.sw_if_index,
1809 flags=flags, is_add=1)
1810 self.vapi.nat44_interface_add_del_feature(
1811 sw_if_index=self.pg1.sw_if_index,
1813 self.vapi.nat44_forwarding_enable_disable(enable=1)
1815 real_ip = self.pg0.remote_ip4
1816 alias_ip = self.nat_addr
1817 flags = self.config_flags.NAT_IS_ADDR_ONLY
1818 self.vapi.nat44_add_del_static_mapping(is_add=1,
1819 local_ip_address=real_ip,
1820 external_ip_address=alias_ip,
1821 external_sw_if_index=0xFFFFFFFF,
1825 # static mapping match
1827 pkts = self.create_stream_out(self.pg1)
1828 self.pg1.add_stream(pkts)
1829 self.pg_enable_capture(self.pg_interfaces)
1831 capture = self.pg0.get_capture(len(pkts))
1832 self.verify_capture_in(capture, self.pg0)
1834 pkts = self.create_stream_in(self.pg0, self.pg1)
1835 self.pg0.add_stream(pkts)
1836 self.pg_enable_capture(self.pg_interfaces)
1838 capture = self.pg1.get_capture(len(pkts))
1839 self.verify_capture_out(capture, same_port=True)
1841 # no static mapping match
1843 host0 = self.pg0.remote_hosts[0]
1844 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1846 pkts = self.create_stream_out(self.pg1,
1847 dst_ip=self.pg0.remote_ip4,
1848 use_inside_ports=True)
1849 self.pg1.add_stream(pkts)
1850 self.pg_enable_capture(self.pg_interfaces)
1852 capture = self.pg0.get_capture(len(pkts))
1853 self.verify_capture_in(capture, self.pg0)
1855 pkts = self.create_stream_in(self.pg0, self.pg1)
1856 self.pg0.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1859 capture = self.pg1.get_capture(len(pkts))
1860 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1863 self.pg0.remote_hosts[0] = host0
1866 self.vapi.nat44_forwarding_enable_disable(enable=0)
1867 flags = self.config_flags.NAT_IS_ADDR_ONLY
1868 self.vapi.nat44_add_del_static_mapping(
1870 local_ip_address=real_ip,
1871 external_ip_address=alias_ip,
1872 external_sw_if_index=0xFFFFFFFF,
1875 def test_static_in(self):
1876 """ 1:1 NAT initialized from inside network """
1878 nat_ip = "10.0.0.10"
1879 self.tcp_port_out = 6303
1880 self.udp_port_out = 6304
1881 self.icmp_id_out = 6305
1883 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1884 flags = self.config_flags.NAT_IS_INSIDE
1885 self.vapi.nat44_interface_add_del_feature(
1886 sw_if_index=self.pg0.sw_if_index,
1887 flags=flags, is_add=1)
1888 self.vapi.nat44_interface_add_del_feature(
1889 sw_if_index=self.pg1.sw_if_index,
1891 sm = self.vapi.nat44_static_mapping_dump()
1892 self.assertEqual(len(sm), 1)
1893 self.assertEqual(sm[0].tag, '')
1894 self.assertEqual(sm[0].protocol, 0)
1895 self.assertEqual(sm[0].local_port, 0)
1896 self.assertEqual(sm[0].external_port, 0)
1899 pkts = self.create_stream_in(self.pg0, self.pg1)
1900 self.pg0.add_stream(pkts)
1901 self.pg_enable_capture(self.pg_interfaces)
1903 capture = self.pg1.get_capture(len(pkts))
1904 self.verify_capture_out(capture, nat_ip, True)
1907 pkts = self.create_stream_out(self.pg1, nat_ip)
1908 self.pg1.add_stream(pkts)
1909 self.pg_enable_capture(self.pg_interfaces)
1911 capture = self.pg0.get_capture(len(pkts))
1912 self.verify_capture_in(capture, self.pg0)
1914 def test_static_out(self):
1915 """ 1:1 NAT initialized from outside network """
1917 nat_ip = "10.0.0.20"
1918 self.tcp_port_out = 6303
1919 self.udp_port_out = 6304
1920 self.icmp_id_out = 6305
1923 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1924 flags = self.config_flags.NAT_IS_INSIDE
1925 self.vapi.nat44_interface_add_del_feature(
1926 sw_if_index=self.pg0.sw_if_index,
1927 flags=flags, is_add=1)
1928 self.vapi.nat44_interface_add_del_feature(
1929 sw_if_index=self.pg1.sw_if_index,
1931 sm = self.vapi.nat44_static_mapping_dump()
1932 self.assertEqual(len(sm), 1)
1933 self.assertEqual(sm[0].tag, tag)
1936 pkts = self.create_stream_out(self.pg1, nat_ip)
1937 self.pg1.add_stream(pkts)
1938 self.pg_enable_capture(self.pg_interfaces)
1940 capture = self.pg0.get_capture(len(pkts))
1941 self.verify_capture_in(capture, self.pg0)
1944 pkts = self.create_stream_in(self.pg0, self.pg1)
1945 self.pg0.add_stream(pkts)
1946 self.pg_enable_capture(self.pg_interfaces)
1948 capture = self.pg1.get_capture(len(pkts))
1949 self.verify_capture_out(capture, nat_ip, True)
1951 def test_static_with_port_in(self):
1952 """ 1:1 NAPT initialized from inside network """
1954 self.tcp_port_out = 3606
1955 self.udp_port_out = 3607
1956 self.icmp_id_out = 3608
1958 self.nat44_add_address(self.nat_addr)
1959 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1960 self.tcp_port_in, self.tcp_port_out,
1961 proto=IP_PROTOS.tcp)
1962 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1963 self.udp_port_in, self.udp_port_out,
1964 proto=IP_PROTOS.udp)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.icmp_id_in, self.icmp_id_out,
1967 proto=IP_PROTOS.icmp)
1968 flags = self.config_flags.NAT_IS_INSIDE
1969 self.vapi.nat44_interface_add_del_feature(
1970 sw_if_index=self.pg0.sw_if_index,
1971 flags=flags, is_add=1)
1972 self.vapi.nat44_interface_add_del_feature(
1973 sw_if_index=self.pg1.sw_if_index,
1977 pkts = self.create_stream_in(self.pg0, self.pg1)
1978 self.pg0.add_stream(pkts)
1979 self.pg_enable_capture(self.pg_interfaces)
1981 capture = self.pg1.get_capture(len(pkts))
1982 self.verify_capture_out(capture)
1985 pkts = self.create_stream_out(self.pg1)
1986 self.pg1.add_stream(pkts)
1987 self.pg_enable_capture(self.pg_interfaces)
1989 capture = self.pg0.get_capture(len(pkts))
1990 self.verify_capture_in(capture, self.pg0)
1992 def test_static_with_port_out(self):
1993 """ 1:1 NAPT initialized from outside network """
1995 self.tcp_port_out = 30606
1996 self.udp_port_out = 30607
1997 self.icmp_id_out = 30608
1999 self.nat44_add_address(self.nat_addr)
2000 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2001 self.tcp_port_in, self.tcp_port_out,
2002 proto=IP_PROTOS.tcp)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2004 self.udp_port_in, self.udp_port_out,
2005 proto=IP_PROTOS.udp)
2006 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2007 self.icmp_id_in, self.icmp_id_out,
2008 proto=IP_PROTOS.icmp)
2009 flags = self.config_flags.NAT_IS_INSIDE
2010 self.vapi.nat44_interface_add_del_feature(
2011 sw_if_index=self.pg0.sw_if_index,
2012 flags=flags, is_add=1)
2013 self.vapi.nat44_interface_add_del_feature(
2014 sw_if_index=self.pg1.sw_if_index,
2018 pkts = self.create_stream_out(self.pg1)
2019 self.pg1.add_stream(pkts)
2020 self.pg_enable_capture(self.pg_interfaces)
2022 capture = self.pg0.get_capture(len(pkts))
2023 self.verify_capture_in(capture, self.pg0)
2026 pkts = self.create_stream_in(self.pg0, self.pg1)
2027 self.pg0.add_stream(pkts)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg1.get_capture(len(pkts))
2031 self.verify_capture_out(capture)
2033 def test_static_vrf_aware(self):
2034 """ 1:1 NAT VRF awareness """
2036 nat_ip1 = "10.0.0.30"
2037 nat_ip2 = "10.0.0.40"
2038 self.tcp_port_out = 6303
2039 self.udp_port_out = 6304
2040 self.icmp_id_out = 6305
2042 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2044 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2046 flags = self.config_flags.NAT_IS_INSIDE
2047 self.vapi.nat44_interface_add_del_feature(
2048 sw_if_index=self.pg3.sw_if_index,
2050 self.vapi.nat44_interface_add_del_feature(
2051 sw_if_index=self.pg0.sw_if_index,
2052 flags=flags, is_add=1)
2053 self.vapi.nat44_interface_add_del_feature(
2054 sw_if_index=self.pg4.sw_if_index,
2055 flags=flags, is_add=1)
2057 # inside interface VRF match NAT44 static mapping VRF
2058 pkts = self.create_stream_in(self.pg4, self.pg3)
2059 self.pg4.add_stream(pkts)
2060 self.pg_enable_capture(self.pg_interfaces)
2062 capture = self.pg3.get_capture(len(pkts))
2063 self.verify_capture_out(capture, nat_ip1, True)
2065 # inside interface VRF don't match NAT44 static mapping VRF (packets
2067 pkts = self.create_stream_in(self.pg0, self.pg3)
2068 self.pg0.add_stream(pkts)
2069 self.pg_enable_capture(self.pg_interfaces)
2071 self.pg3.assert_nothing_captured()
2073 def test_dynamic_to_static(self):
2074 """ Switch from dynamic translation to 1:1NAT """
2075 nat_ip = "10.0.0.10"
2076 self.tcp_port_out = 6303
2077 self.udp_port_out = 6304
2078 self.icmp_id_out = 6305
2080 self.nat44_add_address(self.nat_addr)
2081 flags = self.config_flags.NAT_IS_INSIDE
2082 self.vapi.nat44_interface_add_del_feature(
2083 sw_if_index=self.pg0.sw_if_index,
2084 flags=flags, is_add=1)
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg1.sw_if_index,
2090 pkts = self.create_stream_in(self.pg0, self.pg1)
2091 self.pg0.add_stream(pkts)
2092 self.pg_enable_capture(self.pg_interfaces)
2094 capture = self.pg1.get_capture(len(pkts))
2095 self.verify_capture_out(capture)
2098 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2099 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2100 self.assertEqual(len(sessions), 0)
2101 pkts = self.create_stream_in(self.pg0, self.pg1)
2102 self.pg0.add_stream(pkts)
2103 self.pg_enable_capture(self.pg_interfaces)
2105 capture = self.pg1.get_capture(len(pkts))
2106 self.verify_capture_out(capture, nat_ip, True)
2108 def test_identity_nat(self):
2109 """ Identity NAT """
2110 flags = self.config_flags.NAT_IS_ADDR_ONLY
2111 self.vapi.nat44_add_del_identity_mapping(
2112 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2113 flags=flags, is_add=1)
2114 flags = self.config_flags.NAT_IS_INSIDE
2115 self.vapi.nat44_interface_add_del_feature(
2116 sw_if_index=self.pg0.sw_if_index,
2117 flags=flags, is_add=1)
2118 self.vapi.nat44_interface_add_del_feature(
2119 sw_if_index=self.pg1.sw_if_index,
2122 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2123 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2124 TCP(sport=12345, dport=56789))
2125 self.pg1.add_stream(p)
2126 self.pg_enable_capture(self.pg_interfaces)
2128 capture = self.pg0.get_capture(1)
2133 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2134 self.assertEqual(ip.src, self.pg1.remote_ip4)
2135 self.assertEqual(tcp.dport, 56789)
2136 self.assertEqual(tcp.sport, 12345)
2137 self.assert_packet_checksums_valid(p)
2139 self.logger.error(ppp("Unexpected or invalid packet:", p))
2142 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2143 self.assertEqual(len(sessions), 0)
2144 flags = self.config_flags.NAT_IS_ADDR_ONLY
2145 self.vapi.nat44_add_del_identity_mapping(
2146 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2147 flags=flags, vrf_id=1, is_add=1)
2148 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2149 self.assertEqual(len(identity_mappings), 2)
2151 def test_multiple_inside_interfaces(self):
2152 """ NAT44 multiple non-overlapping address space inside interfaces """
2154 self.nat44_add_address(self.nat_addr)
2155 flags = self.config_flags.NAT_IS_INSIDE
2156 self.vapi.nat44_interface_add_del_feature(
2157 sw_if_index=self.pg0.sw_if_index,
2158 flags=flags, is_add=1)
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg1.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg3.sw_if_index,
2166 # between two NAT44 inside interfaces (no translation)
2167 pkts = self.create_stream_in(self.pg0, self.pg1)
2168 self.pg0.add_stream(pkts)
2169 self.pg_enable_capture(self.pg_interfaces)
2171 capture = self.pg1.get_capture(len(pkts))
2172 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2174 # from NAT44 inside to interface without NAT44 feature (no translation)
2175 pkts = self.create_stream_in(self.pg0, self.pg2)
2176 self.pg0.add_stream(pkts)
2177 self.pg_enable_capture(self.pg_interfaces)
2179 capture = self.pg2.get_capture(len(pkts))
2180 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2182 # in2out 1st interface
2183 pkts = self.create_stream_in(self.pg0, self.pg3)
2184 self.pg0.add_stream(pkts)
2185 self.pg_enable_capture(self.pg_interfaces)
2187 capture = self.pg3.get_capture(len(pkts))
2188 self.verify_capture_out(capture)
2190 # out2in 1st interface
2191 pkts = self.create_stream_out(self.pg3)
2192 self.pg3.add_stream(pkts)
2193 self.pg_enable_capture(self.pg_interfaces)
2195 capture = self.pg0.get_capture(len(pkts))
2196 self.verify_capture_in(capture, self.pg0)
2198 # in2out 2nd interface
2199 pkts = self.create_stream_in(self.pg1, self.pg3)
2200 self.pg1.add_stream(pkts)
2201 self.pg_enable_capture(self.pg_interfaces)
2203 capture = self.pg3.get_capture(len(pkts))
2204 self.verify_capture_out(capture)
2206 # out2in 2nd interface
2207 pkts = self.create_stream_out(self.pg3)
2208 self.pg3.add_stream(pkts)
2209 self.pg_enable_capture(self.pg_interfaces)
2211 capture = self.pg1.get_capture(len(pkts))
2212 self.verify_capture_in(capture, self.pg1)
2214 def test_inside_overlapping_interfaces(self):
2215 """ NAT44 multiple inside interfaces with overlapping address space """
2217 static_nat_ip = "10.0.0.10"
2218 self.nat44_add_address(self.nat_addr)
2219 flags = self.config_flags.NAT_IS_INSIDE
2220 self.vapi.nat44_interface_add_del_feature(
2221 sw_if_index=self.pg3.sw_if_index,
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg4.sw_if_index,
2225 flags=flags, is_add=1)
2226 self.vapi.nat44_interface_add_del_feature(
2227 sw_if_index=self.pg5.sw_if_index,
2228 flags=flags, is_add=1)
2229 self.vapi.nat44_interface_add_del_feature(
2230 sw_if_index=self.pg6.sw_if_index,
2231 flags=flags, is_add=1)
2232 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2235 # between NAT44 inside interfaces with same VRF (no translation)
2236 pkts = self.create_stream_in(self.pg4, self.pg5)
2237 self.pg4.add_stream(pkts)
2238 self.pg_enable_capture(self.pg_interfaces)
2240 capture = self.pg5.get_capture(len(pkts))
2241 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2243 # between NAT44 inside interfaces with different VRF (hairpinning)
2244 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2245 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2246 TCP(sport=1234, dport=5678))
2247 self.pg4.add_stream(p)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg6.get_capture(1)
2255 self.assertEqual(ip.src, self.nat_addr)
2256 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2257 self.assertNotEqual(tcp.sport, 1234)
2258 self.assertEqual(tcp.dport, 5678)
2260 self.logger.error(ppp("Unexpected or invalid packet:", p))
2263 # in2out 1st interface
2264 pkts = self.create_stream_in(self.pg4, self.pg3)
2265 self.pg4.add_stream(pkts)
2266 self.pg_enable_capture(self.pg_interfaces)
2268 capture = self.pg3.get_capture(len(pkts))
2269 self.verify_capture_out(capture)
2271 # out2in 1st interface
2272 pkts = self.create_stream_out(self.pg3)
2273 self.pg3.add_stream(pkts)
2274 self.pg_enable_capture(self.pg_interfaces)
2276 capture = self.pg4.get_capture(len(pkts))
2277 self.verify_capture_in(capture, self.pg4)
2279 # in2out 2nd interface
2280 pkts = self.create_stream_in(self.pg5, self.pg3)
2281 self.pg5.add_stream(pkts)
2282 self.pg_enable_capture(self.pg_interfaces)
2284 capture = self.pg3.get_capture(len(pkts))
2285 self.verify_capture_out(capture)
2287 # out2in 2nd interface
2288 pkts = self.create_stream_out(self.pg3)
2289 self.pg3.add_stream(pkts)
2290 self.pg_enable_capture(self.pg_interfaces)
2292 capture = self.pg5.get_capture(len(pkts))
2293 self.verify_capture_in(capture, self.pg5)
2296 addresses = self.vapi.nat44_address_dump()
2297 self.assertEqual(len(addresses), 1)
2298 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2299 self.assertEqual(len(sessions), 3)
2300 for session in sessions:
2301 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2302 self.assertEqual(str(session.inside_ip_address),
2303 self.pg5.remote_ip4)
2304 self.assertEqual(session.outside_ip_address,
2305 addresses[0].ip_address)
2306 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2307 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2308 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2309 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2310 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2311 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2312 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2313 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2314 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2316 # in2out 3rd interface
2317 pkts = self.create_stream_in(self.pg6, self.pg3)
2318 self.pg6.add_stream(pkts)
2319 self.pg_enable_capture(self.pg_interfaces)
2321 capture = self.pg3.get_capture(len(pkts))
2322 self.verify_capture_out(capture, static_nat_ip, True)
2324 # out2in 3rd interface
2325 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2326 self.pg3.add_stream(pkts)
2327 self.pg_enable_capture(self.pg_interfaces)
2329 capture = self.pg6.get_capture(len(pkts))
2330 self.verify_capture_in(capture, self.pg6)
2332 # general user and session dump verifications
2333 users = self.vapi.nat44_user_dump()
2334 self.assertGreaterEqual(len(users), 3)
2335 addresses = self.vapi.nat44_address_dump()
2336 self.assertEqual(len(addresses), 1)
2338 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2340 for session in sessions:
2341 self.assertEqual(user.ip_address, session.inside_ip_address)
2342 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2343 self.assertTrue(session.protocol in
2344 [IP_PROTOS.tcp, IP_PROTOS.udp,
2346 self.assertFalse(session.flags &
2347 self.config_flags.NAT_IS_EXT_HOST_VALID)
2350 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2351 self.assertGreaterEqual(len(sessions), 4)
2352 for session in sessions:
2353 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2354 self.assertEqual(str(session.inside_ip_address),
2355 self.pg4.remote_ip4)
2356 self.assertEqual(session.outside_ip_address,
2357 addresses[0].ip_address)
2360 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2361 self.assertGreaterEqual(len(sessions), 3)
2362 for session in sessions:
2363 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2364 self.assertEqual(str(session.inside_ip_address),
2365 self.pg6.remote_ip4)
2366 self.assertEqual(str(session.outside_ip_address),
2368 self.assertTrue(session.inside_port in
2369 [self.tcp_port_in, self.udp_port_in,
2372 def test_hairpinning(self):
2373 """ NAT44 hairpinning - 1:1 NAPT """
2375 host = self.pg0.remote_hosts[0]
2376 server = self.pg0.remote_hosts[1]
2379 server_in_port = 5678
2380 server_out_port = 8765
2382 self.nat44_add_address(self.nat_addr)
2383 flags = self.config_flags.NAT_IS_INSIDE
2384 self.vapi.nat44_interface_add_del_feature(
2385 sw_if_index=self.pg0.sw_if_index,
2386 flags=flags, is_add=1)
2387 self.vapi.nat44_interface_add_del_feature(
2388 sw_if_index=self.pg1.sw_if_index,
2391 # add static mapping for server
2392 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2393 server_in_port, server_out_port,
2394 proto=IP_PROTOS.tcp)
2396 # send packet from host to server
2397 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2398 IP(src=host.ip4, dst=self.nat_addr) /
2399 TCP(sport=host_in_port, dport=server_out_port))
2400 self.pg0.add_stream(p)
2401 self.pg_enable_capture(self.pg_interfaces)
2403 capture = self.pg0.get_capture(1)
2408 self.assertEqual(ip.src, self.nat_addr)
2409 self.assertEqual(ip.dst, server.ip4)
2410 self.assertNotEqual(tcp.sport, host_in_port)
2411 self.assertEqual(tcp.dport, server_in_port)
2412 self.assert_packet_checksums_valid(p)
2413 host_out_port = tcp.sport
2415 self.logger.error(ppp("Unexpected or invalid packet:", p))
2418 # send reply from server to host
2419 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2420 IP(src=server.ip4, dst=self.nat_addr) /
2421 TCP(sport=server_in_port, dport=host_out_port))
2422 self.pg0.add_stream(p)
2423 self.pg_enable_capture(self.pg_interfaces)
2425 capture = self.pg0.get_capture(1)
2430 self.assertEqual(ip.src, self.nat_addr)
2431 self.assertEqual(ip.dst, host.ip4)
2432 self.assertEqual(tcp.sport, server_out_port)
2433 self.assertEqual(tcp.dport, host_in_port)
2434 self.assert_packet_checksums_valid(p)
2436 self.logger.error(ppp("Unexpected or invalid packet:", p))
2439 def test_hairpinning2(self):
2440 """ NAT44 hairpinning - 1:1 NAT"""
2442 server1_nat_ip = "10.0.0.10"
2443 server2_nat_ip = "10.0.0.11"
2444 host = self.pg0.remote_hosts[0]
2445 server1 = self.pg0.remote_hosts[1]
2446 server2 = self.pg0.remote_hosts[2]
2447 server_tcp_port = 22
2448 server_udp_port = 20
2450 self.nat44_add_address(self.nat_addr)
2451 flags = self.config_flags.NAT_IS_INSIDE
2452 self.vapi.nat44_interface_add_del_feature(
2453 sw_if_index=self.pg0.sw_if_index,
2454 flags=flags, is_add=1)
2455 self.vapi.nat44_interface_add_del_feature(
2456 sw_if_index=self.pg1.sw_if_index,
2459 # add static mapping for servers
2460 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2461 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2466 IP(src=host.ip4, dst=server1_nat_ip) /
2467 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=host.ip4, dst=server1_nat_ip) /
2471 UDP(sport=self.udp_port_in, dport=server_udp_port))
2473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2474 IP(src=host.ip4, dst=server1_nat_ip) /
2475 ICMP(id=self.icmp_id_in, type='echo-request'))
2477 self.pg0.add_stream(pkts)
2478 self.pg_enable_capture(self.pg_interfaces)
2480 capture = self.pg0.get_capture(len(pkts))
2481 for packet in capture:
2483 self.assertEqual(packet[IP].src, self.nat_addr)
2484 self.assertEqual(packet[IP].dst, server1.ip4)
2485 if packet.haslayer(TCP):
2486 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2487 self.assertEqual(packet[TCP].dport, server_tcp_port)
2488 self.tcp_port_out = packet[TCP].sport
2489 self.assert_packet_checksums_valid(packet)
2490 elif packet.haslayer(UDP):
2491 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2492 self.assertEqual(packet[UDP].dport, server_udp_port)
2493 self.udp_port_out = packet[UDP].sport
2495 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2496 self.icmp_id_out = packet[ICMP].id
2498 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2503 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2504 IP(src=server1.ip4, dst=self.nat_addr) /
2505 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server1.ip4, dst=self.nat_addr) /
2509 UDP(sport=server_udp_port, dport=self.udp_port_out))
2511 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2512 IP(src=server1.ip4, dst=self.nat_addr) /
2513 ICMP(id=self.icmp_id_out, type='echo-reply'))
2515 self.pg0.add_stream(pkts)
2516 self.pg_enable_capture(self.pg_interfaces)
2518 capture = self.pg0.get_capture(len(pkts))
2519 for packet in capture:
2521 self.assertEqual(packet[IP].src, server1_nat_ip)
2522 self.assertEqual(packet[IP].dst, host.ip4)
2523 if packet.haslayer(TCP):
2524 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2525 self.assertEqual(packet[TCP].sport, server_tcp_port)
2526 self.assert_packet_checksums_valid(packet)
2527 elif packet.haslayer(UDP):
2528 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2529 self.assertEqual(packet[UDP].sport, server_udp_port)
2531 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2533 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2536 # server2 to server1
2538 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2539 IP(src=server2.ip4, dst=server1_nat_ip) /
2540 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2542 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2543 IP(src=server2.ip4, dst=server1_nat_ip) /
2544 UDP(sport=self.udp_port_in, dport=server_udp_port))
2546 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2547 IP(src=server2.ip4, dst=server1_nat_ip) /
2548 ICMP(id=self.icmp_id_in, type='echo-request'))
2550 self.pg0.add_stream(pkts)
2551 self.pg_enable_capture(self.pg_interfaces)
2553 capture = self.pg0.get_capture(len(pkts))
2554 for packet in capture:
2556 self.assertEqual(packet[IP].src, server2_nat_ip)
2557 self.assertEqual(packet[IP].dst, server1.ip4)
2558 if packet.haslayer(TCP):
2559 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2560 self.assertEqual(packet[TCP].dport, server_tcp_port)
2561 self.tcp_port_out = packet[TCP].sport
2562 self.assert_packet_checksums_valid(packet)
2563 elif packet.haslayer(UDP):
2564 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2565 self.assertEqual(packet[UDP].dport, server_udp_port)
2566 self.udp_port_out = packet[UDP].sport
2568 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2569 self.icmp_id_out = packet[ICMP].id
2571 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2574 # server1 to server2
2576 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2577 IP(src=server1.ip4, dst=server2_nat_ip) /
2578 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2581 IP(src=server1.ip4, dst=server2_nat_ip) /
2582 UDP(sport=server_udp_port, dport=self.udp_port_out))
2584 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2585 IP(src=server1.ip4, dst=server2_nat_ip) /
2586 ICMP(id=self.icmp_id_out, type='echo-reply'))
2588 self.pg0.add_stream(pkts)
2589 self.pg_enable_capture(self.pg_interfaces)
2591 capture = self.pg0.get_capture(len(pkts))
2592 for packet in capture:
2594 self.assertEqual(packet[IP].src, server1_nat_ip)
2595 self.assertEqual(packet[IP].dst, server2.ip4)
2596 if packet.haslayer(TCP):
2597 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2598 self.assertEqual(packet[TCP].sport, server_tcp_port)
2599 self.assert_packet_checksums_valid(packet)
2600 elif packet.haslayer(UDP):
2601 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2602 self.assertEqual(packet[UDP].sport, server_udp_port)
2604 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2606 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2609 def test_interface_addr(self):
2610 """ Acquire NAT44 addresses from interface """
2611 self.vapi.nat44_add_del_interface_addr(
2613 sw_if_index=self.pg7.sw_if_index)
2615 # no address in NAT pool
2616 addresses = self.vapi.nat44_address_dump()
2617 self.assertEqual(0, len(addresses))
2619 # configure interface address and check NAT address pool
2620 self.pg7.config_ip4()
2621 addresses = self.vapi.nat44_address_dump()
2622 self.assertEqual(1, len(addresses))
2623 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2625 # remove interface address and check NAT address pool
2626 self.pg7.unconfig_ip4()
2627 addresses = self.vapi.nat44_address_dump()
2628 self.assertEqual(0, len(addresses))
2630 def test_interface_addr_static_mapping(self):
2631 """ Static mapping with addresses from interface """
2634 self.vapi.nat44_add_del_interface_addr(
2636 sw_if_index=self.pg7.sw_if_index)
2637 self.nat44_add_static_mapping(
2639 external_sw_if_index=self.pg7.sw_if_index,
2642 # static mappings with external interface
2643 static_mappings = self.vapi.nat44_static_mapping_dump()
2644 self.assertEqual(1, len(static_mappings))
2645 self.assertEqual(self.pg7.sw_if_index,
2646 static_mappings[0].external_sw_if_index)
2647 self.assertEqual(static_mappings[0].tag, tag)
2649 # configure interface address and check static mappings
2650 self.pg7.config_ip4()
2651 static_mappings = self.vapi.nat44_static_mapping_dump()
2652 self.assertEqual(2, len(static_mappings))
2654 for sm in static_mappings:
2655 if sm.external_sw_if_index == 0xFFFFFFFF:
2656 self.assertEqual(str(sm.external_ip_address),
2658 self.assertEqual(sm.tag, tag)
2660 self.assertTrue(resolved)
2662 # remove interface address and check static mappings
2663 self.pg7.unconfig_ip4()
2664 static_mappings = self.vapi.nat44_static_mapping_dump()
2665 self.assertEqual(1, len(static_mappings))
2666 self.assertEqual(self.pg7.sw_if_index,
2667 static_mappings[0].external_sw_if_index)
2668 self.assertEqual(static_mappings[0].tag, tag)
2670 # configure interface address again and check static mappings
2671 self.pg7.config_ip4()
2672 static_mappings = self.vapi.nat44_static_mapping_dump()
2673 self.assertEqual(2, len(static_mappings))
2675 for sm in static_mappings:
2676 if sm.external_sw_if_index == 0xFFFFFFFF:
2677 self.assertEqual(str(sm.external_ip_address),
2679 self.assertEqual(sm.tag, tag)
2681 self.assertTrue(resolved)
2683 # remove static mapping
2684 self.nat44_add_static_mapping(
2686 external_sw_if_index=self.pg7.sw_if_index,
2689 static_mappings = self.vapi.nat44_static_mapping_dump()
2690 self.assertEqual(0, len(static_mappings))
2692 def test_interface_addr_identity_nat(self):
2693 """ Identity NAT with addresses from interface """
2696 self.vapi.nat44_add_del_interface_addr(
2698 sw_if_index=self.pg7.sw_if_index)
2699 self.vapi.nat44_add_del_identity_mapping(
2701 sw_if_index=self.pg7.sw_if_index,
2703 protocol=IP_PROTOS.tcp,
2706 # identity mappings with external interface
2707 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2708 self.assertEqual(1, len(identity_mappings))
2709 self.assertEqual(self.pg7.sw_if_index,
2710 identity_mappings[0].sw_if_index)
2712 # configure interface address and check identity mappings
2713 self.pg7.config_ip4()
2714 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2716 self.assertEqual(2, len(identity_mappings))
2717 for sm in identity_mappings:
2718 if sm.sw_if_index == 0xFFFFFFFF:
2719 self.assertEqual(str(identity_mappings[0].ip_address),
2721 self.assertEqual(port, identity_mappings[0].port)
2722 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2724 self.assertTrue(resolved)
2726 # remove interface address and check identity mappings
2727 self.pg7.unconfig_ip4()
2728 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2729 self.assertEqual(1, len(identity_mappings))
2730 self.assertEqual(self.pg7.sw_if_index,
2731 identity_mappings[0].sw_if_index)
2733 def test_ipfix_nat44_sess(self):
2734 """ IPFIX logging NAT44 session created/deleted """
2735 self.ipfix_domain_id = 10
2736 self.ipfix_src_port = 20202
2737 collector_port = 30303
2738 bind_layers(UDP, IPFIX, dport=30303)
2739 self.nat44_add_address(self.nat_addr)
2740 flags = self.config_flags.NAT_IS_INSIDE
2741 self.vapi.nat44_interface_add_del_feature(
2742 sw_if_index=self.pg0.sw_if_index,
2743 flags=flags, is_add=1)
2744 self.vapi.nat44_interface_add_del_feature(
2745 sw_if_index=self.pg1.sw_if_index,
2747 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2748 src_address=self.pg3.local_ip4,
2750 template_interval=10,
2751 collector_port=collector_port)
2752 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2753 src_port=self.ipfix_src_port,
2756 pkts = self.create_stream_in(self.pg0, self.pg1)
2757 self.pg0.add_stream(pkts)
2758 self.pg_enable_capture(self.pg_interfaces)
2760 capture = self.pg1.get_capture(len(pkts))
2761 self.verify_capture_out(capture)
2762 self.nat44_add_address(self.nat_addr, is_add=0)
2763 self.vapi.ipfix_flush()
2764 capture = self.pg3.get_capture(9)
2765 ipfix = IPFIXDecoder()
2766 # first load template
2768 self.assertTrue(p.haslayer(IPFIX))
2769 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2770 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2771 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2772 self.assertEqual(p[UDP].dport, collector_port)
2773 self.assertEqual(p[IPFIX].observationDomainID,
2774 self.ipfix_domain_id)
2775 if p.haslayer(Template):
2776 ipfix.add_template(p.getlayer(Template))
2777 # verify events in data set
2779 if p.haslayer(Data):
2780 data = ipfix.decode_data_set(p.getlayer(Set))
2781 self.verify_ipfix_nat44_ses(data)
2783 def test_ipfix_addr_exhausted(self):
2784 """ IPFIX logging NAT addresses exhausted """
2785 flags = self.config_flags.NAT_IS_INSIDE
2786 self.vapi.nat44_interface_add_del_feature(
2787 sw_if_index=self.pg0.sw_if_index,
2788 flags=flags, is_add=1)
2789 self.vapi.nat44_interface_add_del_feature(
2790 sw_if_index=self.pg1.sw_if_index,
2792 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2793 src_address=self.pg3.local_ip4,
2795 template_interval=10)
2796 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2797 src_port=self.ipfix_src_port,
2800 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2801 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2803 self.pg0.add_stream(p)
2804 self.pg_enable_capture(self.pg_interfaces)
2806 self.pg1.assert_nothing_captured()
2808 self.vapi.ipfix_flush()
2809 capture = self.pg3.get_capture(9)
2810 ipfix = IPFIXDecoder()
2811 # first load template
2813 self.assertTrue(p.haslayer(IPFIX))
2814 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2815 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2816 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2817 self.assertEqual(p[UDP].dport, 4739)
2818 self.assertEqual(p[IPFIX].observationDomainID,
2819 self.ipfix_domain_id)
2820 if p.haslayer(Template):
2821 ipfix.add_template(p.getlayer(Template))
2822 # verify events in data set
2824 if p.haslayer(Data):
2825 data = ipfix.decode_data_set(p.getlayer(Set))
2826 self.verify_ipfix_addr_exhausted(data)
2828 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2829 def test_ipfix_max_sessions(self):
2830 """ IPFIX logging maximum session entries exceeded """
2831 self.nat44_add_address(self.nat_addr)
2832 flags = self.config_flags.NAT_IS_INSIDE
2833 self.vapi.nat44_interface_add_del_feature(
2834 sw_if_index=self.pg0.sw_if_index,
2835 flags=flags, is_add=1)
2836 self.vapi.nat44_interface_add_del_feature(
2837 sw_if_index=self.pg1.sw_if_index,
2840 nat44_config = self.vapi.nat_show_config()
2841 max_sessions = 10 * nat44_config.translation_buckets
2844 for i in range(0, max_sessions):
2845 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2846 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2847 IP(src=src, dst=self.pg1.remote_ip4) /
2850 self.pg0.add_stream(pkts)
2851 self.pg_enable_capture(self.pg_interfaces)
2854 self.pg1.get_capture(max_sessions)
2855 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2856 src_address=self.pg3.local_ip4,
2858 template_interval=10)
2859 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2860 src_port=self.ipfix_src_port,
2863 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2864 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2866 self.pg0.add_stream(p)
2867 self.pg_enable_capture(self.pg_interfaces)
2869 self.pg1.assert_nothing_captured()
2871 self.vapi.ipfix_flush()
2872 capture = self.pg3.get_capture(9)
2873 ipfix = IPFIXDecoder()
2874 # first load template
2876 self.assertTrue(p.haslayer(IPFIX))
2877 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2878 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2879 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2880 self.assertEqual(p[UDP].dport, 4739)
2881 self.assertEqual(p[IPFIX].observationDomainID,
2882 self.ipfix_domain_id)
2883 if p.haslayer(Template):
2884 ipfix.add_template(p.getlayer(Template))
2885 # verify events in data set
2887 if p.haslayer(Data):
2888 data = ipfix.decode_data_set(p.getlayer(Set))
2889 self.verify_ipfix_max_sessions(data, max_sessions)
2891 def test_syslog_apmap(self):
2892 """ Test syslog address and port mapping creation and deletion """
2893 self.vapi.syslog_set_filter(
2894 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2895 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2896 self.nat44_add_address(self.nat_addr)
2897 flags = self.config_flags.NAT_IS_INSIDE
2898 self.vapi.nat44_interface_add_del_feature(
2899 sw_if_index=self.pg0.sw_if_index,
2900 flags=flags, is_add=1)
2901 self.vapi.nat44_interface_add_del_feature(
2902 sw_if_index=self.pg1.sw_if_index,
2905 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2906 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2907 TCP(sport=self.tcp_port_in, dport=20))
2908 self.pg0.add_stream(p)
2909 self.pg_enable_capture(self.pg_interfaces)
2911 capture = self.pg1.get_capture(1)
2912 self.tcp_port_out = capture[0][TCP].sport
2913 capture = self.pg3.get_capture(1)
2914 self.verify_syslog_apmap(capture[0][Raw].load)
2916 self.pg_enable_capture(self.pg_interfaces)
2918 self.nat44_add_address(self.nat_addr, is_add=0)
2919 capture = self.pg3.get_capture(1)
2920 self.verify_syslog_apmap(capture[0][Raw].load, False)
2922 def test_pool_addr_fib(self):
2923 """ NAT44 add pool addresses to FIB """
2924 static_addr = '10.0.0.10'
2925 self.nat44_add_address(self.nat_addr)
2926 flags = self.config_flags.NAT_IS_INSIDE
2927 self.vapi.nat44_interface_add_del_feature(
2928 sw_if_index=self.pg0.sw_if_index,
2929 flags=flags, is_add=1)
2930 self.vapi.nat44_interface_add_del_feature(
2931 sw_if_index=self.pg1.sw_if_index,
2933 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2936 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2937 ARP(op=ARP.who_has, pdst=self.nat_addr,
2938 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2939 self.pg1.add_stream(p)
2940 self.pg_enable_capture(self.pg_interfaces)
2942 capture = self.pg1.get_capture(1)
2943 self.assertTrue(capture[0].haslayer(ARP))
2944 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2947 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2948 ARP(op=ARP.who_has, pdst=static_addr,
2949 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2950 self.pg1.add_stream(p)
2951 self.pg_enable_capture(self.pg_interfaces)
2953 capture = self.pg1.get_capture(1)
2954 self.assertTrue(capture[0].haslayer(ARP))
2955 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2957 # send ARP to non-NAT44 interface
2958 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2959 ARP(op=ARP.who_has, pdst=self.nat_addr,
2960 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2961 self.pg2.add_stream(p)
2962 self.pg_enable_capture(self.pg_interfaces)
2964 self.pg1.assert_nothing_captured()
2966 # remove addresses and verify
2967 self.nat44_add_address(self.nat_addr, is_add=0)
2968 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2971 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2972 ARP(op=ARP.who_has, pdst=self.nat_addr,
2973 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2974 self.pg1.add_stream(p)
2975 self.pg_enable_capture(self.pg_interfaces)
2977 self.pg1.assert_nothing_captured()
2979 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2980 ARP(op=ARP.who_has, pdst=static_addr,
2981 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2982 self.pg1.add_stream(p)
2983 self.pg_enable_capture(self.pg_interfaces)
2985 self.pg1.assert_nothing_captured()
2987 def test_vrf_mode(self):
2988 """ NAT44 tenant VRF aware address pool mode """
2992 nat_ip1 = "10.0.0.10"
2993 nat_ip2 = "10.0.0.11"
2995 self.pg0.unconfig_ip4()
2996 self.pg1.unconfig_ip4()
2997 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2998 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2999 self.pg0.set_table_ip4(vrf_id1)
3000 self.pg1.set_table_ip4(vrf_id2)
3001 self.pg0.config_ip4()
3002 self.pg1.config_ip4()
3003 self.pg0.resolve_arp()
3004 self.pg1.resolve_arp()
3006 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3007 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3008 flags = self.config_flags.NAT_IS_INSIDE
3009 self.vapi.nat44_interface_add_del_feature(
3010 sw_if_index=self.pg0.sw_if_index,
3011 flags=flags, is_add=1)
3012 self.vapi.nat44_interface_add_del_feature(
3013 sw_if_index=self.pg1.sw_if_index,
3014 flags=flags, is_add=1)
3015 self.vapi.nat44_interface_add_del_feature(
3016 sw_if_index=self.pg2.sw_if_index,
3021 pkts = self.create_stream_in(self.pg0, self.pg2)
3022 self.pg0.add_stream(pkts)
3023 self.pg_enable_capture(self.pg_interfaces)
3025 capture = self.pg2.get_capture(len(pkts))
3026 self.verify_capture_out(capture, nat_ip1)
3029 pkts = self.create_stream_in(self.pg1, self.pg2)
3030 self.pg1.add_stream(pkts)
3031 self.pg_enable_capture(self.pg_interfaces)
3033 capture = self.pg2.get_capture(len(pkts))
3034 self.verify_capture_out(capture, nat_ip2)
3037 self.pg0.unconfig_ip4()
3038 self.pg1.unconfig_ip4()
3039 self.pg0.set_table_ip4(0)
3040 self.pg1.set_table_ip4(0)
3041 self.pg0.config_ip4()
3042 self.pg1.config_ip4()
3043 self.pg0.resolve_arp()
3044 self.pg1.resolve_arp()
3045 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3046 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3048 def test_vrf_feature_independent(self):
3049 """ NAT44 tenant VRF independent address pool mode """
3051 nat_ip1 = "10.0.0.10"
3052 nat_ip2 = "10.0.0.11"
3054 self.nat44_add_address(nat_ip1)
3055 self.nat44_add_address(nat_ip2, vrf_id=99)
3056 flags = self.config_flags.NAT_IS_INSIDE
3057 self.vapi.nat44_interface_add_del_feature(
3058 sw_if_index=self.pg0.sw_if_index,
3059 flags=flags, is_add=1)
3060 self.vapi.nat44_interface_add_del_feature(
3061 sw_if_index=self.pg1.sw_if_index,
3062 flags=flags, is_add=1)
3063 self.vapi.nat44_interface_add_del_feature(
3064 sw_if_index=self.pg2.sw_if_index,
3068 pkts = self.create_stream_in(self.pg0, self.pg2)
3069 self.pg0.add_stream(pkts)
3070 self.pg_enable_capture(self.pg_interfaces)
3072 capture = self.pg2.get_capture(len(pkts))
3073 self.verify_capture_out(capture, nat_ip1)
3076 pkts = self.create_stream_in(self.pg1, self.pg2)
3077 self.pg1.add_stream(pkts)
3078 self.pg_enable_capture(self.pg_interfaces)
3080 capture = self.pg2.get_capture(len(pkts))
3081 self.verify_capture_out(capture, nat_ip1)
3083 def create_routes_and_neigbors(self):
3084 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3085 [VppRoutePath(self.pg7.remote_ip4,
3086 self.pg7.sw_if_index)])
3087 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3088 [VppRoutePath(self.pg8.remote_ip4,
3089 self.pg8.sw_if_index)])
3093 n1 = VppNeighbor(self,
3094 self.pg7.sw_if_index,
3095 self.pg7.remote_mac,
3096 self.pg7.remote_ip4,
3098 n2 = VppNeighbor(self,
3099 self.pg8.sw_if_index,
3100 self.pg8.remote_mac,
3101 self.pg8.remote_ip4,
3106 def test_dynamic_ipless_interfaces(self):
3107 """ NAT44 interfaces without configured IP address """
3108 self.create_routes_and_neigbors()
3109 self.nat44_add_address(self.nat_addr)
3110 flags = self.config_flags.NAT_IS_INSIDE
3111 self.vapi.nat44_interface_add_del_feature(
3112 sw_if_index=self.pg7.sw_if_index,
3113 flags=flags, is_add=1)
3114 self.vapi.nat44_interface_add_del_feature(
3115 sw_if_index=self.pg8.sw_if_index,
3119 pkts = self.create_stream_in(self.pg7, self.pg8)
3120 self.pg7.add_stream(pkts)
3121 self.pg_enable_capture(self.pg_interfaces)
3123 capture = self.pg8.get_capture(len(pkts))
3124 self.verify_capture_out(capture)
3127 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3128 self.pg8.add_stream(pkts)
3129 self.pg_enable_capture(self.pg_interfaces)
3131 capture = self.pg7.get_capture(len(pkts))
3132 self.verify_capture_in(capture, self.pg7)
3134 def test_static_ipless_interfaces(self):
3135 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3137 self.create_routes_and_neigbors()
3138 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3139 flags = self.config_flags.NAT_IS_INSIDE
3140 self.vapi.nat44_interface_add_del_feature(
3141 sw_if_index=self.pg7.sw_if_index,
3142 flags=flags, is_add=1)
3143 self.vapi.nat44_interface_add_del_feature(
3144 sw_if_index=self.pg8.sw_if_index,
3148 pkts = self.create_stream_out(self.pg8)
3149 self.pg8.add_stream(pkts)
3150 self.pg_enable_capture(self.pg_interfaces)
3152 capture = self.pg7.get_capture(len(pkts))
3153 self.verify_capture_in(capture, self.pg7)
3156 pkts = self.create_stream_in(self.pg7, self.pg8)
3157 self.pg7.add_stream(pkts)
3158 self.pg_enable_capture(self.pg_interfaces)
3160 capture = self.pg8.get_capture(len(pkts))
3161 self.verify_capture_out(capture, self.nat_addr, True)
3163 def test_static_with_port_ipless_interfaces(self):
3164 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3166 self.tcp_port_out = 30606
3167 self.udp_port_out = 30607
3168 self.icmp_id_out = 30608
3170 self.create_routes_and_neigbors()
3171 self.nat44_add_address(self.nat_addr)
3172 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3173 self.tcp_port_in, self.tcp_port_out,
3174 proto=IP_PROTOS.tcp)
3175 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3176 self.udp_port_in, self.udp_port_out,
3177 proto=IP_PROTOS.udp)
3178 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3179 self.icmp_id_in, self.icmp_id_out,
3180 proto=IP_PROTOS.icmp)
3181 flags = self.config_flags.NAT_IS_INSIDE
3182 self.vapi.nat44_interface_add_del_feature(
3183 sw_if_index=self.pg7.sw_if_index,
3184 flags=flags, is_add=1)
3185 self.vapi.nat44_interface_add_del_feature(
3186 sw_if_index=self.pg8.sw_if_index,
3190 pkts = self.create_stream_out(self.pg8)
3191 self.pg8.add_stream(pkts)
3192 self.pg_enable_capture(self.pg_interfaces)
3194 capture = self.pg7.get_capture(len(pkts))
3195 self.verify_capture_in(capture, self.pg7)
3198 pkts = self.create_stream_in(self.pg7, self.pg8)
3199 self.pg7.add_stream(pkts)
3200 self.pg_enable_capture(self.pg_interfaces)
3202 capture = self.pg8.get_capture(len(pkts))
3203 self.verify_capture_out(capture)
3205 def test_static_unknown_proto(self):
3206 """ 1:1 NAT translate packet with unknown protocol """
3207 nat_ip = "10.0.0.10"
3208 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3209 flags = self.config_flags.NAT_IS_INSIDE
3210 self.vapi.nat44_interface_add_del_feature(
3211 sw_if_index=self.pg0.sw_if_index,
3212 flags=flags, is_add=1)
3213 self.vapi.nat44_interface_add_del_feature(
3214 sw_if_index=self.pg1.sw_if_index,
3218 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3219 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3221 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3222 TCP(sport=1234, dport=1234))
3223 self.pg0.add_stream(p)
3224 self.pg_enable_capture(self.pg_interfaces)
3226 p = self.pg1.get_capture(1)
3229 self.assertEqual(packet[IP].src, nat_ip)
3230 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3231 self.assertEqual(packet.haslayer(GRE), 1)
3232 self.assert_packet_checksums_valid(packet)
3234 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3238 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3239 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3241 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3242 TCP(sport=1234, dport=1234))
3243 self.pg1.add_stream(p)
3244 self.pg_enable_capture(self.pg_interfaces)
3246 p = self.pg0.get_capture(1)
3249 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3250 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3251 self.assertEqual(packet.haslayer(GRE), 1)
3252 self.assert_packet_checksums_valid(packet)
3254 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3257 def test_hairpinning_static_unknown_proto(self):
3258 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3260 host = self.pg0.remote_hosts[0]
3261 server = self.pg0.remote_hosts[1]
3263 host_nat_ip = "10.0.0.10"
3264 server_nat_ip = "10.0.0.11"
3266 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3267 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3268 flags = self.config_flags.NAT_IS_INSIDE
3269 self.vapi.nat44_interface_add_del_feature(
3270 sw_if_index=self.pg0.sw_if_index,
3271 flags=flags, is_add=1)
3272 self.vapi.nat44_interface_add_del_feature(
3273 sw_if_index=self.pg1.sw_if_index,
3277 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3278 IP(src=host.ip4, dst=server_nat_ip) /
3280 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3281 TCP(sport=1234, dport=1234))
3282 self.pg0.add_stream(p)
3283 self.pg_enable_capture(self.pg_interfaces)
3285 p = self.pg0.get_capture(1)
3288 self.assertEqual(packet[IP].src, host_nat_ip)
3289 self.assertEqual(packet[IP].dst, server.ip4)
3290 self.assertEqual(packet.haslayer(GRE), 1)
3291 self.assert_packet_checksums_valid(packet)
3293 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3297 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3298 IP(src=server.ip4, dst=host_nat_ip) /
3300 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3301 TCP(sport=1234, dport=1234))
3302 self.pg0.add_stream(p)
3303 self.pg_enable_capture(self.pg_interfaces)
3305 p = self.pg0.get_capture(1)
3308 self.assertEqual(packet[IP].src, server_nat_ip)
3309 self.assertEqual(packet[IP].dst, host.ip4)
3310 self.assertEqual(packet.haslayer(GRE), 1)
3311 self.assert_packet_checksums_valid(packet)
3313 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3316 def test_output_feature(self):
3317 """ NAT44 interface output feature (in2out postrouting) """
3318 self.nat44_add_address(self.nat_addr)
3319 flags = self.config_flags.NAT_IS_INSIDE
3320 self.vapi.nat44_interface_add_del_output_feature(
3321 is_add=1, flags=flags,
3322 sw_if_index=self.pg0.sw_if_index)
3323 self.vapi.nat44_interface_add_del_output_feature(
3324 is_add=1, flags=flags,
3325 sw_if_index=self.pg1.sw_if_index)
3326 self.vapi.nat44_interface_add_del_output_feature(
3328 sw_if_index=self.pg3.sw_if_index)
3331 pkts = self.create_stream_in(self.pg0, self.pg3)
3332 self.pg0.add_stream(pkts)
3333 self.pg_enable_capture(self.pg_interfaces)
3335 capture = self.pg3.get_capture(len(pkts))
3336 self.verify_capture_out(capture)
3339 pkts = self.create_stream_out(self.pg3)
3340 self.pg3.add_stream(pkts)
3341 self.pg_enable_capture(self.pg_interfaces)
3343 capture = self.pg0.get_capture(len(pkts))
3344 self.verify_capture_in(capture, self.pg0)
3346 # from non-NAT interface to NAT inside interface
3347 pkts = self.create_stream_in(self.pg2, self.pg0)
3348 self.pg2.add_stream(pkts)
3349 self.pg_enable_capture(self.pg_interfaces)
3351 capture = self.pg0.get_capture(len(pkts))
3352 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3354 def test_output_feature_vrf_aware(self):
3355 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3356 nat_ip_vrf10 = "10.0.0.10"
3357 nat_ip_vrf20 = "10.0.0.20"
3359 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3360 [VppRoutePath(self.pg3.remote_ip4,
3361 self.pg3.sw_if_index)],
3363 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3364 [VppRoutePath(self.pg3.remote_ip4,
3365 self.pg3.sw_if_index)],
3370 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3371 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3372 flags = self.config_flags.NAT_IS_INSIDE
3373 self.vapi.nat44_interface_add_del_output_feature(
3374 is_add=1, flags=flags,
3375 sw_if_index=self.pg4.sw_if_index)
3376 self.vapi.nat44_interface_add_del_output_feature(
3377 is_add=1, flags=flags,
3378 sw_if_index=self.pg6.sw_if_index)
3379 self.vapi.nat44_interface_add_del_output_feature(
3381 sw_if_index=self.pg3.sw_if_index)
3384 pkts = self.create_stream_in(self.pg4, self.pg3)
3385 self.pg4.add_stream(pkts)
3386 self.pg_enable_capture(self.pg_interfaces)
3388 capture = self.pg3.get_capture(len(pkts))
3389 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3392 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3393 self.pg3.add_stream(pkts)
3394 self.pg_enable_capture(self.pg_interfaces)
3396 capture = self.pg4.get_capture(len(pkts))
3397 self.verify_capture_in(capture, self.pg4)
3400 pkts = self.create_stream_in(self.pg6, self.pg3)
3401 self.pg6.add_stream(pkts)
3402 self.pg_enable_capture(self.pg_interfaces)
3404 capture = self.pg3.get_capture(len(pkts))
3405 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3408 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3409 self.pg3.add_stream(pkts)
3410 self.pg_enable_capture(self.pg_interfaces)
3412 capture = self.pg6.get_capture(len(pkts))
3413 self.verify_capture_in(capture, self.pg6)
3415 def test_output_feature_hairpinning(self):
3416 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3417 host = self.pg0.remote_hosts[0]
3418 server = self.pg0.remote_hosts[1]
3421 server_in_port = 5678
3422 server_out_port = 8765
3424 self.nat44_add_address(self.nat_addr)
3425 flags = self.config_flags.NAT_IS_INSIDE
3426 self.vapi.nat44_interface_add_del_output_feature(
3427 is_add=1, flags=flags,
3428 sw_if_index=self.pg0.sw_if_index)
3429 self.vapi.nat44_interface_add_del_output_feature(
3431 sw_if_index=self.pg1.sw_if_index)
3433 # add static mapping for server
3434 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3435 server_in_port, server_out_port,
3436 proto=IP_PROTOS.tcp)
3438 # send packet from host to server
3439 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3440 IP(src=host.ip4, dst=self.nat_addr) /
3441 TCP(sport=host_in_port, dport=server_out_port))
3442 self.pg0.add_stream(p)
3443 self.pg_enable_capture(self.pg_interfaces)
3445 capture = self.pg0.get_capture(1)
3450 self.assertEqual(ip.src, self.nat_addr)
3451 self.assertEqual(ip.dst, server.ip4)
3452 self.assertNotEqual(tcp.sport, host_in_port)
3453 self.assertEqual(tcp.dport, server_in_port)
3454 self.assert_packet_checksums_valid(p)
3455 host_out_port = tcp.sport
3457 self.logger.error(ppp("Unexpected or invalid packet:", p))
3460 # send reply from server to host
3461 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3462 IP(src=server.ip4, dst=self.nat_addr) /
3463 TCP(sport=server_in_port, dport=host_out_port))
3464 self.pg0.add_stream(p)
3465 self.pg_enable_capture(self.pg_interfaces)
3467 capture = self.pg0.get_capture(1)
3472 self.assertEqual(ip.src, self.nat_addr)
3473 self.assertEqual(ip.dst, host.ip4)
3474 self.assertEqual(tcp.sport, server_out_port)
3475 self.assertEqual(tcp.dport, host_in_port)
3476 self.assert_packet_checksums_valid(p)
3478 self.logger.error(ppp("Unexpected or invalid packet:", p))
3481 def test_one_armed_nat44(self):
3482 """ One armed NAT44 """
3483 remote_host = self.pg9.remote_hosts[0]
3484 local_host = self.pg9.remote_hosts[1]
3487 self.nat44_add_address(self.nat_addr)
3488 flags = self.config_flags.NAT_IS_INSIDE
3489 self.vapi.nat44_interface_add_del_feature(
3490 sw_if_index=self.pg9.sw_if_index,
3492 self.vapi.nat44_interface_add_del_feature(
3493 sw_if_index=self.pg9.sw_if_index,
3494 flags=flags, is_add=1)
3497 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3498 IP(src=local_host.ip4, dst=remote_host.ip4) /
3499 TCP(sport=12345, dport=80))
3500 self.pg9.add_stream(p)
3501 self.pg_enable_capture(self.pg_interfaces)
3503 capture = self.pg9.get_capture(1)
3508 self.assertEqual(ip.src, self.nat_addr)
3509 self.assertEqual(ip.dst, remote_host.ip4)
3510 self.assertNotEqual(tcp.sport, 12345)
3511 external_port = tcp.sport
3512 self.assertEqual(tcp.dport, 80)
3513 self.assert_packet_checksums_valid(p)
3515 self.logger.error(ppp("Unexpected or invalid packet:", p))
3519 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3520 IP(src=remote_host.ip4, dst=self.nat_addr) /
3521 TCP(sport=80, dport=external_port))
3522 self.pg9.add_stream(p)
3523 self.pg_enable_capture(self.pg_interfaces)
3525 capture = self.pg9.get_capture(1)
3530 self.assertEqual(ip.src, remote_host.ip4)
3531 self.assertEqual(ip.dst, local_host.ip4)
3532 self.assertEqual(tcp.sport, 80)
3533 self.assertEqual(tcp.dport, 12345)
3534 self.assert_packet_checksums_valid(p)
3536 self.logger.error(ppp("Unexpected or invalid packet:", p))
3539 err = self.statistics.get_err_counter(
3540 '/err/nat44-classify/next in2out')
3541 self.assertEqual(err, 1)
3542 err = self.statistics.get_err_counter(
3543 '/err/nat44-classify/next out2in')
3544 self.assertEqual(err, 1)
3546 def test_del_session(self):
3547 """ Delete NAT44 session """
3548 self.nat44_add_address(self.nat_addr)
3549 flags = self.config_flags.NAT_IS_INSIDE
3550 self.vapi.nat44_interface_add_del_feature(
3551 sw_if_index=self.pg0.sw_if_index,
3552 flags=flags, is_add=1)
3553 self.vapi.nat44_interface_add_del_feature(
3554 sw_if_index=self.pg1.sw_if_index,
3557 pkts = self.create_stream_in(self.pg0, self.pg1)
3558 self.pg0.add_stream(pkts)
3559 self.pg_enable_capture(self.pg_interfaces)
3561 self.pg1.get_capture(len(pkts))
3563 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3564 nsessions = len(sessions)
3566 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3567 port=sessions[0].inside_port,
3568 protocol=sessions[0].protocol,
3569 flags=self.config_flags.NAT_IS_INSIDE)
3570 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3571 port=sessions[1].outside_port,
3572 protocol=sessions[1].protocol)
3574 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3575 self.assertEqual(nsessions - len(sessions), 2)
3577 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3578 port=sessions[0].inside_port,
3579 protocol=sessions[0].protocol,
3580 flags=self.config_flags.NAT_IS_INSIDE)
3582 self.verify_no_nat44_user()
3584 def test_set_get_reass(self):
3585 """ NAT44 set/get virtual fragmentation reassembly """
3586 reas_cfg1 = self.vapi.nat_get_reass()
3588 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3589 max_reass=reas_cfg1.ip4_max_reass * 2,
3590 max_frag=reas_cfg1.ip4_max_frag * 2,
3593 reas_cfg2 = self.vapi.nat_get_reass()
3595 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3596 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3597 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3599 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3601 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3603 def test_frag_in_order(self):
3604 """ NAT44 translate fragments arriving in order """
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 reas_cfg1 = self.vapi.nat_get_reass()
3616 # this test was intermittently failing in some cases
3617 # until we temporarily bump the reassembly timeouts
3618 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
3621 self.frag_in_order(proto=IP_PROTOS.tcp)
3622 self.frag_in_order(proto=IP_PROTOS.udp)
3623 self.frag_in_order(proto=IP_PROTOS.icmp)
3625 # restore the reassembly timeouts
3626 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
3627 max_reass=reas_cfg1.ip4_max_reass,
3628 max_frag=reas_cfg1.ip4_max_frag,
3629 drop_frag=reas_cfg1.ip4_drop_frag)
3631 def test_frag_forwarding(self):
3632 """ NAT44 forwarding fragment test """
3633 self.vapi.nat44_add_del_interface_addr(
3635 sw_if_index=self.pg1.sw_if_index)
3636 flags = self.config_flags.NAT_IS_INSIDE
3637 self.vapi.nat44_interface_add_del_feature(
3638 sw_if_index=self.pg0.sw_if_index,
3639 flags=flags, is_add=1)
3640 self.vapi.nat44_interface_add_del_feature(
3641 sw_if_index=self.pg1.sw_if_index,
3643 self.vapi.nat44_forwarding_enable_disable(enable=1)
3645 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3646 pkts = self.create_stream_frag(self.pg1,
3647 self.pg0.remote_ip4,
3651 proto=IP_PROTOS.udp)
3652 self.pg1.add_stream(pkts)
3653 self.pg_enable_capture(self.pg_interfaces)
3655 frags = self.pg0.get_capture(len(pkts))
3656 p = self.reass_frags_and_verify(frags,
3657 self.pg1.remote_ip4,
3658 self.pg0.remote_ip4)
3659 self.assertEqual(p[UDP].sport, 4789)
3660 self.assertEqual(p[UDP].dport, 4789)
3661 self.assertEqual(data, p[Raw].load)
3663 def test_reass_hairpinning(self):
3664 """ NAT44 fragments hairpinning """
3666 self.server = self.pg0.remote_hosts[1]
3667 self.host_in_port = random.randint(1025, 65535)
3668 self.server_in_port = random.randint(1025, 65535)
3669 self.server_out_port = random.randint(1025, 65535)
3671 self.nat44_add_address(self.nat_addr)
3672 flags = self.config_flags.NAT_IS_INSIDE
3673 self.vapi.nat44_interface_add_del_feature(
3674 sw_if_index=self.pg0.sw_if_index,
3675 flags=flags, is_add=1)
3676 self.vapi.nat44_interface_add_del_feature(
3677 sw_if_index=self.pg1.sw_if_index,
3679 # add static mapping for server
3680 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3681 self.server_in_port,
3682 self.server_out_port,
3683 proto=IP_PROTOS.tcp)
3684 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3685 self.server_in_port,
3686 self.server_out_port,
3687 proto=IP_PROTOS.udp)
3688 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3690 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3691 self.reass_hairpinning(proto=IP_PROTOS.udp)
3692 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3694 def test_frag_out_of_order(self):
3695 """ NAT44 translate fragments arriving out of order """
3697 self.nat44_add_address(self.nat_addr)
3698 flags = self.config_flags.NAT_IS_INSIDE
3699 self.vapi.nat44_interface_add_del_feature(
3700 sw_if_index=self.pg0.sw_if_index,
3701 flags=flags, is_add=1)
3702 self.vapi.nat44_interface_add_del_feature(
3703 sw_if_index=self.pg1.sw_if_index,
3706 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3707 self.frag_out_of_order(proto=IP_PROTOS.udp)
3708 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3710 def test_port_restricted(self):
3711 """ Port restricted NAT44 (MAP-E CE) """
3712 self.nat44_add_address(self.nat_addr)
3713 flags = self.config_flags.NAT_IS_INSIDE
3714 self.vapi.nat44_interface_add_del_feature(
3715 sw_if_index=self.pg0.sw_if_index,
3716 flags=flags, is_add=1)
3717 self.vapi.nat44_interface_add_del_feature(
3718 sw_if_index=self.pg1.sw_if_index,
3720 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3725 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3726 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3727 TCP(sport=4567, dport=22))
3728 self.pg0.add_stream(p)
3729 self.pg_enable_capture(self.pg_interfaces)
3731 capture = self.pg1.get_capture(1)
3736 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3737 self.assertEqual(ip.src, self.nat_addr)
3738 self.assertEqual(tcp.dport, 22)
3739 self.assertNotEqual(tcp.sport, 4567)
3740 self.assertEqual((tcp.sport >> 6) & 63, 10)
3741 self.assert_packet_checksums_valid(p)
3743 self.logger.error(ppp("Unexpected or invalid packet:", p))
3746 def test_port_range(self):
3747 """ External address port range """
3748 self.nat44_add_address(self.nat_addr)
3749 flags = self.config_flags.NAT_IS_INSIDE
3750 self.vapi.nat44_interface_add_del_feature(
3751 sw_if_index=self.pg0.sw_if_index,
3752 flags=flags, is_add=1)
3753 self.vapi.nat44_interface_add_del_feature(
3754 sw_if_index=self.pg1.sw_if_index,
3756 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3761 for port in range(0, 5):
3762 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3763 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3764 TCP(sport=1125 + port))
3766 self.pg0.add_stream(pkts)
3767 self.pg_enable_capture(self.pg_interfaces)
3769 capture = self.pg1.get_capture(3)
3772 self.assertGreaterEqual(tcp.sport, 1025)
3773 self.assertLessEqual(tcp.sport, 1027)
3775 def test_ipfix_max_frags(self):
3776 """ IPFIX logging maximum fragments pending reassembly exceeded """
3777 self.nat44_add_address(self.nat_addr)
3778 flags = self.config_flags.NAT_IS_INSIDE
3779 self.vapi.nat44_interface_add_del_feature(
3780 sw_if_index=self.pg0.sw_if_index,
3781 flags=flags, is_add=1)
3782 self.vapi.nat44_interface_add_del_feature(
3783 sw_if_index=self.pg1.sw_if_index,
3785 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3787 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
3788 src_address=self.pg3.local_ip4,
3790 template_interval=10)
3791 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3792 src_port=self.ipfix_src_port,
3795 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3796 self.tcp_port_in = random.randint(1025, 65535)
3797 pkts = self.create_stream_frag(self.pg0,
3798 self.pg1.remote_ip4,
3803 self.pg0.add_stream(pkts)
3804 self.pg_enable_capture(self.pg_interfaces)
3806 self.pg1.assert_nothing_captured()
3808 self.vapi.ipfix_flush()
3809 capture = self.pg3.get_capture(9)
3810 ipfix = IPFIXDecoder()
3811 # first load template
3813 self.assertTrue(p.haslayer(IPFIX))
3814 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3815 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3816 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3817 self.assertEqual(p[UDP].dport, 4739)
3818 self.assertEqual(p[IPFIX].observationDomainID,
3819 self.ipfix_domain_id)
3820 if p.haslayer(Template):
3821 ipfix.add_template(p.getlayer(Template))
3822 # verify events in data set
3824 if p.haslayer(Data):
3825 data = ipfix.decode_data_set(p.getlayer(Set))
3826 self.verify_ipfix_max_fragments_ip4(data, 1,
3827 self.pg0.remote_ip4n)
3829 def test_multiple_outside_vrf(self):
3830 """ Multiple outside VRF """
3834 self.pg1.unconfig_ip4()
3835 self.pg2.unconfig_ip4()
3836 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3837 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3838 self.pg1.set_table_ip4(vrf_id1)
3839 self.pg2.set_table_ip4(vrf_id2)
3840 self.pg1.config_ip4()
3841 self.pg2.config_ip4()
3842 self.pg1.resolve_arp()
3843 self.pg2.resolve_arp()
3845 self.nat44_add_address(self.nat_addr)
3846 flags = self.config_flags.NAT_IS_INSIDE
3847 self.vapi.nat44_interface_add_del_feature(
3848 sw_if_index=self.pg0.sw_if_index,
3849 flags=flags, is_add=1)
3850 self.vapi.nat44_interface_add_del_feature(
3851 sw_if_index=self.pg1.sw_if_index,
3853 self.vapi.nat44_interface_add_del_feature(
3854 sw_if_index=self.pg2.sw_if_index,
3859 pkts = self.create_stream_in(self.pg0, self.pg1)
3860 self.pg0.add_stream(pkts)
3861 self.pg_enable_capture(self.pg_interfaces)
3863 capture = self.pg1.get_capture(len(pkts))
3864 self.verify_capture_out(capture, self.nat_addr)
3866 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3867 self.pg1.add_stream(pkts)
3868 self.pg_enable_capture(self.pg_interfaces)
3870 capture = self.pg0.get_capture(len(pkts))
3871 self.verify_capture_in(capture, self.pg0)
3873 self.tcp_port_in = 60303
3874 self.udp_port_in = 60304
3875 self.icmp_id_in = 60305
3878 pkts = self.create_stream_in(self.pg0, self.pg2)
3879 self.pg0.add_stream(pkts)
3880 self.pg_enable_capture(self.pg_interfaces)
3882 capture = self.pg2.get_capture(len(pkts))
3883 self.verify_capture_out(capture, self.nat_addr)
3885 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3886 self.pg2.add_stream(pkts)
3887 self.pg_enable_capture(self.pg_interfaces)
3889 capture = self.pg0.get_capture(len(pkts))
3890 self.verify_capture_in(capture, self.pg0)
3893 self.nat44_add_address(self.nat_addr, is_add=0)
3894 self.pg1.unconfig_ip4()
3895 self.pg2.unconfig_ip4()
3896 self.pg1.set_table_ip4(0)
3897 self.pg2.set_table_ip4(0)
3898 self.pg1.config_ip4()
3899 self.pg2.config_ip4()
3900 self.pg1.resolve_arp()
3901 self.pg2.resolve_arp()
3903 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3904 def test_session_timeout(self):
3905 """ NAT44 session timeouts """
3906 self.nat44_add_address(self.nat_addr)
3907 flags = self.config_flags.NAT_IS_INSIDE
3908 self.vapi.nat44_interface_add_del_feature(
3909 sw_if_index=self.pg0.sw_if_index,
3910 flags=flags, is_add=1)
3911 self.vapi.nat44_interface_add_del_feature(
3912 sw_if_index=self.pg1.sw_if_index,
3914 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3915 tcp_transitory=240, icmp=60)
3919 for i in range(0, max_sessions):
3920 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3921 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3922 IP(src=src, dst=self.pg1.remote_ip4) /
3923 UDP(sport=1025, dport=53))
3925 self.pg0.add_stream(pkts)
3926 self.pg_enable_capture(self.pg_interfaces)
3928 self.pg1.get_capture(max_sessions)
3933 for i in range(0, max_sessions):
3934 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3935 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3936 IP(src=src, dst=self.pg1.remote_ip4) /
3937 UDP(sport=1026, dport=53))
3939 self.pg0.add_stream(pkts)
3940 self.pg_enable_capture(self.pg_interfaces)
3942 self.pg1.get_capture(max_sessions)
3945 users = self.vapi.nat44_user_dump()
3947 nsessions = nsessions + user.nsessions
3948 self.assertLess(nsessions, 2 * max_sessions)
3950 def test_mss_clamping(self):
3951 """ TCP MSS clamping """
3952 self.nat44_add_address(self.nat_addr)
3953 flags = self.config_flags.NAT_IS_INSIDE
3954 self.vapi.nat44_interface_add_del_feature(
3955 sw_if_index=self.pg0.sw_if_index,
3956 flags=flags, is_add=1)
3957 self.vapi.nat44_interface_add_del_feature(
3958 sw_if_index=self.pg1.sw_if_index,
3961 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3962 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3963 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3964 flags="S", options=[('MSS', 1400)]))
3966 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3967 self.pg0.add_stream(p)
3968 self.pg_enable_capture(self.pg_interfaces)
3970 capture = self.pg1.get_capture(1)
3971 # Negotiated MSS value greater than configured - changed
3972 self.verify_mss_value(capture[0], 1000)
3974 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3975 self.pg0.add_stream(p)
3976 self.pg_enable_capture(self.pg_interfaces)
3978 capture = self.pg1.get_capture(1)
3979 # MSS clamping disabled - negotiated MSS unchanged
3980 self.verify_mss_value(capture[0], 1400)
3982 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3983 self.pg0.add_stream(p)
3984 self.pg_enable_capture(self.pg_interfaces)
3986 capture = self.pg1.get_capture(1)
3987 # Negotiated MSS value smaller than configured - unchanged
3988 self.verify_mss_value(capture[0], 1400)
3990 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3991 def test_ha_send(self):
3992 """ Send HA session synchronization events (active) """
3993 self.nat44_add_address(self.nat_addr)
3994 flags = self.config_flags.NAT_IS_INSIDE
3995 self.vapi.nat44_interface_add_del_feature(
3996 sw_if_index=self.pg0.sw_if_index,
3997 flags=flags, is_add=1)
3998 self.vapi.nat44_interface_add_del_feature(
3999 sw_if_index=self.pg1.sw_if_index,
4001 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4004 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4005 port=12346, session_refresh_interval=10)
4006 bind_layers(UDP, HANATStateSync, sport=12345)
4009 pkts = self.create_stream_in(self.pg0, self.pg1)
4010 self.pg0.add_stream(pkts)
4011 self.pg_enable_capture(self.pg_interfaces)
4013 capture = self.pg1.get_capture(len(pkts))
4014 self.verify_capture_out(capture)
4015 # active send HA events
4016 self.vapi.nat_ha_flush()
4017 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4018 self.assertEqual(stats[0][0], 3)
4019 capture = self.pg3.get_capture(1)
4021 self.assert_packet_checksums_valid(p)
4025 hanat = p[HANATStateSync]
4027 self.logger.error(ppp("Invalid packet:", p))
4030 self.assertEqual(ip.src, self.pg3.local_ip4)
4031 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4032 self.assertEqual(udp.sport, 12345)
4033 self.assertEqual(udp.dport, 12346)
4034 self.assertEqual(hanat.version, 1)
4035 self.assertEqual(hanat.thread_index, 0)
4036 self.assertEqual(hanat.count, 3)
4037 seq = hanat.sequence_number
4038 for event in hanat.events:
4039 self.assertEqual(event.event_type, 1)
4040 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4041 self.assertEqual(event.out_addr, self.nat_addr)
4042 self.assertEqual(event.fib_index, 0)
4044 # ACK received events
4045 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4046 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4047 UDP(sport=12346, dport=12345) /
4048 HANATStateSync(sequence_number=seq, flags='ACK'))
4049 self.pg3.add_stream(ack)
4051 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4052 self.assertEqual(stats[0][0], 1)
4054 # delete one session
4055 self.pg_enable_capture(self.pg_interfaces)
4056 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
4057 port=self.tcp_port_in,
4058 protocol=IP_PROTOS.tcp,
4059 flags=self.config_flags.NAT_IS_INSIDE)
4060 self.vapi.nat_ha_flush()
4061 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4062 self.assertEqual(stats[0][0], 1)
4063 capture = self.pg3.get_capture(1)
4066 hanat = p[HANATStateSync]
4068 self.logger.error(ppp("Invalid packet:", p))
4071 self.assertGreater(hanat.sequence_number, seq)
4073 # do not send ACK, active retry send HA event again
4074 self.pg_enable_capture(self.pg_interfaces)
4076 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4077 self.assertEqual(stats[0][0], 3)
4078 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4079 self.assertEqual(stats[0][0], 1)
4080 capture = self.pg3.get_capture(3)
4081 for packet in capture:
4082 self.assertEqual(packet, p)
4084 # session counters refresh
4085 pkts = self.create_stream_out(self.pg1)
4086 self.pg1.add_stream(pkts)
4087 self.pg_enable_capture(self.pg_interfaces)
4089 self.pg0.get_capture(2)
4090 self.vapi.nat_ha_flush()
4091 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4092 self.assertEqual(stats[0][0], 2)
4093 capture = self.pg3.get_capture(1)
4095 self.assert_packet_checksums_valid(p)
4099 hanat = p[HANATStateSync]
4101 self.logger.error(ppp("Invalid packet:", p))
4104 self.assertEqual(ip.src, self.pg3.local_ip4)
4105 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4106 self.assertEqual(udp.sport, 12345)
4107 self.assertEqual(udp.dport, 12346)
4108 self.assertEqual(hanat.version, 1)
4109 self.assertEqual(hanat.count, 2)
4110 seq = hanat.sequence_number
4111 for event in hanat.events:
4112 self.assertEqual(event.event_type, 3)
4113 self.assertEqual(event.out_addr, self.nat_addr)
4114 self.assertEqual(event.fib_index, 0)
4115 self.assertEqual(event.total_pkts, 2)
4116 self.assertGreater(event.total_bytes, 0)
4118 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4119 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4120 UDP(sport=12346, dport=12345) /
4121 HANATStateSync(sequence_number=seq, flags='ACK'))
4122 self.pg3.add_stream(ack)
4124 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4125 self.assertEqual(stats[0][0], 2)
4127 def test_ha_recv(self):
4128 """ Receive HA session synchronization events (passive) """
4129 self.nat44_add_address(self.nat_addr)
4130 flags = self.config_flags.NAT_IS_INSIDE
4131 self.vapi.nat44_interface_add_del_feature(
4132 sw_if_index=self.pg0.sw_if_index,
4133 flags=flags, is_add=1)
4134 self.vapi.nat44_interface_add_del_feature(
4135 sw_if_index=self.pg1.sw_if_index,
4137 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4140 bind_layers(UDP, HANATStateSync, sport=12345)
4142 self.tcp_port_out = random.randint(1025, 65535)
4143 self.udp_port_out = random.randint(1025, 65535)
4145 # send HA session add events to failover/passive
4146 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4147 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4148 UDP(sport=12346, dport=12345) /
4149 HANATStateSync(sequence_number=1, events=[
4150 Event(event_type='add', protocol='tcp',
4151 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4152 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4153 eh_addr=self.pg1.remote_ip4,
4154 ehn_addr=self.pg1.remote_ip4,
4155 eh_port=self.tcp_external_port,
4156 ehn_port=self.tcp_external_port, fib_index=0),
4157 Event(event_type='add', protocol='udp',
4158 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4159 in_port=self.udp_port_in, out_port=self.udp_port_out,
4160 eh_addr=self.pg1.remote_ip4,
4161 ehn_addr=self.pg1.remote_ip4,
4162 eh_port=self.udp_external_port,
4163 ehn_port=self.udp_external_port, fib_index=0)]))
4165 self.pg3.add_stream(p)
4166 self.pg_enable_capture(self.pg_interfaces)
4169 capture = self.pg3.get_capture(1)
4172 hanat = p[HANATStateSync]
4174 self.logger.error(ppp("Invalid packet:", p))
4177 self.assertEqual(hanat.sequence_number, 1)
4178 self.assertEqual(hanat.flags, 'ACK')
4179 self.assertEqual(hanat.version, 1)
4180 self.assertEqual(hanat.thread_index, 0)
4181 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4182 self.assertEqual(stats[0][0], 1)
4183 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4184 self.assertEqual(stats[0][0], 2)
4185 users = self.statistics.get_counter('/nat44/total-users')
4186 self.assertEqual(users[0][0], 1)
4187 sessions = self.statistics.get_counter('/nat44/total-sessions')
4188 self.assertEqual(sessions[0][0], 2)
4189 users = self.vapi.nat44_user_dump()
4190 self.assertEqual(len(users), 1)
4191 self.assertEqual(str(users[0].ip_address),
4192 self.pg0.remote_ip4)
4193 # there should be 2 sessions created by HA
4194 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4196 self.assertEqual(len(sessions), 2)
4197 for session in sessions:
4198 self.assertEqual(str(session.inside_ip_address),
4199 self.pg0.remote_ip4)
4200 self.assertEqual(str(session.outside_ip_address),
4202 self.assertIn(session.inside_port,
4203 [self.tcp_port_in, self.udp_port_in])
4204 self.assertIn(session.outside_port,
4205 [self.tcp_port_out, self.udp_port_out])
4206 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4208 # send HA session delete event to failover/passive
4209 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4210 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4211 UDP(sport=12346, dport=12345) /
4212 HANATStateSync(sequence_number=2, events=[
4213 Event(event_type='del', protocol='udp',
4214 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4215 in_port=self.udp_port_in, out_port=self.udp_port_out,
4216 eh_addr=self.pg1.remote_ip4,
4217 ehn_addr=self.pg1.remote_ip4,
4218 eh_port=self.udp_external_port,
4219 ehn_port=self.udp_external_port, fib_index=0)]))
4221 self.pg3.add_stream(p)
4222 self.pg_enable_capture(self.pg_interfaces)
4225 capture = self.pg3.get_capture(1)
4228 hanat = p[HANATStateSync]
4230 self.logger.error(ppp("Invalid packet:", p))
4233 self.assertEqual(hanat.sequence_number, 2)
4234 self.assertEqual(hanat.flags, 'ACK')
4235 self.assertEqual(hanat.version, 1)
4236 users = self.vapi.nat44_user_dump()
4237 self.assertEqual(len(users), 1)
4238 self.assertEqual(str(users[0].ip_address),
4239 self.pg0.remote_ip4)
4240 # now we should have only 1 session, 1 deleted by HA
4241 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4243 self.assertEqual(len(sessions), 1)
4244 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4245 self.assertEqual(stats[0][0], 1)
4247 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4248 self.assertEqual(stats, 2)
4250 # send HA session refresh event to failover/passive
4251 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4252 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4253 UDP(sport=12346, dport=12345) /
4254 HANATStateSync(sequence_number=3, events=[
4255 Event(event_type='refresh', protocol='tcp',
4256 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4257 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4258 eh_addr=self.pg1.remote_ip4,
4259 ehn_addr=self.pg1.remote_ip4,
4260 eh_port=self.tcp_external_port,
4261 ehn_port=self.tcp_external_port, fib_index=0,
4262 total_bytes=1024, total_pkts=2)]))
4263 self.pg3.add_stream(p)
4264 self.pg_enable_capture(self.pg_interfaces)
4267 capture = self.pg3.get_capture(1)
4270 hanat = p[HANATStateSync]
4272 self.logger.error(ppp("Invalid packet:", p))
4275 self.assertEqual(hanat.sequence_number, 3)
4276 self.assertEqual(hanat.flags, 'ACK')
4277 self.assertEqual(hanat.version, 1)
4278 users = self.vapi.nat44_user_dump()
4279 self.assertEqual(len(users), 1)
4280 self.assertEqual(str(users[0].ip_address),
4281 self.pg0.remote_ip4)
4282 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4284 self.assertEqual(len(sessions), 1)
4285 session = sessions[0]
4286 self.assertEqual(session.total_bytes, 1024)
4287 self.assertEqual(session.total_pkts, 2)
4288 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4289 self.assertEqual(stats[0][0], 1)
4291 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4292 self.assertEqual(stats, 3)
4294 # send packet to test session created by HA
4295 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4296 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4297 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4298 self.pg1.add_stream(p)
4299 self.pg_enable_capture(self.pg_interfaces)
4301 capture = self.pg0.get_capture(1)
4307 self.logger.error(ppp("Invalid packet:", p))
4310 self.assertEqual(ip.src, self.pg1.remote_ip4)
4311 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4312 self.assertEqual(tcp.sport, self.tcp_external_port)
4313 self.assertEqual(tcp.dport, self.tcp_port_in)
4316 super(TestNAT44, self).tearDown()
4318 self.vapi.cli("clear logging")
4320 def show_commands_at_teardown(self):
4321 self.logger.info(self.vapi.cli("show nat44 addresses"))
4322 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4323 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4324 self.logger.info(self.vapi.cli("show nat44 interface address"))
4325 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4326 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4327 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4328 self.logger.info(self.vapi.cli("show nat timeouts"))
4330 self.vapi.cli("show nat addr-port-assignment-alg"))
4331 self.logger.info(self.vapi.cli("show nat ha"))
4334 class TestNAT44EndpointDependent2(MethodHolder):
4335 """ Endpoint-Dependent session test cases """
4340 def setUpConstants(cls):
4341 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4342 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent",
4343 "translation", "hash", "buckets", "1",
4344 "icmp", "timeout", str(cls.icmp_timeout), "}"])
4347 def setUpClass(cls):
4348 super(TestNAT44EndpointDependent2, cls).setUpClass()
4350 translation_buckets = 1
4351 cls.max_translations = 10 * translation_buckets
4353 cls.create_pg_interfaces(range(2))
4354 cls.interfaces = list(cls.pg_interfaces[0:2])
4356 for i in cls.interfaces:
4361 cls.pg0.generate_remote_hosts(1)
4362 cls.pg0.configure_ipv4_neighbors()
4364 cls.pg1.generate_remote_hosts(1)
4365 cls.pg1.configure_ipv4_neighbors()
4368 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4371 def create_icmp_stream(self, in_if, out_if, count):
4373 Create ICMP packet stream for inside network
4375 :param in_if: Inside interface
4376 :param out_if: Outside interface
4377 :param count: Number of packets
4380 self.assertTrue(count > 0)
4381 icmp_id = random.randint(0, 65535 - (count - 1))
4384 for i in range(count):
4385 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4386 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4387 ICMP(id=icmp_id + i, type='echo-request'))
4391 def send_pkts(self, pkts, expected=None):
4392 self.pg0.add_stream(pkts)
4393 self.pg_enable_capture(self.pg_interfaces)
4395 return self.pg1.get_capture(
4396 len(pkts) if expected is None else expected)
4398 def test_session_cleanup(self):
4399 """ NAT44 session cleanup test """
4401 self.nat44_add_address(self.pg1.local_ip4)
4402 flags = self.config_flags.NAT_IS_INSIDE
4403 self.vapi.nat44_interface_add_del_feature(
4404 sw_if_index=self.pg0.sw_if_index,
4405 flags=flags, is_add=1)
4406 self.vapi.nat44_interface_add_del_feature(
4407 sw_if_index=self.pg1.sw_if_index,
4410 nat_config = self.vapi.nat_show_config()
4411 self.assertEqual(1, nat_config.endpoint_dependent)
4413 pkts = self.create_icmp_stream(self.pg0, self.pg1,
4414 self.max_translations + 2)
4418 self.send_pkts(pkts[0:self.max_translations])
4420 # false positive test
4421 self.send_pkts(pkts[self.max_translations:sz - 1], 0)
4423 sleep(self.icmp_timeout)
4426 self.send_pkts(pkts[self.max_translations + 1:sz])
4429 class TestNAT44EndpointDependent(MethodHolder):
4430 """ Endpoint-Dependent mapping and filtering test cases """
4433 def setUpConstants(cls):
4434 super(TestNAT44EndpointDependent, cls).setUpConstants()
4435 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4438 def setUpClass(cls):
4439 super(TestNAT44EndpointDependent, cls).setUpClass()
4440 cls.vapi.cli("set log class nat level debug")
4442 cls.tcp_port_in = 6303
4443 cls.tcp_port_out = 6303
4444 cls.udp_port_in = 6304
4445 cls.udp_port_out = 6304
4446 cls.icmp_id_in = 6305
4447 cls.icmp_id_out = 6305
4448 cls.nat_addr = '10.0.0.3'
4449 cls.ipfix_src_port = 4739
4450 cls.ipfix_domain_id = 1
4451 cls.tcp_external_port = 80
4453 cls.create_pg_interfaces(range(9))
4454 cls.interfaces = list(cls.pg_interfaces[0:3])
4456 for i in cls.interfaces:
4461 cls.pg0.generate_remote_hosts(3)
4462 cls.pg0.configure_ipv4_neighbors()
4466 cls.pg4.generate_remote_hosts(2)
4467 cls.pg4.config_ip4()
4468 cls.vapi.sw_interface_add_del_address(
4469 sw_if_index=cls.pg4.sw_if_index,
4470 prefix="10.0.0.1/24")
4473 cls.pg4.resolve_arp()
4474 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4475 cls.pg4.resolve_arp()
4477 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4478 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4480 cls.pg5._local_ip4 = "10.1.1.1"
4481 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4482 cls.pg5.set_table_ip4(1)
4483 cls.pg5.config_ip4()
4485 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4486 [VppRoutePath("0.0.0.0",
4487 cls.pg5.sw_if_index)],
4492 cls.pg6._local_ip4 = "10.1.2.1"
4493 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4494 cls.pg6.set_table_ip4(1)
4495 cls.pg6.config_ip4()
4498 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4499 [VppRoutePath("0.0.0.0",
4500 cls.pg6.sw_if_index)],
4503 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4504 [VppRoutePath("0.0.0.0",
4509 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4510 [VppRoutePath("0.0.0.0", 0xffffffff,
4514 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4515 [VppRoutePath(cls.pg1.local_ip4,
4516 cls.pg1.sw_if_index)],
4523 cls.pg5.resolve_arp()
4524 cls.pg6.resolve_arp()
4527 cls.pg7.config_ip4()
4528 cls.pg7.resolve_arp()
4529 cls.pg7.generate_remote_hosts(3)
4530 cls.pg7.configure_ipv4_neighbors()
4533 cls.pg8.config_ip4()
4534 cls.pg8.resolve_arp()
4537 super(TestNAT44EndpointDependent, cls).tearDownClass()
4541 def tearDownClass(cls):
4542 super(TestNAT44EndpointDependent, cls).tearDownClass()
4544 def test_frag_in_order(self):
4545 """ NAT44 translate fragments arriving in order """
4546 self.nat44_add_address(self.nat_addr)
4547 flags = self.config_flags.NAT_IS_INSIDE
4548 self.vapi.nat44_interface_add_del_feature(
4549 sw_if_index=self.pg0.sw_if_index,
4550 flags=flags, is_add=1)
4551 self.vapi.nat44_interface_add_del_feature(
4552 sw_if_index=self.pg1.sw_if_index,
4554 self.frag_in_order(proto=IP_PROTOS.tcp)
4555 self.frag_in_order(proto=IP_PROTOS.udp)
4556 self.frag_in_order(proto=IP_PROTOS.icmp)
4558 def test_frag_in_order_dont_translate(self):
4559 """ NAT44 don't translate fragments arriving in order """
4560 flags = self.config_flags.NAT_IS_INSIDE
4561 self.vapi.nat44_interface_add_del_feature(
4562 sw_if_index=self.pg0.sw_if_index,
4563 flags=flags, is_add=1)
4564 self.vapi.nat44_interface_add_del_feature(
4565 sw_if_index=self.pg1.sw_if_index,
4567 self.vapi.nat44_forwarding_enable_disable(enable=True)
4568 reas_cfg1 = self.vapi.nat_get_reass()
4569 # this test was intermittently failing in some cases
4570 # until we temporarily bump the reassembly timeouts
4571 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4573 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4574 # restore the reassembly timeouts
4575 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4576 max_reass=reas_cfg1.ip4_max_reass,
4577 max_frag=reas_cfg1.ip4_max_frag,
4578 drop_frag=reas_cfg1.ip4_drop_frag)
4580 def test_frag_out_of_order(self):
4581 """ NAT44 translate fragments arriving out of order """
4582 self.nat44_add_address(self.nat_addr)
4583 flags = self.config_flags.NAT_IS_INSIDE
4584 self.vapi.nat44_interface_add_del_feature(
4585 sw_if_index=self.pg0.sw_if_index,
4586 flags=flags, is_add=1)
4587 self.vapi.nat44_interface_add_del_feature(
4588 sw_if_index=self.pg1.sw_if_index,
4590 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4591 self.frag_out_of_order(proto=IP_PROTOS.udp)
4592 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4594 def test_frag_out_of_order_dont_translate(self):
4595 """ NAT44 don't translate fragments arriving out of order """
4596 flags = self.config_flags.NAT_IS_INSIDE
4597 self.vapi.nat44_interface_add_del_feature(
4598 sw_if_index=self.pg0.sw_if_index,
4599 flags=flags, is_add=1)
4600 self.vapi.nat44_interface_add_del_feature(
4601 sw_if_index=self.pg1.sw_if_index,
4603 self.vapi.nat44_forwarding_enable_disable(enable=True)
4604 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4606 def test_frag_in_order_in_plus_out(self):
4607 """ in+out interface fragments in order """
4608 flags = self.config_flags.NAT_IS_INSIDE
4609 self.vapi.nat44_interface_add_del_feature(
4610 sw_if_index=self.pg0.sw_if_index,
4612 self.vapi.nat44_interface_add_del_feature(
4613 sw_if_index=self.pg0.sw_if_index,
4614 flags=flags, is_add=1)
4615 self.vapi.nat44_interface_add_del_feature(
4616 sw_if_index=self.pg1.sw_if_index,
4618 self.vapi.nat44_interface_add_del_feature(
4619 sw_if_index=self.pg1.sw_if_index,
4620 flags=flags, is_add=1)
4622 self.server = self.pg1.remote_hosts[0]
4624 self.server_in_addr = self.server.ip4
4625 self.server_out_addr = '11.11.11.11'
4626 self.server_in_port = random.randint(1025, 65535)
4627 self.server_out_port = random.randint(1025, 65535)
4629 self.nat44_add_address(self.server_out_addr)
4631 # add static mappings for server
4632 self.nat44_add_static_mapping(self.server_in_addr,
4633 self.server_out_addr,
4634 self.server_in_port,
4635 self.server_out_port,
4636 proto=IP_PROTOS.tcp)
4637 self.nat44_add_static_mapping(self.server_in_addr,
4638 self.server_out_addr,
4639 self.server_in_port,
4640 self.server_out_port,
4641 proto=IP_PROTOS.udp)
4642 self.nat44_add_static_mapping(self.server_in_addr,
4643 self.server_out_addr,
4644 proto=IP_PROTOS.icmp)
4646 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4649 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4650 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4651 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4653 def test_frag_out_of_order_in_plus_out(self):
4654 """ in+out interface fragments out of order """
4655 flags = self.config_flags.NAT_IS_INSIDE
4656 self.vapi.nat44_interface_add_del_feature(
4657 sw_if_index=self.pg0.sw_if_index,
4659 self.vapi.nat44_interface_add_del_feature(
4660 sw_if_index=self.pg0.sw_if_index,
4661 flags=flags, is_add=1)
4662 self.vapi.nat44_interface_add_del_feature(
4663 sw_if_index=self.pg1.sw_if_index,
4665 self.vapi.nat44_interface_add_del_feature(
4666 sw_if_index=self.pg1.sw_if_index,
4667 flags=flags, is_add=1)
4669 self.server = self.pg1.remote_hosts[0]
4671 self.server_in_addr = self.server.ip4
4672 self.server_out_addr = '11.11.11.11'
4673 self.server_in_port = random.randint(1025, 65535)
4674 self.server_out_port = random.randint(1025, 65535)
4676 self.nat44_add_address(self.server_out_addr)
4678 # add static mappings for server
4679 self.nat44_add_static_mapping(self.server_in_addr,
4680 self.server_out_addr,
4681 self.server_in_port,
4682 self.server_out_port,
4683 proto=IP_PROTOS.tcp)
4684 self.nat44_add_static_mapping(self.server_in_addr,
4685 self.server_out_addr,
4686 self.server_in_port,
4687 self.server_out_port,
4688 proto=IP_PROTOS.udp)
4689 self.nat44_add_static_mapping(self.server_in_addr,
4690 self.server_out_addr,
4691 proto=IP_PROTOS.icmp)
4693 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4696 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4697 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4698 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4700 def test_reass_hairpinning(self):
4701 """ NAT44 fragments hairpinning """
4702 self.server = self.pg0.remote_hosts[1]
4703 self.host_in_port = random.randint(1025, 65535)
4704 self.server_in_port = random.randint(1025, 65535)
4705 self.server_out_port = random.randint(1025, 65535)
4707 self.nat44_add_address(self.nat_addr)
4708 flags = self.config_flags.NAT_IS_INSIDE
4709 self.vapi.nat44_interface_add_del_feature(
4710 sw_if_index=self.pg0.sw_if_index,
4711 flags=flags, is_add=1)
4712 self.vapi.nat44_interface_add_del_feature(
4713 sw_if_index=self.pg1.sw_if_index,
4715 # add static mapping for server
4716 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4717 self.server_in_port,
4718 self.server_out_port,
4719 proto=IP_PROTOS.tcp)
4720 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4721 self.server_in_port,
4722 self.server_out_port,
4723 proto=IP_PROTOS.udp)
4724 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4726 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4727 self.reass_hairpinning(proto=IP_PROTOS.udp)
4728 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4730 def test_dynamic(self):
4731 """ NAT44 dynamic translation test """
4733 self.nat44_add_address(self.nat_addr)
4734 flags = self.config_flags.NAT_IS_INSIDE
4735 self.vapi.nat44_interface_add_del_feature(
4736 sw_if_index=self.pg0.sw_if_index,
4737 flags=flags, is_add=1)
4738 self.vapi.nat44_interface_add_del_feature(
4739 sw_if_index=self.pg1.sw_if_index,
4742 nat_config = self.vapi.nat_show_config()
4743 self.assertEqual(1, nat_config.endpoint_dependent)
4746 tcpn = self.statistics.get_err_counter(
4747 '/err/nat44-ed-in2out-slowpath/TCP packets')
4748 udpn = self.statistics.get_err_counter(
4749 '/err/nat44-ed-in2out-slowpath/UDP packets')
4750 icmpn = self.statistics.get_err_counter(
4751 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4752 totaln = self.statistics.get_err_counter(
4753 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4755 pkts = self.create_stream_in(self.pg0, self.pg1)
4756 self.pg0.add_stream(pkts)
4757 self.pg_enable_capture(self.pg_interfaces)
4759 capture = self.pg1.get_capture(len(pkts))
4760 self.verify_capture_out(capture)
4762 err = self.statistics.get_err_counter(
4763 '/err/nat44-ed-in2out-slowpath/TCP packets')
4764 self.assertEqual(err - tcpn, 2)
4765 err = self.statistics.get_err_counter(
4766 '/err/nat44-ed-in2out-slowpath/UDP packets')
4767 self.assertEqual(err - udpn, 1)
4768 err = self.statistics.get_err_counter(
4769 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4770 self.assertEqual(err - icmpn, 1)
4771 err = self.statistics.get_err_counter(
4772 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4773 self.assertEqual(err - totaln, 4)
4776 tcpn = self.statistics.get_err_counter(
4777 '/err/nat44-ed-out2in/TCP packets')
4778 udpn = self.statistics.get_err_counter(
4779 '/err/nat44-ed-out2in/UDP packets')
4780 icmpn = self.statistics.get_err_counter(
4781 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4782 totaln = self.statistics.get_err_counter(
4783 '/err/nat44-ed-out2in/good out2in packets processed')
4785 pkts = self.create_stream_out(self.pg1)
4786 self.pg1.add_stream(pkts)
4787 self.pg_enable_capture(self.pg_interfaces)
4789 capture = self.pg0.get_capture(len(pkts))
4790 self.verify_capture_in(capture, self.pg0)
4792 err = self.statistics.get_err_counter(
4793 '/err/nat44-ed-out2in/TCP packets')
4794 self.assertEqual(err - tcpn, 2)
4795 err = self.statistics.get_err_counter(
4796 '/err/nat44-ed-out2in/UDP packets')
4797 self.assertEqual(err - udpn, 1)
4798 err = self.statistics.get_err_counter(
4799 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4800 self.assertEqual(err - icmpn, 1)
4801 err = self.statistics.get_err_counter(
4802 '/err/nat44-ed-out2in/good out2in packets processed')
4803 self.assertEqual(err - totaln, 3)
4805 users = self.statistics.get_counter('/nat44/total-users')
4806 self.assertEqual(users[0][0], 1)
4807 sessions = self.statistics.get_counter('/nat44/total-sessions')
4808 self.assertEqual(sessions[0][0], 3)
4810 def test_dynamic_output_feature_vrf(self):
4811 """ NAT44 dynamic translation test: output-feature, VRF"""
4813 # other then default (0)
4816 self.nat44_add_address(self.nat_addr)
4817 flags = self.config_flags.NAT_IS_INSIDE
4818 self.vapi.nat44_interface_add_del_output_feature(
4819 sw_if_index=self.pg7.sw_if_index,
4820 flags=flags, is_add=1)
4821 self.vapi.nat44_interface_add_del_output_feature(
4822 sw_if_index=self.pg8.sw_if_index,
4826 self.vapi.ip_table_add_del(is_add=1,
4827 table={'table_id': new_vrf_id})
4829 self.pg7.unconfig_ip4()
4830 self.pg7.set_table_ip4(new_vrf_id)
4831 self.pg7.config_ip4()
4832 self.pg7.resolve_arp()
4834 self.pg8.unconfig_ip4()
4835 self.pg8.set_table_ip4(new_vrf_id)
4836 self.pg8.config_ip4()
4837 self.pg8.resolve_arp()
4839 nat_config = self.vapi.nat_show_config()
4840 self.assertEqual(1, nat_config.endpoint_dependent)
4843 tcpn = self.statistics.get_err_counter(
4844 '/err/nat44-ed-in2out-slowpath/TCP packets')
4845 udpn = self.statistics.get_err_counter(
4846 '/err/nat44-ed-in2out-slowpath/UDP packets')
4847 icmpn = self.statistics.get_err_counter(
4848 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4849 totaln = self.statistics.get_err_counter(
4850 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4852 pkts = self.create_stream_in(self.pg7, self.pg8)
4853 self.pg7.add_stream(pkts)
4854 self.pg_enable_capture(self.pg_interfaces)
4856 capture = self.pg8.get_capture(len(pkts))
4857 self.verify_capture_out(capture)
4859 err = self.statistics.get_err_counter(
4860 '/err/nat44-ed-in2out-slowpath/TCP packets')
4861 self.assertEqual(err - tcpn, 2)
4862 err = self.statistics.get_err_counter(
4863 '/err/nat44-ed-in2out-slowpath/UDP packets')
4864 self.assertEqual(err - udpn, 1)
4865 err = self.statistics.get_err_counter(
4866 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4867 self.assertEqual(err - icmpn, 1)
4868 err = self.statistics.get_err_counter(
4869 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4870 self.assertEqual(err - totaln, 4)
4873 tcpn = self.statistics.get_err_counter(
4874 '/err/nat44-ed-out2in/TCP packets')
4875 udpn = self.statistics.get_err_counter(
4876 '/err/nat44-ed-out2in/UDP packets')
4877 icmpn = self.statistics.get_err_counter(
4878 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4879 totaln = self.statistics.get_err_counter(
4880 '/err/nat44-ed-out2in/good out2in packets processed')
4882 pkts = self.create_stream_out(self.pg8)
4883 self.pg8.add_stream(pkts)
4884 self.pg_enable_capture(self.pg_interfaces)
4886 capture = self.pg7.get_capture(len(pkts))
4887 self.verify_capture_in(capture, self.pg7)
4889 err = self.statistics.get_err_counter(
4890 '/err/nat44-ed-out2in/TCP packets')
4891 self.assertEqual(err - tcpn, 2)
4892 err = self.statistics.get_err_counter(
4893 '/err/nat44-ed-out2in/UDP packets')
4894 self.assertEqual(err - udpn, 1)
4895 err = self.statistics.get_err_counter(
4896 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4897 self.assertEqual(err - icmpn, 1)
4898 err = self.statistics.get_err_counter(
4899 '/err/nat44-ed-out2in/good out2in packets processed')
4900 self.assertEqual(err - totaln, 3)
4902 users = self.statistics.get_counter('/nat44/total-users')
4903 self.assertEqual(users[0][0], 1)
4904 sessions = self.statistics.get_counter('/nat44/total-sessions')
4905 self.assertEqual(sessions[0][0], 3)
4908 self.pg7.unconfig_ip4()
4909 self.pg7.set_table_ip4(1)
4910 self.pg7.config_ip4()
4911 self.pg7.resolve_arp()
4913 self.pg8.unconfig_ip4()
4914 self.pg8.set_table_ip4(1)
4915 self.pg8.config_ip4()
4916 self.pg8.resolve_arp()
4918 self.vapi.ip_table_add_del(is_add=0,
4919 table={'table_id': new_vrf_id})
4921 def test_forwarding(self):
4922 """ NAT44 forwarding test """
4924 flags = self.config_flags.NAT_IS_INSIDE
4925 self.vapi.nat44_interface_add_del_feature(
4926 sw_if_index=self.pg0.sw_if_index,
4927 flags=flags, is_add=1)
4928 self.vapi.nat44_interface_add_del_feature(
4929 sw_if_index=self.pg1.sw_if_index,
4931 self.vapi.nat44_forwarding_enable_disable(enable=1)
4933 real_ip = self.pg0.remote_ip4
4934 alias_ip = self.nat_addr
4935 flags = self.config_flags.NAT_IS_ADDR_ONLY
4936 self.vapi.nat44_add_del_static_mapping(is_add=1,
4937 local_ip_address=real_ip,
4938 external_ip_address=alias_ip,
4939 external_sw_if_index=0xFFFFFFFF,
4943 # in2out - static mapping match
4945 pkts = self.create_stream_out(self.pg1)
4946 self.pg1.add_stream(pkts)
4947 self.pg_enable_capture(self.pg_interfaces)
4949 capture = self.pg0.get_capture(len(pkts))
4950 self.verify_capture_in(capture, self.pg0)
4952 pkts = self.create_stream_in(self.pg0, self.pg1)
4953 self.pg0.add_stream(pkts)
4954 self.pg_enable_capture(self.pg_interfaces)
4956 capture = self.pg1.get_capture(len(pkts))
4957 self.verify_capture_out(capture, same_port=True)
4959 # in2out - no static mapping match
4961 host0 = self.pg0.remote_hosts[0]
4962 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4964 pkts = self.create_stream_out(self.pg1,
4965 dst_ip=self.pg0.remote_ip4,
4966 use_inside_ports=True)
4967 self.pg1.add_stream(pkts)
4968 self.pg_enable_capture(self.pg_interfaces)
4970 capture = self.pg0.get_capture(len(pkts))
4971 self.verify_capture_in(capture, self.pg0)
4973 pkts = self.create_stream_in(self.pg0, self.pg1)
4974 self.pg0.add_stream(pkts)
4975 self.pg_enable_capture(self.pg_interfaces)
4977 capture = self.pg1.get_capture(len(pkts))
4978 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4981 self.pg0.remote_hosts[0] = host0
4983 user = self.pg0.remote_hosts[1]
4984 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4985 self.assertEqual(len(sessions), 3)
4986 self.assertTrue(sessions[0].flags &
4987 self.config_flags.NAT_IS_EXT_HOST_VALID)
4988 self.vapi.nat44_del_session(
4989 address=sessions[0].inside_ip_address,
4990 port=sessions[0].inside_port,
4991 protocol=sessions[0].protocol,
4992 flags=(self.config_flags.NAT_IS_INSIDE |
4993 self.config_flags.NAT_IS_EXT_HOST_VALID),
4994 ext_host_address=sessions[0].ext_host_address,
4995 ext_host_port=sessions[0].ext_host_port)
4996 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4997 self.assertEqual(len(sessions), 2)
5000 self.vapi.nat44_forwarding_enable_disable(enable=0)
5001 flags = self.config_flags.NAT_IS_ADDR_ONLY
5002 self.vapi.nat44_add_del_static_mapping(
5004 local_ip_address=real_ip,
5005 external_ip_address=alias_ip,
5006 external_sw_if_index=0xFFFFFFFF,
5009 def test_static_lb(self):
5010 """ NAT44 local service load balancing """
5011 external_addr_n = self.nat_addr
5014 server1 = self.pg0.remote_hosts[0]
5015 server2 = self.pg0.remote_hosts[1]
5017 locals = [{'addr': server1.ip4,
5021 {'addr': server2.ip4,
5026 self.nat44_add_address(self.nat_addr)
5027 self.vapi.nat44_add_del_lb_static_mapping(
5029 external_addr=external_addr_n,
5030 external_port=external_port,
5031 protocol=IP_PROTOS.tcp,
5032 local_num=len(locals),
5034 flags = self.config_flags.NAT_IS_INSIDE
5035 self.vapi.nat44_interface_add_del_feature(
5036 sw_if_index=self.pg0.sw_if_index,
5037 flags=flags, is_add=1)
5038 self.vapi.nat44_interface_add_del_feature(
5039 sw_if_index=self.pg1.sw_if_index,
5042 # from client to service
5043 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5044 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5045 TCP(sport=12345, dport=external_port))
5046 self.pg1.add_stream(p)
5047 self.pg_enable_capture(self.pg_interfaces)
5049 capture = self.pg0.get_capture(1)
5055 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5056 if ip.dst == server1.ip4:
5060 self.assertEqual(tcp.dport, local_port)
5061 self.assert_packet_checksums_valid(p)
5063 self.logger.error(ppp("Unexpected or invalid packet:", p))
5066 # from service back to client
5067 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5068 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5069 TCP(sport=local_port, dport=12345))
5070 self.pg0.add_stream(p)
5071 self.pg_enable_capture(self.pg_interfaces)
5073 capture = self.pg1.get_capture(1)
5078 self.assertEqual(ip.src, self.nat_addr)
5079 self.assertEqual(tcp.sport, external_port)
5080 self.assert_packet_checksums_valid(p)
5082 self.logger.error(ppp("Unexpected or invalid packet:", p))
5085 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5086 self.assertEqual(len(sessions), 1)
5087 self.assertTrue(sessions[0].flags &
5088 self.config_flags.NAT_IS_EXT_HOST_VALID)
5089 self.vapi.nat44_del_session(
5090 address=sessions[0].inside_ip_address,
5091 port=sessions[0].inside_port,
5092 protocol=sessions[0].protocol,
5093 flags=(self.config_flags.NAT_IS_INSIDE |
5094 self.config_flags.NAT_IS_EXT_HOST_VALID),
5095 ext_host_address=sessions[0].ext_host_address,
5096 ext_host_port=sessions[0].ext_host_port)
5097 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5098 self.assertEqual(len(sessions), 0)
5100 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5101 def test_static_lb_multi_clients(self):
5102 """ NAT44 local service load balancing - multiple clients"""
5104 external_addr = self.nat_addr
5107 server1 = self.pg0.remote_hosts[0]
5108 server2 = self.pg0.remote_hosts[1]
5109 server3 = self.pg0.remote_hosts[2]
5111 locals = [{'addr': server1.ip4,
5115 {'addr': server2.ip4,
5120 self.nat44_add_address(self.nat_addr)
5121 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5122 external_addr=external_addr,
5123 external_port=external_port,
5124 protocol=IP_PROTOS.tcp,
5125 local_num=len(locals),
5127 flags = self.config_flags.NAT_IS_INSIDE
5128 self.vapi.nat44_interface_add_del_feature(
5129 sw_if_index=self.pg0.sw_if_index,
5130 flags=flags, is_add=1)
5131 self.vapi.nat44_interface_add_del_feature(
5132 sw_if_index=self.pg1.sw_if_index,
5137 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5139 for client in clients:
5140 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5141 IP(src=client, dst=self.nat_addr) /
5142 TCP(sport=12345, dport=external_port))
5144 self.pg1.add_stream(pkts)
5145 self.pg_enable_capture(self.pg_interfaces)
5147 capture = self.pg0.get_capture(len(pkts))
5149 if p[IP].dst == server1.ip4:
5153 self.assertGreater(server1_n, server2_n)
5156 'addr': server3.ip4,
5163 self.vapi.nat44_lb_static_mapping_add_del_local(
5165 external_addr=external_addr,
5166 external_port=external_port,
5168 protocol=IP_PROTOS.tcp)
5172 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5174 for client in clients:
5175 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5176 IP(src=client, dst=self.nat_addr) /
5177 TCP(sport=12346, dport=external_port))
5179 self.assertGreater(len(pkts), 0)
5180 self.pg1.add_stream(pkts)
5181 self.pg_enable_capture(self.pg_interfaces)
5183 capture = self.pg0.get_capture(len(pkts))
5185 if p[IP].dst == server1.ip4:
5187 elif p[IP].dst == server2.ip4:
5191 self.assertGreater(server1_n, 0)
5192 self.assertGreater(server2_n, 0)
5193 self.assertGreater(server3_n, 0)
5196 'addr': server2.ip4,
5202 # remove one back-end
5203 self.vapi.nat44_lb_static_mapping_add_del_local(
5205 external_addr=external_addr,
5206 external_port=external_port,
5208 protocol=IP_PROTOS.tcp)
5212 self.pg1.add_stream(pkts)
5213 self.pg_enable_capture(self.pg_interfaces)
5215 capture = self.pg0.get_capture(len(pkts))
5217 if p[IP].dst == server1.ip4:
5219 elif p[IP].dst == server2.ip4:
5223 self.assertGreater(server1_n, 0)
5224 self.assertEqual(server2_n, 0)
5225 self.assertGreater(server3_n, 0)
5227 def test_static_lb_2(self):
5228 """ NAT44 local service load balancing (asymmetrical rule) """
5229 external_addr = self.nat_addr
5232 server1 = self.pg0.remote_hosts[0]
5233 server2 = self.pg0.remote_hosts[1]
5235 locals = [{'addr': server1.ip4,
5239 {'addr': server2.ip4,
5244 self.vapi.nat44_forwarding_enable_disable(enable=1)
5245 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5246 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5247 external_addr=external_addr,
5248 external_port=external_port,
5249 protocol=IP_PROTOS.tcp,
5250 local_num=len(locals),
5252 flags = self.config_flags.NAT_IS_INSIDE
5253 self.vapi.nat44_interface_add_del_feature(
5254 sw_if_index=self.pg0.sw_if_index,
5255 flags=flags, is_add=1)
5256 self.vapi.nat44_interface_add_del_feature(
5257 sw_if_index=self.pg1.sw_if_index,
5260 # from client to service
5261 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5262 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5263 TCP(sport=12345, dport=external_port))
5264 self.pg1.add_stream(p)
5265 self.pg_enable_capture(self.pg_interfaces)
5267 capture = self.pg0.get_capture(1)
5273 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5274 if ip.dst == server1.ip4:
5278 self.assertEqual(tcp.dport, local_port)
5279 self.assert_packet_checksums_valid(p)
5281 self.logger.error(ppp("Unexpected or invalid packet:", p))
5284 # from service back to client
5285 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5286 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5287 TCP(sport=local_port, dport=12345))
5288 self.pg0.add_stream(p)
5289 self.pg_enable_capture(self.pg_interfaces)
5291 capture = self.pg1.get_capture(1)
5296 self.assertEqual(ip.src, self.nat_addr)
5297 self.assertEqual(tcp.sport, external_port)
5298 self.assert_packet_checksums_valid(p)
5300 self.logger.error(ppp("Unexpected or invalid packet:", p))
5303 # from client to server (no translation)
5304 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5305 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5306 TCP(sport=12346, dport=local_port))
5307 self.pg1.add_stream(p)
5308 self.pg_enable_capture(self.pg_interfaces)
5310 capture = self.pg0.get_capture(1)
5316 self.assertEqual(ip.dst, server1.ip4)
5317 self.assertEqual(tcp.dport, local_port)
5318 self.assert_packet_checksums_valid(p)
5320 self.logger.error(ppp("Unexpected or invalid packet:", p))
5323 # from service back to client (no translation)
5324 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5325 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5326 TCP(sport=local_port, dport=12346))
5327 self.pg0.add_stream(p)
5328 self.pg_enable_capture(self.pg_interfaces)
5330 capture = self.pg1.get_capture(1)
5335 self.assertEqual(ip.src, server1.ip4)
5336 self.assertEqual(tcp.sport, local_port)
5337 self.assert_packet_checksums_valid(p)
5339 self.logger.error(ppp("Unexpected or invalid packet:", p))
5342 def test_lb_affinity(self):
5343 """ NAT44 local service load balancing affinity """
5344 external_addr = self.nat_addr
5347 server1 = self.pg0.remote_hosts[0]
5348 server2 = self.pg0.remote_hosts[1]
5350 locals = [{'addr': server1.ip4,
5354 {'addr': server2.ip4,
5359 self.nat44_add_address(self.nat_addr)
5360 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5361 external_addr=external_addr,
5362 external_port=external_port,
5363 protocol=IP_PROTOS.tcp,
5365 local_num=len(locals),
5367 flags = self.config_flags.NAT_IS_INSIDE
5368 self.vapi.nat44_interface_add_del_feature(
5369 sw_if_index=self.pg0.sw_if_index,
5370 flags=flags, is_add=1)
5371 self.vapi.nat44_interface_add_del_feature(
5372 sw_if_index=self.pg1.sw_if_index,
5375 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5376 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5377 TCP(sport=1025, dport=external_port))
5378 self.pg1.add_stream(p)
5379 self.pg_enable_capture(self.pg_interfaces)
5381 capture = self.pg0.get_capture(1)
5382 backend = capture[0][IP].dst
5384 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5385 self.assertEqual(len(sessions), 1)
5386 self.assertTrue(sessions[0].flags &
5387 self.config_flags.NAT_IS_EXT_HOST_VALID)
5388 self.vapi.nat44_del_session(
5389 address=sessions[0].inside_ip_address,
5390 port=sessions[0].inside_port,
5391 protocol=sessions[0].protocol,
5392 flags=(self.config_flags.NAT_IS_INSIDE |
5393 self.config_flags.NAT_IS_EXT_HOST_VALID),
5394 ext_host_address=sessions[0].ext_host_address,
5395 ext_host_port=sessions[0].ext_host_port)
5398 for port in range(1030, 1100):
5399 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5400 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5401 TCP(sport=port, dport=external_port))
5403 self.pg1.add_stream(pkts)
5404 self.pg_enable_capture(self.pg_interfaces)
5406 capture = self.pg0.get_capture(len(pkts))
5408 self.assertEqual(p[IP].dst, backend)
5410 def test_unknown_proto(self):
5411 """ NAT44 translate packet with unknown protocol """
5412 self.nat44_add_address(self.nat_addr)
5413 flags = self.config_flags.NAT_IS_INSIDE
5414 self.vapi.nat44_interface_add_del_feature(
5415 sw_if_index=self.pg0.sw_if_index,
5416 flags=flags, is_add=1)
5417 self.vapi.nat44_interface_add_del_feature(
5418 sw_if_index=self.pg1.sw_if_index,
5422 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5423 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5424 TCP(sport=self.tcp_port_in, dport=20))
5425 self.pg0.add_stream(p)
5426 self.pg_enable_capture(self.pg_interfaces)
5428 p = self.pg1.get_capture(1)
5430 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5431 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5433 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5434 TCP(sport=1234, dport=1234))
5435 self.pg0.add_stream(p)
5436 self.pg_enable_capture(self.pg_interfaces)
5438 p = self.pg1.get_capture(1)
5441 self.assertEqual(packet[IP].src, self.nat_addr)
5442 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5443 self.assertEqual(packet.haslayer(GRE), 1)
5444 self.assert_packet_checksums_valid(packet)
5446 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5450 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5451 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5453 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5454 TCP(sport=1234, dport=1234))
5455 self.pg1.add_stream(p)
5456 self.pg_enable_capture(self.pg_interfaces)
5458 p = self.pg0.get_capture(1)
5461 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5462 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5463 self.assertEqual(packet.haslayer(GRE), 1)
5464 self.assert_packet_checksums_valid(packet)
5466 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5469 def test_hairpinning_unknown_proto(self):
5470 """ NAT44 translate packet with unknown protocol - hairpinning """
5471 host = self.pg0.remote_hosts[0]
5472 server = self.pg0.remote_hosts[1]
5474 server_out_port = 8765
5475 server_nat_ip = "10.0.0.11"
5477 self.nat44_add_address(self.nat_addr)
5478 flags = self.config_flags.NAT_IS_INSIDE
5479 self.vapi.nat44_interface_add_del_feature(
5480 sw_if_index=self.pg0.sw_if_index,
5481 flags=flags, is_add=1)
5482 self.vapi.nat44_interface_add_del_feature(
5483 sw_if_index=self.pg1.sw_if_index,
5486 # add static mapping for server
5487 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5490 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5491 IP(src=host.ip4, dst=server_nat_ip) /
5492 TCP(sport=host_in_port, dport=server_out_port))
5493 self.pg0.add_stream(p)
5494 self.pg_enable_capture(self.pg_interfaces)
5496 self.pg0.get_capture(1)
5498 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5499 IP(src=host.ip4, dst=server_nat_ip) /
5501 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5502 TCP(sport=1234, dport=1234))
5503 self.pg0.add_stream(p)
5504 self.pg_enable_capture(self.pg_interfaces)
5506 p = self.pg0.get_capture(1)
5509 self.assertEqual(packet[IP].src, self.nat_addr)
5510 self.assertEqual(packet[IP].dst, server.ip4)
5511 self.assertEqual(packet.haslayer(GRE), 1)
5512 self.assert_packet_checksums_valid(packet)
5514 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5518 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5519 IP(src=server.ip4, dst=self.nat_addr) /
5521 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5522 TCP(sport=1234, dport=1234))
5523 self.pg0.add_stream(p)
5524 self.pg_enable_capture(self.pg_interfaces)
5526 p = self.pg0.get_capture(1)
5529 self.assertEqual(packet[IP].src, server_nat_ip)
5530 self.assertEqual(packet[IP].dst, host.ip4)
5531 self.assertEqual(packet.haslayer(GRE), 1)
5532 self.assert_packet_checksums_valid(packet)
5534 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5537 def test_output_feature_and_service(self):
5538 """ NAT44 interface output feature and services """
5539 external_addr = '1.2.3.4'
5543 self.vapi.nat44_forwarding_enable_disable(enable=1)
5544 self.nat44_add_address(self.nat_addr)
5545 flags = self.config_flags.NAT_IS_ADDR_ONLY
5546 self.vapi.nat44_add_del_identity_mapping(
5547 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5548 flags=flags, is_add=1)
5549 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5550 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5551 local_port, external_port,
5552 proto=IP_PROTOS.tcp, flags=flags)
5553 flags = self.config_flags.NAT_IS_INSIDE
5554 self.vapi.nat44_interface_add_del_feature(
5555 sw_if_index=self.pg0.sw_if_index,
5557 self.vapi.nat44_interface_add_del_feature(
5558 sw_if_index=self.pg0.sw_if_index,
5559 flags=flags, is_add=1)
5560 self.vapi.nat44_interface_add_del_output_feature(
5562 sw_if_index=self.pg1.sw_if_index)
5564 # from client to service
5565 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5566 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5567 TCP(sport=12345, dport=external_port))
5568 self.pg1.add_stream(p)
5569 self.pg_enable_capture(self.pg_interfaces)
5571 capture = self.pg0.get_capture(1)
5576 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5577 self.assertEqual(tcp.dport, local_port)
5578 self.assert_packet_checksums_valid(p)
5580 self.logger.error(ppp("Unexpected or invalid packet:", p))
5583 # from service back to client
5584 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5585 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5586 TCP(sport=local_port, dport=12345))
5587 self.pg0.add_stream(p)
5588 self.pg_enable_capture(self.pg_interfaces)
5590 capture = self.pg1.get_capture(1)
5595 self.assertEqual(ip.src, external_addr)
5596 self.assertEqual(tcp.sport, external_port)
5597 self.assert_packet_checksums_valid(p)
5599 self.logger.error(ppp("Unexpected or invalid packet:", p))
5602 # from local network host to external network
5603 pkts = self.create_stream_in(self.pg0, self.pg1)
5604 self.pg0.add_stream(pkts)
5605 self.pg_enable_capture(self.pg_interfaces)
5607 capture = self.pg1.get_capture(len(pkts))
5608 self.verify_capture_out(capture)
5609 pkts = self.create_stream_in(self.pg0, self.pg1)
5610 self.pg0.add_stream(pkts)
5611 self.pg_enable_capture(self.pg_interfaces)
5613 capture = self.pg1.get_capture(len(pkts))
5614 self.verify_capture_out(capture)
5616 # from external network back to local network host
5617 pkts = self.create_stream_out(self.pg1)
5618 self.pg1.add_stream(pkts)
5619 self.pg_enable_capture(self.pg_interfaces)
5621 capture = self.pg0.get_capture(len(pkts))
5622 self.verify_capture_in(capture, self.pg0)
5624 def test_output_feature_and_service2(self):
5625 """ NAT44 interface output feature and service host direct access """
5626 self.vapi.nat44_forwarding_enable_disable(enable=1)
5627 self.nat44_add_address(self.nat_addr)
5628 self.vapi.nat44_interface_add_del_output_feature(
5630 sw_if_index=self.pg1.sw_if_index)
5632 # session initiated from service host - translate
5633 pkts = self.create_stream_in(self.pg0, self.pg1)
5634 self.pg0.add_stream(pkts)
5635 self.pg_enable_capture(self.pg_interfaces)
5637 capture = self.pg1.get_capture(len(pkts))
5638 self.verify_capture_out(capture)
5640 pkts = self.create_stream_out(self.pg1)
5641 self.pg1.add_stream(pkts)
5642 self.pg_enable_capture(self.pg_interfaces)
5644 capture = self.pg0.get_capture(len(pkts))
5645 self.verify_capture_in(capture, self.pg0)
5647 # session initiated from remote host - do not translate
5648 self.tcp_port_in = 60303
5649 self.udp_port_in = 60304
5650 self.icmp_id_in = 60305
5651 pkts = self.create_stream_out(self.pg1,
5652 self.pg0.remote_ip4,
5653 use_inside_ports=True)
5654 self.pg1.add_stream(pkts)
5655 self.pg_enable_capture(self.pg_interfaces)
5657 capture = self.pg0.get_capture(len(pkts))
5658 self.verify_capture_in(capture, self.pg0)
5660 pkts = self.create_stream_in(self.pg0, self.pg1)
5661 self.pg0.add_stream(pkts)
5662 self.pg_enable_capture(self.pg_interfaces)
5664 capture = self.pg1.get_capture(len(pkts))
5665 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5668 def test_output_feature_and_service3(self):
5669 """ NAT44 interface output feature and DST NAT """
5670 external_addr = '1.2.3.4'
5674 self.vapi.nat44_forwarding_enable_disable(enable=1)
5675 self.nat44_add_address(self.nat_addr)
5676 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5677 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5678 local_port, external_port,
5679 proto=IP_PROTOS.tcp, flags=flags)
5680 flags = self.config_flags.NAT_IS_INSIDE
5681 self.vapi.nat44_interface_add_del_feature(
5682 sw_if_index=self.pg0.sw_if_index,
5684 self.vapi.nat44_interface_add_del_feature(
5685 sw_if_index=self.pg0.sw_if_index,
5686 flags=flags, is_add=1)
5687 self.vapi.nat44_interface_add_del_output_feature(
5689 sw_if_index=self.pg1.sw_if_index)
5691 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5692 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5693 TCP(sport=12345, dport=external_port))
5694 self.pg0.add_stream(p)
5695 self.pg_enable_capture(self.pg_interfaces)
5697 capture = self.pg1.get_capture(1)
5702 self.assertEqual(ip.src, self.pg0.remote_ip4)
5703 self.assertEqual(tcp.sport, 12345)
5704 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5705 self.assertEqual(tcp.dport, local_port)
5706 self.assert_packet_checksums_valid(p)
5708 self.logger.error(ppp("Unexpected or invalid packet:", p))
5711 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5712 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5713 TCP(sport=local_port, dport=12345))
5714 self.pg1.add_stream(p)
5715 self.pg_enable_capture(self.pg_interfaces)
5717 capture = self.pg0.get_capture(1)
5722 self.assertEqual(ip.src, external_addr)
5723 self.assertEqual(tcp.sport, external_port)
5724 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5725 self.assertEqual(tcp.dport, 12345)
5726 self.assert_packet_checksums_valid(p)
5728 self.logger.error(ppp("Unexpected or invalid packet:", p))
5731 def test_next_src_nat(self):
5732 """ On way back forward packet to nat44-in2out node. """
5733 twice_nat_addr = '10.0.1.3'
5736 post_twice_nat_port = 0
5738 self.vapi.nat44_forwarding_enable_disable(enable=1)
5739 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5740 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5741 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5742 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5743 local_port, external_port,
5744 proto=IP_PROTOS.tcp, vrf_id=1,
5746 self.vapi.nat44_interface_add_del_feature(
5747 sw_if_index=self.pg6.sw_if_index,
5750 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5751 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5752 TCP(sport=12345, dport=external_port))
5753 self.pg6.add_stream(p)
5754 self.pg_enable_capture(self.pg_interfaces)
5756 capture = self.pg6.get_capture(1)
5761 self.assertEqual(ip.src, twice_nat_addr)
5762 self.assertNotEqual(tcp.sport, 12345)
5763 post_twice_nat_port = tcp.sport
5764 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5765 self.assertEqual(tcp.dport, local_port)
5766 self.assert_packet_checksums_valid(p)
5768 self.logger.error(ppp("Unexpected or invalid packet:", p))
5771 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5772 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5773 TCP(sport=local_port, dport=post_twice_nat_port))
5774 self.pg6.add_stream(p)
5775 self.pg_enable_capture(self.pg_interfaces)
5777 capture = self.pg6.get_capture(1)
5782 self.assertEqual(ip.src, self.pg1.remote_ip4)
5783 self.assertEqual(tcp.sport, external_port)
5784 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5785 self.assertEqual(tcp.dport, 12345)
5786 self.assert_packet_checksums_valid(p)
5788 self.logger.error(ppp("Unexpected or invalid packet:", p))
5791 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5793 twice_nat_addr = '10.0.1.3'
5801 port_in1 = port_in + 1
5802 port_in2 = port_in + 2
5807 server1 = self.pg0.remote_hosts[0]
5808 server2 = self.pg0.remote_hosts[1]
5820 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5823 self.nat44_add_address(self.nat_addr)
5824 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5828 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5830 flags |= self.config_flags.NAT_IS_TWICE_NAT
5833 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5835 proto=IP_PROTOS.tcp,
5838 locals = [{'addr': server1.ip4,
5842 {'addr': server2.ip4,
5846 out_addr = self.nat_addr
5848 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5849 external_addr=out_addr,
5850 external_port=port_out,
5851 protocol=IP_PROTOS.tcp,
5852 local_num=len(locals),
5854 flags = self.config_flags.NAT_IS_INSIDE
5855 self.vapi.nat44_interface_add_del_feature(
5856 sw_if_index=pg0.sw_if_index,
5857 flags=flags, is_add=1)
5858 self.vapi.nat44_interface_add_del_feature(
5859 sw_if_index=pg1.sw_if_index,
5866 assert client_id is not None
5868 client = self.pg0.remote_hosts[0]
5869 elif client_id == 2:
5870 client = self.pg0.remote_hosts[1]
5872 client = pg1.remote_hosts[0]
5873 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5874 IP(src=client.ip4, dst=self.nat_addr) /
5875 TCP(sport=eh_port_out, dport=port_out))
5877 self.pg_enable_capture(self.pg_interfaces)
5879 capture = pg0.get_capture(1)
5885 if ip.dst == server1.ip4:
5891 self.assertEqual(ip.dst, server.ip4)
5893 self.assertIn(tcp.dport, [port_in1, port_in2])
5895 self.assertEqual(tcp.dport, port_in)
5897 self.assertEqual(ip.src, twice_nat_addr)
5898 self.assertNotEqual(tcp.sport, eh_port_out)
5900 self.assertEqual(ip.src, client.ip4)
5901 self.assertEqual(tcp.sport, eh_port_out)
5903 eh_port_in = tcp.sport
5904 saved_port_in = tcp.dport
5905 self.assert_packet_checksums_valid(p)
5907 self.logger.error(ppp("Unexpected or invalid packet:", p))
5910 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5911 IP(src=server.ip4, dst=eh_addr_in) /
5912 TCP(sport=saved_port_in, dport=eh_port_in))
5914 self.pg_enable_capture(self.pg_interfaces)
5916 capture = pg1.get_capture(1)
5921 self.assertEqual(ip.dst, client.ip4)
5922 self.assertEqual(ip.src, self.nat_addr)
5923 self.assertEqual(tcp.dport, eh_port_out)
5924 self.assertEqual(tcp.sport, port_out)
5925 self.assert_packet_checksums_valid(p)
5927 self.logger.error(ppp("Unexpected or invalid packet:", p))
5931 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5932 self.assertEqual(len(sessions), 1)
5933 self.assertTrue(sessions[0].flags &
5934 self.config_flags.NAT_IS_EXT_HOST_VALID)
5935 self.assertTrue(sessions[0].flags &
5936 self.config_flags.NAT_IS_TWICE_NAT)
5937 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5938 self.vapi.nat44_del_session(
5939 address=sessions[0].inside_ip_address,
5940 port=sessions[0].inside_port,
5941 protocol=sessions[0].protocol,
5942 flags=(self.config_flags.NAT_IS_INSIDE |
5943 self.config_flags.NAT_IS_EXT_HOST_VALID),
5944 ext_host_address=sessions[0].ext_host_nat_address,
5945 ext_host_port=sessions[0].ext_host_nat_port)
5946 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5947 self.assertEqual(len(sessions), 0)
5949 def test_twice_nat(self):
5951 self.twice_nat_common()
5953 def test_self_twice_nat_positive(self):
5954 """ Self Twice NAT44 (positive test) """
5955 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5957 def test_self_twice_nat_negative(self):
5958 """ Self Twice NAT44 (negative test) """
5959 self.twice_nat_common(self_twice_nat=True)
5961 def test_twice_nat_lb(self):
5962 """ Twice NAT44 local service load balancing """
5963 self.twice_nat_common(lb=True)
5965 def test_self_twice_nat_lb_positive(self):
5966 """ Self Twice NAT44 local service load balancing (positive test) """
5967 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5970 def test_self_twice_nat_lb_negative(self):
5971 """ Self Twice NAT44 local service load balancing (negative test) """
5972 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5975 def test_twice_nat_interface_addr(self):
5976 """ Acquire twice NAT44 addresses from interface """
5977 flags = self.config_flags.NAT_IS_TWICE_NAT
5978 self.vapi.nat44_add_del_interface_addr(
5980 sw_if_index=self.pg3.sw_if_index,
5983 # no address in NAT pool
5984 adresses = self.vapi.nat44_address_dump()
5985 self.assertEqual(0, len(adresses))
5987 # configure interface address and check NAT address pool
5988 self.pg3.config_ip4()
5989 adresses = self.vapi.nat44_address_dump()
5990 self.assertEqual(1, len(adresses))
5991 self.assertEqual(str(adresses[0].ip_address),
5993 self.assertEqual(adresses[0].flags, flags)
5995 # remove interface address and check NAT address pool
5996 self.pg3.unconfig_ip4()
5997 adresses = self.vapi.nat44_address_dump()
5998 self.assertEqual(0, len(adresses))
6000 def test_tcp_close(self):
6001 """ Close TCP session from inside network - output feature """
6002 self.vapi.nat44_forwarding_enable_disable(enable=1)
6003 self.nat44_add_address(self.pg1.local_ip4)
6004 twice_nat_addr = '10.0.1.3'
6005 service_ip = '192.168.16.150'
6006 self.nat44_add_address(twice_nat_addr, twice_nat=1)
6007 flags = self.config_flags.NAT_IS_INSIDE
6008 self.vapi.nat44_interface_add_del_feature(
6009 sw_if_index=self.pg0.sw_if_index,
6011 self.vapi.nat44_interface_add_del_feature(
6012 sw_if_index=self.pg0.sw_if_index,
6013 flags=flags, is_add=1)
6014 self.vapi.nat44_interface_add_del_output_feature(
6016 sw_if_index=self.pg1.sw_if_index)
6017 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6018 self.config_flags.NAT_IS_TWICE_NAT)
6019 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6023 proto=IP_PROTOS.tcp,
6025 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6026 start_sessnum = len(sessions)
6028 # SYN packet out->in
6029 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6030 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6031 TCP(sport=33898, dport=80, flags="S"))
6032 self.pg1.add_stream(p)
6033 self.pg_enable_capture(self.pg_interfaces)
6035 capture = self.pg0.get_capture(1)
6037 tcp_port = p[TCP].sport
6039 # SYN + ACK packet in->out
6040 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6041 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6042 TCP(sport=80, dport=tcp_port, flags="SA"))
6043 self.pg0.add_stream(p)
6044 self.pg_enable_capture(self.pg_interfaces)
6046 self.pg1.get_capture(1)
6048 # ACK packet out->in
6049 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6050 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6051 TCP(sport=33898, dport=80, flags="A"))
6052 self.pg1.add_stream(p)
6053 self.pg_enable_capture(self.pg_interfaces)
6055 self.pg0.get_capture(1)
6057 # FIN packet in -> out
6058 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6059 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6060 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6061 self.pg0.add_stream(p)
6062 self.pg_enable_capture(self.pg_interfaces)
6064 self.pg1.get_capture(1)
6066 # FIN+ACK packet out -> in
6067 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6068 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6069 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6070 self.pg1.add_stream(p)
6071 self.pg_enable_capture(self.pg_interfaces)
6073 self.pg0.get_capture(1)
6075 # ACK packet in -> out
6076 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6077 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6078 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6079 self.pg0.add_stream(p)
6080 self.pg_enable_capture(self.pg_interfaces)
6082 self.pg1.get_capture(1)
6084 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6086 self.assertEqual(len(sessions) - start_sessnum, 0)
6088 def test_tcp_session_close_in(self):
6089 """ Close TCP session from inside network """
6090 self.tcp_port_out = 10505
6091 self.nat44_add_address(self.nat_addr)
6092 flags = self.config_flags.NAT_IS_TWICE_NAT
6093 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6097 proto=IP_PROTOS.tcp,
6099 flags = self.config_flags.NAT_IS_INSIDE
6100 self.vapi.nat44_interface_add_del_feature(
6101 sw_if_index=self.pg0.sw_if_index,
6102 flags=flags, is_add=1)
6103 self.vapi.nat44_interface_add_del_feature(
6104 sw_if_index=self.pg1.sw_if_index,
6107 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6108 start_sessnum = len(sessions)
6110 self.initiate_tcp_session(self.pg0, self.pg1)
6112 # FIN packet in -> out
6113 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6114 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6115 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6116 flags="FA", seq=100, ack=300))
6117 self.pg0.add_stream(p)
6118 self.pg_enable_capture(self.pg_interfaces)
6120 self.pg1.get_capture(1)
6124 # ACK packet out -> in
6125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6126 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6127 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6128 flags="A", seq=300, ack=101))
6131 # FIN packet out -> in
6132 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6133 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6134 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6135 flags="FA", seq=300, ack=101))
6138 self.pg1.add_stream(pkts)
6139 self.pg_enable_capture(self.pg_interfaces)
6141 self.pg0.get_capture(2)
6143 # ACK packet in -> out
6144 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6145 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6146 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6147 flags="A", seq=101, ack=301))
6148 self.pg0.add_stream(p)
6149 self.pg_enable_capture(self.pg_interfaces)
6151 self.pg1.get_capture(1)
6153 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6155 self.assertEqual(len(sessions) - start_sessnum, 0)
6157 def test_tcp_session_close_out(self):
6158 """ Close TCP session from outside network """
6159 self.tcp_port_out = 10505
6160 self.nat44_add_address(self.nat_addr)
6161 flags = self.config_flags.NAT_IS_TWICE_NAT
6162 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6166 proto=IP_PROTOS.tcp,
6168 flags = self.config_flags.NAT_IS_INSIDE
6169 self.vapi.nat44_interface_add_del_feature(
6170 sw_if_index=self.pg0.sw_if_index,
6171 flags=flags, is_add=1)
6172 self.vapi.nat44_interface_add_del_feature(
6173 sw_if_index=self.pg1.sw_if_index,
6176 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6177 start_sessnum = len(sessions)
6179 self.initiate_tcp_session(self.pg0, self.pg1)
6181 # FIN packet out -> in
6182 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6183 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6184 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6185 flags="FA", seq=100, ack=300))
6186 self.pg1.add_stream(p)
6187 self.pg_enable_capture(self.pg_interfaces)
6189 self.pg0.get_capture(1)
6191 # FIN+ACK packet in -> out
6192 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6193 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6194 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6195 flags="FA", seq=300, ack=101))
6197 self.pg0.add_stream(p)
6198 self.pg_enable_capture(self.pg_interfaces)
6200 self.pg1.get_capture(1)
6202 # ACK packet out -> in
6203 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6204 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6205 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6206 flags="A", seq=101, ack=301))
6207 self.pg1.add_stream(p)
6208 self.pg_enable_capture(self.pg_interfaces)
6210 self.pg0.get_capture(1)
6212 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6214 self.assertEqual(len(sessions) - start_sessnum, 0)
6216 def test_tcp_session_close_simultaneous(self):
6217 """ Close TCP session from inside network """
6218 self.tcp_port_out = 10505
6219 self.nat44_add_address(self.nat_addr)
6220 flags = self.config_flags.NAT_IS_TWICE_NAT
6221 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6225 proto=IP_PROTOS.tcp,
6227 flags = self.config_flags.NAT_IS_INSIDE
6228 self.vapi.nat44_interface_add_del_feature(
6229 sw_if_index=self.pg0.sw_if_index,
6230 flags=flags, is_add=1)
6231 self.vapi.nat44_interface_add_del_feature(
6232 sw_if_index=self.pg1.sw_if_index,
6235 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6236 start_sessnum = len(sessions)
6238 self.initiate_tcp_session(self.pg0, self.pg1)
6240 # FIN packet in -> out
6241 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6242 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6243 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6244 flags="FA", seq=100, ack=300))
6245 self.pg0.add_stream(p)
6246 self.pg_enable_capture(self.pg_interfaces)
6248 self.pg1.get_capture(1)
6250 # FIN packet out -> in
6251 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6252 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6253 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6254 flags="FA", seq=300, ack=100))
6255 self.pg1.add_stream(p)
6256 self.pg_enable_capture(self.pg_interfaces)
6258 self.pg0.get_capture(1)
6260 # ACK packet in -> out
6261 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6262 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6263 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6264 flags="A", seq=101, ack=301))
6265 self.pg0.add_stream(p)
6266 self.pg_enable_capture(self.pg_interfaces)
6268 self.pg1.get_capture(1)
6270 # ACK packet out -> in
6271 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6272 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6273 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6274 flags="A", seq=301, ack=101))
6275 self.pg1.add_stream(p)
6276 self.pg_enable_capture(self.pg_interfaces)
6278 self.pg0.get_capture(1)
6280 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6282 self.assertEqual(len(sessions) - start_sessnum, 0)
6284 def test_one_armed_nat44_static(self):
6285 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6286 remote_host = self.pg4.remote_hosts[0]
6287 local_host = self.pg4.remote_hosts[1]
6292 self.vapi.nat44_forwarding_enable_disable(enable=1)
6293 self.nat44_add_address(self.nat_addr, twice_nat=1)
6294 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6295 self.config_flags.NAT_IS_TWICE_NAT)
6296 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6297 local_port, external_port,
6298 proto=IP_PROTOS.tcp, flags=flags)
6299 flags = self.config_flags.NAT_IS_INSIDE
6300 self.vapi.nat44_interface_add_del_feature(
6301 sw_if_index=self.pg4.sw_if_index,
6303 self.vapi.nat44_interface_add_del_feature(
6304 sw_if_index=self.pg4.sw_if_index,
6305 flags=flags, is_add=1)
6307 # from client to service
6308 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6309 IP(src=remote_host.ip4, dst=self.nat_addr) /
6310 TCP(sport=12345, dport=external_port))
6311 self.pg4.add_stream(p)
6312 self.pg_enable_capture(self.pg_interfaces)
6314 capture = self.pg4.get_capture(1)
6319 self.assertEqual(ip.dst, local_host.ip4)
6320 self.assertEqual(ip.src, self.nat_addr)
6321 self.assertEqual(tcp.dport, local_port)
6322 self.assertNotEqual(tcp.sport, 12345)
6323 eh_port_in = tcp.sport
6324 self.assert_packet_checksums_valid(p)
6326 self.logger.error(ppp("Unexpected or invalid packet:", p))
6329 # from service back to client
6330 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6331 IP(src=local_host.ip4, dst=self.nat_addr) /
6332 TCP(sport=local_port, dport=eh_port_in))
6333 self.pg4.add_stream(p)
6334 self.pg_enable_capture(self.pg_interfaces)
6336 capture = self.pg4.get_capture(1)
6341 self.assertEqual(ip.src, self.nat_addr)
6342 self.assertEqual(ip.dst, remote_host.ip4)
6343 self.assertEqual(tcp.sport, external_port)
6344 self.assertEqual(tcp.dport, 12345)
6345 self.assert_packet_checksums_valid(p)
6347 self.logger.error(ppp("Unexpected or invalid packet:", p))
6350 def test_static_with_port_out2(self):
6351 """ 1:1 NAPT asymmetrical rule """
6356 self.vapi.nat44_forwarding_enable_disable(enable=1)
6357 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6358 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6359 local_port, external_port,
6360 proto=IP_PROTOS.tcp, flags=flags)
6361 flags = self.config_flags.NAT_IS_INSIDE
6362 self.vapi.nat44_interface_add_del_feature(
6363 sw_if_index=self.pg0.sw_if_index,
6364 flags=flags, is_add=1)
6365 self.vapi.nat44_interface_add_del_feature(
6366 sw_if_index=self.pg1.sw_if_index,
6369 # from client to service
6370 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6371 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6372 TCP(sport=12345, dport=external_port))
6373 self.pg1.add_stream(p)
6374 self.pg_enable_capture(self.pg_interfaces)
6376 capture = self.pg0.get_capture(1)
6381 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6382 self.assertEqual(tcp.dport, local_port)
6383 self.assert_packet_checksums_valid(p)
6385 self.logger.error(ppp("Unexpected or invalid packet:", p))
6389 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6390 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6391 ICMP(type=11) / capture[0][IP])
6392 self.pg0.add_stream(p)
6393 self.pg_enable_capture(self.pg_interfaces)
6395 capture = self.pg1.get_capture(1)
6398 self.assertEqual(p[IP].src, self.nat_addr)
6400 self.assertEqual(inner.dst, self.nat_addr)
6401 self.assertEqual(inner[TCPerror].dport, external_port)
6403 self.logger.error(ppp("Unexpected or invalid packet:", p))
6406 # from service back to client
6407 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6408 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6409 TCP(sport=local_port, dport=12345))
6410 self.pg0.add_stream(p)
6411 self.pg_enable_capture(self.pg_interfaces)
6413 capture = self.pg1.get_capture(1)
6418 self.assertEqual(ip.src, self.nat_addr)
6419 self.assertEqual(tcp.sport, external_port)
6420 self.assert_packet_checksums_valid(p)
6422 self.logger.error(ppp("Unexpected or invalid packet:", p))
6426 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6427 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6428 ICMP(type=11) / capture[0][IP])
6429 self.pg1.add_stream(p)
6430 self.pg_enable_capture(self.pg_interfaces)
6432 capture = self.pg0.get_capture(1)
6435 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6437 self.assertEqual(inner.src, self.pg0.remote_ip4)
6438 self.assertEqual(inner[TCPerror].sport, local_port)
6440 self.logger.error(ppp("Unexpected or invalid packet:", p))
6443 # from client to server (no translation)
6444 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6445 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6446 TCP(sport=12346, dport=local_port))
6447 self.pg1.add_stream(p)
6448 self.pg_enable_capture(self.pg_interfaces)
6450 capture = self.pg0.get_capture(1)
6455 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6456 self.assertEqual(tcp.dport, local_port)
6457 self.assert_packet_checksums_valid(p)
6459 self.logger.error(ppp("Unexpected or invalid packet:", p))
6462 # from service back to client (no translation)
6463 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6464 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6465 TCP(sport=local_port, dport=12346))
6466 self.pg0.add_stream(p)
6467 self.pg_enable_capture(self.pg_interfaces)
6469 capture = self.pg1.get_capture(1)
6474 self.assertEqual(ip.src, self.pg0.remote_ip4)
6475 self.assertEqual(tcp.sport, local_port)
6476 self.assert_packet_checksums_valid(p)
6478 self.logger.error(ppp("Unexpected or invalid packet:", p))
6481 def test_output_feature(self):
6482 """ NAT44 interface output feature (in2out postrouting) """
6483 self.vapi.nat44_forwarding_enable_disable(enable=1)
6484 self.nat44_add_address(self.nat_addr)
6485 self.vapi.nat44_interface_add_del_feature(
6486 sw_if_index=self.pg0.sw_if_index,
6488 self.vapi.nat44_interface_add_del_output_feature(
6490 sw_if_index=self.pg1.sw_if_index)
6493 pkts = self.create_stream_in(self.pg0, self.pg1)
6494 self.pg0.add_stream(pkts)
6495 self.pg_enable_capture(self.pg_interfaces)
6497 capture = self.pg1.get_capture(len(pkts))
6498 self.verify_capture_out(capture)
6501 pkts = self.create_stream_out(self.pg1)
6502 self.pg1.add_stream(pkts)
6503 self.pg_enable_capture(self.pg_interfaces)
6505 capture = self.pg0.get_capture(len(pkts))
6506 self.verify_capture_in(capture, self.pg0)
6508 def test_multiple_vrf(self):
6509 """ Multiple VRF setup """
6510 external_addr = '1.2.3.4'
6515 self.vapi.nat44_forwarding_enable_disable(enable=1)
6516 self.nat44_add_address(self.nat_addr)
6517 flags = self.config_flags.NAT_IS_INSIDE
6518 self.vapi.nat44_interface_add_del_feature(
6519 sw_if_index=self.pg0.sw_if_index,
6521 self.vapi.nat44_interface_add_del_feature(
6522 sw_if_index=self.pg0.sw_if_index,
6523 flags=flags, is_add=1)
6524 self.vapi.nat44_interface_add_del_output_feature(
6526 sw_if_index=self.pg1.sw_if_index)
6527 self.vapi.nat44_interface_add_del_feature(
6528 sw_if_index=self.pg5.sw_if_index,
6530 self.vapi.nat44_interface_add_del_feature(
6531 sw_if_index=self.pg5.sw_if_index,
6532 flags=flags, is_add=1)
6533 self.vapi.nat44_interface_add_del_feature(
6534 sw_if_index=self.pg6.sw_if_index,
6536 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6537 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6538 local_port, external_port, vrf_id=1,
6539 proto=IP_PROTOS.tcp, flags=flags)
6540 self.nat44_add_static_mapping(
6541 self.pg0.remote_ip4,
6542 external_sw_if_index=self.pg0.sw_if_index,
6543 local_port=local_port,
6545 external_port=external_port,
6546 proto=IP_PROTOS.tcp,
6550 # from client to service (both VRF1)
6551 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6552 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6553 TCP(sport=12345, dport=external_port))
6554 self.pg6.add_stream(p)
6555 self.pg_enable_capture(self.pg_interfaces)
6557 capture = self.pg5.get_capture(1)
6562 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6563 self.assertEqual(tcp.dport, local_port)
6564 self.assert_packet_checksums_valid(p)
6566 self.logger.error(ppp("Unexpected or invalid packet:", p))
6569 # from service back to client (both VRF1)
6570 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6571 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6572 TCP(sport=local_port, dport=12345))
6573 self.pg5.add_stream(p)
6574 self.pg_enable_capture(self.pg_interfaces)
6576 capture = self.pg6.get_capture(1)
6581 self.assertEqual(ip.src, external_addr)
6582 self.assertEqual(tcp.sport, external_port)
6583 self.assert_packet_checksums_valid(p)
6585 self.logger.error(ppp("Unexpected or invalid packet:", p))
6588 # dynamic NAT from VRF1 to VRF0 (output-feature)
6589 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6590 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6591 TCP(sport=2345, dport=22))
6592 self.pg5.add_stream(p)
6593 self.pg_enable_capture(self.pg_interfaces)
6595 capture = self.pg1.get_capture(1)
6600 self.assertEqual(ip.src, self.nat_addr)
6601 self.assertNotEqual(tcp.sport, 2345)
6602 self.assert_packet_checksums_valid(p)
6605 self.logger.error(ppp("Unexpected or invalid packet:", p))
6608 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6609 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6610 TCP(sport=22, dport=port))
6611 self.pg1.add_stream(p)
6612 self.pg_enable_capture(self.pg_interfaces)
6614 capture = self.pg5.get_capture(1)
6619 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6620 self.assertEqual(tcp.dport, 2345)
6621 self.assert_packet_checksums_valid(p)
6623 self.logger.error(ppp("Unexpected or invalid packet:", p))
6626 # from client VRF1 to service VRF0
6627 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6628 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6629 TCP(sport=12346, dport=external_port))
6630 self.pg6.add_stream(p)
6631 self.pg_enable_capture(self.pg_interfaces)
6633 capture = self.pg0.get_capture(1)
6638 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6639 self.assertEqual(tcp.dport, local_port)
6640 self.assert_packet_checksums_valid(p)
6642 self.logger.error(ppp("Unexpected or invalid packet:", p))
6645 # from service VRF0 back to client VRF1
6646 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6647 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6648 TCP(sport=local_port, dport=12346))
6649 self.pg0.add_stream(p)
6650 self.pg_enable_capture(self.pg_interfaces)
6652 capture = self.pg6.get_capture(1)
6657 self.assertEqual(ip.src, self.pg0.local_ip4)
6658 self.assertEqual(tcp.sport, external_port)
6659 self.assert_packet_checksums_valid(p)
6661 self.logger.error(ppp("Unexpected or invalid packet:", p))
6664 # from client VRF0 to service VRF1
6665 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6666 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6667 TCP(sport=12347, dport=external_port))
6668 self.pg0.add_stream(p)
6669 self.pg_enable_capture(self.pg_interfaces)
6671 capture = self.pg5.get_capture(1)
6676 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6677 self.assertEqual(tcp.dport, local_port)
6678 self.assert_packet_checksums_valid(p)
6680 self.logger.error(ppp("Unexpected or invalid packet:", p))
6683 # from service VRF1 back to client VRF0
6684 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6685 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6686 TCP(sport=local_port, dport=12347))
6687 self.pg5.add_stream(p)
6688 self.pg_enable_capture(self.pg_interfaces)
6690 capture = self.pg0.get_capture(1)
6695 self.assertEqual(ip.src, external_addr)
6696 self.assertEqual(tcp.sport, external_port)
6697 self.assert_packet_checksums_valid(p)
6699 self.logger.error(ppp("Unexpected or invalid packet:", p))
6702 # from client to server (both VRF1, no translation)
6703 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6704 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6705 TCP(sport=12348, dport=local_port))
6706 self.pg6.add_stream(p)
6707 self.pg_enable_capture(self.pg_interfaces)
6709 capture = self.pg5.get_capture(1)
6714 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6715 self.assertEqual(tcp.dport, local_port)
6716 self.assert_packet_checksums_valid(p)
6718 self.logger.error(ppp("Unexpected or invalid packet:", p))
6721 # from server back to client (both VRF1, no translation)
6722 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6723 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6724 TCP(sport=local_port, dport=12348))
6725 self.pg5.add_stream(p)
6726 self.pg_enable_capture(self.pg_interfaces)
6728 capture = self.pg6.get_capture(1)
6733 self.assertEqual(ip.src, self.pg5.remote_ip4)
6734 self.assertEqual(tcp.sport, local_port)
6735 self.assert_packet_checksums_valid(p)
6737 self.logger.error(ppp("Unexpected or invalid packet:", p))
6740 # from client VRF1 to server VRF0 (no translation)
6741 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6742 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6743 TCP(sport=local_port, dport=12349))
6744 self.pg0.add_stream(p)
6745 self.pg_enable_capture(self.pg_interfaces)
6747 capture = self.pg6.get_capture(1)
6752 self.assertEqual(ip.src, self.pg0.remote_ip4)
6753 self.assertEqual(tcp.sport, local_port)
6754 self.assert_packet_checksums_valid(p)
6756 self.logger.error(ppp("Unexpected or invalid packet:", p))
6759 # from server VRF0 back to client VRF1 (no translation)
6760 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6761 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6762 TCP(sport=local_port, dport=12349))
6763 self.pg0.add_stream(p)
6764 self.pg_enable_capture(self.pg_interfaces)
6766 capture = self.pg6.get_capture(1)
6771 self.assertEqual(ip.src, self.pg0.remote_ip4)
6772 self.assertEqual(tcp.sport, local_port)
6773 self.assert_packet_checksums_valid(p)
6775 self.logger.error(ppp("Unexpected or invalid packet:", p))
6778 # from client VRF0 to server VRF1 (no translation)
6779 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6780 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6781 TCP(sport=12344, dport=local_port))
6782 self.pg0.add_stream(p)
6783 self.pg_enable_capture(self.pg_interfaces)
6785 capture = self.pg5.get_capture(1)
6790 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6791 self.assertEqual(tcp.dport, local_port)
6792 self.assert_packet_checksums_valid(p)
6794 self.logger.error(ppp("Unexpected or invalid packet:", p))
6797 # from server VRF1 back to client VRF0 (no translation)
6798 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6799 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6800 TCP(sport=local_port, dport=12344))
6801 self.pg5.add_stream(p)
6802 self.pg_enable_capture(self.pg_interfaces)
6804 capture = self.pg0.get_capture(1)
6809 self.assertEqual(ip.src, self.pg5.remote_ip4)
6810 self.assertEqual(tcp.sport, local_port)
6811 self.assert_packet_checksums_valid(p)
6813 self.logger.error(ppp("Unexpected or invalid packet:", p))
6816 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6817 def test_session_timeout(self):
6818 """ NAT44 session timeouts """
6819 self.nat44_add_address(self.nat_addr)
6820 flags = self.config_flags.NAT_IS_INSIDE
6821 self.vapi.nat44_interface_add_del_feature(
6822 sw_if_index=self.pg0.sw_if_index,
6823 flags=flags, is_add=1)
6824 self.vapi.nat44_interface_add_del_feature(
6825 sw_if_index=self.pg1.sw_if_index,
6827 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6828 tcp_transitory=240, icmp=5)
6832 for i in range(0, max_sessions):
6833 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6834 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6835 IP(src=src, dst=self.pg1.remote_ip4) /
6836 ICMP(id=1025, type='echo-request'))
6838 self.pg0.add_stream(pkts)
6839 self.pg_enable_capture(self.pg_interfaces)
6841 self.pg1.get_capture(max_sessions)
6846 for i in range(0, max_sessions):
6847 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6848 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6849 IP(src=src, dst=self.pg1.remote_ip4) /
6850 ICMP(id=1026, type='echo-request'))
6852 self.pg0.add_stream(pkts)
6853 self.pg_enable_capture(self.pg_interfaces)
6855 self.pg1.get_capture(max_sessions)
6858 users = self.vapi.nat44_user_dump()
6860 nsessions = nsessions + user.nsessions
6861 self.assertLess(nsessions, 2 * max_sessions)
6863 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6864 def test_session_rst_timeout(self):
6865 """ NAT44 session RST timeouts """
6866 self.nat44_add_address(self.nat_addr)
6867 flags = self.config_flags.NAT_IS_INSIDE
6868 self.vapi.nat44_interface_add_del_feature(
6869 sw_if_index=self.pg0.sw_if_index,
6870 flags=flags, is_add=1)
6871 self.vapi.nat44_interface_add_del_feature(
6872 sw_if_index=self.pg1.sw_if_index,
6874 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6875 tcp_transitory=5, icmp=60)
6877 self.initiate_tcp_session(self.pg0, self.pg1)
6878 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6879 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6880 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6882 self.pg0.add_stream(p)
6883 self.pg_enable_capture(self.pg_interfaces)
6885 self.pg1.get_capture(1)
6889 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6890 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6891 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6893 self.pg0.add_stream(p)
6894 self.pg_enable_capture(self.pg_interfaces)
6896 self.pg1.get_capture(1)
6899 users = self.vapi.nat44_user_dump()
6900 self.assertEqual(len(users), 1)
6901 self.assertEqual(str(users[0].ip_address),
6902 self.pg0.remote_ip4)
6903 self.assertEqual(users[0].nsessions, 1)
6905 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6906 def test_session_limit_per_user(self):
6907 """ Maximum sessions per user limit """
6908 self.nat44_add_address(self.nat_addr)
6909 flags = self.config_flags.NAT_IS_INSIDE
6910 self.vapi.nat44_interface_add_del_feature(
6911 sw_if_index=self.pg0.sw_if_index,
6912 flags=flags, is_add=1)
6913 self.vapi.nat44_interface_add_del_feature(
6914 sw_if_index=self.pg1.sw_if_index,
6916 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
6917 src_address=self.pg2.local_ip4,
6919 template_interval=10)
6920 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6921 tcp_transitory=240, icmp=60)
6923 # get maximum number of translations per user
6924 nat44_config = self.vapi.nat_show_config()
6927 for port in range(0, nat44_config.max_translations_per_user):
6928 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6929 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6930 UDP(sport=1025 + port, dport=1025 + port))
6933 self.pg0.add_stream(pkts)
6934 self.pg_enable_capture(self.pg_interfaces)
6936 capture = self.pg1.get_capture(len(pkts))
6938 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6939 src_port=self.ipfix_src_port,
6942 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6943 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6944 UDP(sport=3001, dport=3002))
6945 self.pg0.add_stream(p)
6946 self.pg_enable_capture(self.pg_interfaces)
6948 capture = self.pg1.assert_nothing_captured()
6950 # verify IPFIX logging
6951 self.vapi.ipfix_flush()
6953 capture = self.pg2.get_capture(10)
6954 ipfix = IPFIXDecoder()
6955 # first load template
6957 self.assertTrue(p.haslayer(IPFIX))
6958 if p.haslayer(Template):
6959 ipfix.add_template(p.getlayer(Template))
6960 # verify events in data set
6962 if p.haslayer(Data):
6963 data = ipfix.decode_data_set(p.getlayer(Set))
6964 self.verify_ipfix_max_entries_per_user(
6966 nat44_config.max_translations_per_user,
6967 self.pg0.remote_ip4)
6970 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6971 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6972 UDP(sport=3001, dport=3002))
6973 self.pg0.add_stream(p)
6974 self.pg_enable_capture(self.pg_interfaces)
6976 self.pg1.get_capture(1)
6978 def test_syslog_sess(self):
6979 """ Test syslog session creation and deletion """
6980 self.vapi.syslog_set_filter(
6981 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6982 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6983 self.nat44_add_address(self.nat_addr)
6984 flags = self.config_flags.NAT_IS_INSIDE
6985 self.vapi.nat44_interface_add_del_feature(
6986 sw_if_index=self.pg0.sw_if_index,
6987 flags=flags, is_add=1)
6988 self.vapi.nat44_interface_add_del_feature(
6989 sw_if_index=self.pg1.sw_if_index,
6992 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6993 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6994 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6995 self.pg0.add_stream(p)
6996 self.pg_enable_capture(self.pg_interfaces)
6998 capture = self.pg1.get_capture(1)
6999 self.tcp_port_out = capture[0][TCP].sport
7000 capture = self.pg2.get_capture(1)
7001 self.verify_syslog_sess(capture[0][Raw].load)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 self.nat44_add_address(self.nat_addr, is_add=0)
7006 capture = self.pg2.get_capture(1)
7007 self.verify_syslog_sess(capture[0][Raw].load, False)
7010 super(TestNAT44EndpointDependent, self).tearDown()
7011 if not self.vpp_dead:
7013 self.vapi.cli("clear logging")
7015 def show_commands_at_teardown(self):
7016 self.logger.info(self.vapi.cli("show nat44 addresses"))
7017 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7018 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7019 self.logger.info(self.vapi.cli("show nat44 interface address"))
7020 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7021 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7022 self.logger.info(self.vapi.cli("show nat timeouts"))
7025 class TestNAT44Out2InDPO(MethodHolder):
7026 """ NAT44 Test Cases using out2in DPO """
7029 def setUpConstants(cls):
7030 super(TestNAT44Out2InDPO, cls).setUpConstants()
7031 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7034 def setUpClass(cls):
7035 super(TestNAT44Out2InDPO, cls).setUpClass()
7036 cls.vapi.cli("set log class nat level debug")
7039 cls.tcp_port_in = 6303
7040 cls.tcp_port_out = 6303
7041 cls.udp_port_in = 6304
7042 cls.udp_port_out = 6304
7043 cls.icmp_id_in = 6305
7044 cls.icmp_id_out = 6305
7045 cls.nat_addr = '10.0.0.3'
7046 cls.dst_ip4 = '192.168.70.1'
7048 cls.create_pg_interfaces(range(2))
7051 cls.pg0.config_ip4()
7052 cls.pg0.resolve_arp()
7055 cls.pg1.config_ip6()
7056 cls.pg1.resolve_ndp()
7058 r1 = VppIpRoute(cls, "::", 0,
7059 [VppRoutePath(cls.pg1.remote_ip6,
7060 cls.pg1.sw_if_index)],
7065 super(TestNAT44Out2InDPO, cls).tearDownClass()
7069 def tearDownClass(cls):
7070 super(TestNAT44Out2InDPO, cls).tearDownClass()
7072 def configure_xlat(self):
7073 self.dst_ip6_pfx = '1:2:3::'
7074 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7076 self.dst_ip6_pfx_len = 96
7077 self.src_ip6_pfx = '4:5:6::'
7078 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7080 self.src_ip6_pfx_len = 96
7081 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7082 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7083 '\x00\x00\x00\x00', 0)
7085 @unittest.skip('Temporary disabled')
7086 def test_464xlat_ce(self):
7087 """ Test 464XLAT CE with NAT44 """
7089 nat_config = self.vapi.nat_show_config()
7090 self.assertEqual(1, nat_config.out2in_dpo)
7092 self.configure_xlat()
7094 flags = self.config_flags.NAT_IS_INSIDE
7095 self.vapi.nat44_interface_add_del_feature(
7096 sw_if_index=self.pg0.sw_if_index,
7097 flags=flags, is_add=1)
7098 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7099 last_ip_address=self.nat_addr_n,
7100 vrf_id=0xFFFFFFFF, is_add=1)
7102 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7103 self.dst_ip6_pfx_len)
7104 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7105 self.src_ip6_pfx_len)
7108 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7109 self.pg0.add_stream(pkts)
7110 self.pg_enable_capture(self.pg_interfaces)
7112 capture = self.pg1.get_capture(len(pkts))
7113 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7116 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7118 self.pg1.add_stream(pkts)
7119 self.pg_enable_capture(self.pg_interfaces)
7121 capture = self.pg0.get_capture(len(pkts))
7122 self.verify_capture_in(capture, self.pg0)
7124 self.vapi.nat44_interface_add_del_feature(
7125 sw_if_index=self.pg0.sw_if_index,
7127 self.vapi.nat44_add_del_address_range(
7128 first_ip_address=self.nat_addr_n,
7129 last_ip_address=self.nat_addr_n,
7132 @unittest.skip('Temporary disabled')
7133 def test_464xlat_ce_no_nat(self):
7134 """ Test 464XLAT CE without NAT44 """
7136 self.configure_xlat()
7138 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7139 self.dst_ip6_pfx_len)
7140 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7141 self.src_ip6_pfx_len)
7143 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7144 self.pg0.add_stream(pkts)
7145 self.pg_enable_capture(self.pg_interfaces)
7147 capture = self.pg1.get_capture(len(pkts))
7148 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7149 nat_ip=out_dst_ip6, same_port=True)
7151 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7152 self.pg1.add_stream(pkts)
7153 self.pg_enable_capture(self.pg_interfaces)
7155 capture = self.pg0.get_capture(len(pkts))
7156 self.verify_capture_in(capture, self.pg0)
7159 class TestDeterministicNAT(MethodHolder):
7160 """ Deterministic NAT Test Cases """
7163 def setUpConstants(cls):
7164 super(TestDeterministicNAT, cls).setUpConstants()
7165 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7168 def setUpClass(cls):
7169 super(TestDeterministicNAT, cls).setUpClass()
7170 cls.vapi.cli("set log class nat level debug")
7173 cls.tcp_port_in = 6303
7174 cls.tcp_external_port = 6303
7175 cls.udp_port_in = 6304
7176 cls.udp_external_port = 6304
7177 cls.icmp_id_in = 6305
7178 cls.nat_addr = '10.0.0.3'
7180 cls.create_pg_interfaces(range(3))
7181 cls.interfaces = list(cls.pg_interfaces)
7183 for i in cls.interfaces:
7188 cls.pg0.generate_remote_hosts(2)
7189 cls.pg0.configure_ipv4_neighbors()
7192 super(TestDeterministicNAT, cls).tearDownClass()
7196 def tearDownClass(cls):
7197 super(TestDeterministicNAT, cls).tearDownClass()
7199 def create_stream_in(self, in_if, out_if, ttl=64):
7201 Create packet stream for inside network
7203 :param in_if: Inside interface
7204 :param out_if: Outside interface
7205 :param ttl: TTL of generated packets
7209 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7210 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7211 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7215 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7216 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7217 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7221 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7222 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7223 ICMP(id=self.icmp_id_in, type='echo-request'))
7228 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7230 Create packet stream for outside network
7232 :param out_if: Outside interface
7233 :param dst_ip: Destination IP address (Default use global NAT address)
7234 :param ttl: TTL of generated packets
7237 dst_ip = self.nat_addr
7240 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7241 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7242 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7246 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7247 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7248 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7252 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7253 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7254 ICMP(id=self.icmp_external_id, type='echo-reply'))
7259 def verify_capture_out(self, capture, nat_ip=None):
7261 Verify captured packets on outside network
7263 :param capture: Captured packets
7264 :param nat_ip: Translated IP address (Default use global NAT address)
7265 :param same_port: Source port number is not translated (Default False)
7268 nat_ip = self.nat_addr
7269 for packet in capture:
7271 self.assertEqual(packet[IP].src, nat_ip)
7272 if packet.haslayer(TCP):
7273 self.tcp_port_out = packet[TCP].sport
7274 elif packet.haslayer(UDP):
7275 self.udp_port_out = packet[UDP].sport
7277 self.icmp_external_id = packet[ICMP].id
7279 self.logger.error(ppp("Unexpected or invalid packet "
7280 "(outside network):", packet))
7283 def test_deterministic_mode(self):
7284 """ NAT plugin run deterministic mode """
7285 in_addr = '172.16.255.0'
7286 out_addr = '172.17.255.50'
7287 in_addr_t = '172.16.255.20'
7291 nat_config = self.vapi.nat_show_config()
7292 self.assertEqual(1, nat_config.deterministic)
7294 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7295 in_plen=in_plen, out_addr=out_addr,
7298 rep1 = self.vapi.nat_det_forward(in_addr_t)
7299 self.assertEqual(str(rep1.out_addr), out_addr)
7300 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7302 self.assertEqual(str(rep2.in_addr), in_addr_t)
7304 deterministic_mappings = self.vapi.nat_det_map_dump()
7305 self.assertEqual(len(deterministic_mappings), 1)
7306 dsm = deterministic_mappings[0]
7307 self.assertEqual(in_addr, str(dsm.in_addr))
7308 self.assertEqual(in_plen, dsm.in_plen)
7309 self.assertEqual(out_addr, str(dsm.out_addr))
7310 self.assertEqual(out_plen, dsm.out_plen)
7312 self.clear_nat_det()
7313 deterministic_mappings = self.vapi.nat_det_map_dump()
7314 self.assertEqual(len(deterministic_mappings), 0)
7316 def test_set_timeouts(self):
7317 """ Set deterministic NAT timeouts """
7318 timeouts_before = self.vapi.nat_get_timeouts()
7320 self.vapi.nat_set_timeouts(
7321 udp=timeouts_before.udp + 10,
7322 tcp_established=timeouts_before.tcp_established + 10,
7323 tcp_transitory=timeouts_before.tcp_transitory + 10,
7324 icmp=timeouts_before.icmp + 10)
7326 timeouts_after = self.vapi.nat_get_timeouts()
7328 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7329 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7330 self.assertNotEqual(timeouts_before.tcp_established,
7331 timeouts_after.tcp_established)
7332 self.assertNotEqual(timeouts_before.tcp_transitory,
7333 timeouts_after.tcp_transitory)
7335 def test_det_in(self):
7336 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7338 nat_ip = "10.0.0.10"
7340 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7342 out_addr=socket.inet_aton(nat_ip),
7345 flags = self.config_flags.NAT_IS_INSIDE
7346 self.vapi.nat44_interface_add_del_feature(
7347 sw_if_index=self.pg0.sw_if_index,
7348 flags=flags, is_add=1)
7349 self.vapi.nat44_interface_add_del_feature(
7350 sw_if_index=self.pg1.sw_if_index,
7354 pkts = self.create_stream_in(self.pg0, self.pg1)
7355 self.pg0.add_stream(pkts)
7356 self.pg_enable_capture(self.pg_interfaces)
7358 capture = self.pg1.get_capture(len(pkts))
7359 self.verify_capture_out(capture, nat_ip)
7362 pkts = self.create_stream_out(self.pg1, nat_ip)
7363 self.pg1.add_stream(pkts)
7364 self.pg_enable_capture(self.pg_interfaces)
7366 capture = self.pg0.get_capture(len(pkts))
7367 self.verify_capture_in(capture, self.pg0)
7370 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7371 self.assertEqual(len(sessions), 3)
7375 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7376 self.assertEqual(s.in_port, self.tcp_port_in)
7377 self.assertEqual(s.out_port, self.tcp_port_out)
7378 self.assertEqual(s.ext_port, self.tcp_external_port)
7382 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7383 self.assertEqual(s.in_port, self.udp_port_in)
7384 self.assertEqual(s.out_port, self.udp_port_out)
7385 self.assertEqual(s.ext_port, self.udp_external_port)
7389 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7390 self.assertEqual(s.in_port, self.icmp_id_in)
7391 self.assertEqual(s.out_port, self.icmp_external_id)
7393 def test_multiple_users(self):
7394 """ Deterministic NAT multiple users """
7396 nat_ip = "10.0.0.10"
7398 external_port = 6303
7400 host0 = self.pg0.remote_hosts[0]
7401 host1 = self.pg0.remote_hosts[1]
7403 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7404 out_addr=socket.inet_aton(nat_ip),
7406 flags = self.config_flags.NAT_IS_INSIDE
7407 self.vapi.nat44_interface_add_del_feature(
7408 sw_if_index=self.pg0.sw_if_index,
7409 flags=flags, is_add=1)
7410 self.vapi.nat44_interface_add_del_feature(
7411 sw_if_index=self.pg1.sw_if_index,
7415 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7416 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7417 TCP(sport=port_in, dport=external_port))
7418 self.pg0.add_stream(p)
7419 self.pg_enable_capture(self.pg_interfaces)
7421 capture = self.pg1.get_capture(1)
7426 self.assertEqual(ip.src, nat_ip)
7427 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7428 self.assertEqual(tcp.dport, external_port)
7429 port_out0 = tcp.sport
7431 self.logger.error(ppp("Unexpected or invalid packet:", p))
7435 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7436 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7437 TCP(sport=port_in, dport=external_port))
7438 self.pg0.add_stream(p)
7439 self.pg_enable_capture(self.pg_interfaces)
7441 capture = self.pg1.get_capture(1)
7446 self.assertEqual(ip.src, nat_ip)
7447 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7448 self.assertEqual(tcp.dport, external_port)
7449 port_out1 = tcp.sport
7451 self.logger.error(ppp("Unexpected or invalid packet:", p))
7454 dms = self.vapi.nat_det_map_dump()
7455 self.assertEqual(1, len(dms))
7456 self.assertEqual(2, dms[0].ses_num)
7459 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7460 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7461 TCP(sport=external_port, dport=port_out0))
7462 self.pg1.add_stream(p)
7463 self.pg_enable_capture(self.pg_interfaces)
7465 capture = self.pg0.get_capture(1)
7470 self.assertEqual(ip.src, self.pg1.remote_ip4)
7471 self.assertEqual(ip.dst, host0.ip4)
7472 self.assertEqual(tcp.dport, port_in)
7473 self.assertEqual(tcp.sport, external_port)
7475 self.logger.error(ppp("Unexpected or invalid packet:", p))
7479 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7480 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7481 TCP(sport=external_port, dport=port_out1))
7482 self.pg1.add_stream(p)
7483 self.pg_enable_capture(self.pg_interfaces)
7485 capture = self.pg0.get_capture(1)
7490 self.assertEqual(ip.src, self.pg1.remote_ip4)
7491 self.assertEqual(ip.dst, host1.ip4)
7492 self.assertEqual(tcp.dport, port_in)
7493 self.assertEqual(tcp.sport, external_port)
7495 self.logger.error(ppp("Unexpected or invalid packet", p))
7498 # session close api test
7499 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7501 self.pg1.remote_ip4,
7503 dms = self.vapi.nat_det_map_dump()
7504 self.assertEqual(dms[0].ses_num, 1)
7506 self.vapi.nat_det_close_session_in(host0.ip4,
7508 self.pg1.remote_ip4,
7510 dms = self.vapi.nat_det_map_dump()
7511 self.assertEqual(dms[0].ses_num, 0)
7513 def test_tcp_session_close_detection_in(self):
7514 """ Deterministic NAT TCP session close from inside network """
7515 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7517 out_addr=socket.inet_aton(self.nat_addr),
7519 flags = self.config_flags.NAT_IS_INSIDE
7520 self.vapi.nat44_interface_add_del_feature(
7521 sw_if_index=self.pg0.sw_if_index,
7522 flags=flags, is_add=1)
7523 self.vapi.nat44_interface_add_del_feature(
7524 sw_if_index=self.pg1.sw_if_index,
7527 self.initiate_tcp_session(self.pg0, self.pg1)
7529 # close the session from inside
7531 # FIN packet in -> out
7532 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7533 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7534 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7536 self.pg0.add_stream(p)
7537 self.pg_enable_capture(self.pg_interfaces)
7539 self.pg1.get_capture(1)
7543 # ACK packet out -> in
7544 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7545 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7546 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7550 # FIN packet out -> in
7551 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7552 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7553 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7557 self.pg1.add_stream(pkts)
7558 self.pg_enable_capture(self.pg_interfaces)
7560 self.pg0.get_capture(2)
7562 # ACK packet in -> out
7563 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7564 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7565 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7567 self.pg0.add_stream(p)
7568 self.pg_enable_capture(self.pg_interfaces)
7570 self.pg1.get_capture(1)
7572 # Check if deterministic NAT44 closed the session
7573 dms = self.vapi.nat_det_map_dump()
7574 self.assertEqual(0, dms[0].ses_num)
7576 self.logger.error("TCP session termination failed")
7579 def test_tcp_session_close_detection_out(self):
7580 """ Deterministic NAT TCP session close from outside network """
7581 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7583 out_addr=socket.inet_aton(self.nat_addr),
7585 flags = self.config_flags.NAT_IS_INSIDE
7586 self.vapi.nat44_interface_add_del_feature(
7587 sw_if_index=self.pg0.sw_if_index,
7588 flags=flags, is_add=1)
7589 self.vapi.nat44_interface_add_del_feature(
7590 sw_if_index=self.pg1.sw_if_index,
7593 self.initiate_tcp_session(self.pg0, self.pg1)
7595 # close the session from outside
7597 # FIN packet out -> in
7598 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7599 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7600 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7602 self.pg1.add_stream(p)
7603 self.pg_enable_capture(self.pg_interfaces)
7605 self.pg0.get_capture(1)
7609 # ACK packet in -> out
7610 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7611 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7612 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7616 # ACK packet in -> out
7617 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7618 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7619 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7623 self.pg0.add_stream(pkts)
7624 self.pg_enable_capture(self.pg_interfaces)
7626 self.pg1.get_capture(2)
7628 # ACK packet out -> in
7629 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7630 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7631 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7633 self.pg1.add_stream(p)
7634 self.pg_enable_capture(self.pg_interfaces)
7636 self.pg0.get_capture(1)
7638 # Check if deterministic NAT44 closed the session
7639 dms = self.vapi.nat_det_map_dump()
7640 self.assertEqual(0, dms[0].ses_num)
7642 self.logger.error("TCP session termination failed")
7645 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7646 def test_session_timeout(self):
7647 """ Deterministic NAT session timeouts """
7648 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7650 out_addr=socket.inet_aton(self.nat_addr),
7652 flags = self.config_flags.NAT_IS_INSIDE
7653 self.vapi.nat44_interface_add_del_feature(
7654 sw_if_index=self.pg0.sw_if_index,
7655 flags=flags, is_add=1)
7656 self.vapi.nat44_interface_add_del_feature(
7657 sw_if_index=self.pg1.sw_if_index,
7660 self.initiate_tcp_session(self.pg0, self.pg1)
7661 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7663 pkts = self.create_stream_in(self.pg0, self.pg1)
7664 self.pg0.add_stream(pkts)
7665 self.pg_enable_capture(self.pg_interfaces)
7667 capture = self.pg1.get_capture(len(pkts))
7670 dms = self.vapi.nat_det_map_dump()
7671 self.assertEqual(0, dms[0].ses_num)
7673 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7674 def test_session_limit_per_user(self):
7675 """ Deterministic NAT maximum sessions per user limit """
7676 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7678 out_addr=socket.inet_aton(self.nat_addr),
7680 flags = self.config_flags.NAT_IS_INSIDE
7681 self.vapi.nat44_interface_add_del_feature(
7682 sw_if_index=self.pg0.sw_if_index,
7683 flags=flags, is_add=1)
7684 self.vapi.nat44_interface_add_del_feature(
7685 sw_if_index=self.pg1.sw_if_index,
7687 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7688 src_address=self.pg2.local_ip4,
7690 template_interval=10)
7691 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7695 for port in range(1025, 2025):
7696 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7697 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7698 UDP(sport=port, dport=port))
7701 self.pg0.add_stream(pkts)
7702 self.pg_enable_capture(self.pg_interfaces)
7704 capture = self.pg1.get_capture(len(pkts))
7706 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7707 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7708 UDP(sport=3001, dport=3002))
7709 self.pg0.add_stream(p)
7710 self.pg_enable_capture(self.pg_interfaces)
7712 capture = self.pg1.assert_nothing_captured()
7714 # verify ICMP error packet
7715 capture = self.pg0.get_capture(1)
7717 self.assertTrue(p.haslayer(ICMP))
7719 self.assertEqual(icmp.type, 3)
7720 self.assertEqual(icmp.code, 1)
7721 self.assertTrue(icmp.haslayer(IPerror))
7722 inner_ip = icmp[IPerror]
7723 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7724 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7726 dms = self.vapi.nat_det_map_dump()
7728 self.assertEqual(1000, dms[0].ses_num)
7730 # verify IPFIX logging
7731 self.vapi.ipfix_flush()
7733 capture = self.pg2.get_capture(2)
7734 ipfix = IPFIXDecoder()
7735 # first load template
7737 self.assertTrue(p.haslayer(IPFIX))
7738 if p.haslayer(Template):
7739 ipfix.add_template(p.getlayer(Template))
7740 # verify events in data set
7742 if p.haslayer(Data):
7743 data = ipfix.decode_data_set(p.getlayer(Set))
7744 self.verify_ipfix_max_entries_per_user(data,
7746 self.pg0.remote_ip4)
7748 def clear_nat_det(self):
7750 Clear deterministic NAT configuration.
7752 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7754 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7755 tcp_transitory=240, icmp=60)
7756 deterministic_mappings = self.vapi.nat_det_map_dump()
7757 for dsm in deterministic_mappings:
7758 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7759 in_plen=dsm.in_plen,
7760 out_addr=dsm.out_addr,
7761 out_plen=dsm.out_plen)
7763 interfaces = self.vapi.nat44_interface_dump()
7764 for intf in interfaces:
7765 self.vapi.nat44_interface_add_del_feature(
7766 sw_if_index=intf.sw_if_index,
7770 super(TestDeterministicNAT, self).tearDown()
7771 if not self.vpp_dead:
7772 self.clear_nat_det()
7774 def show_commands_at_teardown(self):
7775 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7776 self.logger.info(self.vapi.cli("show nat timeouts"))
7778 self.vapi.cli("show nat44 deterministic mappings"))
7780 self.vapi.cli("show nat44 deterministic sessions"))
7783 class TestNAT64(MethodHolder):
7784 """ NAT64 Test Cases """
7787 def setUpConstants(cls):
7788 super(TestNAT64, cls).setUpConstants()
7789 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7790 "nat64 st hash buckets 256", "}"])
7793 def setUpClass(cls):
7794 super(TestNAT64, cls).setUpClass()
7797 cls.tcp_port_in = 6303
7798 cls.tcp_port_out = 6303
7799 cls.udp_port_in = 6304
7800 cls.udp_port_out = 6304
7801 cls.icmp_id_in = 6305
7802 cls.icmp_id_out = 6305
7803 cls.tcp_external_port = 80
7804 cls.nat_addr = '10.0.0.3'
7805 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7807 cls.vrf1_nat_addr = '10.0.10.3'
7808 cls.ipfix_src_port = 4739
7809 cls.ipfix_domain_id = 1
7811 cls.create_pg_interfaces(range(6))
7812 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7813 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7814 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7816 cls.vapi.ip_table_add_del(is_add=1,
7817 table={'table_id': cls.vrf1_id,
7820 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7822 cls.pg0.generate_remote_hosts(2)
7824 for i in cls.ip6_interfaces:
7827 i.configure_ipv6_neighbors()
7829 for i in cls.ip4_interfaces:
7835 cls.pg3.config_ip4()
7836 cls.pg3.resolve_arp()
7837 cls.pg3.config_ip6()
7838 cls.pg3.configure_ipv6_neighbors()
7841 cls.pg5.config_ip6()
7844 super(TestNAT64, cls).tearDownClass()
7848 def tearDownClass(cls):
7849 super(TestNAT64, cls).tearDownClass()
7851 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7852 """ NAT64 inside interface handles Neighbor Advertisement """
7854 flags = self.config_flags.NAT_IS_INSIDE
7855 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7856 sw_if_index=self.pg5.sw_if_index)
7859 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7860 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7861 ICMPv6EchoRequest())
7863 self.pg5.add_stream(pkts)
7864 self.pg_enable_capture(self.pg_interfaces)
7867 # Wait for Neighbor Solicitation
7868 capture = self.pg5.get_capture(len(pkts))
7871 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7872 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7873 tgt = packet[ICMPv6ND_NS].tgt
7875 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7878 # Send Neighbor Advertisement
7879 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7880 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7881 ICMPv6ND_NA(tgt=tgt) /
7882 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7884 self.pg5.add_stream(pkts)
7885 self.pg_enable_capture(self.pg_interfaces)
7888 # Try to send ping again
7890 self.pg5.add_stream(pkts)
7891 self.pg_enable_capture(self.pg_interfaces)
7894 # Wait for ping reply
7895 capture = self.pg5.get_capture(len(pkts))
7898 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7899 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7900 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7902 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7905 def test_pool(self):
7906 """ Add/delete address to NAT64 pool """
7907 nat_addr = '1.2.3.4'
7909 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7911 vrf_id=0xFFFFFFFF, is_add=1)
7913 addresses = self.vapi.nat64_pool_addr_dump()
7914 self.assertEqual(len(addresses), 1)
7915 self.assertEqual(str(addresses[0].address), nat_addr)
7917 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7919 vrf_id=0xFFFFFFFF, is_add=0)
7921 addresses = self.vapi.nat64_pool_addr_dump()
7922 self.assertEqual(len(addresses), 0)
7924 def test_interface(self):
7925 """ Enable/disable NAT64 feature on the interface """
7926 flags = self.config_flags.NAT_IS_INSIDE
7927 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7928 sw_if_index=self.pg0.sw_if_index)
7929 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7930 sw_if_index=self.pg1.sw_if_index)
7932 interfaces = self.vapi.nat64_interface_dump()
7933 self.assertEqual(len(interfaces), 2)
7936 for intf in interfaces:
7937 if intf.sw_if_index == self.pg0.sw_if_index:
7938 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7940 elif intf.sw_if_index == self.pg1.sw_if_index:
7941 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7943 self.assertTrue(pg0_found)
7944 self.assertTrue(pg1_found)
7946 features = self.vapi.cli("show interface features pg0")
7947 self.assertIn('nat64-in2out', features)
7948 features = self.vapi.cli("show interface features pg1")
7949 self.assertIn('nat64-out2in', features)
7951 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7952 sw_if_index=self.pg0.sw_if_index)
7953 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7954 sw_if_index=self.pg1.sw_if_index)
7956 interfaces = self.vapi.nat64_interface_dump()
7957 self.assertEqual(len(interfaces), 0)
7959 def test_static_bib(self):
7960 """ Add/delete static BIB entry """
7961 in_addr = '2001:db8:85a3::8a2e:370:7334'
7962 out_addr = '10.1.1.3'
7965 proto = IP_PROTOS.tcp
7967 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7968 i_port=in_port, o_port=out_port,
7969 proto=proto, vrf_id=0, is_add=1)
7970 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7973 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7975 self.assertEqual(str(bibe.i_addr), in_addr)
7976 self.assertEqual(str(bibe.o_addr), out_addr)
7977 self.assertEqual(bibe.i_port, in_port)
7978 self.assertEqual(bibe.o_port, out_port)
7979 self.assertEqual(static_bib_num, 1)
7980 bibs = self.statistics.get_counter('/nat64/total-bibs')
7981 self.assertEqual(bibs[0][0], 1)
7983 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7984 i_port=in_port, o_port=out_port,
7985 proto=proto, vrf_id=0, is_add=0)
7986 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7989 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7991 self.assertEqual(static_bib_num, 0)
7992 bibs = self.statistics.get_counter('/nat64/total-bibs')
7993 self.assertEqual(bibs[0][0], 0)
7995 def test_set_timeouts(self):
7996 """ Set NAT64 timeouts """
7997 # verify default values
7998 timeouts = self.vapi.nat_get_timeouts()
7999 self.assertEqual(timeouts.udp, 300)
8000 self.assertEqual(timeouts.icmp, 60)
8001 self.assertEqual(timeouts.tcp_transitory, 240)
8002 self.assertEqual(timeouts.tcp_established, 7440)
8004 # set and verify custom values
8005 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
8006 tcp_transitory=250, icmp=30)
8007 timeouts = self.vapi.nat_get_timeouts()
8008 self.assertEqual(timeouts.udp, 200)
8009 self.assertEqual(timeouts.icmp, 30)
8010 self.assertEqual(timeouts.tcp_transitory, 250)
8011 self.assertEqual(timeouts.tcp_established, 7450)
8013 def test_dynamic(self):
8014 """ NAT64 dynamic translation test """
8015 self.tcp_port_in = 6303
8016 self.udp_port_in = 6304
8017 self.icmp_id_in = 6305
8019 ses_num_start = self.nat64_get_ses_num()
8021 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8022 end_addr=self.nat_addr,
8025 flags = self.config_flags.NAT_IS_INSIDE
8026 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8027 sw_if_index=self.pg0.sw_if_index)
8028 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8029 sw_if_index=self.pg1.sw_if_index)
8032 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8033 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8034 icmpn = self.statistics.get_err_counter(
8035 '/err/nat64-in2out/ICMP packets')
8036 totaln = self.statistics.get_err_counter(
8037 '/err/nat64-in2out/good in2out packets processed')
8039 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8040 self.pg0.add_stream(pkts)
8041 self.pg_enable_capture(self.pg_interfaces)
8043 capture = self.pg1.get_capture(len(pkts))
8044 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8045 dst_ip=self.pg1.remote_ip4)
8047 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8048 self.assertEqual(err - tcpn, 1)
8049 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8050 self.assertEqual(err - udpn, 1)
8051 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8052 self.assertEqual(err - icmpn, 1)
8053 err = self.statistics.get_err_counter(
8054 '/err/nat64-in2out/good in2out packets processed')
8055 self.assertEqual(err - totaln, 3)
8058 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8059 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8060 icmpn = self.statistics.get_err_counter(
8061 '/err/nat64-out2in/ICMP packets')
8062 totaln = self.statistics.get_err_counter(
8063 '/err/nat64-out2in/good out2in packets processed')
8065 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8066 self.pg1.add_stream(pkts)
8067 self.pg_enable_capture(self.pg_interfaces)
8069 capture = self.pg0.get_capture(len(pkts))
8070 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8071 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8073 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8074 self.assertEqual(err - tcpn, 2)
8075 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8076 self.assertEqual(err - udpn, 1)
8077 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8078 self.assertEqual(err - icmpn, 1)
8079 err = self.statistics.get_err_counter(
8080 '/err/nat64-out2in/good out2in packets processed')
8081 self.assertEqual(err - totaln, 4)
8083 bibs = self.statistics.get_counter('/nat64/total-bibs')
8084 self.assertEqual(bibs[0][0], 3)
8085 sessions = self.statistics.get_counter('/nat64/total-sessions')
8086 self.assertEqual(sessions[0][0], 3)
8089 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8090 self.pg0.add_stream(pkts)
8091 self.pg_enable_capture(self.pg_interfaces)
8093 capture = self.pg1.get_capture(len(pkts))
8094 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8095 dst_ip=self.pg1.remote_ip4)
8098 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8099 self.pg1.add_stream(pkts)
8100 self.pg_enable_capture(self.pg_interfaces)
8102 capture = self.pg0.get_capture(len(pkts))
8103 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8105 ses_num_end = self.nat64_get_ses_num()
8107 self.assertEqual(ses_num_end - ses_num_start, 3)
8109 # tenant with specific VRF
8110 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8111 end_addr=self.vrf1_nat_addr,
8112 vrf_id=self.vrf1_id, is_add=1)
8113 flags = self.config_flags.NAT_IS_INSIDE
8114 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8115 sw_if_index=self.pg2.sw_if_index)
8117 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8118 self.pg2.add_stream(pkts)
8119 self.pg_enable_capture(self.pg_interfaces)
8121 capture = self.pg1.get_capture(len(pkts))
8122 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8123 dst_ip=self.pg1.remote_ip4)
8125 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8126 self.pg1.add_stream(pkts)
8127 self.pg_enable_capture(self.pg_interfaces)
8129 capture = self.pg2.get_capture(len(pkts))
8130 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8132 def test_static(self):
8133 """ NAT64 static translation test """
8134 self.tcp_port_in = 60303
8135 self.udp_port_in = 60304
8136 self.icmp_id_in = 60305
8137 self.tcp_port_out = 60303
8138 self.udp_port_out = 60304
8139 self.icmp_id_out = 60305
8141 ses_num_start = self.nat64_get_ses_num()
8143 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8144 end_addr=self.nat_addr,
8147 flags = self.config_flags.NAT_IS_INSIDE
8148 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8149 sw_if_index=self.pg0.sw_if_index)
8150 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8151 sw_if_index=self.pg1.sw_if_index)
8153 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8154 o_addr=self.nat_addr,
8155 i_port=self.tcp_port_in,
8156 o_port=self.tcp_port_out,
8157 proto=IP_PROTOS.tcp, vrf_id=0,
8159 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8160 o_addr=self.nat_addr,
8161 i_port=self.udp_port_in,
8162 o_port=self.udp_port_out,
8163 proto=IP_PROTOS.udp, vrf_id=0,
8165 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8166 o_addr=self.nat_addr,
8167 i_port=self.icmp_id_in,
8168 o_port=self.icmp_id_out,
8169 proto=IP_PROTOS.icmp, vrf_id=0,
8173 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8174 self.pg0.add_stream(pkts)
8175 self.pg_enable_capture(self.pg_interfaces)
8177 capture = self.pg1.get_capture(len(pkts))
8178 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8179 dst_ip=self.pg1.remote_ip4, same_port=True)
8182 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8183 self.pg1.add_stream(pkts)
8184 self.pg_enable_capture(self.pg_interfaces)
8186 capture = self.pg0.get_capture(len(pkts))
8187 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8188 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8190 ses_num_end = self.nat64_get_ses_num()
8192 self.assertEqual(ses_num_end - ses_num_start, 3)
8194 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8195 def test_session_timeout(self):
8196 """ NAT64 session timeout """
8197 self.icmp_id_in = 1234
8198 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8199 end_addr=self.nat_addr,
8202 flags = self.config_flags.NAT_IS_INSIDE
8203 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8204 sw_if_index=self.pg0.sw_if_index)
8205 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8206 sw_if_index=self.pg1.sw_if_index)
8207 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8211 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8212 self.pg0.add_stream(pkts)
8213 self.pg_enable_capture(self.pg_interfaces)
8215 capture = self.pg1.get_capture(len(pkts))
8217 ses_num_before_timeout = self.nat64_get_ses_num()
8221 # ICMP and TCP session after timeout
8222 ses_num_after_timeout = self.nat64_get_ses_num()
8223 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8225 def test_icmp_error(self):
8226 """ NAT64 ICMP Error message translation """
8227 self.tcp_port_in = 6303
8228 self.udp_port_in = 6304
8229 self.icmp_id_in = 6305
8231 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8232 end_addr=self.nat_addr,
8235 flags = self.config_flags.NAT_IS_INSIDE
8236 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8237 sw_if_index=self.pg0.sw_if_index)
8238 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8239 sw_if_index=self.pg1.sw_if_index)
8241 # send some packets to create sessions
8242 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8243 self.pg0.add_stream(pkts)
8244 self.pg_enable_capture(self.pg_interfaces)
8246 capture_ip4 = self.pg1.get_capture(len(pkts))
8247 self.verify_capture_out(capture_ip4,
8248 nat_ip=self.nat_addr,
8249 dst_ip=self.pg1.remote_ip4)
8251 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8252 self.pg1.add_stream(pkts)
8253 self.pg_enable_capture(self.pg_interfaces)
8255 capture_ip6 = self.pg0.get_capture(len(pkts))
8256 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8257 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8258 self.pg0.remote_ip6)
8261 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8262 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8263 ICMPv6DestUnreach(code=1) /
8264 packet[IPv6] for packet in capture_ip6]
8265 self.pg0.add_stream(pkts)
8266 self.pg_enable_capture(self.pg_interfaces)
8268 capture = self.pg1.get_capture(len(pkts))
8269 for packet in capture:
8271 self.assertEqual(packet[IP].src, self.nat_addr)
8272 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8273 self.assertEqual(packet[ICMP].type, 3)
8274 self.assertEqual(packet[ICMP].code, 13)
8275 inner = packet[IPerror]
8276 self.assertEqual(inner.src, self.pg1.remote_ip4)
8277 self.assertEqual(inner.dst, self.nat_addr)
8278 self.assert_packet_checksums_valid(packet)
8279 if inner.haslayer(TCPerror):
8280 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8281 elif inner.haslayer(UDPerror):
8282 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8284 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8286 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8290 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8291 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8292 ICMP(type=3, code=13) /
8293 packet[IP] for packet in capture_ip4]
8294 self.pg1.add_stream(pkts)
8295 self.pg_enable_capture(self.pg_interfaces)
8297 capture = self.pg0.get_capture(len(pkts))
8298 for packet in capture:
8300 self.assertEqual(packet[IPv6].src, ip.src)
8301 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8302 icmp = packet[ICMPv6DestUnreach]
8303 self.assertEqual(icmp.code, 1)
8304 inner = icmp[IPerror6]
8305 self.assertEqual(inner.src, self.pg0.remote_ip6)
8306 self.assertEqual(inner.dst, ip.src)
8307 self.assert_icmpv6_checksum_valid(packet)
8308 if inner.haslayer(TCPerror):
8309 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8310 elif inner.haslayer(UDPerror):
8311 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8313 self.assertEqual(inner[ICMPv6EchoRequest].id,
8316 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8319 def test_hairpinning(self):
8320 """ NAT64 hairpinning """
8322 client = self.pg0.remote_hosts[0]
8323 server = self.pg0.remote_hosts[1]
8324 server_tcp_in_port = 22
8325 server_tcp_out_port = 4022
8326 server_udp_in_port = 23
8327 server_udp_out_port = 4023
8328 client_tcp_in_port = 1234
8329 client_udp_in_port = 1235
8330 client_tcp_out_port = 0
8331 client_udp_out_port = 0
8332 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8333 nat_addr_ip6 = ip.src
8335 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8336 end_addr=self.nat_addr,
8339 flags = self.config_flags.NAT_IS_INSIDE
8340 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8341 sw_if_index=self.pg0.sw_if_index)
8342 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8343 sw_if_index=self.pg1.sw_if_index)
8345 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8346 o_addr=self.nat_addr,
8347 i_port=server_tcp_in_port,
8348 o_port=server_tcp_out_port,
8349 proto=IP_PROTOS.tcp, vrf_id=0,
8351 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8352 o_addr=self.nat_addr,
8353 i_port=server_udp_in_port,
8354 o_port=server_udp_out_port,
8355 proto=IP_PROTOS.udp, vrf_id=0,
8360 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8361 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8362 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8364 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8365 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8366 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8368 self.pg0.add_stream(pkts)
8369 self.pg_enable_capture(self.pg_interfaces)
8371 capture = self.pg0.get_capture(len(pkts))
8372 for packet in capture:
8374 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8375 self.assertEqual(packet[IPv6].dst, server.ip6)
8376 self.assert_packet_checksums_valid(packet)
8377 if packet.haslayer(TCP):
8378 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8379 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8380 client_tcp_out_port = packet[TCP].sport
8382 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8383 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8384 client_udp_out_port = packet[UDP].sport
8386 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8392 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8393 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8396 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8397 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8399 self.pg0.add_stream(pkts)
8400 self.pg_enable_capture(self.pg_interfaces)
8402 capture = self.pg0.get_capture(len(pkts))
8403 for packet in capture:
8405 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8406 self.assertEqual(packet[IPv6].dst, client.ip6)
8407 self.assert_packet_checksums_valid(packet)
8408 if packet.haslayer(TCP):
8409 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8410 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8412 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8413 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8420 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8421 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8422 ICMPv6DestUnreach(code=1) /
8423 packet[IPv6] for packet in capture]
8424 self.pg0.add_stream(pkts)
8425 self.pg_enable_capture(self.pg_interfaces)
8427 capture = self.pg0.get_capture(len(pkts))
8428 for packet in capture:
8430 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8431 self.assertEqual(packet[IPv6].dst, server.ip6)
8432 icmp = packet[ICMPv6DestUnreach]
8433 self.assertEqual(icmp.code, 1)
8434 inner = icmp[IPerror6]
8435 self.assertEqual(inner.src, server.ip6)
8436 self.assertEqual(inner.dst, nat_addr_ip6)
8437 self.assert_packet_checksums_valid(packet)
8438 if inner.haslayer(TCPerror):
8439 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8440 self.assertEqual(inner[TCPerror].dport,
8441 client_tcp_out_port)
8443 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8444 self.assertEqual(inner[UDPerror].dport,
8445 client_udp_out_port)
8447 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8450 def test_prefix(self):
8451 """ NAT64 Network-Specific Prefix """
8453 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8454 end_addr=self.nat_addr,
8457 flags = self.config_flags.NAT_IS_INSIDE
8458 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8459 sw_if_index=self.pg0.sw_if_index)
8460 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8461 sw_if_index=self.pg1.sw_if_index)
8462 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8463 end_addr=self.vrf1_nat_addr,
8464 vrf_id=self.vrf1_id, is_add=1)
8465 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8466 sw_if_index=self.pg2.sw_if_index)
8469 global_pref64 = "2001:db8::"
8470 global_pref64_len = 32
8471 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8472 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8475 prefix = self.vapi.nat64_prefix_dump()
8476 self.assertEqual(len(prefix), 1)
8477 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8478 self.assertEqual(prefix[0].vrf_id, 0)
8480 # Add tenant specific prefix
8481 vrf1_pref64 = "2001:db8:122:300::"
8482 vrf1_pref64_len = 56
8483 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8484 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8485 vrf_id=self.vrf1_id, is_add=1)
8487 prefix = self.vapi.nat64_prefix_dump()
8488 self.assertEqual(len(prefix), 2)
8491 pkts = self.create_stream_in_ip6(self.pg0,
8494 plen=global_pref64_len)
8495 self.pg0.add_stream(pkts)
8496 self.pg_enable_capture(self.pg_interfaces)
8498 capture = self.pg1.get_capture(len(pkts))
8499 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8500 dst_ip=self.pg1.remote_ip4)
8502 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8503 self.pg1.add_stream(pkts)
8504 self.pg_enable_capture(self.pg_interfaces)
8506 capture = self.pg0.get_capture(len(pkts))
8507 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8510 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8512 # Tenant specific prefix
8513 pkts = self.create_stream_in_ip6(self.pg2,
8516 plen=vrf1_pref64_len)
8517 self.pg2.add_stream(pkts)
8518 self.pg_enable_capture(self.pg_interfaces)
8520 capture = self.pg1.get_capture(len(pkts))
8521 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8522 dst_ip=self.pg1.remote_ip4)
8524 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8525 self.pg1.add_stream(pkts)
8526 self.pg_enable_capture(self.pg_interfaces)
8528 capture = self.pg2.get_capture(len(pkts))
8529 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8532 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8534 def test_unknown_proto(self):
8535 """ NAT64 translate packet with unknown protocol """
8537 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8538 end_addr=self.nat_addr,
8541 flags = self.config_flags.NAT_IS_INSIDE
8542 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8543 sw_if_index=self.pg0.sw_if_index)
8544 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8545 sw_if_index=self.pg1.sw_if_index)
8546 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8549 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8550 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8551 TCP(sport=self.tcp_port_in, dport=20))
8552 self.pg0.add_stream(p)
8553 self.pg_enable_capture(self.pg_interfaces)
8555 p = self.pg1.get_capture(1)
8557 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8558 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8560 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8561 TCP(sport=1234, dport=1234))
8562 self.pg0.add_stream(p)
8563 self.pg_enable_capture(self.pg_interfaces)
8565 p = self.pg1.get_capture(1)
8568 self.assertEqual(packet[IP].src, self.nat_addr)
8569 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8570 self.assertEqual(packet.haslayer(GRE), 1)
8571 self.assert_packet_checksums_valid(packet)
8573 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8577 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8578 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8580 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8581 TCP(sport=1234, dport=1234))
8582 self.pg1.add_stream(p)
8583 self.pg_enable_capture(self.pg_interfaces)
8585 p = self.pg0.get_capture(1)
8588 self.assertEqual(packet[IPv6].src, remote_ip6)
8589 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8590 self.assertEqual(packet[IPv6].nh, 47)
8592 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8595 def test_hairpinning_unknown_proto(self):
8596 """ NAT64 translate packet with unknown protocol - hairpinning """
8598 client = self.pg0.remote_hosts[0]
8599 server = self.pg0.remote_hosts[1]
8600 server_tcp_in_port = 22
8601 server_tcp_out_port = 4022
8602 client_tcp_in_port = 1234
8603 client_tcp_out_port = 1235
8604 server_nat_ip = "10.0.0.100"
8605 client_nat_ip = "10.0.0.110"
8606 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8607 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8609 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8610 end_addr=client_nat_ip,
8613 flags = self.config_flags.NAT_IS_INSIDE
8614 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8615 sw_if_index=self.pg0.sw_if_index)
8616 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8617 sw_if_index=self.pg1.sw_if_index)
8619 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8620 o_addr=server_nat_ip,
8621 i_port=server_tcp_in_port,
8622 o_port=server_tcp_out_port,
8623 proto=IP_PROTOS.tcp, vrf_id=0,
8626 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8627 o_addr=server_nat_ip, i_port=0,
8629 proto=IP_PROTOS.gre, vrf_id=0,
8632 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8633 o_addr=client_nat_ip,
8634 i_port=client_tcp_in_port,
8635 o_port=client_tcp_out_port,
8636 proto=IP_PROTOS.tcp, vrf_id=0,
8640 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8641 IPv6(src=client.ip6, dst=server_nat_ip6) /
8642 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8643 self.pg0.add_stream(p)
8644 self.pg_enable_capture(self.pg_interfaces)
8646 p = self.pg0.get_capture(1)
8648 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8649 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8651 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8652 TCP(sport=1234, dport=1234))
8653 self.pg0.add_stream(p)
8654 self.pg_enable_capture(self.pg_interfaces)
8656 p = self.pg0.get_capture(1)
8659 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8660 self.assertEqual(packet[IPv6].dst, server.ip6)
8661 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8663 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8667 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8668 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8670 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8671 TCP(sport=1234, dport=1234))
8672 self.pg0.add_stream(p)
8673 self.pg_enable_capture(self.pg_interfaces)
8675 p = self.pg0.get_capture(1)
8678 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8679 self.assertEqual(packet[IPv6].dst, client.ip6)
8680 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8682 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8685 def test_one_armed_nat64(self):
8686 """ One armed NAT64 """
8688 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8692 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8693 end_addr=self.nat_addr,
8696 flags = self.config_flags.NAT_IS_INSIDE
8697 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8698 sw_if_index=self.pg3.sw_if_index)
8699 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8700 sw_if_index=self.pg3.sw_if_index)
8703 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8704 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8705 TCP(sport=12345, dport=80))
8706 self.pg3.add_stream(p)
8707 self.pg_enable_capture(self.pg_interfaces)
8709 capture = self.pg3.get_capture(1)
8714 self.assertEqual(ip.src, self.nat_addr)
8715 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8716 self.assertNotEqual(tcp.sport, 12345)
8717 external_port = tcp.sport
8718 self.assertEqual(tcp.dport, 80)
8719 self.assert_packet_checksums_valid(p)
8721 self.logger.error(ppp("Unexpected or invalid packet:", p))
8725 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8726 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8727 TCP(sport=80, dport=external_port))
8728 self.pg3.add_stream(p)
8729 self.pg_enable_capture(self.pg_interfaces)
8731 capture = self.pg3.get_capture(1)
8736 self.assertEqual(ip.src, remote_host_ip6)
8737 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8738 self.assertEqual(tcp.sport, 80)
8739 self.assertEqual(tcp.dport, 12345)
8740 self.assert_packet_checksums_valid(p)
8742 self.logger.error(ppp("Unexpected or invalid packet:", p))
8745 def test_frag_in_order(self):
8746 """ NAT64 translate fragments arriving in order """
8747 self.tcp_port_in = random.randint(1025, 65535)
8749 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8750 end_addr=self.nat_addr,
8753 flags = self.config_flags.NAT_IS_INSIDE
8754 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8755 sw_if_index=self.pg0.sw_if_index)
8756 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8757 sw_if_index=self.pg1.sw_if_index)
8759 reass = self.vapi.nat_reass_dump()
8760 reass_n_start = len(reass)
8764 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8765 self.tcp_port_in, 20, data)
8766 self.pg0.add_stream(pkts)
8767 self.pg_enable_capture(self.pg_interfaces)
8769 frags = self.pg1.get_capture(len(pkts))
8770 p = self.reass_frags_and_verify(frags,
8772 self.pg1.remote_ip4)
8773 self.assertEqual(p[TCP].dport, 20)
8774 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8775 self.tcp_port_out = p[TCP].sport
8776 self.assertEqual(data, p[Raw].load)
8779 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8780 pkts = self.create_stream_frag(self.pg1,
8785 self.pg1.add_stream(pkts)
8786 self.pg_enable_capture(self.pg_interfaces)
8788 frags = self.pg0.get_capture(len(pkts))
8789 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8790 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8791 self.assertEqual(p[TCP].sport, 20)
8792 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8793 self.assertEqual(data, p[Raw].load)
8795 reass = self.vapi.nat_reass_dump()
8796 reass_n_end = len(reass)
8798 self.assertEqual(reass_n_end - reass_n_start, 2)
8800 def test_reass_hairpinning(self):
8801 """ NAT64 fragments hairpinning """
8803 server = self.pg0.remote_hosts[1]
8804 server_in_port = random.randint(1025, 65535)
8805 server_out_port = random.randint(1025, 65535)
8806 client_in_port = random.randint(1025, 65535)
8807 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8808 nat_addr_ip6 = ip.src
8810 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8811 end_addr=self.nat_addr,
8814 flags = self.config_flags.NAT_IS_INSIDE
8815 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8816 sw_if_index=self.pg0.sw_if_index)
8817 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8818 sw_if_index=self.pg1.sw_if_index)
8820 # add static BIB entry for server
8821 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8822 o_addr=self.nat_addr,
8823 i_port=server_in_port,
8824 o_port=server_out_port,
8825 proto=IP_PROTOS.tcp, vrf_id=0,
8828 # send packet from host to server
8829 pkts = self.create_stream_frag_ip6(self.pg0,
8834 self.pg0.add_stream(pkts)
8835 self.pg_enable_capture(self.pg_interfaces)
8837 frags = self.pg0.get_capture(len(pkts))
8838 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8839 self.assertNotEqual(p[TCP].sport, client_in_port)
8840 self.assertEqual(p[TCP].dport, server_in_port)
8841 self.assertEqual(data, p[Raw].load)
8843 def test_frag_out_of_order(self):
8844 """ NAT64 translate fragments arriving out of order """
8845 self.tcp_port_in = random.randint(1025, 65535)
8847 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8848 end_addr=self.nat_addr,
8851 flags = self.config_flags.NAT_IS_INSIDE
8852 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8853 sw_if_index=self.pg0.sw_if_index)
8854 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8855 sw_if_index=self.pg1.sw_if_index)
8859 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8860 self.tcp_port_in, 20, data)
8862 self.pg0.add_stream(pkts)
8863 self.pg_enable_capture(self.pg_interfaces)
8865 frags = self.pg1.get_capture(len(pkts))
8866 p = self.reass_frags_and_verify(frags,
8868 self.pg1.remote_ip4)
8869 self.assertEqual(p[TCP].dport, 20)
8870 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8871 self.tcp_port_out = p[TCP].sport
8872 self.assertEqual(data, p[Raw].load)
8875 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8876 pkts = self.create_stream_frag(self.pg1,
8882 self.pg1.add_stream(pkts)
8883 self.pg_enable_capture(self.pg_interfaces)
8885 frags = self.pg0.get_capture(len(pkts))
8886 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8887 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8888 self.assertEqual(p[TCP].sport, 20)
8889 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8890 self.assertEqual(data, p[Raw].load)
8892 def test_interface_addr(self):
8893 """ Acquire NAT64 pool addresses from interface """
8894 self.vapi.nat64_add_del_interface_addr(
8896 sw_if_index=self.pg4.sw_if_index)
8898 # no address in NAT64 pool
8899 addresses = self.vapi.nat44_address_dump()
8900 self.assertEqual(0, len(addresses))
8902 # configure interface address and check NAT64 address pool
8903 self.pg4.config_ip4()
8904 addresses = self.vapi.nat64_pool_addr_dump()
8905 self.assertEqual(len(addresses), 1)
8907 self.assertEqual(str(addresses[0].address),
8910 # remove interface address and check NAT64 address pool
8911 self.pg4.unconfig_ip4()
8912 addresses = self.vapi.nat64_pool_addr_dump()
8913 self.assertEqual(0, len(addresses))
8915 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8916 def test_ipfix_max_bibs_sessions(self):
8917 """ IPFIX logging maximum session and BIB entries exceeded """
8920 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8924 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8925 end_addr=self.nat_addr,
8928 flags = self.config_flags.NAT_IS_INSIDE
8929 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8930 sw_if_index=self.pg0.sw_if_index)
8931 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8932 sw_if_index=self.pg1.sw_if_index)
8936 for i in range(0, max_bibs):
8937 src = "fd01:aa::%x" % (i)
8938 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8939 IPv6(src=src, dst=remote_host_ip6) /
8940 TCP(sport=12345, dport=80))
8942 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8943 IPv6(src=src, dst=remote_host_ip6) /
8944 TCP(sport=12345, dport=22))
8946 self.pg0.add_stream(pkts)
8947 self.pg_enable_capture(self.pg_interfaces)
8949 self.pg1.get_capture(max_sessions)
8951 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8952 src_address=self.pg3.local_ip4,
8954 template_interval=10)
8955 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8956 src_port=self.ipfix_src_port,
8959 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8960 IPv6(src=src, dst=remote_host_ip6) /
8961 TCP(sport=12345, dport=25))
8962 self.pg0.add_stream(p)
8963 self.pg_enable_capture(self.pg_interfaces)
8965 self.pg1.assert_nothing_captured()
8967 self.vapi.ipfix_flush()
8968 capture = self.pg3.get_capture(9)
8969 ipfix = IPFIXDecoder()
8970 # first load template
8972 self.assertTrue(p.haslayer(IPFIX))
8973 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8974 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8975 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8976 self.assertEqual(p[UDP].dport, 4739)
8977 self.assertEqual(p[IPFIX].observationDomainID,
8978 self.ipfix_domain_id)
8979 if p.haslayer(Template):
8980 ipfix.add_template(p.getlayer(Template))
8981 # verify events in data set
8983 if p.haslayer(Data):
8984 data = ipfix.decode_data_set(p.getlayer(Set))
8985 self.verify_ipfix_max_sessions(data, max_sessions)
8987 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8988 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8989 TCP(sport=12345, dport=80))
8990 self.pg0.add_stream(p)
8991 self.pg_enable_capture(self.pg_interfaces)
8993 self.pg1.assert_nothing_captured()
8995 self.vapi.ipfix_flush()
8996 capture = self.pg3.get_capture(1)
8997 # verify events in data set
8999 self.assertTrue(p.haslayer(IPFIX))
9000 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9001 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9002 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9003 self.assertEqual(p[UDP].dport, 4739)
9004 self.assertEqual(p[IPFIX].observationDomainID,
9005 self.ipfix_domain_id)
9006 if p.haslayer(Data):
9007 data = ipfix.decode_data_set(p.getlayer(Set))
9008 self.verify_ipfix_max_bibs(data, max_bibs)
9010 def test_ipfix_max_frags(self):
9011 """ IPFIX logging maximum fragments pending reassembly exceeded """
9012 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9013 end_addr=self.nat_addr,
9016 flags = self.config_flags.NAT_IS_INSIDE
9017 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9018 sw_if_index=self.pg0.sw_if_index)
9019 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9020 sw_if_index=self.pg1.sw_if_index)
9021 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
9022 drop_frag=0, is_ip6=1)
9023 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9024 src_address=self.pg3.local_ip4,
9026 template_interval=10)
9027 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9028 src_port=self.ipfix_src_port,
9032 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9033 self.tcp_port_in, 20, data)
9035 self.pg0.add_stream(pkts)
9036 self.pg_enable_capture(self.pg_interfaces)
9038 self.pg1.assert_nothing_captured()
9040 self.vapi.ipfix_flush()
9041 capture = self.pg3.get_capture(9)
9042 ipfix = IPFIXDecoder()
9043 # first load template
9045 self.assertTrue(p.haslayer(IPFIX))
9046 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9047 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9048 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9049 self.assertEqual(p[UDP].dport, 4739)
9050 self.assertEqual(p[IPFIX].observationDomainID,
9051 self.ipfix_domain_id)
9052 if p.haslayer(Template):
9053 ipfix.add_template(p.getlayer(Template))
9054 # verify events in data set
9056 if p.haslayer(Data):
9057 data = ipfix.decode_data_set(p.getlayer(Set))
9058 self.verify_ipfix_max_fragments_ip6(data, 1,
9059 self.pg0.remote_ip6n)
9061 def test_ipfix_bib_ses(self):
9062 """ IPFIX logging NAT64 BIB/session create and delete events """
9063 self.tcp_port_in = random.randint(1025, 65535)
9064 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9068 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9069 end_addr=self.nat_addr,
9072 flags = self.config_flags.NAT_IS_INSIDE
9073 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9074 sw_if_index=self.pg0.sw_if_index)
9075 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9076 sw_if_index=self.pg1.sw_if_index)
9077 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9078 src_address=self.pg3.local_ip4,
9080 template_interval=10)
9081 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9082 src_port=self.ipfix_src_port,
9086 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9087 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9088 TCP(sport=self.tcp_port_in, dport=25))
9089 self.pg0.add_stream(p)
9090 self.pg_enable_capture(self.pg_interfaces)
9092 p = self.pg1.get_capture(1)
9093 self.tcp_port_out = p[0][TCP].sport
9094 self.vapi.ipfix_flush()
9095 capture = self.pg3.get_capture(10)
9096 ipfix = IPFIXDecoder()
9097 # first load template
9099 self.assertTrue(p.haslayer(IPFIX))
9100 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9101 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9102 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9103 self.assertEqual(p[UDP].dport, 4739)
9104 self.assertEqual(p[IPFIX].observationDomainID,
9105 self.ipfix_domain_id)
9106 if p.haslayer(Template):
9107 ipfix.add_template(p.getlayer(Template))
9108 # verify events in data set
9110 if p.haslayer(Data):
9111 data = ipfix.decode_data_set(p.getlayer(Set))
9112 if scapy.compat.orb(data[0][230]) == 10:
9113 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
9114 elif scapy.compat.orb(data[0][230]) == 6:
9115 self.verify_ipfix_nat64_ses(data,
9117 self.pg0.remote_ip6n,
9118 self.pg1.remote_ip4,
9121 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9124 self.pg_enable_capture(self.pg_interfaces)
9125 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9126 end_addr=self.nat_addr,
9129 self.vapi.ipfix_flush()
9130 capture = self.pg3.get_capture(2)
9131 # verify events in data set
9133 self.assertTrue(p.haslayer(IPFIX))
9134 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9135 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9136 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9137 self.assertEqual(p[UDP].dport, 4739)
9138 self.assertEqual(p[IPFIX].observationDomainID,
9139 self.ipfix_domain_id)
9140 if p.haslayer(Data):
9141 data = ipfix.decode_data_set(p.getlayer(Set))
9142 if scapy.compat.orb(data[0][230]) == 11:
9143 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9144 elif scapy.compat.orb(data[0][230]) == 7:
9145 self.verify_ipfix_nat64_ses(data,
9147 self.pg0.remote_ip6n,
9148 self.pg1.remote_ip4,
9151 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9153 def test_syslog_sess(self):
9154 """ Test syslog session creation and deletion """
9155 self.tcp_port_in = random.randint(1025, 65535)
9156 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9160 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9161 end_addr=self.nat_addr,
9164 flags = self.config_flags.NAT_IS_INSIDE
9165 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9166 sw_if_index=self.pg0.sw_if_index)
9167 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9168 sw_if_index=self.pg1.sw_if_index)
9169 self.vapi.syslog_set_filter(
9170 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9171 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9173 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9174 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9175 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9176 self.pg0.add_stream(p)
9177 self.pg_enable_capture(self.pg_interfaces)
9179 p = self.pg1.get_capture(1)
9180 self.tcp_port_out = p[0][TCP].sport
9181 capture = self.pg3.get_capture(1)
9182 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9184 self.pg_enable_capture(self.pg_interfaces)
9186 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9187 end_addr=self.nat_addr,
9190 capture = self.pg3.get_capture(1)
9191 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9193 def nat64_get_ses_num(self):
9195 Return number of active NAT64 sessions.
9197 st = self.vapi.nat64_st_dump(proto=255)
9200 def clear_nat64(self):
9202 Clear NAT64 configuration.
9204 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9205 src_port=self.ipfix_src_port,
9207 self.ipfix_src_port = 4739
9208 self.ipfix_domain_id = 1
9210 self.vapi.syslog_set_filter(
9211 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9213 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9214 tcp_transitory=240, icmp=60)
9216 interfaces = self.vapi.nat64_interface_dump()
9217 for intf in interfaces:
9218 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9219 sw_if_index=intf.sw_if_index)
9221 bib = self.vapi.nat64_bib_dump(proto=255)
9223 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9224 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9232 adresses = self.vapi.nat64_pool_addr_dump()
9233 for addr in adresses:
9234 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9235 end_addr=addr.address,
9239 prefixes = self.vapi.nat64_prefix_dump()
9240 for prefix in prefixes:
9241 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9242 vrf_id=prefix.vrf_id, is_add=0)
9244 bibs = self.statistics.get_counter('/nat64/total-bibs')
9245 self.assertEqual(bibs[0][0], 0)
9246 sessions = self.statistics.get_counter('/nat64/total-sessions')
9247 self.assertEqual(sessions[0][0], 0)
9250 super(TestNAT64, self).tearDown()
9251 if not self.vpp_dead:
9254 def show_commands_at_teardown(self):
9255 self.logger.info(self.vapi.cli("show nat64 pool"))
9256 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9257 self.logger.info(self.vapi.cli("show nat64 prefix"))
9258 self.logger.info(self.vapi.cli("show nat64 bib all"))
9259 self.logger.info(self.vapi.cli("show nat64 session table all"))
9260 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9263 class TestDSlite(MethodHolder):
9264 """ DS-Lite Test Cases """
9267 def setUpClass(cls):
9268 super(TestDSlite, cls).setUpClass()
9271 cls.nat_addr = '10.0.0.3'
9273 cls.create_pg_interfaces(range(3))
9275 cls.pg0.config_ip4()
9276 cls.pg0.resolve_arp()
9278 cls.pg1.config_ip6()
9279 cls.pg1.generate_remote_hosts(2)
9280 cls.pg1.configure_ipv6_neighbors()
9282 cls.pg2.config_ip4()
9283 cls.pg2.resolve_arp()
9286 super(TestDSlite, cls).tearDownClass()
9290 def tearDownClass(cls):
9291 super(TestDSlite, cls).tearDownClass()
9293 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9295 message = data.decode('utf-8')
9297 message = SyslogMessage.parse(message)
9298 except ParseError as e:
9299 self.logger.error(e)
9301 self.assertEqual(message.severity, SyslogSeverity.info)
9302 self.assertEqual(message.appname, 'NAT')
9303 self.assertEqual(message.msgid, 'APMADD')
9304 sd_params = message.sd.get('napmap')
9305 self.assertTrue(sd_params is not None)
9306 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9307 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9308 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9309 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9310 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9311 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9312 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9313 self.assertTrue(sd_params.get('SSUBIX') is not None)
9314 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9316 def test_dslite(self):
9317 """ Test DS-Lite """
9318 nat_config = self.vapi.nat_show_config()
9319 self.assertEqual(0, nat_config.dslite_ce)
9321 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9322 end_addr=self.nat_addr,
9324 aftr_ip4 = '192.0.0.1'
9325 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9326 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9327 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
9330 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9331 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9332 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9333 UDP(sport=20000, dport=10000))
9334 self.pg1.add_stream(p)
9335 self.pg_enable_capture(self.pg_interfaces)
9337 capture = self.pg0.get_capture(1)
9338 capture = capture[0]
9339 self.assertFalse(capture.haslayer(IPv6))
9340 self.assertEqual(capture[IP].src, self.nat_addr)
9341 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9342 self.assertNotEqual(capture[UDP].sport, 20000)
9343 self.assertEqual(capture[UDP].dport, 10000)
9344 self.assert_packet_checksums_valid(capture)
9345 out_port = capture[UDP].sport
9346 capture = self.pg2.get_capture(1)
9347 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9348 20000, self.nat_addr, out_port,
9349 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9351 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9352 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9353 UDP(sport=10000, dport=out_port))
9354 self.pg0.add_stream(p)
9355 self.pg_enable_capture(self.pg_interfaces)
9357 capture = self.pg1.get_capture(1)
9358 capture = capture[0]
9359 self.assertEqual(capture[IPv6].src, aftr_ip6)
9360 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9361 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9362 self.assertEqual(capture[IP].dst, '192.168.1.1')
9363 self.assertEqual(capture[UDP].sport, 10000)
9364 self.assertEqual(capture[UDP].dport, 20000)
9365 self.assert_packet_checksums_valid(capture)
9368 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9369 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9370 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9371 TCP(sport=20001, dport=10001))
9372 self.pg1.add_stream(p)
9373 self.pg_enable_capture(self.pg_interfaces)
9375 capture = self.pg0.get_capture(1)
9376 capture = capture[0]
9377 self.assertFalse(capture.haslayer(IPv6))
9378 self.assertEqual(capture[IP].src, self.nat_addr)
9379 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9380 self.assertNotEqual(capture[TCP].sport, 20001)
9381 self.assertEqual(capture[TCP].dport, 10001)
9382 self.assert_packet_checksums_valid(capture)
9383 out_port = capture[TCP].sport
9385 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9386 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9387 TCP(sport=10001, dport=out_port))
9388 self.pg0.add_stream(p)
9389 self.pg_enable_capture(self.pg_interfaces)
9391 capture = self.pg1.get_capture(1)
9392 capture = capture[0]
9393 self.assertEqual(capture[IPv6].src, aftr_ip6)
9394 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9395 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9396 self.assertEqual(capture[IP].dst, '192.168.1.1')
9397 self.assertEqual(capture[TCP].sport, 10001)
9398 self.assertEqual(capture[TCP].dport, 20001)
9399 self.assert_packet_checksums_valid(capture)
9402 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9403 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9404 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9405 ICMP(id=4000, type='echo-request'))
9406 self.pg1.add_stream(p)
9407 self.pg_enable_capture(self.pg_interfaces)
9409 capture = self.pg0.get_capture(1)
9410 capture = capture[0]
9411 self.assertFalse(capture.haslayer(IPv6))
9412 self.assertEqual(capture[IP].src, self.nat_addr)
9413 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9414 self.assertNotEqual(capture[ICMP].id, 4000)
9415 self.assert_packet_checksums_valid(capture)
9416 out_id = capture[ICMP].id
9418 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9419 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9420 ICMP(id=out_id, type='echo-reply'))
9421 self.pg0.add_stream(p)
9422 self.pg_enable_capture(self.pg_interfaces)
9424 capture = self.pg1.get_capture(1)
9425 capture = capture[0]
9426 self.assertEqual(capture[IPv6].src, aftr_ip6)
9427 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9428 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9429 self.assertEqual(capture[IP].dst, '192.168.1.1')
9430 self.assertEqual(capture[ICMP].id, 4000)
9431 self.assert_packet_checksums_valid(capture)
9433 # ping DS-Lite AFTR tunnel endpoint address
9434 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9435 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9436 ICMPv6EchoRequest())
9437 self.pg1.add_stream(p)
9438 self.pg_enable_capture(self.pg_interfaces)
9440 capture = self.pg1.get_capture(1)
9441 capture = capture[0]
9442 self.assertEqual(capture[IPv6].src, aftr_ip6)
9443 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9444 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9446 b4s = self.statistics.get_counter('/dslite/total-b4s')
9447 self.assertEqual(b4s[0][0], 2)
9448 sessions = self.statistics.get_counter('/dslite/total-sessions')
9449 self.assertEqual(sessions[0][0], 3)
9452 super(TestDSlite, self).tearDown()
9454 def show_commands_at_teardown(self):
9455 self.logger.info(self.vapi.cli("show dslite pool"))
9457 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9458 self.logger.info(self.vapi.cli("show dslite sessions"))
9461 class TestDSliteCE(MethodHolder):
9462 """ DS-Lite CE Test Cases """
9465 def setUpConstants(cls):
9466 super(TestDSliteCE, cls).setUpConstants()
9467 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9470 def setUpClass(cls):
9471 super(TestDSliteCE, cls).setUpClass()
9474 cls.create_pg_interfaces(range(2))
9476 cls.pg0.config_ip4()
9477 cls.pg0.resolve_arp()
9479 cls.pg1.config_ip6()
9480 cls.pg1.generate_remote_hosts(1)
9481 cls.pg1.configure_ipv6_neighbors()
9484 super(TestDSliteCE, cls).tearDownClass()
9488 def tearDownClass(cls):
9489 super(TestDSliteCE, cls).tearDownClass()
9491 def test_dslite_ce(self):
9492 """ Test DS-Lite CE """
9494 nat_config = self.vapi.nat_show_config()
9495 self.assertEqual(1, nat_config.dslite_ce)
9497 b4_ip4 = '192.0.0.2'
9498 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9499 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9501 aftr_ip4 = '192.0.0.1'
9502 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9503 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9504 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9506 r1 = VppIpRoute(self, aftr_ip6, 128,
9507 [VppRoutePath(self.pg1.remote_ip6,
9508 self.pg1.sw_if_index)])
9512 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9513 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9514 UDP(sport=10000, dport=20000))
9515 self.pg0.add_stream(p)
9516 self.pg_enable_capture(self.pg_interfaces)
9518 capture = self.pg1.get_capture(1)
9519 capture = capture[0]
9520 self.assertEqual(capture[IPv6].src, b4_ip6)
9521 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9522 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9523 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9524 self.assertEqual(capture[UDP].sport, 10000)
9525 self.assertEqual(capture[UDP].dport, 20000)
9526 self.assert_packet_checksums_valid(capture)
9529 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9530 IPv6(dst=b4_ip6, src=aftr_ip6) /
9531 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9532 UDP(sport=20000, dport=10000))
9533 self.pg1.add_stream(p)
9534 self.pg_enable_capture(self.pg_interfaces)
9536 capture = self.pg0.get_capture(1)
9537 capture = capture[0]
9538 self.assertFalse(capture.haslayer(IPv6))
9539 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9540 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9541 self.assertEqual(capture[UDP].sport, 20000)
9542 self.assertEqual(capture[UDP].dport, 10000)
9543 self.assert_packet_checksums_valid(capture)
9545 # ping DS-Lite B4 tunnel endpoint address
9546 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9547 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9548 ICMPv6EchoRequest())
9549 self.pg1.add_stream(p)
9550 self.pg_enable_capture(self.pg_interfaces)
9552 capture = self.pg1.get_capture(1)
9553 capture = capture[0]
9554 self.assertEqual(capture[IPv6].src, b4_ip6)
9555 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9556 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9559 super(TestDSliteCE, self).tearDown()
9561 def show_commands_at_teardown(self):
9563 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9565 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9568 class TestNAT66(MethodHolder):
9569 """ NAT66 Test Cases """
9572 def setUpClass(cls):
9573 super(TestNAT66, cls).setUpClass()
9576 cls.nat_addr = 'fd01:ff::2'
9578 cls.create_pg_interfaces(range(2))
9579 cls.interfaces = list(cls.pg_interfaces)
9581 for i in cls.interfaces:
9584 i.configure_ipv6_neighbors()
9587 super(TestNAT66, cls).tearDownClass()
9591 def tearDownClass(cls):
9592 super(TestNAT66, cls).tearDownClass()
9594 def test_static(self):
9595 """ 1:1 NAT66 test """
9596 flags = self.config_flags.NAT_IS_INSIDE
9597 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9598 sw_if_index=self.pg0.sw_if_index)
9599 self.vapi.nat66_add_del_interface(is_add=1,
9600 sw_if_index=self.pg1.sw_if_index)
9601 self.vapi.nat66_add_del_static_mapping(
9602 local_ip_address=self.pg0.remote_ip6n,
9603 external_ip_address=self.nat_addr,
9608 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9609 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9612 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9613 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9616 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9617 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9618 ICMPv6EchoRequest())
9620 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9621 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9622 GRE() / IP() / TCP())
9624 self.pg0.add_stream(pkts)
9625 self.pg_enable_capture(self.pg_interfaces)
9627 capture = self.pg1.get_capture(len(pkts))
9628 for packet in capture:
9630 self.assertEqual(packet[IPv6].src, self.nat_addr)
9631 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9632 self.assert_packet_checksums_valid(packet)
9634 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9639 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9640 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9643 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9644 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9647 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9648 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9651 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9652 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9653 GRE() / IP() / TCP())
9655 self.pg1.add_stream(pkts)
9656 self.pg_enable_capture(self.pg_interfaces)
9658 capture = self.pg0.get_capture(len(pkts))
9659 for packet in capture:
9661 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9662 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9663 self.assert_packet_checksums_valid(packet)
9665 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9668 sm = self.vapi.nat66_static_mapping_dump()
9669 self.assertEqual(len(sm), 1)
9670 self.assertEqual(sm[0].total_pkts, 8)
9672 def test_check_no_translate(self):
9673 """ NAT66 translate only when egress interface is outside interface """
9674 flags = self.config_flags.NAT_IS_INSIDE
9675 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9676 sw_if_index=self.pg0.sw_if_index)
9677 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9678 sw_if_index=self.pg1.sw_if_index)
9679 self.vapi.nat66_add_del_static_mapping(
9680 local_ip_address=self.pg0.remote_ip6n,
9681 external_ip_address=self.nat_addr,
9685 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9686 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9688 self.pg0.add_stream([p])
9689 self.pg_enable_capture(self.pg_interfaces)
9691 capture = self.pg1.get_capture(1)
9694 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9695 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9697 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9700 def clear_nat66(self):
9702 Clear NAT66 configuration.
9704 interfaces = self.vapi.nat66_interface_dump()
9705 for intf in interfaces:
9706 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9707 sw_if_index=intf.sw_if_index)
9709 static_mappings = self.vapi.nat66_static_mapping_dump()
9710 for sm in static_mappings:
9711 self.vapi.nat66_add_del_static_mapping(
9712 local_ip_address=sm.local_ip_address,
9713 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9717 super(TestNAT66, self).tearDown()
9720 def show_commands_at_teardown(self):
9721 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9722 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9725 if __name__ == '__main__':
9726 unittest.main(testRunner=VppTestRunner)