8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
33 from ipaddress import IPv6Network
36 # NAT HA protocol event data
39 fields_desc = [ByteEnumField("event_type", None,
40 {1: "add", 2: "del", 3: "refresh"}),
41 ByteEnumField("protocol", None,
42 {0: "udp", 1: "tcp", 2: "icmp"}),
43 ShortField("flags", 0),
44 IPField("in_addr", None),
45 IPField("out_addr", None),
46 ShortField("in_port", None),
47 ShortField("out_port", None),
48 IPField("eh_addr", None),
49 IPField("ehn_addr", None),
50 ShortField("eh_port", None),
51 ShortField("ehn_port", None),
52 IntField("fib_index", None),
53 IntField("total_pkts", 0),
54 LongField("total_bytes", 0)]
56 def extract_padding(self, s):
60 # NAT HA protocol header
61 class HANATStateSync(Packet):
62 name = "HA NAT state sync"
63 fields_desc = [XByteField("version", 1),
64 FlagsField("flags", 0, 8, ['ACK']),
65 FieldLenField("count", None, count_of="events"),
66 IntField("sequence_number", 1),
67 IntField("thread_index", 0),
68 PacketListField("events", [], Event,
69 count_from=lambda pkt: pkt.count)]
72 class MethodHolder(VppTestCase):
73 """ NAT create capture and verify method holder """
76 def config_flags(self):
77 return VppEnum.vl_api_nat_config_flags_t
80 def SYSLOG_SEVERITY(self):
81 return VppEnum.vl_api_syslog_severity_t
83 def clear_nat44(self):
85 Clear NAT44 configuration.
87 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
88 if self.pg7.has_ip4_config:
89 self.pg7.unconfig_ip4()
91 self.vapi.nat44_forwarding_enable_disable(enable=0)
93 interfaces = self.vapi.nat44_interface_addr_dump()
94 for intf in interfaces:
95 self.vapi.nat44_add_del_interface_addr(
97 sw_if_index=intf.sw_if_index,
100 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
101 src_port=self.ipfix_src_port,
103 self.ipfix_src_port = 4739
104 self.ipfix_domain_id = 1
106 self.vapi.syslog_set_filter(
107 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
109 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
111 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
112 session_refresh_interval=10)
114 interfaces = self.vapi.nat44_interface_dump()
115 for intf in interfaces:
116 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
117 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
118 self.vapi.nat44_interface_add_del_feature(
119 sw_if_index=intf.sw_if_index)
120 self.vapi.nat44_interface_add_del_feature(
121 sw_if_index=intf.sw_if_index,
124 interfaces = self.vapi.nat44_interface_output_feature_dump()
125 for intf in interfaces:
126 self.vapi.nat44_interface_add_del_output_feature(
129 sw_if_index=intf.sw_if_index)
130 static_mappings = self.vapi.nat44_static_mapping_dump()
131 for sm in static_mappings:
132 self.vapi.nat44_add_del_static_mapping(
134 local_ip_address=sm.local_ip_address,
135 external_ip_address=sm.external_ip_address,
136 external_sw_if_index=sm.external_sw_if_index,
137 local_port=sm.local_port,
138 external_port=sm.external_port,
140 protocol=sm.protocol,
141 flags=sm.flags, tag=sm.tag)
143 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
144 for lb_sm in lb_static_mappings:
145 self.vapi.nat44_add_del_lb_static_mapping(
148 external_addr=lb_sm.external_addr,
149 external_port=lb_sm.external_port,
150 protocol=lb_sm.protocol,
151 local_num=0, locals=[],
154 identity_mappings = self.vapi.nat44_identity_mapping_dump()
155 for id_m in identity_mappings:
156 self.vapi.nat44_add_del_identity_mapping(
157 ip_address=id_m.ip_address,
158 sw_if_index=id_m.sw_if_index,
162 protocol=id_m.protocol)
164 addresses = self.vapi.nat44_address_dump()
165 for addr in addresses:
166 self.vapi.nat44_add_del_address_range(
167 first_ip_address=addr.ip_address,
168 last_ip_address=addr.ip_address,
169 vrf_id=0xFFFFFFFF, flags=addr.flags)
171 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
173 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
174 drop_frag=0, is_ip6=1)
175 self.verify_no_nat44_user()
176 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
177 tcp_transitory=240, icmp=60)
178 self.vapi.nat_set_addr_and_port_alloc_alg()
179 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
181 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
182 local_port=0, external_port=0, vrf_id=0,
183 is_add=1, external_sw_if_index=0xFFFFFFFF,
184 proto=0, tag="", flags=0):
186 Add/delete NAT44 static mapping
188 :param local_ip: Local IP address
189 :param external_ip: External IP address
190 :param local_port: Local port number (Optional)
191 :param external_port: External port number (Optional)
192 :param vrf_id: VRF ID (Default 0)
193 :param is_add: 1 if add, 0 if delete (Default add)
194 :param external_sw_if_index: External interface instead of IP address
195 :param proto: IP protocol (Mandatory if port specified)
196 :param tag: Opaque string tag
197 :param flags: NAT configuration flags
200 if not (local_port and external_port):
201 flags |= self.config_flags.NAT_IS_ADDR_ONLY
203 self.vapi.nat44_add_del_static_mapping(
205 local_ip_address=local_ip,
206 external_ip_address=external_ip,
207 external_sw_if_index=external_sw_if_index,
208 local_port=local_port,
209 external_port=external_port,
210 vrf_id=vrf_id, protocol=proto,
214 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
216 Add/delete NAT44 address
218 :param ip: IP address
219 :param is_add: 1 if add, 0 if delete (Default add)
220 :param twice_nat: twice NAT address for external hosts
222 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
223 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
229 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
231 Create packet stream for inside network
233 :param in_if: Inside interface
234 :param out_if: Outside interface
235 :param dst_ip: Destination address
236 :param ttl: TTL of generated packets
239 dst_ip = out_if.remote_ip4
243 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
244 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
245 TCP(sport=self.tcp_port_in, dport=20))
249 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
250 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
251 UDP(sport=self.udp_port_in, dport=20))
255 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
256 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
257 ICMP(id=self.icmp_id_in, type='echo-request'))
262 def compose_ip6(self, ip4, pref, plen):
264 Compose IPv4-embedded IPv6 addresses
266 :param ip4: IPv4 address
267 :param pref: IPv6 prefix
268 :param plen: IPv6 prefix length
269 :returns: IPv4-embedded IPv6 addresses
271 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
272 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
287 pref_n[10] = ip4_n[3]
291 pref_n[10] = ip4_n[2]
292 pref_n[11] = ip4_n[3]
295 pref_n[10] = ip4_n[1]
296 pref_n[11] = ip4_n[2]
297 pref_n[12] = ip4_n[3]
299 pref_n[12] = ip4_n[0]
300 pref_n[13] = ip4_n[1]
301 pref_n[14] = ip4_n[2]
302 pref_n[15] = ip4_n[3]
303 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
304 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
306 def extract_ip4(self, ip6, plen):
308 Extract IPv4 address embedded in IPv6 addresses
310 :param ip6: IPv6 address
311 :param plen: IPv6 prefix length
312 :returns: extracted IPv4 address
314 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
346 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
348 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
350 Create IPv6 packet stream for inside network
352 :param in_if: Inside interface
353 :param out_if: Outside interface
354 :param ttl: Hop Limit of generated packets
355 :param pref: NAT64 prefix
356 :param plen: NAT64 prefix length
360 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
362 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
365 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
366 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
367 TCP(sport=self.tcp_port_in, dport=20))
371 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
372 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
373 UDP(sport=self.udp_port_in, dport=20))
377 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
378 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
379 ICMPv6EchoRequest(id=self.icmp_id_in))
384 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
385 use_inside_ports=False):
387 Create packet stream for outside network
389 :param out_if: Outside interface
390 :param dst_ip: Destination IP address (Default use global NAT address)
391 :param ttl: TTL of generated packets
392 :param use_inside_ports: Use inside NAT ports as destination ports
393 instead of outside ports
396 dst_ip = self.nat_addr
397 if not use_inside_ports:
398 tcp_port = self.tcp_port_out
399 udp_port = self.udp_port_out
400 icmp_id = self.icmp_id_out
402 tcp_port = self.tcp_port_in
403 udp_port = self.udp_port_in
404 icmp_id = self.icmp_id_in
407 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
408 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
409 TCP(dport=tcp_port, sport=20))
413 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
414 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
415 UDP(dport=udp_port, sport=20))
419 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
420 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
421 ICMP(id=icmp_id, type='echo-reply'))
426 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
428 Create packet stream for outside network
430 :param out_if: Outside interface
431 :param dst_ip: Destination IP address (Default use global NAT address)
432 :param hl: HL of generated packets
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
438 TCP(dport=self.tcp_port_out, sport=20))
442 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
443 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
444 UDP(dport=self.udp_port_out, sport=20))
448 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
449 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
450 ICMPv6EchoReply(id=self.icmp_id_out))
455 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
456 dst_ip=None, is_ip6=False):
458 Verify captured packets on outside network
460 :param capture: Captured packets
461 :param nat_ip: Translated IP address (Default use global NAT address)
462 :param same_port: Source port number is not translated (Default False)
463 :param dst_ip: Destination IP address (Default do not verify)
464 :param is_ip6: If L3 protocol is IPv6 (Default False)
468 ICMP46 = ICMPv6EchoRequest
473 nat_ip = self.nat_addr
474 for packet in capture:
477 self.assert_packet_checksums_valid(packet)
478 self.assertEqual(packet[IP46].src, nat_ip)
479 if dst_ip is not None:
480 self.assertEqual(packet[IP46].dst, dst_ip)
481 if packet.haslayer(TCP):
483 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
486 packet[TCP].sport, self.tcp_port_in)
487 self.tcp_port_out = packet[TCP].sport
488 self.assert_packet_checksums_valid(packet)
489 elif packet.haslayer(UDP):
491 self.assertEqual(packet[UDP].sport, self.udp_port_in)
494 packet[UDP].sport, self.udp_port_in)
495 self.udp_port_out = packet[UDP].sport
498 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
500 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
501 self.icmp_id_out = packet[ICMP46].id
502 self.assert_packet_checksums_valid(packet)
504 self.logger.error(ppp("Unexpected or invalid packet "
505 "(outside network):", packet))
508 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
511 Verify captured packets on outside network
513 :param capture: Captured packets
514 :param nat_ip: Translated IP address
515 :param same_port: Source port number is not translated (Default False)
516 :param dst_ip: Destination IP address (Default do not verify)
518 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
521 def verify_capture_in(self, capture, in_if):
523 Verify captured packets on inside network
525 :param capture: Captured packets
526 :param in_if: Inside interface
528 for packet in capture:
530 self.assert_packet_checksums_valid(packet)
531 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
532 if packet.haslayer(TCP):
533 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
534 elif packet.haslayer(UDP):
535 self.assertEqual(packet[UDP].dport, self.udp_port_in)
537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
539 self.logger.error(ppp("Unexpected or invalid packet "
540 "(inside network):", packet))
543 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
545 Verify captured IPv6 packets on inside network
547 :param capture: Captured packets
548 :param src_ip: Source IP
549 :param dst_ip: Destination IP address
551 for packet in capture:
553 self.assertEqual(packet[IPv6].src, src_ip)
554 self.assertEqual(packet[IPv6].dst, dst_ip)
555 self.assert_packet_checksums_valid(packet)
556 if packet.haslayer(TCP):
557 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
558 elif packet.haslayer(UDP):
559 self.assertEqual(packet[UDP].dport, self.udp_port_in)
561 self.assertEqual(packet[ICMPv6EchoReply].id,
564 self.logger.error(ppp("Unexpected or invalid packet "
565 "(inside network):", packet))
568 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
570 Verify captured packet that don't have to be translated
572 :param capture: Captured packets
573 :param ingress_if: Ingress interface
574 :param egress_if: Egress interface
576 for packet in capture:
578 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
579 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
580 if packet.haslayer(TCP):
581 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
582 elif packet.haslayer(UDP):
583 self.assertEqual(packet[UDP].sport, self.udp_port_in)
585 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(inside network):", packet))
591 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
594 Verify captured packets with ICMP errors on outside network
596 :param capture: Captured packets
597 :param src_ip: Translated IP address or IP address of VPP
598 (Default use global NAT address)
599 :param icmp_type: Type of error ICMP packet
600 we are expecting (Default 11)
603 src_ip = self.nat_addr
604 for packet in capture:
606 self.assertEqual(packet[IP].src, src_ip)
607 self.assertEqual(packet.haslayer(ICMP), 1)
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].dport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].dport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(outside network):", packet))
625 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
627 Verify captured packets with ICMP errors on inside network
629 :param capture: Captured packets
630 :param in_if: Inside interface
631 :param icmp_type: Type of error ICMP packet
632 we are expecting (Default 11)
634 for packet in capture:
636 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
637 self.assertEqual(packet.haslayer(ICMP), 1)
639 self.assertEqual(icmp.type, icmp_type)
640 self.assertTrue(icmp.haslayer(IPerror))
641 inner_ip = icmp[IPerror]
642 if inner_ip.haslayer(TCPerror):
643 self.assertEqual(inner_ip[TCPerror].sport,
645 elif inner_ip.haslayer(UDPerror):
646 self.assertEqual(inner_ip[UDPerror].sport,
649 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
651 self.logger.error(ppp("Unexpected or invalid packet "
652 "(inside network):", packet))
655 def create_stream_frag(self, src_if, dst, sport, dport, data,
656 proto=IP_PROTOS.tcp, echo_reply=False):
658 Create fragmented packet stream
660 :param src_if: Source interface
661 :param dst: Destination IPv4 address
662 :param sport: Source port
663 :param dport: Destination port
664 :param data: Payload data
665 :param proto: protocol (TCP, UDP, ICMP)
666 :param echo_reply: use echo_reply if protocol is ICMP
669 if proto == IP_PROTOS.tcp:
670 p = (IP(src=src_if.remote_ip4, dst=dst) /
671 TCP(sport=sport, dport=dport) /
673 p = p.__class__(scapy.compat.raw(p))
674 chksum = p[TCP].chksum
675 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
676 elif proto == IP_PROTOS.udp:
677 proto_header = UDP(sport=sport, dport=dport)
678 elif proto == IP_PROTOS.icmp:
680 proto_header = ICMP(id=sport, type='echo-request')
682 proto_header = ICMP(id=sport, type='echo-reply')
684 raise Exception("Unsupported protocol")
685 id = random.randint(0, 65535)
687 if proto == IP_PROTOS.tcp:
690 raw = Raw(data[0:16])
691 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
692 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
696 if proto == IP_PROTOS.tcp:
697 raw = Raw(data[4:20])
699 raw = Raw(data[16:32])
700 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
701 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
705 if proto == IP_PROTOS.tcp:
709 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
710 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
716 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
717 pref=None, plen=0, frag_size=128):
719 Create fragmented packet stream
721 :param src_if: Source interface
722 :param dst: Destination IPv4 address
723 :param sport: Source TCP port
724 :param dport: Destination TCP port
725 :param data: Payload data
726 :param pref: NAT64 prefix
727 :param plen: NAT64 prefix length
728 :param fragsize: size of fragments
732 dst_ip6 = ''.join(['64:ff9b::', dst])
734 dst_ip6 = self.compose_ip6(dst, pref, plen)
736 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
737 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
738 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
739 TCP(sport=sport, dport=dport) /
742 return fragment6(p, frag_size)
744 def reass_frags_and_verify(self, frags, src, dst):
746 Reassemble and verify fragmented packet
748 :param frags: Captured fragments
749 :param src: Source IPv4 address to verify
750 :param dst: Destination IPv4 address to verify
752 :returns: Reassembled IPv4 packet
756 self.assertEqual(p[IP].src, src)
757 self.assertEqual(p[IP].dst, dst)
758 self.assert_ip_checksum_valid(p)
759 buffer.seek(p[IP].frag * 8)
760 buffer.write(bytes(p[IP].payload))
761 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
762 proto=frags[0][IP].proto)
763 if ip.proto == IP_PROTOS.tcp:
764 p = (ip / TCP(buffer.getvalue()))
765 self.assert_tcp_checksum_valid(p)
766 elif ip.proto == IP_PROTOS.udp:
767 p = (ip / UDP(buffer.getvalue()[:8]) /
768 Raw(buffer.getvalue()[8:]))
769 elif ip.proto == IP_PROTOS.icmp:
770 p = (ip / ICMP(buffer.getvalue()))
773 def reass_frags_and_verify_ip6(self, frags, src, dst):
775 Reassemble and verify fragmented packet
777 :param frags: Captured fragments
778 :param src: Source IPv6 address to verify
779 :param dst: Destination IPv6 address to verify
781 :returns: Reassembled IPv6 packet
785 self.assertEqual(p[IPv6].src, src)
786 self.assertEqual(p[IPv6].dst, dst)
787 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
788 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
789 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
790 nh=frags[0][IPv6ExtHdrFragment].nh)
791 if ip.nh == IP_PROTOS.tcp:
792 p = (ip / TCP(buffer.getvalue()))
793 elif ip.nh == IP_PROTOS.udp:
794 p = (ip / UDP(buffer.getvalue()))
795 self.assert_packet_checksums_valid(p)
798 def initiate_tcp_session(self, in_if, out_if):
800 Initiates TCP session
802 :param in_if: Inside interface
803 :param out_if: Outside interface
807 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
808 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
809 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
812 self.pg_enable_capture(self.pg_interfaces)
814 capture = out_if.get_capture(1)
816 self.tcp_port_out = p[TCP].sport
818 # SYN + ACK packet out->in
819 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
820 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
821 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
824 self.pg_enable_capture(self.pg_interfaces)
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 out_if.get_capture(1)
839 self.logger.error("TCP 3 way handshake failed")
842 def verify_ipfix_nat44_ses(self, data):
844 Verify IPFIX NAT44 session create/delete event
846 :param data: Decoded IPFIX data records
848 nat44_ses_create_num = 0
849 nat44_ses_delete_num = 0
850 self.assertEqual(6, len(data))
853 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
854 if scapy.compat.orb(record[230]) == 4:
855 nat44_ses_create_num += 1
857 nat44_ses_delete_num += 1
859 self.assertEqual(self.pg0.remote_ip4n, record[8])
860 # postNATSourceIPv4Address
861 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
864 self.assertEqual(struct.pack("!I", 0), record[234])
865 # protocolIdentifier/sourceTransportPort
866 # /postNAPTSourceTransportPort
867 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
868 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
869 self.assertEqual(struct.pack("!H", self.icmp_id_out),
871 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
872 self.assertEqual(struct.pack("!H", self.tcp_port_in),
874 self.assertEqual(struct.pack("!H", self.tcp_port_out),
876 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.udp_port_in),
879 self.assertEqual(struct.pack("!H", self.udp_port_out),
882 self.fail("Invalid protocol")
883 self.assertEqual(3, nat44_ses_create_num)
884 self.assertEqual(3, nat44_ses_delete_num)
886 def verify_ipfix_addr_exhausted(self, data):
888 Verify IPFIX NAT addresses event
890 :param data: Decoded IPFIX data records
892 self.assertEqual(1, len(data))
895 self.assertEqual(scapy.compat.orb(record[230]), 3)
897 self.assertEqual(struct.pack("!I", 0), record[283])
899 def verify_ipfix_max_sessions(self, data, limit):
901 Verify IPFIX maximum session entries exceeded event
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum session entries that can be created.
906 self.assertEqual(1, len(data))
909 self.assertEqual(scapy.compat.orb(record[230]), 13)
910 # natQuotaExceededEvent
911 self.assertEqual(struct.pack("I", 1), record[466])
913 self.assertEqual(struct.pack("I", limit), record[471])
915 def verify_ipfix_max_bibs(self, data, limit):
917 Verify IPFIX maximum BIB entries exceeded event
919 :param data: Decoded IPFIX data records
920 :param limit: Number of maximum BIB entries that can be created.
922 self.assertEqual(1, len(data))
925 self.assertEqual(scapy.compat.orb(record[230]), 13)
926 # natQuotaExceededEvent
927 self.assertEqual(struct.pack("I", 2), record[466])
929 self.assertEqual(struct.pack("I", limit), record[472])
931 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
933 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
935 :param data: Decoded IPFIX data records
936 :param limit: Number of maximum fragments pending reassembly
937 :param src_addr: IPv6 source address
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 5), record[466])
945 # maxFragmentsPendingReassembly
946 self.assertEqual(struct.pack("I", limit), record[475])
948 self.assertEqual(src_addr, record[27])
950 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
952 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
954 :param data: Decoded IPFIX data records
955 :param limit: Number of maximum fragments pending reassembly
956 :param src_addr: IPv4 source address
958 self.assertEqual(1, len(data))
961 self.assertEqual(scapy.compat.orb(record[230]), 13)
962 # natQuotaExceededEvent
963 self.assertEqual(struct.pack("I", 5), record[466])
964 # maxFragmentsPendingReassembly
965 self.assertEqual(struct.pack("I", limit), record[475])
967 self.assertEqual(src_addr, record[8])
969 def verify_ipfix_bib(self, data, is_create, src_addr):
971 Verify IPFIX NAT64 BIB create and delete events
973 :param data: Decoded IPFIX data records
974 :param is_create: Create event if nonzero value otherwise delete event
975 :param src_addr: IPv6 source address
977 self.assertEqual(1, len(data))
981 self.assertEqual(scapy.compat.orb(record[230]), 10)
983 self.assertEqual(scapy.compat.orb(record[230]), 11)
985 self.assertEqual(src_addr, record[27])
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
997 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1000 Verify IPFIX NAT64 session create and delete events
1002 :param data: Decoded IPFIX data records
1003 :param is_create: Create event if nonzero value otherwise delete event
1004 :param src_addr: IPv6 source address
1005 :param dst_addr: IPv4 destination address
1006 :param dst_port: destination TCP port
1008 self.assertEqual(1, len(data))
1012 self.assertEqual(scapy.compat.orb(record[230]), 6)
1014 self.assertEqual(scapy.compat.orb(record[230]), 7)
1016 self.assertEqual(src_addr, record[27])
1017 # destinationIPv6Address
1018 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1019 self.compose_ip6(dst_addr,
1023 # postNATSourceIPv4Address
1024 self.assertEqual(self.nat_addr_n, record[225])
1025 # postNATDestinationIPv4Address
1026 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1028 # protocolIdentifier
1029 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1031 self.assertEqual(struct.pack("!I", 0), record[234])
1032 # sourceTransportPort
1033 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1034 # postNAPTSourceTransportPort
1035 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1036 # destinationTransportPort
1037 self.assertEqual(struct.pack("!H", dst_port), record[11])
1038 # postNAPTDestinationTransportPort
1039 self.assertEqual(struct.pack("!H", dst_port), record[228])
1041 def verify_no_nat44_user(self):
1042 """ Verify that there is no NAT44 user """
1043 users = self.vapi.nat44_user_dump()
1044 self.assertEqual(len(users), 0)
1045 users = self.statistics.get_counter('/nat44/total-users')
1046 self.assertEqual(users[0][0], 0)
1047 sessions = self.statistics.get_counter('/nat44/total-sessions')
1048 self.assertEqual(sessions[0][0], 0)
1050 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1052 Verify IPFIX maximum entries per user exceeded event
1054 :param data: Decoded IPFIX data records
1055 :param limit: Number of maximum entries per user
1056 :param src_addr: IPv4 source address
1058 self.assertEqual(1, len(data))
1061 self.assertEqual(scapy.compat.orb(record[230]), 13)
1062 # natQuotaExceededEvent
1063 self.assertEqual(struct.pack("I", 3), record[466])
1065 self.assertEqual(struct.pack("I", limit), record[473])
1067 self.assertEqual(src_addr, record[8])
1069 def verify_syslog_apmap(self, data, is_add=True):
1070 message = data.decode('utf-8')
1072 message = SyslogMessage.parse(message)
1073 except ParseError as e:
1074 self.logger.error(e)
1077 self.assertEqual(message.severity, SyslogSeverity.info)
1078 self.assertEqual(message.appname, 'NAT')
1079 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1080 sd_params = message.sd.get('napmap')
1081 self.assertTrue(sd_params is not None)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1085 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1086 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1087 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1088 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1089 self.assertTrue(sd_params.get('SSUBIX') is not None)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1092 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1093 message = data.decode('utf-8')
1095 message = SyslogMessage.parse(message)
1096 except ParseError as e:
1097 self.logger.error(e)
1100 self.assertEqual(message.severity, SyslogSeverity.info)
1101 self.assertEqual(message.appname, 'NAT')
1102 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1103 sd_params = message.sd.get('nsess')
1104 self.assertTrue(sd_params is not None)
1106 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1107 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1109 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1110 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1113 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1114 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1115 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1116 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1117 self.assertEqual(sd_params.get('SVLAN'), '0')
1118 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1119 self.assertEqual(sd_params.get('XDPORT'),
1120 "%d" % self.tcp_external_port)
1122 def verify_mss_value(self, pkt, mss):
1124 Verify TCP MSS value
1129 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1130 raise TypeError("Not a TCP/IP packet")
1132 for option in pkt[TCP].options:
1133 if option[0] == 'MSS':
1134 self.assertEqual(option[1], mss)
1135 self.assert_tcp_checksum_valid(pkt)
1138 def proto2layer(proto):
1139 if proto == IP_PROTOS.tcp:
1141 elif proto == IP_PROTOS.udp:
1143 elif proto == IP_PROTOS.icmp:
1146 raise Exception("Unsupported protocol")
1148 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1149 layer = self.proto2layer(proto)
1151 if proto == IP_PROTOS.tcp:
1152 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1154 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1155 self.port_in = random.randint(1025, 65535)
1157 reass = self.vapi.nat_reass_dump()
1158 reass_n_start = len(reass)
1161 pkts = self.create_stream_frag(self.pg0,
1162 self.pg1.remote_ip4,
1167 self.pg0.add_stream(pkts)
1168 self.pg_enable_capture(self.pg_interfaces)
1170 frags = self.pg1.get_capture(len(pkts))
1171 if not dont_translate:
1172 p = self.reass_frags_and_verify(frags,
1174 self.pg1.remote_ip4)
1176 p = self.reass_frags_and_verify(frags,
1177 self.pg0.remote_ip4,
1178 self.pg1.remote_ip4)
1179 if proto != IP_PROTOS.icmp:
1180 if not dont_translate:
1181 self.assertEqual(p[layer].dport, 20)
1182 self.assertNotEqual(p[layer].sport, self.port_in)
1184 self.assertEqual(p[layer].sport, self.port_in)
1186 if not dont_translate:
1187 self.assertNotEqual(p[layer].id, self.port_in)
1189 self.assertEqual(p[layer].id, self.port_in)
1190 self.assertEqual(data, p[Raw].load)
1193 if not dont_translate:
1194 dst_addr = self.nat_addr
1196 dst_addr = self.pg0.remote_ip4
1197 if proto != IP_PROTOS.icmp:
1199 dport = p[layer].sport
1203 pkts = self.create_stream_frag(self.pg1,
1210 self.pg1.add_stream(pkts)
1211 self.pg_enable_capture(self.pg_interfaces)
1213 frags = self.pg0.get_capture(len(pkts))
1214 p = self.reass_frags_and_verify(frags,
1215 self.pg1.remote_ip4,
1216 self.pg0.remote_ip4)
1217 if proto != IP_PROTOS.icmp:
1218 self.assertEqual(p[layer].sport, 20)
1219 self.assertEqual(p[layer].dport, self.port_in)
1221 self.assertEqual(p[layer].id, self.port_in)
1222 self.assertEqual(data, p[Raw].load)
1224 reass = self.vapi.nat_reass_dump()
1225 reass_n_end = len(reass)
1227 self.assertEqual(reass_n_end - reass_n_start, 2)
1229 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1230 layer = self.proto2layer(proto)
1232 if proto == IP_PROTOS.tcp:
1233 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1235 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1236 self.port_in = random.randint(1025, 65535)
1239 reass = self.vapi.nat_reass_dump()
1240 reass_n_start = len(reass)
1243 pkts = self.create_stream_frag(self.pg0,
1244 self.server_out_addr,
1246 self.server_out_port,
1249 self.pg0.add_stream(pkts)
1250 self.pg_enable_capture(self.pg_interfaces)
1252 frags = self.pg1.get_capture(len(pkts))
1253 p = self.reass_frags_and_verify(frags,
1254 self.pg0.remote_ip4,
1255 self.server_in_addr)
1256 if proto != IP_PROTOS.icmp:
1257 self.assertEqual(p[layer].sport, self.port_in)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1260 self.assertEqual(p[layer].id, self.port_in)
1261 self.assertEqual(data, p[Raw].load)
1264 if proto != IP_PROTOS.icmp:
1265 pkts = self.create_stream_frag(self.pg1,
1266 self.pg0.remote_ip4,
1267 self.server_in_port,
1272 pkts = self.create_stream_frag(self.pg1,
1273 self.pg0.remote_ip4,
1279 self.pg1.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg0.get_capture(len(pkts))
1283 p = self.reass_frags_and_verify(frags,
1284 self.server_out_addr,
1285 self.pg0.remote_ip4)
1286 if proto != IP_PROTOS.icmp:
1287 self.assertEqual(p[layer].sport, self.server_out_port)
1288 self.assertEqual(p[layer].dport, self.port_in)
1290 self.assertEqual(p[layer].id, self.port_in)
1291 self.assertEqual(data, p[Raw].load)
1293 reass = self.vapi.nat_reass_dump()
1294 reass_n_end = len(reass)
1296 self.assertEqual(reass_n_end - reass_n_start, 2)
1298 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1299 layer = self.proto2layer(proto)
1301 if proto == IP_PROTOS.tcp:
1302 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1304 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1306 # send packet from host to server
1307 pkts = self.create_stream_frag(self.pg0,
1310 self.server_out_port,
1313 self.pg0.add_stream(pkts)
1314 self.pg_enable_capture(self.pg_interfaces)
1316 frags = self.pg0.get_capture(len(pkts))
1317 p = self.reass_frags_and_verify(frags,
1320 if proto != IP_PROTOS.icmp:
1321 self.assertNotEqual(p[layer].sport, self.host_in_port)
1322 self.assertEqual(p[layer].dport, self.server_in_port)
1324 self.assertNotEqual(p[layer].id, self.host_in_port)
1325 self.assertEqual(data, p[Raw].load)
1327 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1328 layer = self.proto2layer(proto)
1330 if proto == IP_PROTOS.tcp:
1331 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1333 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1334 self.port_in = random.randint(1025, 65535)
1338 pkts = self.create_stream_frag(self.pg0,
1339 self.pg1.remote_ip4,
1345 self.pg0.add_stream(pkts)
1346 self.pg_enable_capture(self.pg_interfaces)
1348 frags = self.pg1.get_capture(len(pkts))
1349 if not dont_translate:
1350 p = self.reass_frags_and_verify(frags,
1352 self.pg1.remote_ip4)
1354 p = self.reass_frags_and_verify(frags,
1355 self.pg0.remote_ip4,
1356 self.pg1.remote_ip4)
1357 if proto != IP_PROTOS.icmp:
1358 if not dont_translate:
1359 self.assertEqual(p[layer].dport, 20)
1360 self.assertNotEqual(p[layer].sport, self.port_in)
1362 self.assertEqual(p[layer].sport, self.port_in)
1364 if not dont_translate:
1365 self.assertNotEqual(p[layer].id, self.port_in)
1367 self.assertEqual(p[layer].id, self.port_in)
1368 self.assertEqual(data, p[Raw].load)
1371 if not dont_translate:
1372 dst_addr = self.nat_addr
1374 dst_addr = self.pg0.remote_ip4
1375 if proto != IP_PROTOS.icmp:
1377 dport = p[layer].sport
1381 pkts = self.create_stream_frag(self.pg1,
1389 self.pg1.add_stream(pkts)
1390 self.pg_enable_capture(self.pg_interfaces)
1392 frags = self.pg0.get_capture(len(pkts))
1393 p = self.reass_frags_and_verify(frags,
1394 self.pg1.remote_ip4,
1395 self.pg0.remote_ip4)
1396 if proto != IP_PROTOS.icmp:
1397 self.assertEqual(p[layer].sport, 20)
1398 self.assertEqual(p[layer].dport, self.port_in)
1400 self.assertEqual(p[layer].id, self.port_in)
1401 self.assertEqual(data, p[Raw].load)
1403 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1404 layer = self.proto2layer(proto)
1406 if proto == IP_PROTOS.tcp:
1407 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1409 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1410 self.port_in = random.randint(1025, 65535)
1414 pkts = self.create_stream_frag(self.pg0,
1415 self.server_out_addr,
1417 self.server_out_port,
1421 self.pg0.add_stream(pkts)
1422 self.pg_enable_capture(self.pg_interfaces)
1424 frags = self.pg1.get_capture(len(pkts))
1425 p = self.reass_frags_and_verify(frags,
1426 self.pg0.remote_ip4,
1427 self.server_in_addr)
1428 if proto != IP_PROTOS.icmp:
1429 self.assertEqual(p[layer].dport, self.server_in_port)
1430 self.assertEqual(p[layer].sport, self.port_in)
1431 self.assertEqual(p[layer].dport, self.server_in_port)
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1437 if proto != IP_PROTOS.icmp:
1438 pkts = self.create_stream_frag(self.pg1,
1439 self.pg0.remote_ip4,
1440 self.server_in_port,
1445 pkts = self.create_stream_frag(self.pg1,
1446 self.pg0.remote_ip4,
1453 self.pg1.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1456 frags = self.pg0.get_capture(len(pkts))
1457 p = self.reass_frags_and_verify(frags,
1458 self.server_out_addr,
1459 self.pg0.remote_ip4)
1460 if proto != IP_PROTOS.icmp:
1461 self.assertEqual(p[layer].sport, self.server_out_port)
1462 self.assertEqual(p[layer].dport, self.port_in)
1464 self.assertEqual(p[layer].id, self.port_in)
1465 self.assertEqual(data, p[Raw].load)
1468 class TestNAT44(MethodHolder):
1469 """ NAT44 Test Cases """
1472 def setUpClass(cls):
1473 super(TestNAT44, cls).setUpClass()
1474 cls.vapi.cli("set log class nat level debug")
1477 cls.tcp_port_in = 6303
1478 cls.tcp_port_out = 6303
1479 cls.udp_port_in = 6304
1480 cls.udp_port_out = 6304
1481 cls.icmp_id_in = 6305
1482 cls.icmp_id_out = 6305
1483 cls.nat_addr = '10.0.0.3'
1484 cls.ipfix_src_port = 4739
1485 cls.ipfix_domain_id = 1
1486 cls.tcp_external_port = 80
1487 cls.udp_external_port = 69
1489 cls.create_pg_interfaces(range(10))
1490 cls.interfaces = list(cls.pg_interfaces[0:4])
1492 for i in cls.interfaces:
1497 cls.pg0.generate_remote_hosts(3)
1498 cls.pg0.configure_ipv4_neighbors()
1500 cls.pg1.generate_remote_hosts(1)
1501 cls.pg1.configure_ipv4_neighbors()
1503 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1504 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1505 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1507 cls.pg4._local_ip4 = "172.16.255.1"
1508 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1509 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1510 cls.pg4.set_table_ip4(10)
1511 cls.pg5._local_ip4 = "172.17.255.3"
1512 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1513 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1514 cls.pg5.set_table_ip4(10)
1515 cls.pg6._local_ip4 = "172.16.255.1"
1516 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1517 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1518 cls.pg6.set_table_ip4(20)
1519 for i in cls.overlapping_interfaces:
1527 cls.pg9.generate_remote_hosts(2)
1528 cls.pg9.config_ip4()
1529 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1530 cls.vapi.sw_interface_add_del_address(
1531 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1534 cls.pg9.resolve_arp()
1535 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1536 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1537 cls.pg9.resolve_arp()
1540 super(TestNAT44, cls).tearDownClass()
1544 def tearDownClass(cls):
1545 super(TestNAT44, cls).tearDownClass()
1547 def test_dynamic(self):
1548 """ NAT44 dynamic translation test """
1549 self.nat44_add_address(self.nat_addr)
1550 flags = self.config_flags.NAT_IS_INSIDE
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg0.sw_if_index,
1553 flags=flags, is_add=1)
1554 self.vapi.nat44_interface_add_del_feature(
1555 sw_if_index=self.pg1.sw_if_index,
1559 tcpn = self.statistics.get_err_counter(
1560 '/err/nat44-in2out-slowpath/TCP packets')
1561 udpn = self.statistics.get_err_counter(
1562 '/err/nat44-in2out-slowpath/UDP packets')
1563 icmpn = self.statistics.get_err_counter(
1564 '/err/nat44-in2out-slowpath/ICMP packets')
1565 totaln = self.statistics.get_err_counter(
1566 '/err/nat44-in2out-slowpath/good in2out packets processed')
1568 pkts = self.create_stream_in(self.pg0, self.pg1)
1569 self.pg0.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1572 capture = self.pg1.get_capture(len(pkts))
1573 self.verify_capture_out(capture)
1575 err = self.statistics.get_err_counter(
1576 '/err/nat44-in2out-slowpath/TCP packets')
1577 self.assertEqual(err - tcpn, 1)
1578 err = self.statistics.get_err_counter(
1579 '/err/nat44-in2out-slowpath/UDP packets')
1580 self.assertEqual(err - udpn, 1)
1581 err = self.statistics.get_err_counter(
1582 '/err/nat44-in2out-slowpath/ICMP packets')
1583 self.assertEqual(err - icmpn, 1)
1584 err = self.statistics.get_err_counter(
1585 '/err/nat44-in2out-slowpath/good in2out packets processed')
1586 self.assertEqual(err - totaln, 3)
1589 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1590 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1591 icmpn = self.statistics.get_err_counter(
1592 '/err/nat44-out2in/ICMP packets')
1593 totaln = self.statistics.get_err_counter(
1594 '/err/nat44-out2in/good out2in packets processed')
1596 pkts = self.create_stream_out(self.pg1)
1597 self.pg1.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1600 capture = self.pg0.get_capture(len(pkts))
1601 self.verify_capture_in(capture, self.pg0)
1603 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1604 self.assertEqual(err - tcpn, 1)
1605 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1606 self.assertEqual(err - udpn, 1)
1607 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1608 self.assertEqual(err - icmpn, 1)
1609 err = self.statistics.get_err_counter(
1610 '/err/nat44-out2in/good out2in packets processed')
1611 self.assertEqual(err - totaln, 3)
1613 users = self.statistics.get_counter('/nat44/total-users')
1614 self.assertEqual(users[0][0], 1)
1615 sessions = self.statistics.get_counter('/nat44/total-sessions')
1616 self.assertEqual(sessions[0][0], 3)
1618 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1619 """ NAT44 handling of client packets with TTL=1 """
1621 self.nat44_add_address(self.nat_addr)
1622 flags = self.config_flags.NAT_IS_INSIDE
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg0.sw_if_index,
1625 flags=flags, is_add=1)
1626 self.vapi.nat44_interface_add_del_feature(
1627 sw_if_index=self.pg1.sw_if_index,
1630 # Client side - generate traffic
1631 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1632 self.pg0.add_stream(pkts)
1633 self.pg_enable_capture(self.pg_interfaces)
1636 # Client side - verify ICMP type 11 packets
1637 capture = self.pg0.get_capture(len(pkts))
1638 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1640 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1641 """ NAT44 handling of server packets with TTL=1 """
1643 self.nat44_add_address(self.nat_addr)
1644 flags = self.config_flags.NAT_IS_INSIDE
1645 self.vapi.nat44_interface_add_del_feature(
1646 sw_if_index=self.pg0.sw_if_index,
1647 flags=flags, is_add=1)
1648 self.vapi.nat44_interface_add_del_feature(
1649 sw_if_index=self.pg1.sw_if_index,
1652 # Client side - create sessions
1653 pkts = self.create_stream_in(self.pg0, self.pg1)
1654 self.pg0.add_stream(pkts)
1655 self.pg_enable_capture(self.pg_interfaces)
1658 # Server side - generate traffic
1659 capture = self.pg1.get_capture(len(pkts))
1660 self.verify_capture_out(capture)
1661 pkts = self.create_stream_out(self.pg1, ttl=1)
1662 self.pg1.add_stream(pkts)
1663 self.pg_enable_capture(self.pg_interfaces)
1666 # Server side - verify ICMP type 11 packets
1667 capture = self.pg1.get_capture(len(pkts))
1668 self.verify_capture_out_with_icmp_errors(capture,
1669 src_ip=self.pg1.local_ip4)
1671 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1672 """ NAT44 handling of error responses to client packets with TTL=2 """
1674 self.nat44_add_address(self.nat_addr)
1675 flags = self.config_flags.NAT_IS_INSIDE
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg0.sw_if_index,
1678 flags=flags, is_add=1)
1679 self.vapi.nat44_interface_add_del_feature(
1680 sw_if_index=self.pg1.sw_if_index,
1683 # Client side - generate traffic
1684 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1685 self.pg0.add_stream(pkts)
1686 self.pg_enable_capture(self.pg_interfaces)
1689 # Server side - simulate ICMP type 11 response
1690 capture = self.pg1.get_capture(len(pkts))
1691 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1692 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1693 ICMP(type=11) / packet[IP] for packet in capture]
1694 self.pg1.add_stream(pkts)
1695 self.pg_enable_capture(self.pg_interfaces)
1698 # Client side - verify ICMP type 11 packets
1699 capture = self.pg0.get_capture(len(pkts))
1700 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1702 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1703 """ NAT44 handling of error responses to server packets with TTL=2 """
1705 self.nat44_add_address(self.nat_addr)
1706 flags = self.config_flags.NAT_IS_INSIDE
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg0.sw_if_index,
1709 flags=flags, is_add=1)
1710 self.vapi.nat44_interface_add_del_feature(
1711 sw_if_index=self.pg1.sw_if_index,
1714 # Client side - create sessions
1715 pkts = self.create_stream_in(self.pg0, self.pg1)
1716 self.pg0.add_stream(pkts)
1717 self.pg_enable_capture(self.pg_interfaces)
1720 # Server side - generate traffic
1721 capture = self.pg1.get_capture(len(pkts))
1722 self.verify_capture_out(capture)
1723 pkts = self.create_stream_out(self.pg1, ttl=2)
1724 self.pg1.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1728 # Client side - simulate ICMP type 11 response
1729 capture = self.pg0.get_capture(len(pkts))
1730 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1731 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1732 ICMP(type=11) / packet[IP] for packet in capture]
1733 self.pg0.add_stream(pkts)
1734 self.pg_enable_capture(self.pg_interfaces)
1737 # Server side - verify ICMP type 11 packets
1738 capture = self.pg1.get_capture(len(pkts))
1739 self.verify_capture_out_with_icmp_errors(capture)
1741 def test_ping_out_interface_from_outside(self):
1742 """ Ping NAT44 out interface from outside network """
1744 self.nat44_add_address(self.nat_addr)
1745 flags = self.config_flags.NAT_IS_INSIDE
1746 self.vapi.nat44_interface_add_del_feature(
1747 sw_if_index=self.pg0.sw_if_index,
1748 flags=flags, is_add=1)
1749 self.vapi.nat44_interface_add_del_feature(
1750 sw_if_index=self.pg1.sw_if_index,
1753 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1754 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1755 ICMP(id=self.icmp_id_out, type='echo-request'))
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg1.get_capture(len(pkts))
1763 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1764 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1765 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1766 self.assertEqual(packet[ICMP].type, 0) # echo reply
1768 self.logger.error(ppp("Unexpected or invalid packet "
1769 "(outside network):", packet))
1772 def test_ping_internal_host_from_outside(self):
1773 """ Ping internal host from outside network """
1775 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1776 flags = self.config_flags.NAT_IS_INSIDE
1777 self.vapi.nat44_interface_add_del_feature(
1778 sw_if_index=self.pg0.sw_if_index,
1779 flags=flags, is_add=1)
1780 self.vapi.nat44_interface_add_del_feature(
1781 sw_if_index=self.pg1.sw_if_index,
1785 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1786 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1787 ICMP(id=self.icmp_id_out, type='echo-request'))
1788 self.pg1.add_stream(pkt)
1789 self.pg_enable_capture(self.pg_interfaces)
1791 capture = self.pg0.get_capture(1)
1792 self.verify_capture_in(capture, self.pg0)
1793 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1796 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1797 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1798 ICMP(id=self.icmp_id_in, type='echo-reply'))
1799 self.pg0.add_stream(pkt)
1800 self.pg_enable_capture(self.pg_interfaces)
1802 capture = self.pg1.get_capture(1)
1803 self.verify_capture_out(capture, same_port=True)
1804 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1806 def test_forwarding(self):
1807 """ NAT44 forwarding test """
1809 flags = self.config_flags.NAT_IS_INSIDE
1810 self.vapi.nat44_interface_add_del_feature(
1811 sw_if_index=self.pg0.sw_if_index,
1812 flags=flags, is_add=1)
1813 self.vapi.nat44_interface_add_del_feature(
1814 sw_if_index=self.pg1.sw_if_index,
1816 self.vapi.nat44_forwarding_enable_disable(enable=1)
1818 real_ip = self.pg0.remote_ip4n
1819 alias_ip = self.nat_addr
1820 flags = self.config_flags.NAT_IS_ADDR_ONLY
1821 self.vapi.nat44_add_del_static_mapping(is_add=1,
1822 local_ip_address=real_ip,
1823 external_ip_address=alias_ip,
1824 external_sw_if_index=0xFFFFFFFF,
1828 # static mapping match
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1837 pkts = self.create_stream_in(self.pg0, self.pg1)
1838 self.pg0.add_stream(pkts)
1839 self.pg_enable_capture(self.pg_interfaces)
1841 capture = self.pg1.get_capture(len(pkts))
1842 self.verify_capture_out(capture, same_port=True)
1844 # no static mapping match
1846 host0 = self.pg0.remote_hosts[0]
1847 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1849 pkts = self.create_stream_out(self.pg1,
1850 dst_ip=self.pg0.remote_ip4,
1851 use_inside_ports=True)
1852 self.pg1.add_stream(pkts)
1853 self.pg_enable_capture(self.pg_interfaces)
1855 capture = self.pg0.get_capture(len(pkts))
1856 self.verify_capture_in(capture, self.pg0)
1858 pkts = self.create_stream_in(self.pg0, self.pg1)
1859 self.pg0.add_stream(pkts)
1860 self.pg_enable_capture(self.pg_interfaces)
1862 capture = self.pg1.get_capture(len(pkts))
1863 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1866 self.pg0.remote_hosts[0] = host0
1869 self.vapi.nat44_forwarding_enable_disable(enable=0)
1870 flags = self.config_flags.NAT_IS_ADDR_ONLY
1871 self.vapi.nat44_add_del_static_mapping(
1873 local_ip_address=real_ip,
1874 external_ip_address=alias_ip,
1875 external_sw_if_index=0xFFFFFFFF,
1878 def test_static_in(self):
1879 """ 1:1 NAT initialized from inside network """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1887 flags = self.config_flags.NAT_IS_INSIDE
1888 self.vapi.nat44_interface_add_del_feature(
1889 sw_if_index=self.pg0.sw_if_index,
1890 flags=flags, is_add=1)
1891 self.vapi.nat44_interface_add_del_feature(
1892 sw_if_index=self.pg1.sw_if_index,
1894 sm = self.vapi.nat44_static_mapping_dump()
1895 self.assertEqual(len(sm), 1)
1896 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], b'')
1897 self.assertEqual(sm[0].protocol, 0)
1898 self.assertEqual(sm[0].local_port, 0)
1899 self.assertEqual(sm[0].external_port, 0)
1902 pkts = self.create_stream_in(self.pg0, self.pg1)
1903 self.pg0.add_stream(pkts)
1904 self.pg_enable_capture(self.pg_interfaces)
1906 capture = self.pg1.get_capture(len(pkts))
1907 self.verify_capture_out(capture, nat_ip, True)
1910 pkts = self.create_stream_out(self.pg1, nat_ip)
1911 self.pg1.add_stream(pkts)
1912 self.pg_enable_capture(self.pg_interfaces)
1914 capture = self.pg0.get_capture(len(pkts))
1915 self.verify_capture_in(capture, self.pg0)
1917 def test_static_out(self):
1918 """ 1:1 NAT initialized from outside network """
1920 nat_ip = "10.0.0.20"
1921 self.tcp_port_out = 6303
1922 self.udp_port_out = 6304
1923 self.icmp_id_out = 6305
1926 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1927 flags = self.config_flags.NAT_IS_INSIDE
1928 self.vapi.nat44_interface_add_del_feature(
1929 sw_if_index=self.pg0.sw_if_index,
1930 flags=flags, is_add=1)
1931 self.vapi.nat44_interface_add_del_feature(
1932 sw_if_index=self.pg1.sw_if_index,
1934 sm = self.vapi.nat44_static_mapping_dump()
1935 self.assertEqual(len(sm), 1)
1936 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1939 pkts = self.create_stream_out(self.pg1, nat_ip)
1940 self.pg1.add_stream(pkts)
1941 self.pg_enable_capture(self.pg_interfaces)
1943 capture = self.pg0.get_capture(len(pkts))
1944 self.verify_capture_in(capture, self.pg0)
1947 pkts = self.create_stream_in(self.pg0, self.pg1)
1948 self.pg0.add_stream(pkts)
1949 self.pg_enable_capture(self.pg_interfaces)
1951 capture = self.pg1.get_capture(len(pkts))
1952 self.verify_capture_out(capture, nat_ip, True)
1954 def test_static_with_port_in(self):
1955 """ 1:1 NAPT initialized from inside network """
1957 self.tcp_port_out = 3606
1958 self.udp_port_out = 3607
1959 self.icmp_id_out = 3608
1961 self.nat44_add_address(self.nat_addr)
1962 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1963 self.tcp_port_in, self.tcp_port_out,
1964 proto=IP_PROTOS.tcp)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.udp_port_in, self.udp_port_out,
1967 proto=IP_PROTOS.udp)
1968 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1969 self.icmp_id_in, self.icmp_id_out,
1970 proto=IP_PROTOS.icmp)
1971 flags = self.config_flags.NAT_IS_INSIDE
1972 self.vapi.nat44_interface_add_del_feature(
1973 sw_if_index=self.pg0.sw_if_index,
1974 flags=flags, is_add=1)
1975 self.vapi.nat44_interface_add_del_feature(
1976 sw_if_index=self.pg1.sw_if_index,
1980 pkts = self.create_stream_in(self.pg0, self.pg1)
1981 self.pg0.add_stream(pkts)
1982 self.pg_enable_capture(self.pg_interfaces)
1984 capture = self.pg1.get_capture(len(pkts))
1985 self.verify_capture_out(capture)
1988 pkts = self.create_stream_out(self.pg1)
1989 self.pg1.add_stream(pkts)
1990 self.pg_enable_capture(self.pg_interfaces)
1992 capture = self.pg0.get_capture(len(pkts))
1993 self.verify_capture_in(capture, self.pg0)
1995 def test_static_with_port_out(self):
1996 """ 1:1 NAPT initialized from outside network """
1998 self.tcp_port_out = 30606
1999 self.udp_port_out = 30607
2000 self.icmp_id_out = 30608
2002 self.nat44_add_address(self.nat_addr)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2004 self.tcp_port_in, self.tcp_port_out,
2005 proto=IP_PROTOS.tcp)
2006 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2007 self.udp_port_in, self.udp_port_out,
2008 proto=IP_PROTOS.udp)
2009 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2010 self.icmp_id_in, self.icmp_id_out,
2011 proto=IP_PROTOS.icmp)
2012 flags = self.config_flags.NAT_IS_INSIDE
2013 self.vapi.nat44_interface_add_del_feature(
2014 sw_if_index=self.pg0.sw_if_index,
2015 flags=flags, is_add=1)
2016 self.vapi.nat44_interface_add_del_feature(
2017 sw_if_index=self.pg1.sw_if_index,
2021 pkts = self.create_stream_out(self.pg1)
2022 self.pg1.add_stream(pkts)
2023 self.pg_enable_capture(self.pg_interfaces)
2025 capture = self.pg0.get_capture(len(pkts))
2026 self.verify_capture_in(capture, self.pg0)
2029 pkts = self.create_stream_in(self.pg0, self.pg1)
2030 self.pg0.add_stream(pkts)
2031 self.pg_enable_capture(self.pg_interfaces)
2033 capture = self.pg1.get_capture(len(pkts))
2034 self.verify_capture_out(capture)
2036 def test_static_vrf_aware(self):
2037 """ 1:1 NAT VRF awareness """
2039 nat_ip1 = "10.0.0.30"
2040 nat_ip2 = "10.0.0.40"
2041 self.tcp_port_out = 6303
2042 self.udp_port_out = 6304
2043 self.icmp_id_out = 6305
2045 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2047 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2049 flags = self.config_flags.NAT_IS_INSIDE
2050 self.vapi.nat44_interface_add_del_feature(
2051 sw_if_index=self.pg3.sw_if_index,
2053 self.vapi.nat44_interface_add_del_feature(
2054 sw_if_index=self.pg0.sw_if_index,
2055 flags=flags, is_add=1)
2056 self.vapi.nat44_interface_add_del_feature(
2057 sw_if_index=self.pg4.sw_if_index,
2058 flags=flags, is_add=1)
2060 # inside interface VRF match NAT44 static mapping VRF
2061 pkts = self.create_stream_in(self.pg4, self.pg3)
2062 self.pg4.add_stream(pkts)
2063 self.pg_enable_capture(self.pg_interfaces)
2065 capture = self.pg3.get_capture(len(pkts))
2066 self.verify_capture_out(capture, nat_ip1, True)
2068 # inside interface VRF don't match NAT44 static mapping VRF (packets
2070 pkts = self.create_stream_in(self.pg0, self.pg3)
2071 self.pg0.add_stream(pkts)
2072 self.pg_enable_capture(self.pg_interfaces)
2074 self.pg3.assert_nothing_captured()
2076 def test_dynamic_to_static(self):
2077 """ Switch from dynamic translation to 1:1NAT """
2078 nat_ip = "10.0.0.10"
2079 self.tcp_port_out = 6303
2080 self.udp_port_out = 6304
2081 self.icmp_id_out = 6305
2083 self.nat44_add_address(self.nat_addr)
2084 flags = self.config_flags.NAT_IS_INSIDE
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg0.sw_if_index,
2087 flags=flags, is_add=1)
2088 self.vapi.nat44_interface_add_del_feature(
2089 sw_if_index=self.pg1.sw_if_index,
2093 pkts = self.create_stream_in(self.pg0, self.pg1)
2094 self.pg0.add_stream(pkts)
2095 self.pg_enable_capture(self.pg_interfaces)
2097 capture = self.pg1.get_capture(len(pkts))
2098 self.verify_capture_out(capture)
2101 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2102 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2103 self.assertEqual(len(sessions), 0)
2104 pkts = self.create_stream_in(self.pg0, self.pg1)
2105 self.pg0.add_stream(pkts)
2106 self.pg_enable_capture(self.pg_interfaces)
2108 capture = self.pg1.get_capture(len(pkts))
2109 self.verify_capture_out(capture, nat_ip, True)
2111 def test_identity_nat(self):
2112 """ Identity NAT """
2113 flags = self.config_flags.NAT_IS_ADDR_ONLY
2114 self.vapi.nat44_add_del_identity_mapping(
2115 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2116 flags=flags, is_add=1)
2117 flags = self.config_flags.NAT_IS_INSIDE
2118 self.vapi.nat44_interface_add_del_feature(
2119 sw_if_index=self.pg0.sw_if_index,
2120 flags=flags, is_add=1)
2121 self.vapi.nat44_interface_add_del_feature(
2122 sw_if_index=self.pg1.sw_if_index,
2125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2126 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2127 TCP(sport=12345, dport=56789))
2128 self.pg1.add_stream(p)
2129 self.pg_enable_capture(self.pg_interfaces)
2131 capture = self.pg0.get_capture(1)
2136 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2137 self.assertEqual(ip.src, self.pg1.remote_ip4)
2138 self.assertEqual(tcp.dport, 56789)
2139 self.assertEqual(tcp.sport, 12345)
2140 self.assert_packet_checksums_valid(p)
2142 self.logger.error(ppp("Unexpected or invalid packet:", p))
2145 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2146 self.assertEqual(len(sessions), 0)
2147 flags = self.config_flags.NAT_IS_ADDR_ONLY
2148 self.vapi.nat44_add_del_identity_mapping(
2149 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2150 flags=flags, vrf_id=1, is_add=1)
2151 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2152 self.assertEqual(len(identity_mappings), 2)
2154 def test_multiple_inside_interfaces(self):
2155 """ NAT44 multiple non-overlapping address space inside interfaces """
2157 self.nat44_add_address(self.nat_addr)
2158 flags = self.config_flags.NAT_IS_INSIDE
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg0.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg1.sw_if_index,
2164 flags=flags, is_add=1)
2165 self.vapi.nat44_interface_add_del_feature(
2166 sw_if_index=self.pg3.sw_if_index,
2169 # between two NAT44 inside interfaces (no translation)
2170 pkts = self.create_stream_in(self.pg0, self.pg1)
2171 self.pg0.add_stream(pkts)
2172 self.pg_enable_capture(self.pg_interfaces)
2174 capture = self.pg1.get_capture(len(pkts))
2175 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2177 # from NAT44 inside to interface without NAT44 feature (no translation)
2178 pkts = self.create_stream_in(self.pg0, self.pg2)
2179 self.pg0.add_stream(pkts)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg2.get_capture(len(pkts))
2183 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2185 # in2out 1st interface
2186 pkts = self.create_stream_in(self.pg0, self.pg3)
2187 self.pg0.add_stream(pkts)
2188 self.pg_enable_capture(self.pg_interfaces)
2190 capture = self.pg3.get_capture(len(pkts))
2191 self.verify_capture_out(capture)
2193 # out2in 1st interface
2194 pkts = self.create_stream_out(self.pg3)
2195 self.pg3.add_stream(pkts)
2196 self.pg_enable_capture(self.pg_interfaces)
2198 capture = self.pg0.get_capture(len(pkts))
2199 self.verify_capture_in(capture, self.pg0)
2201 # in2out 2nd interface
2202 pkts = self.create_stream_in(self.pg1, self.pg3)
2203 self.pg1.add_stream(pkts)
2204 self.pg_enable_capture(self.pg_interfaces)
2206 capture = self.pg3.get_capture(len(pkts))
2207 self.verify_capture_out(capture)
2209 # out2in 2nd interface
2210 pkts = self.create_stream_out(self.pg3)
2211 self.pg3.add_stream(pkts)
2212 self.pg_enable_capture(self.pg_interfaces)
2214 capture = self.pg1.get_capture(len(pkts))
2215 self.verify_capture_in(capture, self.pg1)
2217 def test_inside_overlapping_interfaces(self):
2218 """ NAT44 multiple inside interfaces with overlapping address space """
2220 static_nat_ip = "10.0.0.10"
2221 self.nat44_add_address(self.nat_addr)
2222 flags = self.config_flags.NAT_IS_INSIDE
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg3.sw_if_index,
2226 self.vapi.nat44_interface_add_del_feature(
2227 sw_if_index=self.pg4.sw_if_index,
2228 flags=flags, is_add=1)
2229 self.vapi.nat44_interface_add_del_feature(
2230 sw_if_index=self.pg5.sw_if_index,
2231 flags=flags, is_add=1)
2232 self.vapi.nat44_interface_add_del_feature(
2233 sw_if_index=self.pg6.sw_if_index,
2234 flags=flags, is_add=1)
2235 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2238 # between NAT44 inside interfaces with same VRF (no translation)
2239 pkts = self.create_stream_in(self.pg4, self.pg5)
2240 self.pg4.add_stream(pkts)
2241 self.pg_enable_capture(self.pg_interfaces)
2243 capture = self.pg5.get_capture(len(pkts))
2244 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2246 # between NAT44 inside interfaces with different VRF (hairpinning)
2247 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2248 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2249 TCP(sport=1234, dport=5678))
2250 self.pg4.add_stream(p)
2251 self.pg_enable_capture(self.pg_interfaces)
2253 capture = self.pg6.get_capture(1)
2258 self.assertEqual(ip.src, self.nat_addr)
2259 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2260 self.assertNotEqual(tcp.sport, 1234)
2261 self.assertEqual(tcp.dport, 5678)
2263 self.logger.error(ppp("Unexpected or invalid packet:", p))
2266 # in2out 1st interface
2267 pkts = self.create_stream_in(self.pg4, self.pg3)
2268 self.pg4.add_stream(pkts)
2269 self.pg_enable_capture(self.pg_interfaces)
2271 capture = self.pg3.get_capture(len(pkts))
2272 self.verify_capture_out(capture)
2274 # out2in 1st interface
2275 pkts = self.create_stream_out(self.pg3)
2276 self.pg3.add_stream(pkts)
2277 self.pg_enable_capture(self.pg_interfaces)
2279 capture = self.pg4.get_capture(len(pkts))
2280 self.verify_capture_in(capture, self.pg4)
2282 # in2out 2nd interface
2283 pkts = self.create_stream_in(self.pg5, self.pg3)
2284 self.pg5.add_stream(pkts)
2285 self.pg_enable_capture(self.pg_interfaces)
2287 capture = self.pg3.get_capture(len(pkts))
2288 self.verify_capture_out(capture)
2290 # out2in 2nd interface
2291 pkts = self.create_stream_out(self.pg3)
2292 self.pg3.add_stream(pkts)
2293 self.pg_enable_capture(self.pg_interfaces)
2295 capture = self.pg5.get_capture(len(pkts))
2296 self.verify_capture_in(capture, self.pg5)
2299 addresses = self.vapi.nat44_address_dump()
2300 self.assertEqual(len(addresses), 1)
2301 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2302 self.assertEqual(len(sessions), 3)
2303 for session in sessions:
2304 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2305 self.assertEqual(str(session.inside_ip_address),
2306 self.pg5.remote_ip4)
2307 self.assertEqual(session.outside_ip_address,
2308 addresses[0].ip_address)
2309 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2310 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2311 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2312 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2313 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2314 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2315 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2316 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2317 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2319 # in2out 3rd interface
2320 pkts = self.create_stream_in(self.pg6, self.pg3)
2321 self.pg6.add_stream(pkts)
2322 self.pg_enable_capture(self.pg_interfaces)
2324 capture = self.pg3.get_capture(len(pkts))
2325 self.verify_capture_out(capture, static_nat_ip, True)
2327 # out2in 3rd interface
2328 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2329 self.pg3.add_stream(pkts)
2330 self.pg_enable_capture(self.pg_interfaces)
2332 capture = self.pg6.get_capture(len(pkts))
2333 self.verify_capture_in(capture, self.pg6)
2335 # general user and session dump verifications
2336 users = self.vapi.nat44_user_dump()
2337 self.assertGreaterEqual(len(users), 3)
2338 addresses = self.vapi.nat44_address_dump()
2339 self.assertEqual(len(addresses), 1)
2341 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2343 for session in sessions:
2344 self.assertEqual(user.ip_address, session.inside_ip_address)
2345 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2346 self.assertTrue(session.protocol in
2347 [IP_PROTOS.tcp, IP_PROTOS.udp,
2349 self.assertFalse(session.flags &
2350 self.config_flags.NAT_IS_EXT_HOST_VALID)
2353 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2354 self.assertGreaterEqual(len(sessions), 4)
2355 for session in sessions:
2356 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2357 self.assertEqual(str(session.inside_ip_address),
2358 self.pg4.remote_ip4)
2359 self.assertEqual(session.outside_ip_address,
2360 addresses[0].ip_address)
2363 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2364 self.assertGreaterEqual(len(sessions), 3)
2365 for session in sessions:
2366 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2367 self.assertEqual(str(session.inside_ip_address),
2368 self.pg6.remote_ip4)
2369 self.assertEqual(str(session.outside_ip_address),
2371 self.assertTrue(session.inside_port in
2372 [self.tcp_port_in, self.udp_port_in,
2375 def test_hairpinning(self):
2376 """ NAT44 hairpinning - 1:1 NAPT """
2378 host = self.pg0.remote_hosts[0]
2379 server = self.pg0.remote_hosts[1]
2382 server_in_port = 5678
2383 server_out_port = 8765
2385 self.nat44_add_address(self.nat_addr)
2386 flags = self.config_flags.NAT_IS_INSIDE
2387 self.vapi.nat44_interface_add_del_feature(
2388 sw_if_index=self.pg0.sw_if_index,
2389 flags=flags, is_add=1)
2390 self.vapi.nat44_interface_add_del_feature(
2391 sw_if_index=self.pg1.sw_if_index,
2394 # add static mapping for server
2395 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2396 server_in_port, server_out_port,
2397 proto=IP_PROTOS.tcp)
2399 # send packet from host to server
2400 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2401 IP(src=host.ip4, dst=self.nat_addr) /
2402 TCP(sport=host_in_port, dport=server_out_port))
2403 self.pg0.add_stream(p)
2404 self.pg_enable_capture(self.pg_interfaces)
2406 capture = self.pg0.get_capture(1)
2411 self.assertEqual(ip.src, self.nat_addr)
2412 self.assertEqual(ip.dst, server.ip4)
2413 self.assertNotEqual(tcp.sport, host_in_port)
2414 self.assertEqual(tcp.dport, server_in_port)
2415 self.assert_packet_checksums_valid(p)
2416 host_out_port = tcp.sport
2418 self.logger.error(ppp("Unexpected or invalid packet:", p))
2421 # send reply from server to host
2422 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2423 IP(src=server.ip4, dst=self.nat_addr) /
2424 TCP(sport=server_in_port, dport=host_out_port))
2425 self.pg0.add_stream(p)
2426 self.pg_enable_capture(self.pg_interfaces)
2428 capture = self.pg0.get_capture(1)
2433 self.assertEqual(ip.src, self.nat_addr)
2434 self.assertEqual(ip.dst, host.ip4)
2435 self.assertEqual(tcp.sport, server_out_port)
2436 self.assertEqual(tcp.dport, host_in_port)
2437 self.assert_packet_checksums_valid(p)
2439 self.logger.error(ppp("Unexpected or invalid packet:", p))
2442 def test_hairpinning2(self):
2443 """ NAT44 hairpinning - 1:1 NAT"""
2445 server1_nat_ip = "10.0.0.10"
2446 server2_nat_ip = "10.0.0.11"
2447 host = self.pg0.remote_hosts[0]
2448 server1 = self.pg0.remote_hosts[1]
2449 server2 = self.pg0.remote_hosts[2]
2450 server_tcp_port = 22
2451 server_udp_port = 20
2453 self.nat44_add_address(self.nat_addr)
2454 flags = self.config_flags.NAT_IS_INSIDE
2455 self.vapi.nat44_interface_add_del_feature(
2456 sw_if_index=self.pg0.sw_if_index,
2457 flags=flags, is_add=1)
2458 self.vapi.nat44_interface_add_del_feature(
2459 sw_if_index=self.pg1.sw_if_index,
2462 # add static mapping for servers
2463 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2464 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2469 IP(src=host.ip4, dst=server1_nat_ip) /
2470 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2473 IP(src=host.ip4, dst=server1_nat_ip) /
2474 UDP(sport=self.udp_port_in, dport=server_udp_port))
2476 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2477 IP(src=host.ip4, dst=server1_nat_ip) /
2478 ICMP(id=self.icmp_id_in, type='echo-request'))
2480 self.pg0.add_stream(pkts)
2481 self.pg_enable_capture(self.pg_interfaces)
2483 capture = self.pg0.get_capture(len(pkts))
2484 for packet in capture:
2486 self.assertEqual(packet[IP].src, self.nat_addr)
2487 self.assertEqual(packet[IP].dst, server1.ip4)
2488 if packet.haslayer(TCP):
2489 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2490 self.assertEqual(packet[TCP].dport, server_tcp_port)
2491 self.tcp_port_out = packet[TCP].sport
2492 self.assert_packet_checksums_valid(packet)
2493 elif packet.haslayer(UDP):
2494 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2495 self.assertEqual(packet[UDP].dport, server_udp_port)
2496 self.udp_port_out = packet[UDP].sport
2498 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2499 self.icmp_id_out = packet[ICMP].id
2501 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2507 IP(src=server1.ip4, dst=self.nat_addr) /
2508 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2510 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2511 IP(src=server1.ip4, dst=self.nat_addr) /
2512 UDP(sport=server_udp_port, dport=self.udp_port_out))
2514 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2515 IP(src=server1.ip4, dst=self.nat_addr) /
2516 ICMP(id=self.icmp_id_out, type='echo-reply'))
2518 self.pg0.add_stream(pkts)
2519 self.pg_enable_capture(self.pg_interfaces)
2521 capture = self.pg0.get_capture(len(pkts))
2522 for packet in capture:
2524 self.assertEqual(packet[IP].src, server1_nat_ip)
2525 self.assertEqual(packet[IP].dst, host.ip4)
2526 if packet.haslayer(TCP):
2527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2528 self.assertEqual(packet[TCP].sport, server_tcp_port)
2529 self.assert_packet_checksums_valid(packet)
2530 elif packet.haslayer(UDP):
2531 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2532 self.assertEqual(packet[UDP].sport, server_udp_port)
2534 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2536 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2539 # server2 to server1
2541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2542 IP(src=server2.ip4, dst=server1_nat_ip) /
2543 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2545 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2546 IP(src=server2.ip4, dst=server1_nat_ip) /
2547 UDP(sport=self.udp_port_in, dport=server_udp_port))
2549 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2550 IP(src=server2.ip4, dst=server1_nat_ip) /
2551 ICMP(id=self.icmp_id_in, type='echo-request'))
2553 self.pg0.add_stream(pkts)
2554 self.pg_enable_capture(self.pg_interfaces)
2556 capture = self.pg0.get_capture(len(pkts))
2557 for packet in capture:
2559 self.assertEqual(packet[IP].src, server2_nat_ip)
2560 self.assertEqual(packet[IP].dst, server1.ip4)
2561 if packet.haslayer(TCP):
2562 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2563 self.assertEqual(packet[TCP].dport, server_tcp_port)
2564 self.tcp_port_out = packet[TCP].sport
2565 self.assert_packet_checksums_valid(packet)
2566 elif packet.haslayer(UDP):
2567 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2568 self.assertEqual(packet[UDP].dport, server_udp_port)
2569 self.udp_port_out = packet[UDP].sport
2571 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2572 self.icmp_id_out = packet[ICMP].id
2574 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2577 # server1 to server2
2579 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2580 IP(src=server1.ip4, dst=server2_nat_ip) /
2581 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2583 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2584 IP(src=server1.ip4, dst=server2_nat_ip) /
2585 UDP(sport=server_udp_port, dport=self.udp_port_out))
2587 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2588 IP(src=server1.ip4, dst=server2_nat_ip) /
2589 ICMP(id=self.icmp_id_out, type='echo-reply'))
2591 self.pg0.add_stream(pkts)
2592 self.pg_enable_capture(self.pg_interfaces)
2594 capture = self.pg0.get_capture(len(pkts))
2595 for packet in capture:
2597 self.assertEqual(packet[IP].src, server1_nat_ip)
2598 self.assertEqual(packet[IP].dst, server2.ip4)
2599 if packet.haslayer(TCP):
2600 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2601 self.assertEqual(packet[TCP].sport, server_tcp_port)
2602 self.assert_packet_checksums_valid(packet)
2603 elif packet.haslayer(UDP):
2604 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2605 self.assertEqual(packet[UDP].sport, server_udp_port)
2607 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2612 def test_max_translations_per_user(self):
2613 """ MAX translations per user - recycle the least recently used """
2615 self.nat44_add_address(self.nat_addr)
2616 flags = self.config_flags.NAT_IS_INSIDE
2617 self.vapi.nat44_interface_add_del_feature(
2618 sw_if_index=self.pg0.sw_if_index,
2619 flags=flags, is_add=1)
2620 self.vapi.nat44_interface_add_del_feature(
2621 sw_if_index=self.pg1.sw_if_index,
2624 # get maximum number of translations per user
2625 nat44_config = self.vapi.nat_show_config()
2627 # send more than maximum number of translations per user packets
2628 pkts_num = nat44_config.max_translations_per_user + 5
2630 for port in range(0, pkts_num):
2631 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2632 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2633 TCP(sport=1025 + port))
2635 self.pg0.add_stream(pkts)
2636 self.pg_enable_capture(self.pg_interfaces)
2639 # verify number of translated packet
2640 self.pg1.get_capture(pkts_num)
2642 users = self.vapi.nat44_user_dump()
2644 if user.ip_address == self.pg0.remote_ip4n:
2645 self.assertEqual(user.nsessions,
2646 nat44_config.max_translations_per_user)
2647 self.assertEqual(user.nstaticsessions, 0)
2650 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2652 proto=IP_PROTOS.tcp)
2653 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2654 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2655 TCP(sport=tcp_port))
2656 self.pg0.add_stream(p)
2657 self.pg_enable_capture(self.pg_interfaces)
2659 self.pg1.get_capture(1)
2660 users = self.vapi.nat44_user_dump()
2662 if user.ip_address == self.pg0.remote_ip4n:
2663 self.assertEqual(user.nsessions,
2664 nat44_config.max_translations_per_user - 1)
2665 self.assertEqual(user.nstaticsessions, 1)
2667 def test_interface_addr(self):
2668 """ Acquire NAT44 addresses from interface """
2669 self.vapi.nat44_add_del_interface_addr(
2671 sw_if_index=self.pg7.sw_if_index)
2673 # no address in NAT pool
2674 addresses = self.vapi.nat44_address_dump()
2675 self.assertEqual(0, len(addresses))
2677 # configure interface address and check NAT address pool
2678 self.pg7.config_ip4()
2679 addresses = self.vapi.nat44_address_dump()
2680 self.assertEqual(1, len(addresses))
2681 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2683 # remove interface address and check NAT address pool
2684 self.pg7.unconfig_ip4()
2685 addresses = self.vapi.nat44_address_dump()
2686 self.assertEqual(0, len(addresses))
2688 def test_interface_addr_static_mapping(self):
2689 """ Static mapping with addresses from interface """
2692 self.vapi.nat44_add_del_interface_addr(
2694 sw_if_index=self.pg7.sw_if_index)
2695 self.nat44_add_static_mapping(
2697 external_sw_if_index=self.pg7.sw_if_index,
2700 # static mappings with external interface
2701 static_mappings = self.vapi.nat44_static_mapping_dump()
2702 self.assertEqual(1, len(static_mappings))
2703 self.assertEqual(self.pg7.sw_if_index,
2704 static_mappings[0].external_sw_if_index)
2705 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2707 # configure interface address and check static mappings
2708 self.pg7.config_ip4()
2709 static_mappings = self.vapi.nat44_static_mapping_dump()
2710 self.assertEqual(2, len(static_mappings))
2712 for sm in static_mappings:
2713 if sm.external_sw_if_index == 0xFFFFFFFF:
2714 self.assertEqual(str(sm.external_ip_address),
2716 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2718 self.assertTrue(resolved)
2720 # remove interface address and check static mappings
2721 self.pg7.unconfig_ip4()
2722 static_mappings = self.vapi.nat44_static_mapping_dump()
2723 self.assertEqual(1, len(static_mappings))
2724 self.assertEqual(self.pg7.sw_if_index,
2725 static_mappings[0].external_sw_if_index)
2726 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2728 # configure interface address again and check static mappings
2729 self.pg7.config_ip4()
2730 static_mappings = self.vapi.nat44_static_mapping_dump()
2731 self.assertEqual(2, len(static_mappings))
2733 for sm in static_mappings:
2734 if sm.external_sw_if_index == 0xFFFFFFFF:
2735 self.assertEqual(str(sm.external_ip_address),
2737 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2739 self.assertTrue(resolved)
2741 # remove static mapping
2742 self.nat44_add_static_mapping(
2744 external_sw_if_index=self.pg7.sw_if_index,
2747 static_mappings = self.vapi.nat44_static_mapping_dump()
2748 self.assertEqual(0, len(static_mappings))
2750 def test_interface_addr_identity_nat(self):
2751 """ Identity NAT with addresses from interface """
2754 self.vapi.nat44_add_del_interface_addr(
2756 sw_if_index=self.pg7.sw_if_index)
2757 self.vapi.nat44_add_del_identity_mapping(
2759 sw_if_index=self.pg7.sw_if_index,
2761 protocol=IP_PROTOS.tcp,
2764 # identity mappings with external interface
2765 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2766 self.assertEqual(1, len(identity_mappings))
2767 self.assertEqual(self.pg7.sw_if_index,
2768 identity_mappings[0].sw_if_index)
2770 # configure interface address and check identity mappings
2771 self.pg7.config_ip4()
2772 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2774 self.assertEqual(2, len(identity_mappings))
2775 for sm in identity_mappings:
2776 if sm.sw_if_index == 0xFFFFFFFF:
2777 self.assertEqual(str(identity_mappings[0].ip_address),
2779 self.assertEqual(port, identity_mappings[0].port)
2780 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2782 self.assertTrue(resolved)
2784 # remove interface address and check identity mappings
2785 self.pg7.unconfig_ip4()
2786 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2787 self.assertEqual(1, len(identity_mappings))
2788 self.assertEqual(self.pg7.sw_if_index,
2789 identity_mappings[0].sw_if_index)
2791 def test_ipfix_nat44_sess(self):
2792 """ IPFIX logging NAT44 session created/deleted """
2793 self.ipfix_domain_id = 10
2794 self.ipfix_src_port = 20202
2795 collector_port = 30303
2796 bind_layers(UDP, IPFIX, dport=30303)
2797 self.nat44_add_address(self.nat_addr)
2798 flags = self.config_flags.NAT_IS_INSIDE
2799 self.vapi.nat44_interface_add_del_feature(
2800 sw_if_index=self.pg0.sw_if_index,
2801 flags=flags, is_add=1)
2802 self.vapi.nat44_interface_add_del_feature(
2803 sw_if_index=self.pg1.sw_if_index,
2805 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2806 src_address=self.pg3.local_ip4n,
2808 template_interval=10,
2809 collector_port=collector_port)
2810 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2811 src_port=self.ipfix_src_port,
2814 pkts = self.create_stream_in(self.pg0, self.pg1)
2815 self.pg0.add_stream(pkts)
2816 self.pg_enable_capture(self.pg_interfaces)
2818 capture = self.pg1.get_capture(len(pkts))
2819 self.verify_capture_out(capture)
2820 self.nat44_add_address(self.nat_addr, is_add=0)
2821 self.vapi.ipfix_flush()
2822 capture = self.pg3.get_capture(9)
2823 ipfix = IPFIXDecoder()
2824 # first load template
2826 self.assertTrue(p.haslayer(IPFIX))
2827 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2828 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2829 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2830 self.assertEqual(p[UDP].dport, collector_port)
2831 self.assertEqual(p[IPFIX].observationDomainID,
2832 self.ipfix_domain_id)
2833 if p.haslayer(Template):
2834 ipfix.add_template(p.getlayer(Template))
2835 # verify events in data set
2837 if p.haslayer(Data):
2838 data = ipfix.decode_data_set(p.getlayer(Set))
2839 self.verify_ipfix_nat44_ses(data)
2841 def test_ipfix_addr_exhausted(self):
2842 """ IPFIX logging NAT addresses exhausted """
2843 flags = self.config_flags.NAT_IS_INSIDE
2844 self.vapi.nat44_interface_add_del_feature(
2845 sw_if_index=self.pg0.sw_if_index,
2846 flags=flags, is_add=1)
2847 self.vapi.nat44_interface_add_del_feature(
2848 sw_if_index=self.pg1.sw_if_index,
2850 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2851 src_address=self.pg3.local_ip4n,
2853 template_interval=10)
2854 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2855 src_port=self.ipfix_src_port,
2858 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2859 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2861 self.pg0.add_stream(p)
2862 self.pg_enable_capture(self.pg_interfaces)
2864 self.pg1.assert_nothing_captured()
2866 self.vapi.cli("ipfix flush")
2867 capture = self.pg3.get_capture(9)
2868 ipfix = IPFIXDecoder()
2869 # first load template
2871 self.assertTrue(p.haslayer(IPFIX))
2872 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2873 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2874 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2875 self.assertEqual(p[UDP].dport, 4739)
2876 self.assertEqual(p[IPFIX].observationDomainID,
2877 self.ipfix_domain_id)
2878 if p.haslayer(Template):
2879 ipfix.add_template(p.getlayer(Template))
2880 # verify events in data set
2882 if p.haslayer(Data):
2883 data = ipfix.decode_data_set(p.getlayer(Set))
2884 self.verify_ipfix_addr_exhausted(data)
2886 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2887 def test_ipfix_max_sessions(self):
2888 """ IPFIX logging maximum session entries exceeded """
2889 self.nat44_add_address(self.nat_addr)
2890 flags = self.config_flags.NAT_IS_INSIDE
2891 self.vapi.nat44_interface_add_del_feature(
2892 sw_if_index=self.pg0.sw_if_index,
2893 flags=flags, is_add=1)
2894 self.vapi.nat44_interface_add_del_feature(
2895 sw_if_index=self.pg1.sw_if_index,
2898 nat44_config = self.vapi.nat_show_config()
2899 max_sessions = 10 * nat44_config.translation_buckets
2902 for i in range(0, max_sessions):
2903 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2904 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2905 IP(src=src, dst=self.pg1.remote_ip4) /
2908 self.pg0.add_stream(pkts)
2909 self.pg_enable_capture(self.pg_interfaces)
2912 self.pg1.get_capture(max_sessions)
2913 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2914 src_address=self.pg3.local_ip4n,
2916 template_interval=10)
2917 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2918 src_port=self.ipfix_src_port,
2921 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2922 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2924 self.pg0.add_stream(p)
2925 self.pg_enable_capture(self.pg_interfaces)
2927 self.pg1.assert_nothing_captured()
2929 self.vapi.ipfix_flush()
2930 capture = self.pg3.get_capture(9)
2931 ipfix = IPFIXDecoder()
2932 # first load template
2934 self.assertTrue(p.haslayer(IPFIX))
2935 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2936 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2937 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2938 self.assertEqual(p[UDP].dport, 4739)
2939 self.assertEqual(p[IPFIX].observationDomainID,
2940 self.ipfix_domain_id)
2941 if p.haslayer(Template):
2942 ipfix.add_template(p.getlayer(Template))
2943 # verify events in data set
2945 if p.haslayer(Data):
2946 data = ipfix.decode_data_set(p.getlayer(Set))
2947 self.verify_ipfix_max_sessions(data, max_sessions)
2949 def test_syslog_apmap(self):
2950 """ Test syslog address and port mapping creation and deletion """
2951 self.vapi.syslog_set_filter(
2952 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2953 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2954 self.nat44_add_address(self.nat_addr)
2955 flags = self.config_flags.NAT_IS_INSIDE
2956 self.vapi.nat44_interface_add_del_feature(
2957 sw_if_index=self.pg0.sw_if_index,
2958 flags=flags, is_add=1)
2959 self.vapi.nat44_interface_add_del_feature(
2960 sw_if_index=self.pg1.sw_if_index,
2963 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2964 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2965 TCP(sport=self.tcp_port_in, dport=20))
2966 self.pg0.add_stream(p)
2967 self.pg_enable_capture(self.pg_interfaces)
2969 capture = self.pg1.get_capture(1)
2970 self.tcp_port_out = capture[0][TCP].sport
2971 capture = self.pg3.get_capture(1)
2972 self.verify_syslog_apmap(capture[0][Raw].load)
2974 self.pg_enable_capture(self.pg_interfaces)
2976 self.nat44_add_address(self.nat_addr, is_add=0)
2977 capture = self.pg3.get_capture(1)
2978 self.verify_syslog_apmap(capture[0][Raw].load, False)
2980 def test_pool_addr_fib(self):
2981 """ NAT44 add pool addresses to FIB """
2982 static_addr = '10.0.0.10'
2983 self.nat44_add_address(self.nat_addr)
2984 flags = self.config_flags.NAT_IS_INSIDE
2985 self.vapi.nat44_interface_add_del_feature(
2986 sw_if_index=self.pg0.sw_if_index,
2987 flags=flags, is_add=1)
2988 self.vapi.nat44_interface_add_del_feature(
2989 sw_if_index=self.pg1.sw_if_index,
2991 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2994 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2995 ARP(op=ARP.who_has, pdst=self.nat_addr,
2996 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2997 self.pg1.add_stream(p)
2998 self.pg_enable_capture(self.pg_interfaces)
3000 capture = self.pg1.get_capture(1)
3001 self.assertTrue(capture[0].haslayer(ARP))
3002 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3005 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3006 ARP(op=ARP.who_has, pdst=static_addr,
3007 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 capture = self.pg1.get_capture(1)
3012 self.assertTrue(capture[0].haslayer(ARP))
3013 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3015 # send ARP to non-NAT44 interface
3016 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3017 ARP(op=ARP.who_has, pdst=self.nat_addr,
3018 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3019 self.pg2.add_stream(p)
3020 self.pg_enable_capture(self.pg_interfaces)
3022 self.pg1.assert_nothing_captured()
3024 # remove addresses and verify
3025 self.nat44_add_address(self.nat_addr, is_add=0)
3026 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3029 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3030 ARP(op=ARP.who_has, pdst=self.nat_addr,
3031 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3032 self.pg1.add_stream(p)
3033 self.pg_enable_capture(self.pg_interfaces)
3035 self.pg1.assert_nothing_captured()
3037 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3038 ARP(op=ARP.who_has, pdst=static_addr,
3039 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3040 self.pg1.add_stream(p)
3041 self.pg_enable_capture(self.pg_interfaces)
3043 self.pg1.assert_nothing_captured()
3045 def test_vrf_mode(self):
3046 """ NAT44 tenant VRF aware address pool mode """
3050 nat_ip1 = "10.0.0.10"
3051 nat_ip2 = "10.0.0.11"
3053 self.pg0.unconfig_ip4()
3054 self.pg1.unconfig_ip4()
3055 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3056 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3057 self.pg0.set_table_ip4(vrf_id1)
3058 self.pg1.set_table_ip4(vrf_id2)
3059 self.pg0.config_ip4()
3060 self.pg1.config_ip4()
3061 self.pg0.resolve_arp()
3062 self.pg1.resolve_arp()
3064 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3065 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3066 flags = self.config_flags.NAT_IS_INSIDE
3067 self.vapi.nat44_interface_add_del_feature(
3068 sw_if_index=self.pg0.sw_if_index,
3069 flags=flags, is_add=1)
3070 self.vapi.nat44_interface_add_del_feature(
3071 sw_if_index=self.pg1.sw_if_index,
3072 flags=flags, is_add=1)
3073 self.vapi.nat44_interface_add_del_feature(
3074 sw_if_index=self.pg2.sw_if_index,
3079 pkts = self.create_stream_in(self.pg0, self.pg2)
3080 self.pg0.add_stream(pkts)
3081 self.pg_enable_capture(self.pg_interfaces)
3083 capture = self.pg2.get_capture(len(pkts))
3084 self.verify_capture_out(capture, nat_ip1)
3087 pkts = self.create_stream_in(self.pg1, self.pg2)
3088 self.pg1.add_stream(pkts)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 capture = self.pg2.get_capture(len(pkts))
3092 self.verify_capture_out(capture, nat_ip2)
3095 self.pg0.unconfig_ip4()
3096 self.pg1.unconfig_ip4()
3097 self.pg0.set_table_ip4(0)
3098 self.pg1.set_table_ip4(0)
3099 self.pg0.config_ip4()
3100 self.pg1.config_ip4()
3101 self.pg0.resolve_arp()
3102 self.pg1.resolve_arp()
3103 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3104 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3106 def test_vrf_feature_independent(self):
3107 """ NAT44 tenant VRF independent address pool mode """
3109 nat_ip1 = "10.0.0.10"
3110 nat_ip2 = "10.0.0.11"
3112 self.nat44_add_address(nat_ip1)
3113 self.nat44_add_address(nat_ip2, vrf_id=99)
3114 flags = self.config_flags.NAT_IS_INSIDE
3115 self.vapi.nat44_interface_add_del_feature(
3116 sw_if_index=self.pg0.sw_if_index,
3117 flags=flags, is_add=1)
3118 self.vapi.nat44_interface_add_del_feature(
3119 sw_if_index=self.pg1.sw_if_index,
3120 flags=flags, is_add=1)
3121 self.vapi.nat44_interface_add_del_feature(
3122 sw_if_index=self.pg2.sw_if_index,
3126 pkts = self.create_stream_in(self.pg0, self.pg2)
3127 self.pg0.add_stream(pkts)
3128 self.pg_enable_capture(self.pg_interfaces)
3130 capture = self.pg2.get_capture(len(pkts))
3131 self.verify_capture_out(capture, nat_ip1)
3134 pkts = self.create_stream_in(self.pg1, self.pg2)
3135 self.pg1.add_stream(pkts)
3136 self.pg_enable_capture(self.pg_interfaces)
3138 capture = self.pg2.get_capture(len(pkts))
3139 self.verify_capture_out(capture, nat_ip1)
3141 def create_routes_and_neigbors(self):
3142 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3143 [VppRoutePath(self.pg7.remote_ip4,
3144 self.pg7.sw_if_index)])
3145 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3146 [VppRoutePath(self.pg8.remote_ip4,
3147 self.pg8.sw_if_index)])
3151 n1 = VppNeighbor(self,
3152 self.pg7.sw_if_index,
3153 self.pg7.remote_mac,
3154 self.pg7.remote_ip4,
3156 n2 = VppNeighbor(self,
3157 self.pg8.sw_if_index,
3158 self.pg8.remote_mac,
3159 self.pg8.remote_ip4,
3164 def test_dynamic_ipless_interfaces(self):
3165 """ NAT44 interfaces without configured IP address """
3166 self.create_routes_and_neigbors()
3167 self.nat44_add_address(self.nat_addr)
3168 flags = self.config_flags.NAT_IS_INSIDE
3169 self.vapi.nat44_interface_add_del_feature(
3170 sw_if_index=self.pg7.sw_if_index,
3171 flags=flags, is_add=1)
3172 self.vapi.nat44_interface_add_del_feature(
3173 sw_if_index=self.pg8.sw_if_index,
3177 pkts = self.create_stream_in(self.pg7, self.pg8)
3178 self.pg7.add_stream(pkts)
3179 self.pg_enable_capture(self.pg_interfaces)
3181 capture = self.pg8.get_capture(len(pkts))
3182 self.verify_capture_out(capture)
3185 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3186 self.pg8.add_stream(pkts)
3187 self.pg_enable_capture(self.pg_interfaces)
3189 capture = self.pg7.get_capture(len(pkts))
3190 self.verify_capture_in(capture, self.pg7)
3192 def test_static_ipless_interfaces(self):
3193 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3195 self.create_routes_and_neigbors()
3196 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3197 flags = self.config_flags.NAT_IS_INSIDE
3198 self.vapi.nat44_interface_add_del_feature(
3199 sw_if_index=self.pg7.sw_if_index,
3200 flags=flags, is_add=1)
3201 self.vapi.nat44_interface_add_del_feature(
3202 sw_if_index=self.pg8.sw_if_index,
3206 pkts = self.create_stream_out(self.pg8)
3207 self.pg8.add_stream(pkts)
3208 self.pg_enable_capture(self.pg_interfaces)
3210 capture = self.pg7.get_capture(len(pkts))
3211 self.verify_capture_in(capture, self.pg7)
3214 pkts = self.create_stream_in(self.pg7, self.pg8)
3215 self.pg7.add_stream(pkts)
3216 self.pg_enable_capture(self.pg_interfaces)
3218 capture = self.pg8.get_capture(len(pkts))
3219 self.verify_capture_out(capture, self.nat_addr, True)
3221 def test_static_with_port_ipless_interfaces(self):
3222 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3224 self.tcp_port_out = 30606
3225 self.udp_port_out = 30607
3226 self.icmp_id_out = 30608
3228 self.create_routes_and_neigbors()
3229 self.nat44_add_address(self.nat_addr)
3230 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3231 self.tcp_port_in, self.tcp_port_out,
3232 proto=IP_PROTOS.tcp)
3233 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3234 self.udp_port_in, self.udp_port_out,
3235 proto=IP_PROTOS.udp)
3236 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3237 self.icmp_id_in, self.icmp_id_out,
3238 proto=IP_PROTOS.icmp)
3239 flags = self.config_flags.NAT_IS_INSIDE
3240 self.vapi.nat44_interface_add_del_feature(
3241 sw_if_index=self.pg7.sw_if_index,
3242 flags=flags, is_add=1)
3243 self.vapi.nat44_interface_add_del_feature(
3244 sw_if_index=self.pg8.sw_if_index,
3248 pkts = self.create_stream_out(self.pg8)
3249 self.pg8.add_stream(pkts)
3250 self.pg_enable_capture(self.pg_interfaces)
3252 capture = self.pg7.get_capture(len(pkts))
3253 self.verify_capture_in(capture, self.pg7)
3256 pkts = self.create_stream_in(self.pg7, self.pg8)
3257 self.pg7.add_stream(pkts)
3258 self.pg_enable_capture(self.pg_interfaces)
3260 capture = self.pg8.get_capture(len(pkts))
3261 self.verify_capture_out(capture)
3263 def test_static_unknown_proto(self):
3264 """ 1:1 NAT translate packet with unknown protocol """
3265 nat_ip = "10.0.0.10"
3266 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3267 flags = self.config_flags.NAT_IS_INSIDE
3268 self.vapi.nat44_interface_add_del_feature(
3269 sw_if_index=self.pg0.sw_if_index,
3270 flags=flags, is_add=1)
3271 self.vapi.nat44_interface_add_del_feature(
3272 sw_if_index=self.pg1.sw_if_index,
3276 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3277 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3279 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3280 TCP(sport=1234, dport=1234))
3281 self.pg0.add_stream(p)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 p = self.pg1.get_capture(1)
3287 self.assertEqual(packet[IP].src, nat_ip)
3288 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3289 self.assertEqual(packet.haslayer(GRE), 1)
3290 self.assert_packet_checksums_valid(packet)
3292 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3296 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3297 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3299 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3300 TCP(sport=1234, dport=1234))
3301 self.pg1.add_stream(p)
3302 self.pg_enable_capture(self.pg_interfaces)
3304 p = self.pg0.get_capture(1)
3307 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3308 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3309 self.assertEqual(packet.haslayer(GRE), 1)
3310 self.assert_packet_checksums_valid(packet)
3312 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3315 def test_hairpinning_static_unknown_proto(self):
3316 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3318 host = self.pg0.remote_hosts[0]
3319 server = self.pg0.remote_hosts[1]
3321 host_nat_ip = "10.0.0.10"
3322 server_nat_ip = "10.0.0.11"
3324 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3325 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3326 flags = self.config_flags.NAT_IS_INSIDE
3327 self.vapi.nat44_interface_add_del_feature(
3328 sw_if_index=self.pg0.sw_if_index,
3329 flags=flags, is_add=1)
3330 self.vapi.nat44_interface_add_del_feature(
3331 sw_if_index=self.pg1.sw_if_index,
3335 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3336 IP(src=host.ip4, dst=server_nat_ip) /
3338 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3339 TCP(sport=1234, dport=1234))
3340 self.pg0.add_stream(p)
3341 self.pg_enable_capture(self.pg_interfaces)
3343 p = self.pg0.get_capture(1)
3346 self.assertEqual(packet[IP].src, host_nat_ip)
3347 self.assertEqual(packet[IP].dst, server.ip4)
3348 self.assertEqual(packet.haslayer(GRE), 1)
3349 self.assert_packet_checksums_valid(packet)
3351 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3355 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3356 IP(src=server.ip4, dst=host_nat_ip) /
3358 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3359 TCP(sport=1234, dport=1234))
3360 self.pg0.add_stream(p)
3361 self.pg_enable_capture(self.pg_interfaces)
3363 p = self.pg0.get_capture(1)
3366 self.assertEqual(packet[IP].src, server_nat_ip)
3367 self.assertEqual(packet[IP].dst, host.ip4)
3368 self.assertEqual(packet.haslayer(GRE), 1)
3369 self.assert_packet_checksums_valid(packet)
3371 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3374 def test_output_feature(self):
3375 """ NAT44 interface output feature (in2out postrouting) """
3376 self.nat44_add_address(self.nat_addr)
3377 flags = self.config_flags.NAT_IS_INSIDE
3378 self.vapi.nat44_interface_add_del_output_feature(
3379 is_add=1, flags=flags,
3380 sw_if_index=self.pg0.sw_if_index)
3381 self.vapi.nat44_interface_add_del_output_feature(
3382 is_add=1, flags=flags,
3383 sw_if_index=self.pg1.sw_if_index)
3384 self.vapi.nat44_interface_add_del_output_feature(
3386 sw_if_index=self.pg3.sw_if_index)
3389 pkts = self.create_stream_in(self.pg0, self.pg3)
3390 self.pg0.add_stream(pkts)
3391 self.pg_enable_capture(self.pg_interfaces)
3393 capture = self.pg3.get_capture(len(pkts))
3394 self.verify_capture_out(capture)
3397 pkts = self.create_stream_out(self.pg3)
3398 self.pg3.add_stream(pkts)
3399 self.pg_enable_capture(self.pg_interfaces)
3401 capture = self.pg0.get_capture(len(pkts))
3402 self.verify_capture_in(capture, self.pg0)
3404 # from non-NAT interface to NAT inside interface
3405 pkts = self.create_stream_in(self.pg2, self.pg0)
3406 self.pg2.add_stream(pkts)
3407 self.pg_enable_capture(self.pg_interfaces)
3409 capture = self.pg0.get_capture(len(pkts))
3410 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3412 def test_output_feature_vrf_aware(self):
3413 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3414 nat_ip_vrf10 = "10.0.0.10"
3415 nat_ip_vrf20 = "10.0.0.20"
3417 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3418 [VppRoutePath(self.pg3.remote_ip4,
3419 self.pg3.sw_if_index)],
3421 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3422 [VppRoutePath(self.pg3.remote_ip4,
3423 self.pg3.sw_if_index)],
3428 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3429 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3430 flags = self.config_flags.NAT_IS_INSIDE
3431 self.vapi.nat44_interface_add_del_output_feature(
3432 is_add=1, flags=flags,
3433 sw_if_index=self.pg4.sw_if_index)
3434 self.vapi.nat44_interface_add_del_output_feature(
3435 is_add=1, flags=flags,
3436 sw_if_index=self.pg6.sw_if_index)
3437 self.vapi.nat44_interface_add_del_output_feature(
3439 sw_if_index=self.pg3.sw_if_index)
3442 pkts = self.create_stream_in(self.pg4, self.pg3)
3443 self.pg4.add_stream(pkts)
3444 self.pg_enable_capture(self.pg_interfaces)
3446 capture = self.pg3.get_capture(len(pkts))
3447 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3450 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3451 self.pg3.add_stream(pkts)
3452 self.pg_enable_capture(self.pg_interfaces)
3454 capture = self.pg4.get_capture(len(pkts))
3455 self.verify_capture_in(capture, self.pg4)
3458 pkts = self.create_stream_in(self.pg6, self.pg3)
3459 self.pg6.add_stream(pkts)
3460 self.pg_enable_capture(self.pg_interfaces)
3462 capture = self.pg3.get_capture(len(pkts))
3463 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3466 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3467 self.pg3.add_stream(pkts)
3468 self.pg_enable_capture(self.pg_interfaces)
3470 capture = self.pg6.get_capture(len(pkts))
3471 self.verify_capture_in(capture, self.pg6)
3473 def test_output_feature_hairpinning(self):
3474 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3475 host = self.pg0.remote_hosts[0]
3476 server = self.pg0.remote_hosts[1]
3479 server_in_port = 5678
3480 server_out_port = 8765
3482 self.nat44_add_address(self.nat_addr)
3483 flags = self.config_flags.NAT_IS_INSIDE
3484 self.vapi.nat44_interface_add_del_output_feature(
3485 is_add=1, flags=flags,
3486 sw_if_index=self.pg0.sw_if_index)
3487 self.vapi.nat44_interface_add_del_output_feature(
3489 sw_if_index=self.pg1.sw_if_index)
3491 # add static mapping for server
3492 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3493 server_in_port, server_out_port,
3494 proto=IP_PROTOS.tcp)
3496 # send packet from host to server
3497 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3498 IP(src=host.ip4, dst=self.nat_addr) /
3499 TCP(sport=host_in_port, dport=server_out_port))
3500 self.pg0.add_stream(p)
3501 self.pg_enable_capture(self.pg_interfaces)
3503 capture = self.pg0.get_capture(1)
3508 self.assertEqual(ip.src, self.nat_addr)
3509 self.assertEqual(ip.dst, server.ip4)
3510 self.assertNotEqual(tcp.sport, host_in_port)
3511 self.assertEqual(tcp.dport, server_in_port)
3512 self.assert_packet_checksums_valid(p)
3513 host_out_port = tcp.sport
3515 self.logger.error(ppp("Unexpected or invalid packet:", p))
3518 # send reply from server to host
3519 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3520 IP(src=server.ip4, dst=self.nat_addr) /
3521 TCP(sport=server_in_port, dport=host_out_port))
3522 self.pg0.add_stream(p)
3523 self.pg_enable_capture(self.pg_interfaces)
3525 capture = self.pg0.get_capture(1)
3530 self.assertEqual(ip.src, self.nat_addr)
3531 self.assertEqual(ip.dst, host.ip4)
3532 self.assertEqual(tcp.sport, server_out_port)
3533 self.assertEqual(tcp.dport, host_in_port)
3534 self.assert_packet_checksums_valid(p)
3536 self.logger.error(ppp("Unexpected or invalid packet:", p))
3539 def test_one_armed_nat44(self):
3540 """ One armed NAT44 """
3541 remote_host = self.pg9.remote_hosts[0]
3542 local_host = self.pg9.remote_hosts[1]
3545 self.nat44_add_address(self.nat_addr)
3546 flags = self.config_flags.NAT_IS_INSIDE
3547 self.vapi.nat44_interface_add_del_feature(
3548 sw_if_index=self.pg9.sw_if_index,
3550 self.vapi.nat44_interface_add_del_feature(
3551 sw_if_index=self.pg9.sw_if_index,
3552 flags=flags, is_add=1)
3555 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3556 IP(src=local_host.ip4, dst=remote_host.ip4) /
3557 TCP(sport=12345, dport=80))
3558 self.pg9.add_stream(p)
3559 self.pg_enable_capture(self.pg_interfaces)
3561 capture = self.pg9.get_capture(1)
3566 self.assertEqual(ip.src, self.nat_addr)
3567 self.assertEqual(ip.dst, remote_host.ip4)
3568 self.assertNotEqual(tcp.sport, 12345)
3569 external_port = tcp.sport
3570 self.assertEqual(tcp.dport, 80)
3571 self.assert_packet_checksums_valid(p)
3573 self.logger.error(ppp("Unexpected or invalid packet:", p))
3577 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3578 IP(src=remote_host.ip4, dst=self.nat_addr) /
3579 TCP(sport=80, dport=external_port))
3580 self.pg9.add_stream(p)
3581 self.pg_enable_capture(self.pg_interfaces)
3583 capture = self.pg9.get_capture(1)
3588 self.assertEqual(ip.src, remote_host.ip4)
3589 self.assertEqual(ip.dst, local_host.ip4)
3590 self.assertEqual(tcp.sport, 80)
3591 self.assertEqual(tcp.dport, 12345)
3592 self.assert_packet_checksums_valid(p)
3594 self.logger.error(ppp("Unexpected or invalid packet:", p))
3597 err = self.statistics.get_err_counter(
3598 '/err/nat44-classify/next in2out')
3599 self.assertEqual(err, 1)
3600 err = self.statistics.get_err_counter(
3601 '/err/nat44-classify/next out2in')
3602 self.assertEqual(err, 1)
3604 def test_del_session(self):
3605 """ Delete NAT44 session """
3606 self.nat44_add_address(self.nat_addr)
3607 flags = self.config_flags.NAT_IS_INSIDE
3608 self.vapi.nat44_interface_add_del_feature(
3609 sw_if_index=self.pg0.sw_if_index,
3610 flags=flags, is_add=1)
3611 self.vapi.nat44_interface_add_del_feature(
3612 sw_if_index=self.pg1.sw_if_index,
3615 pkts = self.create_stream_in(self.pg0, self.pg1)
3616 self.pg0.add_stream(pkts)
3617 self.pg_enable_capture(self.pg_interfaces)
3619 self.pg1.get_capture(len(pkts))
3621 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3622 nsessions = len(sessions)
3624 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3625 port=sessions[0].inside_port,
3626 protocol=sessions[0].protocol,
3627 flags=self.config_flags.NAT_IS_INSIDE)
3628 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3629 port=sessions[1].outside_port,
3630 protocol=sessions[1].protocol)
3632 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3633 self.assertEqual(nsessions - len(sessions), 2)
3635 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3636 port=sessions[0].inside_port,
3637 protocol=sessions[0].protocol,
3638 flags=self.config_flags.NAT_IS_INSIDE)
3640 self.verify_no_nat44_user()
3642 def test_set_get_reass(self):
3643 """ NAT44 set/get virtual fragmentation reassembly """
3644 reas_cfg1 = self.vapi.nat_get_reass()
3646 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3647 max_reass=reas_cfg1.ip4_max_reass * 2,
3648 max_frag=reas_cfg1.ip4_max_frag * 2,
3651 reas_cfg2 = self.vapi.nat_get_reass()
3653 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3654 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3655 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3657 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3659 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3661 def test_frag_in_order(self):
3662 """ NAT44 translate fragments arriving in order """
3664 self.nat44_add_address(self.nat_addr)
3665 flags = self.config_flags.NAT_IS_INSIDE
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg0.sw_if_index,
3668 flags=flags, is_add=1)
3669 self.vapi.nat44_interface_add_del_feature(
3670 sw_if_index=self.pg1.sw_if_index,
3673 self.frag_in_order(proto=IP_PROTOS.tcp)
3674 self.frag_in_order(proto=IP_PROTOS.udp)
3675 self.frag_in_order(proto=IP_PROTOS.icmp)
3677 def test_frag_forwarding(self):
3678 """ NAT44 forwarding fragment test """
3679 self.vapi.nat44_add_del_interface_addr(
3681 sw_if_index=self.pg1.sw_if_index)
3682 flags = self.config_flags.NAT_IS_INSIDE
3683 self.vapi.nat44_interface_add_del_feature(
3684 sw_if_index=self.pg0.sw_if_index,
3685 flags=flags, is_add=1)
3686 self.vapi.nat44_interface_add_del_feature(
3687 sw_if_index=self.pg1.sw_if_index,
3689 self.vapi.nat44_forwarding_enable_disable(enable=1)
3691 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3692 pkts = self.create_stream_frag(self.pg1,
3693 self.pg0.remote_ip4,
3697 proto=IP_PROTOS.udp)
3698 self.pg1.add_stream(pkts)
3699 self.pg_enable_capture(self.pg_interfaces)
3701 frags = self.pg0.get_capture(len(pkts))
3702 p = self.reass_frags_and_verify(frags,
3703 self.pg1.remote_ip4,
3704 self.pg0.remote_ip4)
3705 self.assertEqual(p[UDP].sport, 4789)
3706 self.assertEqual(p[UDP].dport, 4789)
3707 self.assertEqual(data, p[Raw].load)
3709 def test_reass_hairpinning(self):
3710 """ NAT44 fragments hairpinning """
3712 self.server = self.pg0.remote_hosts[1]
3713 self.host_in_port = random.randint(1025, 65535)
3714 self.server_in_port = random.randint(1025, 65535)
3715 self.server_out_port = random.randint(1025, 65535)
3717 self.nat44_add_address(self.nat_addr)
3718 flags = self.config_flags.NAT_IS_INSIDE
3719 self.vapi.nat44_interface_add_del_feature(
3720 sw_if_index=self.pg0.sw_if_index,
3721 flags=flags, is_add=1)
3722 self.vapi.nat44_interface_add_del_feature(
3723 sw_if_index=self.pg1.sw_if_index,
3725 # add static mapping for server
3726 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3727 self.server_in_port,
3728 self.server_out_port,
3729 proto=IP_PROTOS.tcp)
3730 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3731 self.server_in_port,
3732 self.server_out_port,
3733 proto=IP_PROTOS.udp)
3734 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3736 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3737 self.reass_hairpinning(proto=IP_PROTOS.udp)
3738 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3740 def test_frag_out_of_order(self):
3741 """ NAT44 translate fragments arriving out of order """
3743 self.nat44_add_address(self.nat_addr)
3744 flags = self.config_flags.NAT_IS_INSIDE
3745 self.vapi.nat44_interface_add_del_feature(
3746 sw_if_index=self.pg0.sw_if_index,
3747 flags=flags, is_add=1)
3748 self.vapi.nat44_interface_add_del_feature(
3749 sw_if_index=self.pg1.sw_if_index,
3752 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3753 self.frag_out_of_order(proto=IP_PROTOS.udp)
3754 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3756 def test_port_restricted(self):
3757 """ Port restricted NAT44 (MAP-E CE) """
3758 self.nat44_add_address(self.nat_addr)
3759 flags = self.config_flags.NAT_IS_INSIDE
3760 self.vapi.nat44_interface_add_del_feature(
3761 sw_if_index=self.pg0.sw_if_index,
3762 flags=flags, is_add=1)
3763 self.vapi.nat44_interface_add_del_feature(
3764 sw_if_index=self.pg1.sw_if_index,
3766 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3771 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3772 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3773 TCP(sport=4567, dport=22))
3774 self.pg0.add_stream(p)
3775 self.pg_enable_capture(self.pg_interfaces)
3777 capture = self.pg1.get_capture(1)
3782 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3783 self.assertEqual(ip.src, self.nat_addr)
3784 self.assertEqual(tcp.dport, 22)
3785 self.assertNotEqual(tcp.sport, 4567)
3786 self.assertEqual((tcp.sport >> 6) & 63, 10)
3787 self.assert_packet_checksums_valid(p)
3789 self.logger.error(ppp("Unexpected or invalid packet:", p))
3792 def test_port_range(self):
3793 """ External address port range """
3794 self.nat44_add_address(self.nat_addr)
3795 flags = self.config_flags.NAT_IS_INSIDE
3796 self.vapi.nat44_interface_add_del_feature(
3797 sw_if_index=self.pg0.sw_if_index,
3798 flags=flags, is_add=1)
3799 self.vapi.nat44_interface_add_del_feature(
3800 sw_if_index=self.pg1.sw_if_index,
3802 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3807 for port in range(0, 5):
3808 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3809 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3810 TCP(sport=1125 + port))
3812 self.pg0.add_stream(pkts)
3813 self.pg_enable_capture(self.pg_interfaces)
3815 capture = self.pg1.get_capture(3)
3818 self.assertGreaterEqual(tcp.sport, 1025)
3819 self.assertLessEqual(tcp.sport, 1027)
3821 def test_ipfix_max_frags(self):
3822 """ IPFIX logging maximum fragments pending reassembly exceeded """
3823 self.nat44_add_address(self.nat_addr)
3824 flags = self.config_flags.NAT_IS_INSIDE
3825 self.vapi.nat44_interface_add_del_feature(
3826 sw_if_index=self.pg0.sw_if_index,
3827 flags=flags, is_add=1)
3828 self.vapi.nat44_interface_add_del_feature(
3829 sw_if_index=self.pg1.sw_if_index,
3831 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3833 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3834 src_address=self.pg3.local_ip4n,
3836 template_interval=10)
3837 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3838 src_port=self.ipfix_src_port,
3841 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3842 self.tcp_port_in = random.randint(1025, 65535)
3843 pkts = self.create_stream_frag(self.pg0,
3844 self.pg1.remote_ip4,
3849 self.pg0.add_stream(pkts)
3850 self.pg_enable_capture(self.pg_interfaces)
3852 self.pg1.assert_nothing_captured()
3854 self.vapi.ipfix_flush()
3855 capture = self.pg3.get_capture(9)
3856 ipfix = IPFIXDecoder()
3857 # first load template
3859 self.assertTrue(p.haslayer(IPFIX))
3860 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3861 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3862 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3863 self.assertEqual(p[UDP].dport, 4739)
3864 self.assertEqual(p[IPFIX].observationDomainID,
3865 self.ipfix_domain_id)
3866 if p.haslayer(Template):
3867 ipfix.add_template(p.getlayer(Template))
3868 # verify events in data set
3870 if p.haslayer(Data):
3871 data = ipfix.decode_data_set(p.getlayer(Set))
3872 self.verify_ipfix_max_fragments_ip4(data, 1,
3873 self.pg0.remote_ip4n)
3875 def test_multiple_outside_vrf(self):
3876 """ Multiple outside VRF """
3880 self.pg1.unconfig_ip4()
3881 self.pg2.unconfig_ip4()
3882 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3883 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3884 self.pg1.set_table_ip4(vrf_id1)
3885 self.pg2.set_table_ip4(vrf_id2)
3886 self.pg1.config_ip4()
3887 self.pg2.config_ip4()
3888 self.pg1.resolve_arp()
3889 self.pg2.resolve_arp()
3891 self.nat44_add_address(self.nat_addr)
3892 flags = self.config_flags.NAT_IS_INSIDE
3893 self.vapi.nat44_interface_add_del_feature(
3894 sw_if_index=self.pg0.sw_if_index,
3895 flags=flags, is_add=1)
3896 self.vapi.nat44_interface_add_del_feature(
3897 sw_if_index=self.pg1.sw_if_index,
3899 self.vapi.nat44_interface_add_del_feature(
3900 sw_if_index=self.pg2.sw_if_index,
3905 pkts = self.create_stream_in(self.pg0, self.pg1)
3906 self.pg0.add_stream(pkts)
3907 self.pg_enable_capture(self.pg_interfaces)
3909 capture = self.pg1.get_capture(len(pkts))
3910 self.verify_capture_out(capture, self.nat_addr)
3912 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3913 self.pg1.add_stream(pkts)
3914 self.pg_enable_capture(self.pg_interfaces)
3916 capture = self.pg0.get_capture(len(pkts))
3917 self.verify_capture_in(capture, self.pg0)
3919 self.tcp_port_in = 60303
3920 self.udp_port_in = 60304
3921 self.icmp_id_in = 60305
3924 pkts = self.create_stream_in(self.pg0, self.pg2)
3925 self.pg0.add_stream(pkts)
3926 self.pg_enable_capture(self.pg_interfaces)
3928 capture = self.pg2.get_capture(len(pkts))
3929 self.verify_capture_out(capture, self.nat_addr)
3931 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3932 self.pg2.add_stream(pkts)
3933 self.pg_enable_capture(self.pg_interfaces)
3935 capture = self.pg0.get_capture(len(pkts))
3936 self.verify_capture_in(capture, self.pg0)
3939 self.nat44_add_address(self.nat_addr, is_add=0)
3940 self.pg1.unconfig_ip4()
3941 self.pg2.unconfig_ip4()
3942 self.pg1.set_table_ip4(0)
3943 self.pg2.set_table_ip4(0)
3944 self.pg1.config_ip4()
3945 self.pg2.config_ip4()
3946 self.pg1.resolve_arp()
3947 self.pg2.resolve_arp()
3949 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3950 def test_session_timeout(self):
3951 """ NAT44 session timeouts """
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,
3960 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3961 tcp_transitory=240, icmp=60)
3965 for i in range(0, max_sessions):
3966 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3967 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3968 IP(src=src, dst=self.pg1.remote_ip4) /
3969 UDP(sport=1025, dport=53))
3971 self.pg0.add_stream(pkts)
3972 self.pg_enable_capture(self.pg_interfaces)
3974 self.pg1.get_capture(max_sessions)
3979 for i in range(0, max_sessions):
3980 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3981 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3982 IP(src=src, dst=self.pg1.remote_ip4) /
3983 UDP(sport=1026, dport=53))
3985 self.pg0.add_stream(pkts)
3986 self.pg_enable_capture(self.pg_interfaces)
3988 self.pg1.get_capture(max_sessions)
3991 users = self.vapi.nat44_user_dump()
3993 nsessions = nsessions + user.nsessions
3994 self.assertLess(nsessions, 2 * max_sessions)
3996 def test_mss_clamping(self):
3997 """ TCP MSS clamping """
3998 self.nat44_add_address(self.nat_addr)
3999 flags = self.config_flags.NAT_IS_INSIDE
4000 self.vapi.nat44_interface_add_del_feature(
4001 sw_if_index=self.pg0.sw_if_index,
4002 flags=flags, is_add=1)
4003 self.vapi.nat44_interface_add_del_feature(
4004 sw_if_index=self.pg1.sw_if_index,
4007 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4008 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4009 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4010 flags="S", options=[('MSS', 1400)]))
4012 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4013 self.pg0.add_stream(p)
4014 self.pg_enable_capture(self.pg_interfaces)
4016 capture = self.pg1.get_capture(1)
4017 # Negotiated MSS value greater than configured - changed
4018 self.verify_mss_value(capture[0], 1000)
4020 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4021 self.pg0.add_stream(p)
4022 self.pg_enable_capture(self.pg_interfaces)
4024 capture = self.pg1.get_capture(1)
4025 # MSS clamping disabled - negotiated MSS unchanged
4026 self.verify_mss_value(capture[0], 1400)
4028 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4029 self.pg0.add_stream(p)
4030 self.pg_enable_capture(self.pg_interfaces)
4032 capture = self.pg1.get_capture(1)
4033 # Negotiated MSS value smaller than configured - unchanged
4034 self.verify_mss_value(capture[0], 1400)
4036 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4037 def test_ha_send(self):
4038 """ Send HA session synchronization events (active) """
4039 self.nat44_add_address(self.nat_addr)
4040 flags = self.config_flags.NAT_IS_INSIDE
4041 self.vapi.nat44_interface_add_del_feature(
4042 sw_if_index=self.pg0.sw_if_index,
4043 flags=flags, is_add=1)
4044 self.vapi.nat44_interface_add_del_feature(
4045 sw_if_index=self.pg1.sw_if_index,
4047 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4050 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4051 port=12346, session_refresh_interval=10)
4052 bind_layers(UDP, HANATStateSync, sport=12345)
4055 pkts = self.create_stream_in(self.pg0, self.pg1)
4056 self.pg0.add_stream(pkts)
4057 self.pg_enable_capture(self.pg_interfaces)
4059 capture = self.pg1.get_capture(len(pkts))
4060 self.verify_capture_out(capture)
4061 # active send HA events
4062 self.vapi.nat_ha_flush()
4063 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4064 self.assertEqual(stats[0][0], 3)
4065 capture = self.pg3.get_capture(1)
4067 self.assert_packet_checksums_valid(p)
4071 hanat = p[HANATStateSync]
4073 self.logger.error(ppp("Invalid packet:", p))
4076 self.assertEqual(ip.src, self.pg3.local_ip4)
4077 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4078 self.assertEqual(udp.sport, 12345)
4079 self.assertEqual(udp.dport, 12346)
4080 self.assertEqual(hanat.version, 1)
4081 self.assertEqual(hanat.thread_index, 0)
4082 self.assertEqual(hanat.count, 3)
4083 seq = hanat.sequence_number
4084 for event in hanat.events:
4085 self.assertEqual(event.event_type, 1)
4086 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4087 self.assertEqual(event.out_addr, self.nat_addr)
4088 self.assertEqual(event.fib_index, 0)
4090 # ACK received events
4091 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4092 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4093 UDP(sport=12346, dport=12345) /
4094 HANATStateSync(sequence_number=seq, flags='ACK'))
4095 self.pg3.add_stream(ack)
4097 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4098 self.assertEqual(stats[0][0], 1)
4100 # delete one session
4101 self.pg_enable_capture(self.pg_interfaces)
4102 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4103 port=self.tcp_port_in,
4104 protocol=IP_PROTOS.tcp,
4105 flags=self.config_flags.NAT_IS_INSIDE)
4106 self.vapi.nat_ha_flush()
4107 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4108 self.assertEqual(stats[0][0], 1)
4109 capture = self.pg3.get_capture(1)
4112 hanat = p[HANATStateSync]
4114 self.logger.error(ppp("Invalid packet:", p))
4117 self.assertGreater(hanat.sequence_number, seq)
4119 # do not send ACK, active retry send HA event again
4120 self.pg_enable_capture(self.pg_interfaces)
4122 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4123 self.assertEqual(stats[0][0], 3)
4124 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4125 self.assertEqual(stats[0][0], 1)
4126 capture = self.pg3.get_capture(3)
4127 for packet in capture:
4128 self.assertEqual(packet, p)
4130 # session counters refresh
4131 pkts = self.create_stream_out(self.pg1)
4132 self.pg1.add_stream(pkts)
4133 self.pg_enable_capture(self.pg_interfaces)
4135 self.pg0.get_capture(2)
4136 self.vapi.nat_ha_flush()
4137 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4138 self.assertEqual(stats[0][0], 2)
4139 capture = self.pg3.get_capture(1)
4141 self.assert_packet_checksums_valid(p)
4145 hanat = p[HANATStateSync]
4147 self.logger.error(ppp("Invalid packet:", p))
4150 self.assertEqual(ip.src, self.pg3.local_ip4)
4151 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4152 self.assertEqual(udp.sport, 12345)
4153 self.assertEqual(udp.dport, 12346)
4154 self.assertEqual(hanat.version, 1)
4155 self.assertEqual(hanat.count, 2)
4156 seq = hanat.sequence_number
4157 for event in hanat.events:
4158 self.assertEqual(event.event_type, 3)
4159 self.assertEqual(event.out_addr, self.nat_addr)
4160 self.assertEqual(event.fib_index, 0)
4161 self.assertEqual(event.total_pkts, 2)
4162 self.assertGreater(event.total_bytes, 0)
4164 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4165 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4166 UDP(sport=12346, dport=12345) /
4167 HANATStateSync(sequence_number=seq, flags='ACK'))
4168 self.pg3.add_stream(ack)
4170 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4171 self.assertEqual(stats[0][0], 2)
4173 def test_ha_recv(self):
4174 """ Receive HA session synchronization events (passive) """
4175 self.nat44_add_address(self.nat_addr)
4176 flags = self.config_flags.NAT_IS_INSIDE
4177 self.vapi.nat44_interface_add_del_feature(
4178 sw_if_index=self.pg0.sw_if_index,
4179 flags=flags, is_add=1)
4180 self.vapi.nat44_interface_add_del_feature(
4181 sw_if_index=self.pg1.sw_if_index,
4183 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4186 bind_layers(UDP, HANATStateSync, sport=12345)
4188 self.tcp_port_out = random.randint(1025, 65535)
4189 self.udp_port_out = random.randint(1025, 65535)
4191 # send HA session add events to failover/passive
4192 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4193 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4194 UDP(sport=12346, dport=12345) /
4195 HANATStateSync(sequence_number=1, events=[
4196 Event(event_type='add', protocol='tcp',
4197 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4198 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4199 eh_addr=self.pg1.remote_ip4,
4200 ehn_addr=self.pg1.remote_ip4,
4201 eh_port=self.tcp_external_port,
4202 ehn_port=self.tcp_external_port, fib_index=0),
4203 Event(event_type='add', protocol='udp',
4204 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4205 in_port=self.udp_port_in, out_port=self.udp_port_out,
4206 eh_addr=self.pg1.remote_ip4,
4207 ehn_addr=self.pg1.remote_ip4,
4208 eh_port=self.udp_external_port,
4209 ehn_port=self.udp_external_port, fib_index=0)]))
4211 self.pg3.add_stream(p)
4212 self.pg_enable_capture(self.pg_interfaces)
4215 capture = self.pg3.get_capture(1)
4218 hanat = p[HANATStateSync]
4220 self.logger.error(ppp("Invalid packet:", p))
4223 self.assertEqual(hanat.sequence_number, 1)
4224 self.assertEqual(hanat.flags, 'ACK')
4225 self.assertEqual(hanat.version, 1)
4226 self.assertEqual(hanat.thread_index, 0)
4227 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4228 self.assertEqual(stats[0][0], 1)
4229 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4230 self.assertEqual(stats[0][0], 2)
4231 users = self.statistics.get_counter('/nat44/total-users')
4232 self.assertEqual(users[0][0], 1)
4233 sessions = self.statistics.get_counter('/nat44/total-sessions')
4234 self.assertEqual(sessions[0][0], 2)
4235 users = self.vapi.nat44_user_dump()
4236 self.assertEqual(len(users), 1)
4237 self.assertEqual(str(users[0].ip_address),
4238 self.pg0.remote_ip4)
4239 # there should be 2 sessions created by HA
4240 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4242 self.assertEqual(len(sessions), 2)
4243 for session in sessions:
4244 self.assertEqual(str(session.inside_ip_address),
4245 self.pg0.remote_ip4)
4246 self.assertEqual(str(session.outside_ip_address),
4248 self.assertIn(session.inside_port,
4249 [self.tcp_port_in, self.udp_port_in])
4250 self.assertIn(session.outside_port,
4251 [self.tcp_port_out, self.udp_port_out])
4252 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4254 # send HA session delete event to failover/passive
4255 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4256 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4257 UDP(sport=12346, dport=12345) /
4258 HANATStateSync(sequence_number=2, events=[
4259 Event(event_type='del', protocol='udp',
4260 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4261 in_port=self.udp_port_in, out_port=self.udp_port_out,
4262 eh_addr=self.pg1.remote_ip4,
4263 ehn_addr=self.pg1.remote_ip4,
4264 eh_port=self.udp_external_port,
4265 ehn_port=self.udp_external_port, fib_index=0)]))
4267 self.pg3.add_stream(p)
4268 self.pg_enable_capture(self.pg_interfaces)
4271 capture = self.pg3.get_capture(1)
4274 hanat = p[HANATStateSync]
4276 self.logger.error(ppp("Invalid packet:", p))
4279 self.assertEqual(hanat.sequence_number, 2)
4280 self.assertEqual(hanat.flags, 'ACK')
4281 self.assertEqual(hanat.version, 1)
4282 users = self.vapi.nat44_user_dump()
4283 self.assertEqual(len(users), 1)
4284 self.assertEqual(str(users[0].ip_address),
4285 self.pg0.remote_ip4)
4286 # now we should have only 1 session, 1 deleted by HA
4287 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4289 self.assertEqual(len(sessions), 1)
4290 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4291 self.assertEqual(stats[0][0], 1)
4293 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4294 self.assertEqual(stats, 2)
4296 # send HA session refresh event to failover/passive
4297 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4298 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4299 UDP(sport=12346, dport=12345) /
4300 HANATStateSync(sequence_number=3, events=[
4301 Event(event_type='refresh', protocol='tcp',
4302 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4303 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4304 eh_addr=self.pg1.remote_ip4,
4305 ehn_addr=self.pg1.remote_ip4,
4306 eh_port=self.tcp_external_port,
4307 ehn_port=self.tcp_external_port, fib_index=0,
4308 total_bytes=1024, total_pkts=2)]))
4309 self.pg3.add_stream(p)
4310 self.pg_enable_capture(self.pg_interfaces)
4313 capture = self.pg3.get_capture(1)
4316 hanat = p[HANATStateSync]
4318 self.logger.error(ppp("Invalid packet:", p))
4321 self.assertEqual(hanat.sequence_number, 3)
4322 self.assertEqual(hanat.flags, 'ACK')
4323 self.assertEqual(hanat.version, 1)
4324 users = self.vapi.nat44_user_dump()
4325 self.assertEqual(len(users), 1)
4326 self.assertEqual(str(users[0].ip_address),
4327 self.pg0.remote_ip4)
4328 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4330 self.assertEqual(len(sessions), 1)
4331 session = sessions[0]
4332 self.assertEqual(session.total_bytes, 1024)
4333 self.assertEqual(session.total_pkts, 2)
4334 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4335 self.assertEqual(stats[0][0], 1)
4337 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4338 self.assertEqual(stats, 3)
4340 # send packet to test session created by HA
4341 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4342 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4343 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4344 self.pg1.add_stream(p)
4345 self.pg_enable_capture(self.pg_interfaces)
4347 capture = self.pg0.get_capture(1)
4353 self.logger.error(ppp("Invalid packet:", p))
4356 self.assertEqual(ip.src, self.pg1.remote_ip4)
4357 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4358 self.assertEqual(tcp.sport, self.tcp_external_port)
4359 self.assertEqual(tcp.dport, self.tcp_port_in)
4362 super(TestNAT44, self).tearDown()
4364 self.vapi.cli("clear logging")
4366 def show_commands_at_teardown(self):
4367 self.logger.info(self.vapi.cli("show nat44 addresses"))
4368 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4369 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4370 self.logger.info(self.vapi.cli("show nat44 interface address"))
4371 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4372 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4373 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4374 self.logger.info(self.vapi.cli("show nat timeouts"))
4376 self.vapi.cli("show nat addr-port-assignment-alg"))
4377 self.logger.info(self.vapi.cli("show nat ha"))
4380 class TestNAT44EndpointDependent(MethodHolder):
4381 """ Endpoint-Dependent mapping and filtering test cases """
4384 def setUpConstants(cls):
4385 super(TestNAT44EndpointDependent, cls).setUpConstants()
4386 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4389 def setUpClass(cls):
4390 super(TestNAT44EndpointDependent, cls).setUpClass()
4391 cls.vapi.cli("set log class nat level debug")
4393 cls.tcp_port_in = 6303
4394 cls.tcp_port_out = 6303
4395 cls.udp_port_in = 6304
4396 cls.udp_port_out = 6304
4397 cls.icmp_id_in = 6305
4398 cls.icmp_id_out = 6305
4399 cls.nat_addr = '10.0.0.3'
4400 cls.ipfix_src_port = 4739
4401 cls.ipfix_domain_id = 1
4402 cls.tcp_external_port = 80
4404 cls.create_pg_interfaces(range(7))
4405 cls.interfaces = list(cls.pg_interfaces[0:3])
4407 for i in cls.interfaces:
4412 cls.pg0.generate_remote_hosts(3)
4413 cls.pg0.configure_ipv4_neighbors()
4417 cls.pg4.generate_remote_hosts(2)
4418 cls.pg4.config_ip4()
4419 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4420 cls.vapi.sw_interface_add_del_address(
4421 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4424 cls.pg4.resolve_arp()
4425 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4426 cls.pg4.resolve_arp()
4428 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4429 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4431 cls.pg5._local_ip4 = "10.1.1.1"
4432 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4434 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4435 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4436 socket.AF_INET, cls.pg5.remote_ip4)
4437 cls.pg5.set_table_ip4(1)
4438 cls.pg5.config_ip4()
4440 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4441 [VppRoutePath("0.0.0.0",
4442 cls.pg5.sw_if_index)],
4447 cls.pg6._local_ip4 = "10.1.2.1"
4448 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4450 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4451 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4452 socket.AF_INET, cls.pg6.remote_ip4)
4453 cls.pg6.set_table_ip4(1)
4454 cls.pg6.config_ip4()
4457 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4458 [VppRoutePath("0.0.0.0",
4459 cls.pg6.sw_if_index)],
4462 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4463 [VppRoutePath("0.0.0.0",
4468 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4469 [VppRoutePath("0.0.0.0", 0xffffffff,
4473 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4474 [VppRoutePath(cls.pg1.local_ip4,
4475 cls.pg1.sw_if_index)],
4482 cls.pg5.resolve_arp()
4483 cls.pg6.resolve_arp()
4486 super(TestNAT44EndpointDependent, cls).tearDownClass()
4490 def tearDownClass(cls):
4491 super(TestNAT44EndpointDependent, cls).tearDownClass()
4493 def test_frag_in_order(self):
4494 """ NAT44 translate fragments arriving in order """
4495 self.nat44_add_address(self.nat_addr)
4496 flags = self.config_flags.NAT_IS_INSIDE
4497 self.vapi.nat44_interface_add_del_feature(
4498 sw_if_index=self.pg0.sw_if_index,
4499 flags=flags, is_add=1)
4500 self.vapi.nat44_interface_add_del_feature(
4501 sw_if_index=self.pg1.sw_if_index,
4503 self.frag_in_order(proto=IP_PROTOS.tcp)
4504 self.frag_in_order(proto=IP_PROTOS.udp)
4505 self.frag_in_order(proto=IP_PROTOS.icmp)
4507 def test_frag_in_order_dont_translate(self):
4508 """ NAT44 don't translate fragments arriving in order """
4509 flags = self.config_flags.NAT_IS_INSIDE
4510 self.vapi.nat44_interface_add_del_feature(
4511 sw_if_index=self.pg0.sw_if_index,
4512 flags=flags, is_add=1)
4513 self.vapi.nat44_interface_add_del_feature(
4514 sw_if_index=self.pg1.sw_if_index,
4516 self.vapi.nat44_forwarding_enable_disable(enable=True)
4517 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4519 def test_frag_out_of_order(self):
4520 """ NAT44 translate fragments arriving out of order """
4521 self.nat44_add_address(self.nat_addr)
4522 flags = self.config_flags.NAT_IS_INSIDE
4523 self.vapi.nat44_interface_add_del_feature(
4524 sw_if_index=self.pg0.sw_if_index,
4525 flags=flags, is_add=1)
4526 self.vapi.nat44_interface_add_del_feature(
4527 sw_if_index=self.pg1.sw_if_index,
4529 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4530 self.frag_out_of_order(proto=IP_PROTOS.udp)
4531 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4533 def test_frag_out_of_order_dont_translate(self):
4534 """ NAT44 don't translate fragments arriving out of order """
4535 flags = self.config_flags.NAT_IS_INSIDE
4536 self.vapi.nat44_interface_add_del_feature(
4537 sw_if_index=self.pg0.sw_if_index,
4538 flags=flags, is_add=1)
4539 self.vapi.nat44_interface_add_del_feature(
4540 sw_if_index=self.pg1.sw_if_index,
4542 self.vapi.nat44_forwarding_enable_disable(enable=True)
4543 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4545 def test_frag_in_order_in_plus_out(self):
4546 """ in+out interface fragments in order """
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,
4551 self.vapi.nat44_interface_add_del_feature(
4552 sw_if_index=self.pg0.sw_if_index,
4553 flags=flags, is_add=1)
4554 self.vapi.nat44_interface_add_del_feature(
4555 sw_if_index=self.pg1.sw_if_index,
4557 self.vapi.nat44_interface_add_del_feature(
4558 sw_if_index=self.pg1.sw_if_index,
4559 flags=flags, is_add=1)
4561 self.server = self.pg1.remote_hosts[0]
4563 self.server_in_addr = self.server.ip4
4564 self.server_out_addr = '11.11.11.11'
4565 self.server_in_port = random.randint(1025, 65535)
4566 self.server_out_port = random.randint(1025, 65535)
4568 self.nat44_add_address(self.server_out_addr)
4570 # add static mappings for server
4571 self.nat44_add_static_mapping(self.server_in_addr,
4572 self.server_out_addr,
4573 self.server_in_port,
4574 self.server_out_port,
4575 proto=IP_PROTOS.tcp)
4576 self.nat44_add_static_mapping(self.server_in_addr,
4577 self.server_out_addr,
4578 self.server_in_port,
4579 self.server_out_port,
4580 proto=IP_PROTOS.udp)
4581 self.nat44_add_static_mapping(self.server_in_addr,
4582 self.server_out_addr,
4583 proto=IP_PROTOS.icmp)
4585 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4588 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4589 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4590 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4592 def test_frag_out_of_order_in_plus_out(self):
4593 """ in+out interface fragments out of order """
4594 flags = self.config_flags.NAT_IS_INSIDE
4595 self.vapi.nat44_interface_add_del_feature(
4596 sw_if_index=self.pg0.sw_if_index,
4598 self.vapi.nat44_interface_add_del_feature(
4599 sw_if_index=self.pg0.sw_if_index,
4600 flags=flags, is_add=1)
4601 self.vapi.nat44_interface_add_del_feature(
4602 sw_if_index=self.pg1.sw_if_index,
4604 self.vapi.nat44_interface_add_del_feature(
4605 sw_if_index=self.pg1.sw_if_index,
4606 flags=flags, is_add=1)
4608 self.server = self.pg1.remote_hosts[0]
4610 self.server_in_addr = self.server.ip4
4611 self.server_out_addr = '11.11.11.11'
4612 self.server_in_port = random.randint(1025, 65535)
4613 self.server_out_port = random.randint(1025, 65535)
4615 self.nat44_add_address(self.server_out_addr)
4617 # add static mappings for server
4618 self.nat44_add_static_mapping(self.server_in_addr,
4619 self.server_out_addr,
4620 self.server_in_port,
4621 self.server_out_port,
4622 proto=IP_PROTOS.tcp)
4623 self.nat44_add_static_mapping(self.server_in_addr,
4624 self.server_out_addr,
4625 self.server_in_port,
4626 self.server_out_port,
4627 proto=IP_PROTOS.udp)
4628 self.nat44_add_static_mapping(self.server_in_addr,
4629 self.server_out_addr,
4630 proto=IP_PROTOS.icmp)
4632 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4635 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4636 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4637 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4639 def test_reass_hairpinning(self):
4640 """ NAT44 fragments hairpinning """
4641 self.server = self.pg0.remote_hosts[1]
4642 self.host_in_port = random.randint(1025, 65535)
4643 self.server_in_port = random.randint(1025, 65535)
4644 self.server_out_port = random.randint(1025, 65535)
4646 self.nat44_add_address(self.nat_addr)
4647 flags = self.config_flags.NAT_IS_INSIDE
4648 self.vapi.nat44_interface_add_del_feature(
4649 sw_if_index=self.pg0.sw_if_index,
4650 flags=flags, is_add=1)
4651 self.vapi.nat44_interface_add_del_feature(
4652 sw_if_index=self.pg1.sw_if_index,
4654 # add static mapping for server
4655 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4656 self.server_in_port,
4657 self.server_out_port,
4658 proto=IP_PROTOS.tcp)
4659 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4660 self.server_in_port,
4661 self.server_out_port,
4662 proto=IP_PROTOS.udp)
4663 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4665 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4666 self.reass_hairpinning(proto=IP_PROTOS.udp)
4667 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4669 def test_dynamic(self):
4670 """ NAT44 dynamic translation test """
4672 self.nat44_add_address(self.nat_addr)
4673 flags = self.config_flags.NAT_IS_INSIDE
4674 self.vapi.nat44_interface_add_del_feature(
4675 sw_if_index=self.pg0.sw_if_index,
4676 flags=flags, is_add=1)
4677 self.vapi.nat44_interface_add_del_feature(
4678 sw_if_index=self.pg1.sw_if_index,
4681 nat_config = self.vapi.nat_show_config()
4682 self.assertEqual(1, nat_config.endpoint_dependent)
4685 tcpn = self.statistics.get_err_counter(
4686 '/err/nat44-ed-in2out-slowpath/TCP packets')
4687 udpn = self.statistics.get_err_counter(
4688 '/err/nat44-ed-in2out-slowpath/UDP packets')
4689 icmpn = self.statistics.get_err_counter(
4690 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4691 totaln = self.statistics.get_err_counter(
4692 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4694 pkts = self.create_stream_in(self.pg0, self.pg1)
4695 self.pg0.add_stream(pkts)
4696 self.pg_enable_capture(self.pg_interfaces)
4698 capture = self.pg1.get_capture(len(pkts))
4699 self.verify_capture_out(capture)
4701 err = self.statistics.get_err_counter(
4702 '/err/nat44-ed-in2out-slowpath/TCP packets')
4703 self.assertEqual(err - tcpn, 1)
4704 err = self.statistics.get_err_counter(
4705 '/err/nat44-ed-in2out-slowpath/UDP packets')
4706 self.assertEqual(err - udpn, 1)
4707 err = self.statistics.get_err_counter(
4708 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4709 self.assertEqual(err - icmpn, 1)
4710 err = self.statistics.get_err_counter(
4711 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4712 self.assertEqual(err - totaln, 3)
4715 tcpn = self.statistics.get_err_counter(
4716 '/err/nat44-ed-out2in/TCP packets')
4717 udpn = self.statistics.get_err_counter(
4718 '/err/nat44-ed-out2in/UDP packets')
4719 icmpn = self.statistics.get_err_counter(
4720 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4721 totaln = self.statistics.get_err_counter(
4722 '/err/nat44-ed-out2in/good out2in packets processed')
4724 pkts = self.create_stream_out(self.pg1)
4725 self.pg1.add_stream(pkts)
4726 self.pg_enable_capture(self.pg_interfaces)
4728 capture = self.pg0.get_capture(len(pkts))
4729 self.verify_capture_in(capture, self.pg0)
4731 err = self.statistics.get_err_counter(
4732 '/err/nat44-ed-out2in/TCP packets')
4733 self.assertEqual(err - tcpn, 1)
4734 err = self.statistics.get_err_counter(
4735 '/err/nat44-ed-out2in/UDP packets')
4736 self.assertEqual(err - udpn, 1)
4737 err = self.statistics.get_err_counter(
4738 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4739 self.assertEqual(err - icmpn, 1)
4740 err = self.statistics.get_err_counter(
4741 '/err/nat44-ed-out2in/good out2in packets processed')
4742 self.assertEqual(err - totaln, 2)
4744 users = self.statistics.get_counter('/nat44/total-users')
4745 self.assertEqual(users[0][0], 1)
4746 sessions = self.statistics.get_counter('/nat44/total-sessions')
4747 self.assertEqual(sessions[0][0], 3)
4749 def test_forwarding(self):
4750 """ NAT44 forwarding test """
4752 flags = self.config_flags.NAT_IS_INSIDE
4753 self.vapi.nat44_interface_add_del_feature(
4754 sw_if_index=self.pg0.sw_if_index,
4755 flags=flags, is_add=1)
4756 self.vapi.nat44_interface_add_del_feature(
4757 sw_if_index=self.pg1.sw_if_index,
4759 self.vapi.nat44_forwarding_enable_disable(enable=1)
4761 real_ip = self.pg0.remote_ip4
4762 alias_ip = self.nat_addr
4763 flags = self.config_flags.NAT_IS_ADDR_ONLY
4764 self.vapi.nat44_add_del_static_mapping(is_add=1,
4765 local_ip_address=real_ip,
4766 external_ip_address=alias_ip,
4767 external_sw_if_index=0xFFFFFFFF,
4771 # in2out - static mapping match
4773 pkts = self.create_stream_out(self.pg1)
4774 self.pg1.add_stream(pkts)
4775 self.pg_enable_capture(self.pg_interfaces)
4777 capture = self.pg0.get_capture(len(pkts))
4778 self.verify_capture_in(capture, self.pg0)
4780 pkts = self.create_stream_in(self.pg0, self.pg1)
4781 self.pg0.add_stream(pkts)
4782 self.pg_enable_capture(self.pg_interfaces)
4784 capture = self.pg1.get_capture(len(pkts))
4785 self.verify_capture_out(capture, same_port=True)
4787 # in2out - no static mapping match
4789 host0 = self.pg0.remote_hosts[0]
4790 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4792 pkts = self.create_stream_out(self.pg1,
4793 dst_ip=self.pg0.remote_ip4,
4794 use_inside_ports=True)
4795 self.pg1.add_stream(pkts)
4796 self.pg_enable_capture(self.pg_interfaces)
4798 capture = self.pg0.get_capture(len(pkts))
4799 self.verify_capture_in(capture, self.pg0)
4801 pkts = self.create_stream_in(self.pg0, self.pg1)
4802 self.pg0.add_stream(pkts)
4803 self.pg_enable_capture(self.pg_interfaces)
4805 capture = self.pg1.get_capture(len(pkts))
4806 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4809 self.pg0.remote_hosts[0] = host0
4811 user = self.pg0.remote_hosts[1]
4812 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4813 self.assertEqual(len(sessions), 3)
4814 self.assertTrue(sessions[0].flags &
4815 self.config_flags.NAT_IS_EXT_HOST_VALID)
4816 self.vapi.nat44_del_session(
4817 address=sessions[0].inside_ip_address,
4818 port=sessions[0].inside_port,
4819 protocol=sessions[0].protocol,
4820 flags=(self.config_flags.NAT_IS_INSIDE |
4821 self.config_flags.NAT_IS_EXT_HOST_VALID),
4822 ext_host_address=sessions[0].ext_host_address,
4823 ext_host_port=sessions[0].ext_host_port)
4824 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4825 self.assertEqual(len(sessions), 2)
4828 self.vapi.nat44_forwarding_enable_disable(enable=0)
4829 flags = self.config_flags.NAT_IS_ADDR_ONLY
4830 self.vapi.nat44_add_del_static_mapping(
4832 local_ip_address=real_ip,
4833 external_ip_address=alias_ip,
4834 external_sw_if_index=0xFFFFFFFF,
4837 def test_static_lb(self):
4838 """ NAT44 local service load balancing """
4839 external_addr_n = self.nat_addr
4842 server1 = self.pg0.remote_hosts[0]
4843 server2 = self.pg0.remote_hosts[1]
4845 locals = [{'addr': server1.ip4n,
4849 {'addr': server2.ip4n,
4854 self.nat44_add_address(self.nat_addr)
4855 self.vapi.nat44_add_del_lb_static_mapping(
4857 external_addr=external_addr_n,
4858 external_port=external_port,
4859 protocol=IP_PROTOS.tcp,
4860 local_num=len(locals),
4862 flags = self.config_flags.NAT_IS_INSIDE
4863 self.vapi.nat44_interface_add_del_feature(
4864 sw_if_index=self.pg0.sw_if_index,
4865 flags=flags, is_add=1)
4866 self.vapi.nat44_interface_add_del_feature(
4867 sw_if_index=self.pg1.sw_if_index,
4870 # from client to service
4871 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4872 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4873 TCP(sport=12345, dport=external_port))
4874 self.pg1.add_stream(p)
4875 self.pg_enable_capture(self.pg_interfaces)
4877 capture = self.pg0.get_capture(1)
4883 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4884 if ip.dst == server1.ip4:
4888 self.assertEqual(tcp.dport, local_port)
4889 self.assert_packet_checksums_valid(p)
4891 self.logger.error(ppp("Unexpected or invalid packet:", p))
4894 # from service back to client
4895 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4896 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4897 TCP(sport=local_port, dport=12345))
4898 self.pg0.add_stream(p)
4899 self.pg_enable_capture(self.pg_interfaces)
4901 capture = self.pg1.get_capture(1)
4906 self.assertEqual(ip.src, self.nat_addr)
4907 self.assertEqual(tcp.sport, external_port)
4908 self.assert_packet_checksums_valid(p)
4910 self.logger.error(ppp("Unexpected or invalid packet:", p))
4913 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4914 self.assertEqual(len(sessions), 1)
4915 self.assertTrue(sessions[0].flags &
4916 self.config_flags.NAT_IS_EXT_HOST_VALID)
4917 self.vapi.nat44_del_session(
4918 address=sessions[0].inside_ip_address,
4919 port=sessions[0].inside_port,
4920 protocol=sessions[0].protocol,
4921 flags=(self.config_flags.NAT_IS_INSIDE |
4922 self.config_flags.NAT_IS_EXT_HOST_VALID),
4923 ext_host_address=sessions[0].ext_host_address,
4924 ext_host_port=sessions[0].ext_host_port)
4925 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4926 self.assertEqual(len(sessions), 0)
4928 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4929 def test_static_lb_multi_clients(self):
4930 """ NAT44 local service load balancing - multiple clients"""
4932 external_addr = self.nat_addr
4935 server1 = self.pg0.remote_hosts[0]
4936 server2 = self.pg0.remote_hosts[1]
4937 server3 = self.pg0.remote_hosts[2]
4939 locals = [{'addr': server1.ip4n,
4943 {'addr': server2.ip4n,
4948 self.nat44_add_address(self.nat_addr)
4949 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4950 external_addr=external_addr,
4951 external_port=external_port,
4952 protocol=IP_PROTOS.tcp,
4953 local_num=len(locals),
4955 flags = self.config_flags.NAT_IS_INSIDE
4956 self.vapi.nat44_interface_add_del_feature(
4957 sw_if_index=self.pg0.sw_if_index,
4958 flags=flags, is_add=1)
4959 self.vapi.nat44_interface_add_del_feature(
4960 sw_if_index=self.pg1.sw_if_index,
4965 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4967 for client in clients:
4968 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4969 IP(src=client, dst=self.nat_addr) /
4970 TCP(sport=12345, dport=external_port))
4972 self.pg1.add_stream(pkts)
4973 self.pg_enable_capture(self.pg_interfaces)
4975 capture = self.pg0.get_capture(len(pkts))
4977 if p[IP].dst == server1.ip4:
4981 self.assertGreater(server1_n, server2_n)
4984 'addr': server3.ip4n,
4991 self.vapi.nat44_lb_static_mapping_add_del_local(
4993 external_addr=external_addr,
4994 external_port=external_port,
4996 protocol=IP_PROTOS.tcp)
5000 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5002 for client in clients:
5003 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5004 IP(src=client, dst=self.nat_addr) /
5005 TCP(sport=12346, dport=external_port))
5007 self.assertGreater(len(pkts), 0)
5008 self.pg1.add_stream(pkts)
5009 self.pg_enable_capture(self.pg_interfaces)
5011 capture = self.pg0.get_capture(len(pkts))
5013 if p[IP].dst == server1.ip4:
5015 elif p[IP].dst == server2.ip4:
5019 self.assertGreater(server1_n, 0)
5020 self.assertGreater(server2_n, 0)
5021 self.assertGreater(server3_n, 0)
5024 'addr': server2.ip4n,
5030 # remove one back-end
5031 self.vapi.nat44_lb_static_mapping_add_del_local(
5033 external_addr=external_addr,
5034 external_port=external_port,
5036 protocol=IP_PROTOS.tcp)
5040 self.pg1.add_stream(pkts)
5041 self.pg_enable_capture(self.pg_interfaces)
5043 capture = self.pg0.get_capture(len(pkts))
5045 if p[IP].dst == server1.ip4:
5047 elif p[IP].dst == server2.ip4:
5051 self.assertGreater(server1_n, 0)
5052 self.assertEqual(server2_n, 0)
5053 self.assertGreater(server3_n, 0)
5055 def test_static_lb_2(self):
5056 """ NAT44 local service load balancing (asymmetrical rule) """
5057 external_addr = self.nat_addr
5060 server1 = self.pg0.remote_hosts[0]
5061 server2 = self.pg0.remote_hosts[1]
5063 locals = [{'addr': server1.ip4n,
5067 {'addr': server2.ip4n,
5072 self.vapi.nat44_forwarding_enable_disable(enable=1)
5073 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5074 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5075 external_addr=external_addr,
5076 external_port=external_port,
5077 protocol=IP_PROTOS.tcp,
5078 local_num=len(locals),
5080 flags = self.config_flags.NAT_IS_INSIDE
5081 self.vapi.nat44_interface_add_del_feature(
5082 sw_if_index=self.pg0.sw_if_index,
5083 flags=flags, is_add=1)
5084 self.vapi.nat44_interface_add_del_feature(
5085 sw_if_index=self.pg1.sw_if_index,
5088 # from client to service
5089 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5090 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5091 TCP(sport=12345, dport=external_port))
5092 self.pg1.add_stream(p)
5093 self.pg_enable_capture(self.pg_interfaces)
5095 capture = self.pg0.get_capture(1)
5101 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5102 if ip.dst == server1.ip4:
5106 self.assertEqual(tcp.dport, local_port)
5107 self.assert_packet_checksums_valid(p)
5109 self.logger.error(ppp("Unexpected or invalid packet:", p))
5112 # from service back to client
5113 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5114 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5115 TCP(sport=local_port, dport=12345))
5116 self.pg0.add_stream(p)
5117 self.pg_enable_capture(self.pg_interfaces)
5119 capture = self.pg1.get_capture(1)
5124 self.assertEqual(ip.src, self.nat_addr)
5125 self.assertEqual(tcp.sport, external_port)
5126 self.assert_packet_checksums_valid(p)
5128 self.logger.error(ppp("Unexpected or invalid packet:", p))
5131 # from client to server (no translation)
5132 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5133 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5134 TCP(sport=12346, dport=local_port))
5135 self.pg1.add_stream(p)
5136 self.pg_enable_capture(self.pg_interfaces)
5138 capture = self.pg0.get_capture(1)
5144 self.assertEqual(ip.dst, server1.ip4)
5145 self.assertEqual(tcp.dport, local_port)
5146 self.assert_packet_checksums_valid(p)
5148 self.logger.error(ppp("Unexpected or invalid packet:", p))
5151 # from service back to client (no translation)
5152 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5153 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5154 TCP(sport=local_port, dport=12346))
5155 self.pg0.add_stream(p)
5156 self.pg_enable_capture(self.pg_interfaces)
5158 capture = self.pg1.get_capture(1)
5163 self.assertEqual(ip.src, server1.ip4)
5164 self.assertEqual(tcp.sport, local_port)
5165 self.assert_packet_checksums_valid(p)
5167 self.logger.error(ppp("Unexpected or invalid packet:", p))
5170 def test_lb_affinity(self):
5171 """ NAT44 local service load balancing affinity """
5172 external_addr = self.nat_addr
5175 server1 = self.pg0.remote_hosts[0]
5176 server2 = self.pg0.remote_hosts[1]
5178 locals = [{'addr': server1.ip4n,
5182 {'addr': server2.ip4n,
5187 self.nat44_add_address(self.nat_addr)
5188 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5189 external_addr=external_addr,
5190 external_port=external_port,
5191 protocol=IP_PROTOS.tcp,
5193 local_num=len(locals),
5195 flags = self.config_flags.NAT_IS_INSIDE
5196 self.vapi.nat44_interface_add_del_feature(
5197 sw_if_index=self.pg0.sw_if_index,
5198 flags=flags, is_add=1)
5199 self.vapi.nat44_interface_add_del_feature(
5200 sw_if_index=self.pg1.sw_if_index,
5203 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5204 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5205 TCP(sport=1025, dport=external_port))
5206 self.pg1.add_stream(p)
5207 self.pg_enable_capture(self.pg_interfaces)
5209 capture = self.pg0.get_capture(1)
5210 backend = capture[0][IP].dst
5212 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5213 self.assertEqual(len(sessions), 1)
5214 self.assertTrue(sessions[0].flags &
5215 self.config_flags.NAT_IS_EXT_HOST_VALID)
5216 self.vapi.nat44_del_session(
5217 address=sessions[0].inside_ip_address,
5218 port=sessions[0].inside_port,
5219 protocol=sessions[0].protocol,
5220 flags=(self.config_flags.NAT_IS_INSIDE |
5221 self.config_flags.NAT_IS_EXT_HOST_VALID),
5222 ext_host_address=sessions[0].ext_host_address,
5223 ext_host_port=sessions[0].ext_host_port)
5226 for port in range(1030, 1100):
5227 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5228 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5229 TCP(sport=port, dport=external_port))
5231 self.pg1.add_stream(pkts)
5232 self.pg_enable_capture(self.pg_interfaces)
5234 capture = self.pg0.get_capture(len(pkts))
5236 self.assertEqual(p[IP].dst, backend)
5238 def test_unknown_proto(self):
5239 """ NAT44 translate packet with unknown protocol """
5240 self.nat44_add_address(self.nat_addr)
5241 flags = self.config_flags.NAT_IS_INSIDE
5242 self.vapi.nat44_interface_add_del_feature(
5243 sw_if_index=self.pg0.sw_if_index,
5244 flags=flags, is_add=1)
5245 self.vapi.nat44_interface_add_del_feature(
5246 sw_if_index=self.pg1.sw_if_index,
5250 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5251 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5252 TCP(sport=self.tcp_port_in, dport=20))
5253 self.pg0.add_stream(p)
5254 self.pg_enable_capture(self.pg_interfaces)
5256 p = self.pg1.get_capture(1)
5258 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5259 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5261 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5262 TCP(sport=1234, dport=1234))
5263 self.pg0.add_stream(p)
5264 self.pg_enable_capture(self.pg_interfaces)
5266 p = self.pg1.get_capture(1)
5269 self.assertEqual(packet[IP].src, self.nat_addr)
5270 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5271 self.assertEqual(packet.haslayer(GRE), 1)
5272 self.assert_packet_checksums_valid(packet)
5274 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5278 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5279 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5281 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5282 TCP(sport=1234, dport=1234))
5283 self.pg1.add_stream(p)
5284 self.pg_enable_capture(self.pg_interfaces)
5286 p = self.pg0.get_capture(1)
5289 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5290 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5291 self.assertEqual(packet.haslayer(GRE), 1)
5292 self.assert_packet_checksums_valid(packet)
5294 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5297 def test_hairpinning_unknown_proto(self):
5298 """ NAT44 translate packet with unknown protocol - hairpinning """
5299 host = self.pg0.remote_hosts[0]
5300 server = self.pg0.remote_hosts[1]
5302 server_out_port = 8765
5303 server_nat_ip = "10.0.0.11"
5305 self.nat44_add_address(self.nat_addr)
5306 flags = self.config_flags.NAT_IS_INSIDE
5307 self.vapi.nat44_interface_add_del_feature(
5308 sw_if_index=self.pg0.sw_if_index,
5309 flags=flags, is_add=1)
5310 self.vapi.nat44_interface_add_del_feature(
5311 sw_if_index=self.pg1.sw_if_index,
5314 # add static mapping for server
5315 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5318 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5319 IP(src=host.ip4, dst=server_nat_ip) /
5320 TCP(sport=host_in_port, dport=server_out_port))
5321 self.pg0.add_stream(p)
5322 self.pg_enable_capture(self.pg_interfaces)
5324 self.pg0.get_capture(1)
5326 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5327 IP(src=host.ip4, dst=server_nat_ip) /
5329 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5330 TCP(sport=1234, dport=1234))
5331 self.pg0.add_stream(p)
5332 self.pg_enable_capture(self.pg_interfaces)
5334 p = self.pg0.get_capture(1)
5337 self.assertEqual(packet[IP].src, self.nat_addr)
5338 self.assertEqual(packet[IP].dst, server.ip4)
5339 self.assertEqual(packet.haslayer(GRE), 1)
5340 self.assert_packet_checksums_valid(packet)
5342 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5346 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5347 IP(src=server.ip4, dst=self.nat_addr) /
5349 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5350 TCP(sport=1234, dport=1234))
5351 self.pg0.add_stream(p)
5352 self.pg_enable_capture(self.pg_interfaces)
5354 p = self.pg0.get_capture(1)
5357 self.assertEqual(packet[IP].src, server_nat_ip)
5358 self.assertEqual(packet[IP].dst, host.ip4)
5359 self.assertEqual(packet.haslayer(GRE), 1)
5360 self.assert_packet_checksums_valid(packet)
5362 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5365 def test_output_feature_and_service(self):
5366 """ NAT44 interface output feature and services """
5367 external_addr = '1.2.3.4'
5371 self.vapi.nat44_forwarding_enable_disable(enable=1)
5372 self.nat44_add_address(self.nat_addr)
5373 flags = self.config_flags.NAT_IS_ADDR_ONLY
5374 self.vapi.nat44_add_del_identity_mapping(
5375 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5376 flags=flags, is_add=1)
5377 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5378 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5379 local_port, external_port,
5380 proto=IP_PROTOS.tcp, flags=flags)
5381 flags = self.config_flags.NAT_IS_INSIDE
5382 self.vapi.nat44_interface_add_del_feature(
5383 sw_if_index=self.pg0.sw_if_index,
5385 self.vapi.nat44_interface_add_del_feature(
5386 sw_if_index=self.pg0.sw_if_index,
5387 flags=flags, is_add=1)
5388 self.vapi.nat44_interface_add_del_output_feature(
5390 sw_if_index=self.pg1.sw_if_index)
5392 # from client to service
5393 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5394 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5395 TCP(sport=12345, dport=external_port))
5396 self.pg1.add_stream(p)
5397 self.pg_enable_capture(self.pg_interfaces)
5399 capture = self.pg0.get_capture(1)
5404 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5405 self.assertEqual(tcp.dport, local_port)
5406 self.assert_packet_checksums_valid(p)
5408 self.logger.error(ppp("Unexpected or invalid packet:", p))
5411 # from service back to client
5412 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5413 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5414 TCP(sport=local_port, dport=12345))
5415 self.pg0.add_stream(p)
5416 self.pg_enable_capture(self.pg_interfaces)
5418 capture = self.pg1.get_capture(1)
5423 self.assertEqual(ip.src, external_addr)
5424 self.assertEqual(tcp.sport, external_port)
5425 self.assert_packet_checksums_valid(p)
5427 self.logger.error(ppp("Unexpected or invalid packet:", p))
5430 # from local network host to external network
5431 pkts = self.create_stream_in(self.pg0, self.pg1)
5432 self.pg0.add_stream(pkts)
5433 self.pg_enable_capture(self.pg_interfaces)
5435 capture = self.pg1.get_capture(len(pkts))
5436 self.verify_capture_out(capture)
5437 pkts = self.create_stream_in(self.pg0, self.pg1)
5438 self.pg0.add_stream(pkts)
5439 self.pg_enable_capture(self.pg_interfaces)
5441 capture = self.pg1.get_capture(len(pkts))
5442 self.verify_capture_out(capture)
5444 # from external network back to local network host
5445 pkts = self.create_stream_out(self.pg1)
5446 self.pg1.add_stream(pkts)
5447 self.pg_enable_capture(self.pg_interfaces)
5449 capture = self.pg0.get_capture(len(pkts))
5450 self.verify_capture_in(capture, self.pg0)
5452 def test_output_feature_and_service2(self):
5453 """ NAT44 interface output feature and service host direct access """
5454 self.vapi.nat44_forwarding_enable_disable(enable=1)
5455 self.nat44_add_address(self.nat_addr)
5456 self.vapi.nat44_interface_add_del_output_feature(
5458 sw_if_index=self.pg1.sw_if_index)
5460 # session initiated from service host - translate
5461 pkts = self.create_stream_in(self.pg0, self.pg1)
5462 self.pg0.add_stream(pkts)
5463 self.pg_enable_capture(self.pg_interfaces)
5465 capture = self.pg1.get_capture(len(pkts))
5466 self.verify_capture_out(capture)
5468 pkts = self.create_stream_out(self.pg1)
5469 self.pg1.add_stream(pkts)
5470 self.pg_enable_capture(self.pg_interfaces)
5472 capture = self.pg0.get_capture(len(pkts))
5473 self.verify_capture_in(capture, self.pg0)
5475 # session initiated from remote host - do not translate
5476 self.tcp_port_in = 60303
5477 self.udp_port_in = 60304
5478 self.icmp_id_in = 60305
5479 pkts = self.create_stream_out(self.pg1,
5480 self.pg0.remote_ip4,
5481 use_inside_ports=True)
5482 self.pg1.add_stream(pkts)
5483 self.pg_enable_capture(self.pg_interfaces)
5485 capture = self.pg0.get_capture(len(pkts))
5486 self.verify_capture_in(capture, self.pg0)
5488 pkts = self.create_stream_in(self.pg0, self.pg1)
5489 self.pg0.add_stream(pkts)
5490 self.pg_enable_capture(self.pg_interfaces)
5492 capture = self.pg1.get_capture(len(pkts))
5493 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5496 def test_output_feature_and_service3(self):
5497 """ NAT44 interface output feature and DST NAT """
5498 external_addr = '1.2.3.4'
5502 self.vapi.nat44_forwarding_enable_disable(enable=1)
5503 self.nat44_add_address(self.nat_addr)
5504 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5505 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5506 local_port, external_port,
5507 proto=IP_PROTOS.tcp, flags=flags)
5508 flags = self.config_flags.NAT_IS_INSIDE
5509 self.vapi.nat44_interface_add_del_feature(
5510 sw_if_index=self.pg0.sw_if_index,
5512 self.vapi.nat44_interface_add_del_feature(
5513 sw_if_index=self.pg0.sw_if_index,
5514 flags=flags, is_add=1)
5515 self.vapi.nat44_interface_add_del_output_feature(
5517 sw_if_index=self.pg1.sw_if_index)
5519 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5520 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5521 TCP(sport=12345, dport=external_port))
5522 self.pg0.add_stream(p)
5523 self.pg_enable_capture(self.pg_interfaces)
5525 capture = self.pg1.get_capture(1)
5530 self.assertEqual(ip.src, self.pg0.remote_ip4)
5531 self.assertEqual(tcp.sport, 12345)
5532 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5533 self.assertEqual(tcp.dport, local_port)
5534 self.assert_packet_checksums_valid(p)
5536 self.logger.error(ppp("Unexpected or invalid packet:", p))
5539 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5540 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5541 TCP(sport=local_port, dport=12345))
5542 self.pg1.add_stream(p)
5543 self.pg_enable_capture(self.pg_interfaces)
5545 capture = self.pg0.get_capture(1)
5550 self.assertEqual(ip.src, external_addr)
5551 self.assertEqual(tcp.sport, external_port)
5552 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5553 self.assertEqual(tcp.dport, 12345)
5554 self.assert_packet_checksums_valid(p)
5556 self.logger.error(ppp("Unexpected or invalid packet:", p))
5559 def test_next_src_nat(self):
5560 """ On way back forward packet to nat44-in2out node. """
5561 twice_nat_addr = '10.0.1.3'
5564 post_twice_nat_port = 0
5566 self.vapi.nat44_forwarding_enable_disable(enable=1)
5567 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5568 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5569 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5570 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5571 local_port, external_port,
5572 proto=IP_PROTOS.tcp, vrf_id=1,
5574 self.vapi.nat44_interface_add_del_feature(
5575 sw_if_index=self.pg6.sw_if_index,
5578 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5579 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5580 TCP(sport=12345, dport=external_port))
5581 self.pg6.add_stream(p)
5582 self.pg_enable_capture(self.pg_interfaces)
5584 capture = self.pg6.get_capture(1)
5589 self.assertEqual(ip.src, twice_nat_addr)
5590 self.assertNotEqual(tcp.sport, 12345)
5591 post_twice_nat_port = tcp.sport
5592 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5593 self.assertEqual(tcp.dport, local_port)
5594 self.assert_packet_checksums_valid(p)
5596 self.logger.error(ppp("Unexpected or invalid packet:", p))
5599 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5600 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5601 TCP(sport=local_port, dport=post_twice_nat_port))
5602 self.pg6.add_stream(p)
5603 self.pg_enable_capture(self.pg_interfaces)
5605 capture = self.pg6.get_capture(1)
5610 self.assertEqual(ip.src, self.pg1.remote_ip4)
5611 self.assertEqual(tcp.sport, external_port)
5612 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5613 self.assertEqual(tcp.dport, 12345)
5614 self.assert_packet_checksums_valid(p)
5616 self.logger.error(ppp("Unexpected or invalid packet:", p))
5619 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5621 twice_nat_addr = '10.0.1.3'
5629 port_in1 = port_in + 1
5630 port_in2 = port_in + 2
5635 server1 = self.pg0.remote_hosts[0]
5636 server2 = self.pg0.remote_hosts[1]
5648 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5651 self.nat44_add_address(self.nat_addr)
5652 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5656 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5658 flags |= self.config_flags.NAT_IS_TWICE_NAT
5661 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5663 proto=IP_PROTOS.tcp,
5666 locals = [{'addr': server1.ip4n,
5670 {'addr': server2.ip4n,
5674 out_addr = self.nat_addr
5676 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5677 external_addr=out_addr,
5678 external_port=port_out,
5679 protocol=IP_PROTOS.tcp,
5680 local_num=len(locals),
5682 flags = self.config_flags.NAT_IS_INSIDE
5683 self.vapi.nat44_interface_add_del_feature(
5684 sw_if_index=pg0.sw_if_index,
5685 flags=flags, is_add=1)
5686 self.vapi.nat44_interface_add_del_feature(
5687 sw_if_index=pg1.sw_if_index,
5694 assert client_id is not None
5696 client = self.pg0.remote_hosts[0]
5697 elif client_id == 2:
5698 client = self.pg0.remote_hosts[1]
5700 client = pg1.remote_hosts[0]
5701 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5702 IP(src=client.ip4, dst=self.nat_addr) /
5703 TCP(sport=eh_port_out, dport=port_out))
5705 self.pg_enable_capture(self.pg_interfaces)
5707 capture = pg0.get_capture(1)
5713 if ip.dst == server1.ip4:
5719 self.assertEqual(ip.dst, server.ip4)
5721 self.assertIn(tcp.dport, [port_in1, port_in2])
5723 self.assertEqual(tcp.dport, port_in)
5725 self.assertEqual(ip.src, twice_nat_addr)
5726 self.assertNotEqual(tcp.sport, eh_port_out)
5728 self.assertEqual(ip.src, client.ip4)
5729 self.assertEqual(tcp.sport, eh_port_out)
5731 eh_port_in = tcp.sport
5732 saved_port_in = tcp.dport
5733 self.assert_packet_checksums_valid(p)
5735 self.logger.error(ppp("Unexpected or invalid packet:", p))
5738 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5739 IP(src=server.ip4, dst=eh_addr_in) /
5740 TCP(sport=saved_port_in, dport=eh_port_in))
5742 self.pg_enable_capture(self.pg_interfaces)
5744 capture = pg1.get_capture(1)
5749 self.assertEqual(ip.dst, client.ip4)
5750 self.assertEqual(ip.src, self.nat_addr)
5751 self.assertEqual(tcp.dport, eh_port_out)
5752 self.assertEqual(tcp.sport, port_out)
5753 self.assert_packet_checksums_valid(p)
5755 self.logger.error(ppp("Unexpected or invalid packet:", p))
5759 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5760 self.assertEqual(len(sessions), 1)
5761 self.assertTrue(sessions[0].flags &
5762 self.config_flags.NAT_IS_EXT_HOST_VALID)
5763 self.assertTrue(sessions[0].flags &
5764 self.config_flags.NAT_IS_TWICE_NAT)
5765 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5766 self.vapi.nat44_del_session(
5767 address=sessions[0].inside_ip_address,
5768 port=sessions[0].inside_port,
5769 protocol=sessions[0].protocol,
5770 flags=(self.config_flags.NAT_IS_INSIDE |
5771 self.config_flags.NAT_IS_EXT_HOST_VALID),
5772 ext_host_address=sessions[0].ext_host_nat_address,
5773 ext_host_port=sessions[0].ext_host_nat_port)
5774 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5775 self.assertEqual(len(sessions), 0)
5777 def test_twice_nat(self):
5779 self.twice_nat_common()
5781 def test_self_twice_nat_positive(self):
5782 """ Self Twice NAT44 (positive test) """
5783 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5785 def test_self_twice_nat_negative(self):
5786 """ Self Twice NAT44 (negative test) """
5787 self.twice_nat_common(self_twice_nat=True)
5789 def test_twice_nat_lb(self):
5790 """ Twice NAT44 local service load balancing """
5791 self.twice_nat_common(lb=True)
5793 def test_self_twice_nat_lb_positive(self):
5794 """ Self Twice NAT44 local service load balancing (positive test) """
5795 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5798 def test_self_twice_nat_lb_negative(self):
5799 """ Self Twice NAT44 local service load balancing (negative test) """
5800 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5803 def test_twice_nat_interface_addr(self):
5804 """ Acquire twice NAT44 addresses from interface """
5805 flags = self.config_flags.NAT_IS_TWICE_NAT
5806 self.vapi.nat44_add_del_interface_addr(
5808 sw_if_index=self.pg3.sw_if_index,
5811 # no address in NAT pool
5812 adresses = self.vapi.nat44_address_dump()
5813 self.assertEqual(0, len(adresses))
5815 # configure interface address and check NAT address pool
5816 self.pg3.config_ip4()
5817 adresses = self.vapi.nat44_address_dump()
5818 self.assertEqual(1, len(adresses))
5819 self.assertEqual(str(adresses[0].ip_address),
5821 self.assertEqual(adresses[0].flags, flags)
5823 # remove interface address and check NAT address pool
5824 self.pg3.unconfig_ip4()
5825 adresses = self.vapi.nat44_address_dump()
5826 self.assertEqual(0, len(adresses))
5828 def test_tcp_close(self):
5829 """ Close TCP session from inside network - output feature """
5830 self.vapi.nat44_forwarding_enable_disable(enable=1)
5831 self.nat44_add_address(self.pg1.local_ip4)
5832 twice_nat_addr = '10.0.1.3'
5833 service_ip = '192.168.16.150'
5834 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5835 flags = self.config_flags.NAT_IS_INSIDE
5836 self.vapi.nat44_interface_add_del_feature(
5837 sw_if_index=self.pg0.sw_if_index,
5839 self.vapi.nat44_interface_add_del_feature(
5840 sw_if_index=self.pg0.sw_if_index,
5841 flags=flags, is_add=1)
5842 self.vapi.nat44_interface_add_del_output_feature(
5844 sw_if_index=self.pg1.sw_if_index)
5845 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5846 self.config_flags.NAT_IS_TWICE_NAT)
5847 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5851 proto=IP_PROTOS.tcp,
5853 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5854 start_sessnum = len(sessions)
5856 # SYN packet out->in
5857 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5858 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5859 TCP(sport=33898, dport=80, flags="S"))
5860 self.pg1.add_stream(p)
5861 self.pg_enable_capture(self.pg_interfaces)
5863 capture = self.pg0.get_capture(1)
5865 tcp_port = p[TCP].sport
5867 # SYN + ACK packet in->out
5868 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5869 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5870 TCP(sport=80, dport=tcp_port, flags="SA"))
5871 self.pg0.add_stream(p)
5872 self.pg_enable_capture(self.pg_interfaces)
5874 self.pg1.get_capture(1)
5876 # ACK packet out->in
5877 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5878 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5879 TCP(sport=33898, dport=80, flags="A"))
5880 self.pg1.add_stream(p)
5881 self.pg_enable_capture(self.pg_interfaces)
5883 self.pg0.get_capture(1)
5885 # FIN packet in -> out
5886 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5887 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5888 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5889 self.pg0.add_stream(p)
5890 self.pg_enable_capture(self.pg_interfaces)
5892 self.pg1.get_capture(1)
5894 # FIN+ACK packet out -> in
5895 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5896 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5897 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5898 self.pg1.add_stream(p)
5899 self.pg_enable_capture(self.pg_interfaces)
5901 self.pg0.get_capture(1)
5903 # ACK packet in -> out
5904 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5905 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5906 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5907 self.pg0.add_stream(p)
5908 self.pg_enable_capture(self.pg_interfaces)
5910 self.pg1.get_capture(1)
5912 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5914 self.assertEqual(len(sessions) - start_sessnum, 0)
5916 def test_tcp_session_close_in(self):
5917 """ Close TCP session from inside network """
5918 self.tcp_port_out = 10505
5919 self.nat44_add_address(self.nat_addr)
5920 flags = self.config_flags.NAT_IS_TWICE_NAT
5921 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5925 proto=IP_PROTOS.tcp,
5927 flags = self.config_flags.NAT_IS_INSIDE
5928 self.vapi.nat44_interface_add_del_feature(
5929 sw_if_index=self.pg0.sw_if_index,
5930 flags=flags, is_add=1)
5931 self.vapi.nat44_interface_add_del_feature(
5932 sw_if_index=self.pg1.sw_if_index,
5935 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5936 start_sessnum = len(sessions)
5938 self.initiate_tcp_session(self.pg0, self.pg1)
5940 # FIN packet in -> out
5941 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5942 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5943 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5944 flags="FA", seq=100, ack=300))
5945 self.pg0.add_stream(p)
5946 self.pg_enable_capture(self.pg_interfaces)
5948 self.pg1.get_capture(1)
5952 # ACK packet out -> in
5953 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5954 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5955 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5956 flags="A", seq=300, ack=101))
5959 # FIN packet out -> in
5960 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5961 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5962 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5963 flags="FA", seq=300, ack=101))
5966 self.pg1.add_stream(pkts)
5967 self.pg_enable_capture(self.pg_interfaces)
5969 self.pg0.get_capture(2)
5971 # ACK packet in -> out
5972 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5973 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5974 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5975 flags="A", seq=101, ack=301))
5976 self.pg0.add_stream(p)
5977 self.pg_enable_capture(self.pg_interfaces)
5979 self.pg1.get_capture(1)
5981 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5983 self.assertEqual(len(sessions) - start_sessnum, 0)
5985 def test_tcp_session_close_out(self):
5986 """ Close TCP session from outside network """
5987 self.tcp_port_out = 10505
5988 self.nat44_add_address(self.nat_addr)
5989 flags = self.config_flags.NAT_IS_TWICE_NAT
5990 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5994 proto=IP_PROTOS.tcp,
5996 flags = self.config_flags.NAT_IS_INSIDE
5997 self.vapi.nat44_interface_add_del_feature(
5998 sw_if_index=self.pg0.sw_if_index,
5999 flags=flags, is_add=1)
6000 self.vapi.nat44_interface_add_del_feature(
6001 sw_if_index=self.pg1.sw_if_index,
6004 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6005 start_sessnum = len(sessions)
6007 self.initiate_tcp_session(self.pg0, self.pg1)
6009 # FIN packet out -> in
6010 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6011 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6012 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6013 flags="FA", seq=100, ack=300))
6014 self.pg1.add_stream(p)
6015 self.pg_enable_capture(self.pg_interfaces)
6017 self.pg0.get_capture(1)
6019 # FIN+ACK packet in -> out
6020 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6021 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6022 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6023 flags="FA", seq=300, ack=101))
6025 self.pg0.add_stream(p)
6026 self.pg_enable_capture(self.pg_interfaces)
6028 self.pg1.get_capture(1)
6030 # ACK packet out -> in
6031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6033 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6034 flags="A", seq=101, ack=301))
6035 self.pg1.add_stream(p)
6036 self.pg_enable_capture(self.pg_interfaces)
6038 self.pg0.get_capture(1)
6040 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6042 self.assertEqual(len(sessions) - start_sessnum, 0)
6044 def test_tcp_session_close_simultaneous(self):
6045 """ Close TCP session from inside network """
6046 self.tcp_port_out = 10505
6047 self.nat44_add_address(self.nat_addr)
6048 flags = self.config_flags.NAT_IS_TWICE_NAT
6049 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6053 proto=IP_PROTOS.tcp,
6055 flags = self.config_flags.NAT_IS_INSIDE
6056 self.vapi.nat44_interface_add_del_feature(
6057 sw_if_index=self.pg0.sw_if_index,
6058 flags=flags, is_add=1)
6059 self.vapi.nat44_interface_add_del_feature(
6060 sw_if_index=self.pg1.sw_if_index,
6063 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6064 start_sessnum = len(sessions)
6066 self.initiate_tcp_session(self.pg0, self.pg1)
6068 # FIN packet in -> out
6069 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6070 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6071 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6072 flags="FA", seq=100, ack=300))
6073 self.pg0.add_stream(p)
6074 self.pg_enable_capture(self.pg_interfaces)
6076 self.pg1.get_capture(1)
6078 # FIN packet out -> in
6079 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6080 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6081 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6082 flags="FA", seq=300, ack=100))
6083 self.pg1.add_stream(p)
6084 self.pg_enable_capture(self.pg_interfaces)
6086 self.pg0.get_capture(1)
6088 # ACK packet in -> out
6089 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6090 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6091 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6092 flags="A", seq=101, ack=301))
6093 self.pg0.add_stream(p)
6094 self.pg_enable_capture(self.pg_interfaces)
6096 self.pg1.get_capture(1)
6098 # ACK packet out -> in
6099 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6100 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6101 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6102 flags="A", seq=301, ack=101))
6103 self.pg1.add_stream(p)
6104 self.pg_enable_capture(self.pg_interfaces)
6106 self.pg0.get_capture(1)
6108 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6110 self.assertEqual(len(sessions) - start_sessnum, 0)
6112 def test_one_armed_nat44_static(self):
6113 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6114 remote_host = self.pg4.remote_hosts[0]
6115 local_host = self.pg4.remote_hosts[1]
6120 self.vapi.nat44_forwarding_enable_disable(enable=1)
6121 self.nat44_add_address(self.nat_addr, twice_nat=1)
6122 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6123 self.config_flags.NAT_IS_TWICE_NAT)
6124 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6125 local_port, external_port,
6126 proto=IP_PROTOS.tcp, flags=flags)
6127 flags = self.config_flags.NAT_IS_INSIDE
6128 self.vapi.nat44_interface_add_del_feature(
6129 sw_if_index=self.pg4.sw_if_index,
6131 self.vapi.nat44_interface_add_del_feature(
6132 sw_if_index=self.pg4.sw_if_index,
6133 flags=flags, is_add=1)
6135 # from client to service
6136 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6137 IP(src=remote_host.ip4, dst=self.nat_addr) /
6138 TCP(sport=12345, dport=external_port))
6139 self.pg4.add_stream(p)
6140 self.pg_enable_capture(self.pg_interfaces)
6142 capture = self.pg4.get_capture(1)
6147 self.assertEqual(ip.dst, local_host.ip4)
6148 self.assertEqual(ip.src, self.nat_addr)
6149 self.assertEqual(tcp.dport, local_port)
6150 self.assertNotEqual(tcp.sport, 12345)
6151 eh_port_in = tcp.sport
6152 self.assert_packet_checksums_valid(p)
6154 self.logger.error(ppp("Unexpected or invalid packet:", p))
6157 # from service back to client
6158 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6159 IP(src=local_host.ip4, dst=self.nat_addr) /
6160 TCP(sport=local_port, dport=eh_port_in))
6161 self.pg4.add_stream(p)
6162 self.pg_enable_capture(self.pg_interfaces)
6164 capture = self.pg4.get_capture(1)
6169 self.assertEqual(ip.src, self.nat_addr)
6170 self.assertEqual(ip.dst, remote_host.ip4)
6171 self.assertEqual(tcp.sport, external_port)
6172 self.assertEqual(tcp.dport, 12345)
6173 self.assert_packet_checksums_valid(p)
6175 self.logger.error(ppp("Unexpected or invalid packet:", p))
6178 def test_static_with_port_out2(self):
6179 """ 1:1 NAPT asymmetrical rule """
6184 self.vapi.nat44_forwarding_enable_disable(enable=1)
6185 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6186 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6187 local_port, external_port,
6188 proto=IP_PROTOS.tcp, flags=flags)
6189 flags = self.config_flags.NAT_IS_INSIDE
6190 self.vapi.nat44_interface_add_del_feature(
6191 sw_if_index=self.pg0.sw_if_index,
6192 flags=flags, is_add=1)
6193 self.vapi.nat44_interface_add_del_feature(
6194 sw_if_index=self.pg1.sw_if_index,
6197 # from client to service
6198 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6199 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6200 TCP(sport=12345, dport=external_port))
6201 self.pg1.add_stream(p)
6202 self.pg_enable_capture(self.pg_interfaces)
6204 capture = self.pg0.get_capture(1)
6209 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6210 self.assertEqual(tcp.dport, local_port)
6211 self.assert_packet_checksums_valid(p)
6213 self.logger.error(ppp("Unexpected or invalid packet:", p))
6217 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6218 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6219 ICMP(type=11) / capture[0][IP])
6220 self.pg0.add_stream(p)
6221 self.pg_enable_capture(self.pg_interfaces)
6223 capture = self.pg1.get_capture(1)
6226 self.assertEqual(p[IP].src, self.nat_addr)
6228 self.assertEqual(inner.dst, self.nat_addr)
6229 self.assertEqual(inner[TCPerror].dport, external_port)
6231 self.logger.error(ppp("Unexpected or invalid packet:", p))
6234 # from service back to client
6235 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6236 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6237 TCP(sport=local_port, dport=12345))
6238 self.pg0.add_stream(p)
6239 self.pg_enable_capture(self.pg_interfaces)
6241 capture = self.pg1.get_capture(1)
6246 self.assertEqual(ip.src, self.nat_addr)
6247 self.assertEqual(tcp.sport, external_port)
6248 self.assert_packet_checksums_valid(p)
6250 self.logger.error(ppp("Unexpected or invalid packet:", p))
6254 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6255 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6256 ICMP(type=11) / capture[0][IP])
6257 self.pg1.add_stream(p)
6258 self.pg_enable_capture(self.pg_interfaces)
6260 capture = self.pg0.get_capture(1)
6263 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6265 self.assertEqual(inner.src, self.pg0.remote_ip4)
6266 self.assertEqual(inner[TCPerror].sport, local_port)
6268 self.logger.error(ppp("Unexpected or invalid packet:", p))
6271 # from client to server (no translation)
6272 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6273 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6274 TCP(sport=12346, dport=local_port))
6275 self.pg1.add_stream(p)
6276 self.pg_enable_capture(self.pg_interfaces)
6278 capture = self.pg0.get_capture(1)
6283 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6284 self.assertEqual(tcp.dport, local_port)
6285 self.assert_packet_checksums_valid(p)
6287 self.logger.error(ppp("Unexpected or invalid packet:", p))
6290 # from service back to client (no translation)
6291 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6292 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6293 TCP(sport=local_port, dport=12346))
6294 self.pg0.add_stream(p)
6295 self.pg_enable_capture(self.pg_interfaces)
6297 capture = self.pg1.get_capture(1)
6302 self.assertEqual(ip.src, self.pg0.remote_ip4)
6303 self.assertEqual(tcp.sport, local_port)
6304 self.assert_packet_checksums_valid(p)
6306 self.logger.error(ppp("Unexpected or invalid packet:", p))
6309 def test_output_feature(self):
6310 """ NAT44 interface output feature (in2out postrouting) """
6311 self.vapi.nat44_forwarding_enable_disable(enable=1)
6312 self.nat44_add_address(self.nat_addr)
6313 self.vapi.nat44_interface_add_del_feature(
6314 sw_if_index=self.pg0.sw_if_index,
6316 self.vapi.nat44_interface_add_del_output_feature(
6318 sw_if_index=self.pg1.sw_if_index)
6321 pkts = self.create_stream_in(self.pg0, self.pg1)
6322 self.pg0.add_stream(pkts)
6323 self.pg_enable_capture(self.pg_interfaces)
6325 capture = self.pg1.get_capture(len(pkts))
6326 self.verify_capture_out(capture)
6329 pkts = self.create_stream_out(self.pg1)
6330 self.pg1.add_stream(pkts)
6331 self.pg_enable_capture(self.pg_interfaces)
6333 capture = self.pg0.get_capture(len(pkts))
6334 self.verify_capture_in(capture, self.pg0)
6336 def test_multiple_vrf(self):
6337 """ Multiple VRF setup """
6338 external_addr = '1.2.3.4'
6343 self.vapi.nat44_forwarding_enable_disable(enable=1)
6344 self.nat44_add_address(self.nat_addr)
6345 flags = self.config_flags.NAT_IS_INSIDE
6346 self.vapi.nat44_interface_add_del_feature(
6347 sw_if_index=self.pg0.sw_if_index,
6349 self.vapi.nat44_interface_add_del_feature(
6350 sw_if_index=self.pg0.sw_if_index,
6351 flags=flags, is_add=1)
6352 self.vapi.nat44_interface_add_del_output_feature(
6354 sw_if_index=self.pg1.sw_if_index)
6355 self.vapi.nat44_interface_add_del_feature(
6356 sw_if_index=self.pg5.sw_if_index,
6358 self.vapi.nat44_interface_add_del_feature(
6359 sw_if_index=self.pg5.sw_if_index,
6360 flags=flags, is_add=1)
6361 self.vapi.nat44_interface_add_del_feature(
6362 sw_if_index=self.pg6.sw_if_index,
6364 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6365 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6366 local_port, external_port, vrf_id=1,
6367 proto=IP_PROTOS.tcp, flags=flags)
6368 self.nat44_add_static_mapping(
6369 self.pg0.remote_ip4,
6370 external_sw_if_index=self.pg0.sw_if_index,
6371 local_port=local_port,
6373 external_port=external_port,
6374 proto=IP_PROTOS.tcp,
6378 # from client to service (both VRF1)
6379 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6380 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6381 TCP(sport=12345, dport=external_port))
6382 self.pg6.add_stream(p)
6383 self.pg_enable_capture(self.pg_interfaces)
6385 capture = self.pg5.get_capture(1)
6390 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6391 self.assertEqual(tcp.dport, local_port)
6392 self.assert_packet_checksums_valid(p)
6394 self.logger.error(ppp("Unexpected or invalid packet:", p))
6397 # from service back to client (both VRF1)
6398 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6399 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6400 TCP(sport=local_port, dport=12345))
6401 self.pg5.add_stream(p)
6402 self.pg_enable_capture(self.pg_interfaces)
6404 capture = self.pg6.get_capture(1)
6409 self.assertEqual(ip.src, external_addr)
6410 self.assertEqual(tcp.sport, external_port)
6411 self.assert_packet_checksums_valid(p)
6413 self.logger.error(ppp("Unexpected or invalid packet:", p))
6416 # dynamic NAT from VRF1 to VRF0 (output-feature)
6417 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6418 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6419 TCP(sport=2345, dport=22))
6420 self.pg5.add_stream(p)
6421 self.pg_enable_capture(self.pg_interfaces)
6423 capture = self.pg1.get_capture(1)
6428 self.assertEqual(ip.src, self.nat_addr)
6429 self.assertNotEqual(tcp.sport, 2345)
6430 self.assert_packet_checksums_valid(p)
6433 self.logger.error(ppp("Unexpected or invalid packet:", p))
6436 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6437 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6438 TCP(sport=22, dport=port))
6439 self.pg1.add_stream(p)
6440 self.pg_enable_capture(self.pg_interfaces)
6442 capture = self.pg5.get_capture(1)
6447 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6448 self.assertEqual(tcp.dport, 2345)
6449 self.assert_packet_checksums_valid(p)
6451 self.logger.error(ppp("Unexpected or invalid packet:", p))
6454 # from client VRF1 to service VRF0
6455 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6456 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6457 TCP(sport=12346, dport=external_port))
6458 self.pg6.add_stream(p)
6459 self.pg_enable_capture(self.pg_interfaces)
6461 capture = self.pg0.get_capture(1)
6466 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6467 self.assertEqual(tcp.dport, local_port)
6468 self.assert_packet_checksums_valid(p)
6470 self.logger.error(ppp("Unexpected or invalid packet:", p))
6473 # from service VRF0 back to client VRF1
6474 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6475 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6476 TCP(sport=local_port, dport=12346))
6477 self.pg0.add_stream(p)
6478 self.pg_enable_capture(self.pg_interfaces)
6480 capture = self.pg6.get_capture(1)
6485 self.assertEqual(ip.src, self.pg0.local_ip4)
6486 self.assertEqual(tcp.sport, external_port)
6487 self.assert_packet_checksums_valid(p)
6489 self.logger.error(ppp("Unexpected or invalid packet:", p))
6492 # from client VRF0 to service VRF1
6493 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6494 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6495 TCP(sport=12347, dport=external_port))
6496 self.pg0.add_stream(p)
6497 self.pg_enable_capture(self.pg_interfaces)
6499 capture = self.pg5.get_capture(1)
6504 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6505 self.assertEqual(tcp.dport, local_port)
6506 self.assert_packet_checksums_valid(p)
6508 self.logger.error(ppp("Unexpected or invalid packet:", p))
6511 # from service VRF1 back to client VRF0
6512 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6513 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6514 TCP(sport=local_port, dport=12347))
6515 self.pg5.add_stream(p)
6516 self.pg_enable_capture(self.pg_interfaces)
6518 capture = self.pg0.get_capture(1)
6523 self.assertEqual(ip.src, external_addr)
6524 self.assertEqual(tcp.sport, external_port)
6525 self.assert_packet_checksums_valid(p)
6527 self.logger.error(ppp("Unexpected or invalid packet:", p))
6530 # from client to server (both VRF1, no translation)
6531 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6532 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6533 TCP(sport=12348, dport=local_port))
6534 self.pg6.add_stream(p)
6535 self.pg_enable_capture(self.pg_interfaces)
6537 capture = self.pg5.get_capture(1)
6542 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6543 self.assertEqual(tcp.dport, local_port)
6544 self.assert_packet_checksums_valid(p)
6546 self.logger.error(ppp("Unexpected or invalid packet:", p))
6549 # from server back to client (both VRF1, no translation)
6550 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6551 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6552 TCP(sport=local_port, dport=12348))
6553 self.pg5.add_stream(p)
6554 self.pg_enable_capture(self.pg_interfaces)
6556 capture = self.pg6.get_capture(1)
6561 self.assertEqual(ip.src, self.pg5.remote_ip4)
6562 self.assertEqual(tcp.sport, local_port)
6563 self.assert_packet_checksums_valid(p)
6565 self.logger.error(ppp("Unexpected or invalid packet:", p))
6568 # from client VRF1 to server VRF0 (no translation)
6569 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6570 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6571 TCP(sport=local_port, dport=12349))
6572 self.pg0.add_stream(p)
6573 self.pg_enable_capture(self.pg_interfaces)
6575 capture = self.pg6.get_capture(1)
6580 self.assertEqual(ip.src, self.pg0.remote_ip4)
6581 self.assertEqual(tcp.sport, local_port)
6582 self.assert_packet_checksums_valid(p)
6584 self.logger.error(ppp("Unexpected or invalid packet:", p))
6587 # from server VRF0 back to client VRF1 (no translation)
6588 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6589 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6590 TCP(sport=local_port, dport=12349))
6591 self.pg0.add_stream(p)
6592 self.pg_enable_capture(self.pg_interfaces)
6594 capture = self.pg6.get_capture(1)
6599 self.assertEqual(ip.src, self.pg0.remote_ip4)
6600 self.assertEqual(tcp.sport, local_port)
6601 self.assert_packet_checksums_valid(p)
6603 self.logger.error(ppp("Unexpected or invalid packet:", p))
6606 # from client VRF0 to server VRF1 (no translation)
6607 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6608 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6609 TCP(sport=12344, dport=local_port))
6610 self.pg0.add_stream(p)
6611 self.pg_enable_capture(self.pg_interfaces)
6613 capture = self.pg5.get_capture(1)
6618 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6619 self.assertEqual(tcp.dport, local_port)
6620 self.assert_packet_checksums_valid(p)
6622 self.logger.error(ppp("Unexpected or invalid packet:", p))
6625 # from server VRF1 back to client VRF0 (no translation)
6626 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6627 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6628 TCP(sport=local_port, dport=12344))
6629 self.pg5.add_stream(p)
6630 self.pg_enable_capture(self.pg_interfaces)
6632 capture = self.pg0.get_capture(1)
6637 self.assertEqual(ip.src, self.pg5.remote_ip4)
6638 self.assertEqual(tcp.sport, local_port)
6639 self.assert_packet_checksums_valid(p)
6641 self.logger.error(ppp("Unexpected or invalid packet:", p))
6644 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6645 def test_session_timeout(self):
6646 """ NAT44 session timeouts """
6647 self.nat44_add_address(self.nat_addr)
6648 flags = self.config_flags.NAT_IS_INSIDE
6649 self.vapi.nat44_interface_add_del_feature(
6650 sw_if_index=self.pg0.sw_if_index,
6651 flags=flags, is_add=1)
6652 self.vapi.nat44_interface_add_del_feature(
6653 sw_if_index=self.pg1.sw_if_index,
6655 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6656 tcp_transitory=240, icmp=5)
6660 for i in range(0, max_sessions):
6661 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6662 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6663 IP(src=src, dst=self.pg1.remote_ip4) /
6664 ICMP(id=1025, type='echo-request'))
6666 self.pg0.add_stream(pkts)
6667 self.pg_enable_capture(self.pg_interfaces)
6669 self.pg1.get_capture(max_sessions)
6674 for i in range(0, max_sessions):
6675 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6676 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6677 IP(src=src, dst=self.pg1.remote_ip4) /
6678 ICMP(id=1026, type='echo-request'))
6680 self.pg0.add_stream(pkts)
6681 self.pg_enable_capture(self.pg_interfaces)
6683 self.pg1.get_capture(max_sessions)
6686 users = self.vapi.nat44_user_dump()
6688 nsessions = nsessions + user.nsessions
6689 self.assertLess(nsessions, 2 * max_sessions)
6691 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6692 def test_session_rst_timeout(self):
6693 """ NAT44 session RST timeouts """
6694 self.nat44_add_address(self.nat_addr)
6695 flags = self.config_flags.NAT_IS_INSIDE
6696 self.vapi.nat44_interface_add_del_feature(
6697 sw_if_index=self.pg0.sw_if_index,
6698 flags=flags, is_add=1)
6699 self.vapi.nat44_interface_add_del_feature(
6700 sw_if_index=self.pg1.sw_if_index,
6702 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6703 tcp_transitory=5, icmp=60)
6705 self.initiate_tcp_session(self.pg0, self.pg1)
6706 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6707 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6708 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6710 self.pg0.add_stream(p)
6711 self.pg_enable_capture(self.pg_interfaces)
6713 self.pg1.get_capture(1)
6717 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6718 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6719 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6721 self.pg0.add_stream(p)
6722 self.pg_enable_capture(self.pg_interfaces)
6724 self.pg1.get_capture(1)
6727 users = self.vapi.nat44_user_dump()
6728 self.assertEqual(len(users), 1)
6729 self.assertEqual(str(users[0].ip_address),
6730 self.pg0.remote_ip4)
6731 self.assertEqual(users[0].nsessions, 1)
6733 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6734 def test_session_limit_per_user(self):
6735 """ Maximum sessions per user limit """
6736 self.nat44_add_address(self.nat_addr)
6737 flags = self.config_flags.NAT_IS_INSIDE
6738 self.vapi.nat44_interface_add_del_feature(
6739 sw_if_index=self.pg0.sw_if_index,
6740 flags=flags, is_add=1)
6741 self.vapi.nat44_interface_add_del_feature(
6742 sw_if_index=self.pg1.sw_if_index,
6744 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6745 src_address=self.pg2.local_ip4n,
6747 template_interval=10)
6748 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6749 tcp_transitory=240, icmp=60)
6751 # get maximum number of translations per user
6752 nat44_config = self.vapi.nat_show_config()
6755 for port in range(0, nat44_config.max_translations_per_user):
6756 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6757 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6758 UDP(sport=1025 + port, dport=1025 + port))
6761 self.pg0.add_stream(pkts)
6762 self.pg_enable_capture(self.pg_interfaces)
6764 capture = self.pg1.get_capture(len(pkts))
6766 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6767 src_port=self.ipfix_src_port,
6770 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6771 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6772 UDP(sport=3001, dport=3002))
6773 self.pg0.add_stream(p)
6774 self.pg_enable_capture(self.pg_interfaces)
6776 capture = self.pg1.assert_nothing_captured()
6778 # verify IPFIX logging
6779 self.vapi.ipfix_flush()
6781 capture = self.pg2.get_capture(10)
6782 ipfix = IPFIXDecoder()
6783 # first load template
6785 self.assertTrue(p.haslayer(IPFIX))
6786 if p.haslayer(Template):
6787 ipfix.add_template(p.getlayer(Template))
6788 # verify events in data set
6790 if p.haslayer(Data):
6791 data = ipfix.decode_data_set(p.getlayer(Set))
6792 self.verify_ipfix_max_entries_per_user(
6794 nat44_config.max_translations_per_user,
6795 self.pg0.remote_ip4n)
6798 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6799 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6800 UDP(sport=3001, dport=3002))
6801 self.pg0.add_stream(p)
6802 self.pg_enable_capture(self.pg_interfaces)
6804 self.pg1.get_capture(1)
6806 def test_syslog_sess(self):
6807 """ Test syslog session creation and deletion """
6808 self.vapi.syslog_set_filter(
6809 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6810 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6811 self.nat44_add_address(self.nat_addr)
6812 flags = self.config_flags.NAT_IS_INSIDE
6813 self.vapi.nat44_interface_add_del_feature(
6814 sw_if_index=self.pg0.sw_if_index,
6815 flags=flags, is_add=1)
6816 self.vapi.nat44_interface_add_del_feature(
6817 sw_if_index=self.pg1.sw_if_index,
6820 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6821 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6822 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6823 self.pg0.add_stream(p)
6824 self.pg_enable_capture(self.pg_interfaces)
6826 capture = self.pg1.get_capture(1)
6827 self.tcp_port_out = capture[0][TCP].sport
6828 capture = self.pg2.get_capture(1)
6829 self.verify_syslog_sess(capture[0][Raw].load)
6831 self.pg_enable_capture(self.pg_interfaces)
6833 self.nat44_add_address(self.nat_addr, is_add=0)
6834 capture = self.pg2.get_capture(1)
6835 self.verify_syslog_sess(capture[0][Raw].load, False)
6838 super(TestNAT44EndpointDependent, self).tearDown()
6839 if not self.vpp_dead:
6841 self.vapi.cli("clear logging")
6843 def show_commands_at_teardown(self):
6844 self.logger.info(self.vapi.cli("show nat44 addresses"))
6845 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6846 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6847 self.logger.info(self.vapi.cli("show nat44 interface address"))
6848 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6849 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6850 self.logger.info(self.vapi.cli("show nat timeouts"))
6853 class TestNAT44Out2InDPO(MethodHolder):
6854 """ NAT44 Test Cases using out2in DPO """
6857 def setUpConstants(cls):
6858 super(TestNAT44Out2InDPO, cls).setUpConstants()
6859 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6862 def setUpClass(cls):
6863 super(TestNAT44Out2InDPO, cls).setUpClass()
6864 cls.vapi.cli("set log class nat level debug")
6867 cls.tcp_port_in = 6303
6868 cls.tcp_port_out = 6303
6869 cls.udp_port_in = 6304
6870 cls.udp_port_out = 6304
6871 cls.icmp_id_in = 6305
6872 cls.icmp_id_out = 6305
6873 cls.nat_addr = '10.0.0.3'
6874 cls.dst_ip4 = '192.168.70.1'
6876 cls.create_pg_interfaces(range(2))
6879 cls.pg0.config_ip4()
6880 cls.pg0.resolve_arp()
6883 cls.pg1.config_ip6()
6884 cls.pg1.resolve_ndp()
6886 r1 = VppIpRoute(cls, "::", 0,
6887 [VppRoutePath(cls.pg1.remote_ip6,
6888 cls.pg1.sw_if_index)],
6893 super(TestNAT44Out2InDPO, cls).tearDownClass()
6897 def tearDownClass(cls):
6898 super(TestNAT44Out2InDPO, cls).tearDownClass()
6900 def configure_xlat(self):
6901 self.dst_ip6_pfx = '1:2:3::'
6902 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6904 self.dst_ip6_pfx_len = 96
6905 self.src_ip6_pfx = '4:5:6::'
6906 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6908 self.src_ip6_pfx_len = 96
6909 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6910 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6911 '\x00\x00\x00\x00', 0)
6913 @unittest.skip('Temporary disabled')
6914 def test_464xlat_ce(self):
6915 """ Test 464XLAT CE with NAT44 """
6917 nat_config = self.vapi.nat_show_config()
6918 self.assertEqual(1, nat_config.out2in_dpo)
6920 self.configure_xlat()
6922 flags = self.config_flags.NAT_IS_INSIDE
6923 self.vapi.nat44_interface_add_del_feature(
6924 sw_if_index=self.pg0.sw_if_index,
6925 flags=flags, is_add=1)
6926 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6927 last_ip_address=self.nat_addr_n,
6928 vrf_id=0xFFFFFFFF, is_add=1)
6930 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6931 self.dst_ip6_pfx_len)
6932 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6933 self.src_ip6_pfx_len)
6936 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6937 self.pg0.add_stream(pkts)
6938 self.pg_enable_capture(self.pg_interfaces)
6940 capture = self.pg1.get_capture(len(pkts))
6941 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6944 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6946 self.pg1.add_stream(pkts)
6947 self.pg_enable_capture(self.pg_interfaces)
6949 capture = self.pg0.get_capture(len(pkts))
6950 self.verify_capture_in(capture, self.pg0)
6952 self.vapi.nat44_interface_add_del_feature(
6953 sw_if_index=self.pg0.sw_if_index,
6955 self.vapi.nat44_add_del_address_range(
6956 first_ip_address=self.nat_addr_n,
6957 last_ip_address=self.nat_addr_n,
6960 @unittest.skip('Temporary disabled')
6961 def test_464xlat_ce_no_nat(self):
6962 """ Test 464XLAT CE without NAT44 """
6964 self.configure_xlat()
6966 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6967 self.dst_ip6_pfx_len)
6968 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6969 self.src_ip6_pfx_len)
6971 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6972 self.pg0.add_stream(pkts)
6973 self.pg_enable_capture(self.pg_interfaces)
6975 capture = self.pg1.get_capture(len(pkts))
6976 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6977 nat_ip=out_dst_ip6, same_port=True)
6979 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6980 self.pg1.add_stream(pkts)
6981 self.pg_enable_capture(self.pg_interfaces)
6983 capture = self.pg0.get_capture(len(pkts))
6984 self.verify_capture_in(capture, self.pg0)
6987 class TestDeterministicNAT(MethodHolder):
6988 """ Deterministic NAT Test Cases """
6991 def setUpConstants(cls):
6992 super(TestDeterministicNAT, cls).setUpConstants()
6993 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
6996 def setUpClass(cls):
6997 super(TestDeterministicNAT, cls).setUpClass()
6998 cls.vapi.cli("set log class nat level debug")
7001 cls.tcp_port_in = 6303
7002 cls.tcp_external_port = 6303
7003 cls.udp_port_in = 6304
7004 cls.udp_external_port = 6304
7005 cls.icmp_id_in = 6305
7006 cls.nat_addr = '10.0.0.3'
7008 cls.create_pg_interfaces(range(3))
7009 cls.interfaces = list(cls.pg_interfaces)
7011 for i in cls.interfaces:
7016 cls.pg0.generate_remote_hosts(2)
7017 cls.pg0.configure_ipv4_neighbors()
7020 super(TestDeterministicNAT, cls).tearDownClass()
7024 def tearDownClass(cls):
7025 super(TestDeterministicNAT, cls).tearDownClass()
7027 def create_stream_in(self, in_if, out_if, ttl=64):
7029 Create packet stream for inside network
7031 :param in_if: Inside interface
7032 :param out_if: Outside interface
7033 :param ttl: TTL of generated packets
7037 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7038 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7039 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7043 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7044 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7045 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7049 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7050 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7051 ICMP(id=self.icmp_id_in, type='echo-request'))
7056 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7058 Create packet stream for outside network
7060 :param out_if: Outside interface
7061 :param dst_ip: Destination IP address (Default use global NAT address)
7062 :param ttl: TTL of generated packets
7065 dst_ip = self.nat_addr
7068 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7069 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7070 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7074 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7075 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7076 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7080 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7081 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7082 ICMP(id=self.icmp_external_id, type='echo-reply'))
7087 def verify_capture_out(self, capture, nat_ip=None):
7089 Verify captured packets on outside network
7091 :param capture: Captured packets
7092 :param nat_ip: Translated IP address (Default use global NAT address)
7093 :param same_port: Source port number is not translated (Default False)
7096 nat_ip = self.nat_addr
7097 for packet in capture:
7099 self.assertEqual(packet[IP].src, nat_ip)
7100 if packet.haslayer(TCP):
7101 self.tcp_port_out = packet[TCP].sport
7102 elif packet.haslayer(UDP):
7103 self.udp_port_out = packet[UDP].sport
7105 self.icmp_external_id = packet[ICMP].id
7107 self.logger.error(ppp("Unexpected or invalid packet "
7108 "(outside network):", packet))
7111 def test_deterministic_mode(self):
7112 """ NAT plugin run deterministic mode """
7113 in_addr = '172.16.255.0'
7114 out_addr = '172.17.255.50'
7115 in_addr_t = '172.16.255.20'
7119 nat_config = self.vapi.nat_show_config()
7120 self.assertEqual(1, nat_config.deterministic)
7122 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7123 in_plen=in_plen, out_addr=out_addr,
7126 rep1 = self.vapi.nat_det_forward(in_addr_t)
7127 self.assertEqual(str(rep1.out_addr), out_addr)
7128 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7130 self.assertEqual(str(rep2.in_addr), in_addr_t)
7132 deterministic_mappings = self.vapi.nat_det_map_dump()
7133 self.assertEqual(len(deterministic_mappings), 1)
7134 dsm = deterministic_mappings[0]
7135 self.assertEqual(in_addr, str(dsm.in_addr))
7136 self.assertEqual(in_plen, dsm.in_plen)
7137 self.assertEqual(out_addr, str(dsm.out_addr))
7138 self.assertEqual(out_plen, dsm.out_plen)
7140 self.clear_nat_det()
7141 deterministic_mappings = self.vapi.nat_det_map_dump()
7142 self.assertEqual(len(deterministic_mappings), 0)
7144 def test_set_timeouts(self):
7145 """ Set deterministic NAT timeouts """
7146 timeouts_before = self.vapi.nat_get_timeouts()
7148 self.vapi.nat_set_timeouts(
7149 udp=timeouts_before.udp + 10,
7150 tcp_established=timeouts_before.tcp_established + 10,
7151 tcp_transitory=timeouts_before.tcp_transitory + 10,
7152 icmp=timeouts_before.icmp + 10)
7154 timeouts_after = self.vapi.nat_get_timeouts()
7156 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7157 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7158 self.assertNotEqual(timeouts_before.tcp_established,
7159 timeouts_after.tcp_established)
7160 self.assertNotEqual(timeouts_before.tcp_transitory,
7161 timeouts_after.tcp_transitory)
7163 def test_det_in(self):
7164 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7166 nat_ip = "10.0.0.10"
7168 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7170 out_addr=socket.inet_aton(nat_ip),
7173 flags = self.config_flags.NAT_IS_INSIDE
7174 self.vapi.nat44_interface_add_del_feature(
7175 sw_if_index=self.pg0.sw_if_index,
7176 flags=flags, is_add=1)
7177 self.vapi.nat44_interface_add_del_feature(
7178 sw_if_index=self.pg1.sw_if_index,
7182 pkts = self.create_stream_in(self.pg0, self.pg1)
7183 self.pg0.add_stream(pkts)
7184 self.pg_enable_capture(self.pg_interfaces)
7186 capture = self.pg1.get_capture(len(pkts))
7187 self.verify_capture_out(capture, nat_ip)
7190 pkts = self.create_stream_out(self.pg1, nat_ip)
7191 self.pg1.add_stream(pkts)
7192 self.pg_enable_capture(self.pg_interfaces)
7194 capture = self.pg0.get_capture(len(pkts))
7195 self.verify_capture_in(capture, self.pg0)
7198 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7199 self.assertEqual(len(sessions), 3)
7203 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7204 self.assertEqual(s.in_port, self.tcp_port_in)
7205 self.assertEqual(s.out_port, self.tcp_port_out)
7206 self.assertEqual(s.ext_port, self.tcp_external_port)
7210 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7211 self.assertEqual(s.in_port, self.udp_port_in)
7212 self.assertEqual(s.out_port, self.udp_port_out)
7213 self.assertEqual(s.ext_port, self.udp_external_port)
7217 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7218 self.assertEqual(s.in_port, self.icmp_id_in)
7219 self.assertEqual(s.out_port, self.icmp_external_id)
7221 def test_multiple_users(self):
7222 """ Deterministic NAT multiple users """
7224 nat_ip = "10.0.0.10"
7226 external_port = 6303
7228 host0 = self.pg0.remote_hosts[0]
7229 host1 = self.pg0.remote_hosts[1]
7231 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7232 out_addr=socket.inet_aton(nat_ip),
7234 flags = self.config_flags.NAT_IS_INSIDE
7235 self.vapi.nat44_interface_add_del_feature(
7236 sw_if_index=self.pg0.sw_if_index,
7237 flags=flags, is_add=1)
7238 self.vapi.nat44_interface_add_del_feature(
7239 sw_if_index=self.pg1.sw_if_index,
7243 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7244 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7245 TCP(sport=port_in, dport=external_port))
7246 self.pg0.add_stream(p)
7247 self.pg_enable_capture(self.pg_interfaces)
7249 capture = self.pg1.get_capture(1)
7254 self.assertEqual(ip.src, nat_ip)
7255 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7256 self.assertEqual(tcp.dport, external_port)
7257 port_out0 = tcp.sport
7259 self.logger.error(ppp("Unexpected or invalid packet:", p))
7263 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7264 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7265 TCP(sport=port_in, dport=external_port))
7266 self.pg0.add_stream(p)
7267 self.pg_enable_capture(self.pg_interfaces)
7269 capture = self.pg1.get_capture(1)
7274 self.assertEqual(ip.src, nat_ip)
7275 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7276 self.assertEqual(tcp.dport, external_port)
7277 port_out1 = tcp.sport
7279 self.logger.error(ppp("Unexpected or invalid packet:", p))
7282 dms = self.vapi.nat_det_map_dump()
7283 self.assertEqual(1, len(dms))
7284 self.assertEqual(2, dms[0].ses_num)
7287 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7288 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7289 TCP(sport=external_port, dport=port_out0))
7290 self.pg1.add_stream(p)
7291 self.pg_enable_capture(self.pg_interfaces)
7293 capture = self.pg0.get_capture(1)
7298 self.assertEqual(ip.src, self.pg1.remote_ip4)
7299 self.assertEqual(ip.dst, host0.ip4)
7300 self.assertEqual(tcp.dport, port_in)
7301 self.assertEqual(tcp.sport, external_port)
7303 self.logger.error(ppp("Unexpected or invalid packet:", p))
7307 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7308 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7309 TCP(sport=external_port, dport=port_out1))
7310 self.pg1.add_stream(p)
7311 self.pg_enable_capture(self.pg_interfaces)
7313 capture = self.pg0.get_capture(1)
7318 self.assertEqual(ip.src, self.pg1.remote_ip4)
7319 self.assertEqual(ip.dst, host1.ip4)
7320 self.assertEqual(tcp.dport, port_in)
7321 self.assertEqual(tcp.sport, external_port)
7323 self.logger.error(ppp("Unexpected or invalid packet", p))
7326 # session close api test
7327 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7329 self.pg1.remote_ip4n,
7331 dms = self.vapi.nat_det_map_dump()
7332 self.assertEqual(dms[0].ses_num, 1)
7334 self.vapi.nat_det_close_session_in(host0.ip4n,
7336 self.pg1.remote_ip4n,
7338 dms = self.vapi.nat_det_map_dump()
7339 self.assertEqual(dms[0].ses_num, 0)
7341 def test_tcp_session_close_detection_in(self):
7342 """ Deterministic NAT TCP session close from inside network """
7343 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7345 out_addr=socket.inet_aton(self.nat_addr),
7347 flags = self.config_flags.NAT_IS_INSIDE
7348 self.vapi.nat44_interface_add_del_feature(
7349 sw_if_index=self.pg0.sw_if_index,
7350 flags=flags, is_add=1)
7351 self.vapi.nat44_interface_add_del_feature(
7352 sw_if_index=self.pg1.sw_if_index,
7355 self.initiate_tcp_session(self.pg0, self.pg1)
7357 # close the session from inside
7359 # FIN packet in -> out
7360 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7361 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7362 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7364 self.pg0.add_stream(p)
7365 self.pg_enable_capture(self.pg_interfaces)
7367 self.pg1.get_capture(1)
7371 # ACK packet out -> in
7372 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7373 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7374 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7378 # FIN packet out -> in
7379 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7380 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7381 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7385 self.pg1.add_stream(pkts)
7386 self.pg_enable_capture(self.pg_interfaces)
7388 self.pg0.get_capture(2)
7390 # ACK packet in -> out
7391 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7392 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7393 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7395 self.pg0.add_stream(p)
7396 self.pg_enable_capture(self.pg_interfaces)
7398 self.pg1.get_capture(1)
7400 # Check if deterministic NAT44 closed the session
7401 dms = self.vapi.nat_det_map_dump()
7402 self.assertEqual(0, dms[0].ses_num)
7404 self.logger.error("TCP session termination failed")
7407 def test_tcp_session_close_detection_out(self):
7408 """ Deterministic NAT TCP session close from outside network """
7409 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7411 out_addr=socket.inet_aton(self.nat_addr),
7413 flags = self.config_flags.NAT_IS_INSIDE
7414 self.vapi.nat44_interface_add_del_feature(
7415 sw_if_index=self.pg0.sw_if_index,
7416 flags=flags, is_add=1)
7417 self.vapi.nat44_interface_add_del_feature(
7418 sw_if_index=self.pg1.sw_if_index,
7421 self.initiate_tcp_session(self.pg0, self.pg1)
7423 # close the session from outside
7425 # FIN packet out -> in
7426 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7427 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7428 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7430 self.pg1.add_stream(p)
7431 self.pg_enable_capture(self.pg_interfaces)
7433 self.pg0.get_capture(1)
7437 # ACK packet in -> out
7438 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7439 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7440 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7444 # ACK packet in -> out
7445 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7446 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7447 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7451 self.pg0.add_stream(pkts)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 self.pg1.get_capture(2)
7456 # ACK packet out -> in
7457 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7458 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7459 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7461 self.pg1.add_stream(p)
7462 self.pg_enable_capture(self.pg_interfaces)
7464 self.pg0.get_capture(1)
7466 # Check if deterministic NAT44 closed the session
7467 dms = self.vapi.nat_det_map_dump()
7468 self.assertEqual(0, dms[0].ses_num)
7470 self.logger.error("TCP session termination failed")
7473 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7474 def test_session_timeout(self):
7475 """ Deterministic NAT session timeouts """
7476 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7478 out_addr=socket.inet_aton(self.nat_addr),
7480 flags = self.config_flags.NAT_IS_INSIDE
7481 self.vapi.nat44_interface_add_del_feature(
7482 sw_if_index=self.pg0.sw_if_index,
7483 flags=flags, is_add=1)
7484 self.vapi.nat44_interface_add_del_feature(
7485 sw_if_index=self.pg1.sw_if_index,
7488 self.initiate_tcp_session(self.pg0, self.pg1)
7489 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7491 pkts = self.create_stream_in(self.pg0, self.pg1)
7492 self.pg0.add_stream(pkts)
7493 self.pg_enable_capture(self.pg_interfaces)
7495 capture = self.pg1.get_capture(len(pkts))
7498 dms = self.vapi.nat_det_map_dump()
7499 self.assertEqual(0, dms[0].ses_num)
7501 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7502 def test_session_limit_per_user(self):
7503 """ Deterministic NAT maximum sessions per user limit """
7504 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7506 out_addr=socket.inet_aton(self.nat_addr),
7508 flags = self.config_flags.NAT_IS_INSIDE
7509 self.vapi.nat44_interface_add_del_feature(
7510 sw_if_index=self.pg0.sw_if_index,
7511 flags=flags, is_add=1)
7512 self.vapi.nat44_interface_add_del_feature(
7513 sw_if_index=self.pg1.sw_if_index,
7515 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7516 src_address=self.pg2.local_ip4n,
7518 template_interval=10)
7519 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7523 for port in range(1025, 2025):
7524 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7525 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7526 UDP(sport=port, dport=port))
7529 self.pg0.add_stream(pkts)
7530 self.pg_enable_capture(self.pg_interfaces)
7532 capture = self.pg1.get_capture(len(pkts))
7534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7536 UDP(sport=3001, dport=3002))
7537 self.pg0.add_stream(p)
7538 self.pg_enable_capture(self.pg_interfaces)
7540 capture = self.pg1.assert_nothing_captured()
7542 # verify ICMP error packet
7543 capture = self.pg0.get_capture(1)
7545 self.assertTrue(p.haslayer(ICMP))
7547 self.assertEqual(icmp.type, 3)
7548 self.assertEqual(icmp.code, 1)
7549 self.assertTrue(icmp.haslayer(IPerror))
7550 inner_ip = icmp[IPerror]
7551 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7552 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7554 dms = self.vapi.nat_det_map_dump()
7556 self.assertEqual(1000, dms[0].ses_num)
7558 # verify IPFIX logging
7559 self.vapi.ipfix_flush()
7561 capture = self.pg2.get_capture(2)
7562 ipfix = IPFIXDecoder()
7563 # first load template
7565 self.assertTrue(p.haslayer(IPFIX))
7566 if p.haslayer(Template):
7567 ipfix.add_template(p.getlayer(Template))
7568 # verify events in data set
7570 if p.haslayer(Data):
7571 data = ipfix.decode_data_set(p.getlayer(Set))
7572 self.verify_ipfix_max_entries_per_user(data,
7574 self.pg0.remote_ip4n)
7576 def clear_nat_det(self):
7578 Clear deterministic NAT configuration.
7580 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7582 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7583 tcp_transitory=240, icmp=60)
7584 deterministic_mappings = self.vapi.nat_det_map_dump()
7585 for dsm in deterministic_mappings:
7586 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7587 in_plen=dsm.in_plen,
7588 out_addr=dsm.out_addr,
7589 out_plen=dsm.out_plen)
7591 interfaces = self.vapi.nat44_interface_dump()
7592 for intf in interfaces:
7593 self.vapi.nat44_interface_add_del_feature(
7594 sw_if_index=intf.sw_if_index,
7598 super(TestDeterministicNAT, self).tearDown()
7599 if not self.vpp_dead:
7600 self.clear_nat_det()
7602 def show_commands_at_teardown(self):
7603 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7604 self.logger.info(self.vapi.cli("show nat timeouts"))
7606 self.vapi.cli("show nat44 deterministic mappings"))
7608 self.vapi.cli("show nat44 deterministic sessions"))
7611 class TestNAT64(MethodHolder):
7612 """ NAT64 Test Cases """
7615 def setUpConstants(cls):
7616 super(TestNAT64, cls).setUpConstants()
7617 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7618 "nat64 st hash buckets 256", "}"])
7621 def setUpClass(cls):
7622 super(TestNAT64, cls).setUpClass()
7625 cls.tcp_port_in = 6303
7626 cls.tcp_port_out = 6303
7627 cls.udp_port_in = 6304
7628 cls.udp_port_out = 6304
7629 cls.icmp_id_in = 6305
7630 cls.icmp_id_out = 6305
7631 cls.tcp_external_port = 80
7632 cls.nat_addr = '10.0.0.3'
7633 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7635 cls.vrf1_nat_addr = '10.0.10.3'
7636 cls.ipfix_src_port = 4739
7637 cls.ipfix_domain_id = 1
7639 cls.create_pg_interfaces(range(6))
7640 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7641 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7642 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7644 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7645 table_id=cls.vrf1_id)
7647 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7649 cls.pg0.generate_remote_hosts(2)
7651 for i in cls.ip6_interfaces:
7654 i.configure_ipv6_neighbors()
7656 for i in cls.ip4_interfaces:
7662 cls.pg3.config_ip4()
7663 cls.pg3.resolve_arp()
7664 cls.pg3.config_ip6()
7665 cls.pg3.configure_ipv6_neighbors()
7668 cls.pg5.config_ip6()
7671 super(TestNAT64, cls).tearDownClass()
7675 def tearDownClass(cls):
7676 super(TestNAT64, cls).tearDownClass()
7678 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7679 """ NAT64 inside interface handles Neighbor Advertisement """
7681 flags = self.config_flags.NAT_IS_INSIDE
7682 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7683 sw_if_index=self.pg5.sw_if_index)
7686 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7687 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7688 ICMPv6EchoRequest())
7690 self.pg5.add_stream(pkts)
7691 self.pg_enable_capture(self.pg_interfaces)
7694 # Wait for Neighbor Solicitation
7695 capture = self.pg5.get_capture(len(pkts))
7698 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7699 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7700 tgt = packet[ICMPv6ND_NS].tgt
7702 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7705 # Send Neighbor Advertisement
7706 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7707 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7708 ICMPv6ND_NA(tgt=tgt) /
7709 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7711 self.pg5.add_stream(pkts)
7712 self.pg_enable_capture(self.pg_interfaces)
7715 # Try to send ping again
7717 self.pg5.add_stream(pkts)
7718 self.pg_enable_capture(self.pg_interfaces)
7721 # Wait for ping reply
7722 capture = self.pg5.get_capture(len(pkts))
7725 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7726 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7727 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7729 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7732 def test_pool(self):
7733 """ Add/delete address to NAT64 pool """
7734 nat_addr = '1.2.3.4'
7736 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7738 vrf_id=0xFFFFFFFF, is_add=1)
7740 addresses = self.vapi.nat64_pool_addr_dump()
7741 self.assertEqual(len(addresses), 1)
7742 self.assertEqual(str(addresses[0].address), nat_addr)
7744 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7746 vrf_id=0xFFFFFFFF, is_add=0)
7748 addresses = self.vapi.nat64_pool_addr_dump()
7749 self.assertEqual(len(addresses), 0)
7751 def test_interface(self):
7752 """ Enable/disable NAT64 feature on the interface """
7753 flags = self.config_flags.NAT_IS_INSIDE
7754 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7755 sw_if_index=self.pg0.sw_if_index)
7756 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7757 sw_if_index=self.pg1.sw_if_index)
7759 interfaces = self.vapi.nat64_interface_dump()
7760 self.assertEqual(len(interfaces), 2)
7763 for intf in interfaces:
7764 if intf.sw_if_index == self.pg0.sw_if_index:
7765 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7767 elif intf.sw_if_index == self.pg1.sw_if_index:
7768 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7770 self.assertTrue(pg0_found)
7771 self.assertTrue(pg1_found)
7773 features = self.vapi.cli("show interface features pg0")
7774 self.assertIn('nat64-in2out', features)
7775 features = self.vapi.cli("show interface features pg1")
7776 self.assertIn('nat64-out2in', features)
7778 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7779 sw_if_index=self.pg0.sw_if_index)
7780 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7781 sw_if_index=self.pg1.sw_if_index)
7783 interfaces = self.vapi.nat64_interface_dump()
7784 self.assertEqual(len(interfaces), 0)
7786 def test_static_bib(self):
7787 """ Add/delete static BIB entry """
7788 in_addr = '2001:db8:85a3::8a2e:370:7334'
7789 out_addr = '10.1.1.3'
7792 proto = IP_PROTOS.tcp
7794 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7795 i_port=in_port, o_port=out_port,
7796 proto=proto, vrf_id=0, is_add=1)
7797 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7800 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7802 self.assertEqual(str(bibe.i_addr), in_addr)
7803 self.assertEqual(str(bibe.o_addr), out_addr)
7804 self.assertEqual(bibe.i_port, in_port)
7805 self.assertEqual(bibe.o_port, out_port)
7806 self.assertEqual(static_bib_num, 1)
7807 bibs = self.statistics.get_counter('/nat64/total-bibs')
7808 self.assertEqual(bibs[0][0], 1)
7810 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7811 i_port=in_port, o_port=out_port,
7812 proto=proto, vrf_id=0, is_add=0)
7813 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7816 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7818 self.assertEqual(static_bib_num, 0)
7819 bibs = self.statistics.get_counter('/nat64/total-bibs')
7820 self.assertEqual(bibs[0][0], 0)
7822 def test_set_timeouts(self):
7823 """ Set NAT64 timeouts """
7824 # verify default values
7825 timeouts = self.vapi.nat_get_timeouts()
7826 self.assertEqual(timeouts.udp, 300)
7827 self.assertEqual(timeouts.icmp, 60)
7828 self.assertEqual(timeouts.tcp_transitory, 240)
7829 self.assertEqual(timeouts.tcp_established, 7440)
7831 # set and verify custom values
7832 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7833 tcp_transitory=250, icmp=30)
7834 timeouts = self.vapi.nat_get_timeouts()
7835 self.assertEqual(timeouts.udp, 200)
7836 self.assertEqual(timeouts.icmp, 30)
7837 self.assertEqual(timeouts.tcp_transitory, 250)
7838 self.assertEqual(timeouts.tcp_established, 7450)
7840 def test_dynamic(self):
7841 """ NAT64 dynamic translation test """
7842 self.tcp_port_in = 6303
7843 self.udp_port_in = 6304
7844 self.icmp_id_in = 6305
7846 ses_num_start = self.nat64_get_ses_num()
7848 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7849 end_addr=self.nat_addr,
7852 flags = self.config_flags.NAT_IS_INSIDE
7853 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7854 sw_if_index=self.pg0.sw_if_index)
7855 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7856 sw_if_index=self.pg1.sw_if_index)
7859 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7860 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7861 icmpn = self.statistics.get_err_counter(
7862 '/err/nat64-in2out/ICMP packets')
7863 totaln = self.statistics.get_err_counter(
7864 '/err/nat64-in2out/good in2out packets processed')
7866 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7867 self.pg0.add_stream(pkts)
7868 self.pg_enable_capture(self.pg_interfaces)
7870 capture = self.pg1.get_capture(len(pkts))
7871 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7872 dst_ip=self.pg1.remote_ip4)
7874 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7875 self.assertEqual(err - tcpn, 1)
7876 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7877 self.assertEqual(err - udpn, 1)
7878 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7879 self.assertEqual(err - icmpn, 1)
7880 err = self.statistics.get_err_counter(
7881 '/err/nat64-in2out/good in2out packets processed')
7882 self.assertEqual(err - totaln, 3)
7885 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7886 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7887 icmpn = self.statistics.get_err_counter(
7888 '/err/nat64-out2in/ICMP packets')
7889 totaln = self.statistics.get_err_counter(
7890 '/err/nat64-out2in/good out2in packets processed')
7892 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7893 self.pg1.add_stream(pkts)
7894 self.pg_enable_capture(self.pg_interfaces)
7896 capture = self.pg0.get_capture(len(pkts))
7897 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7898 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7900 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7901 self.assertEqual(err - tcpn, 1)
7902 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7903 self.assertEqual(err - udpn, 1)
7904 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7905 self.assertEqual(err - icmpn, 1)
7906 err = self.statistics.get_err_counter(
7907 '/err/nat64-out2in/good out2in packets processed')
7908 self.assertEqual(err - totaln, 3)
7910 bibs = self.statistics.get_counter('/nat64/total-bibs')
7911 self.assertEqual(bibs[0][0], 3)
7912 sessions = self.statistics.get_counter('/nat64/total-sessions')
7913 self.assertEqual(sessions[0][0], 3)
7916 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7917 self.pg0.add_stream(pkts)
7918 self.pg_enable_capture(self.pg_interfaces)
7920 capture = self.pg1.get_capture(len(pkts))
7921 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7922 dst_ip=self.pg1.remote_ip4)
7925 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7926 self.pg1.add_stream(pkts)
7927 self.pg_enable_capture(self.pg_interfaces)
7929 capture = self.pg0.get_capture(len(pkts))
7930 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7932 ses_num_end = self.nat64_get_ses_num()
7934 self.assertEqual(ses_num_end - ses_num_start, 3)
7936 # tenant with specific VRF
7937 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7938 end_addr=self.vrf1_nat_addr,
7939 vrf_id=self.vrf1_id, is_add=1)
7940 flags = self.config_flags.NAT_IS_INSIDE
7941 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7942 sw_if_index=self.pg2.sw_if_index)
7944 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7945 self.pg2.add_stream(pkts)
7946 self.pg_enable_capture(self.pg_interfaces)
7948 capture = self.pg1.get_capture(len(pkts))
7949 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7950 dst_ip=self.pg1.remote_ip4)
7952 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7953 self.pg1.add_stream(pkts)
7954 self.pg_enable_capture(self.pg_interfaces)
7956 capture = self.pg2.get_capture(len(pkts))
7957 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7959 def test_static(self):
7960 """ NAT64 static translation test """
7961 self.tcp_port_in = 60303
7962 self.udp_port_in = 60304
7963 self.icmp_id_in = 60305
7964 self.tcp_port_out = 60303
7965 self.udp_port_out = 60304
7966 self.icmp_id_out = 60305
7968 ses_num_start = self.nat64_get_ses_num()
7970 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7971 end_addr=self.nat_addr,
7974 flags = self.config_flags.NAT_IS_INSIDE
7975 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7976 sw_if_index=self.pg0.sw_if_index)
7977 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7978 sw_if_index=self.pg1.sw_if_index)
7980 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7981 o_addr=self.nat_addr,
7982 i_port=self.tcp_port_in,
7983 o_port=self.tcp_port_out,
7984 proto=IP_PROTOS.tcp, vrf_id=0,
7986 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7987 o_addr=self.nat_addr,
7988 i_port=self.udp_port_in,
7989 o_port=self.udp_port_out,
7990 proto=IP_PROTOS.udp, vrf_id=0,
7992 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7993 o_addr=self.nat_addr,
7994 i_port=self.icmp_id_in,
7995 o_port=self.icmp_id_out,
7996 proto=IP_PROTOS.icmp, vrf_id=0,
8000 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8001 self.pg0.add_stream(pkts)
8002 self.pg_enable_capture(self.pg_interfaces)
8004 capture = self.pg1.get_capture(len(pkts))
8005 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8006 dst_ip=self.pg1.remote_ip4, same_port=True)
8009 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8010 self.pg1.add_stream(pkts)
8011 self.pg_enable_capture(self.pg_interfaces)
8013 capture = self.pg0.get_capture(len(pkts))
8014 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8015 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8017 ses_num_end = self.nat64_get_ses_num()
8019 self.assertEqual(ses_num_end - ses_num_start, 3)
8021 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8022 def test_session_timeout(self):
8023 """ NAT64 session timeout """
8024 self.icmp_id_in = 1234
8025 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8026 end_addr=self.nat_addr,
8029 flags = self.config_flags.NAT_IS_INSIDE
8030 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8031 sw_if_index=self.pg0.sw_if_index)
8032 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8033 sw_if_index=self.pg1.sw_if_index)
8034 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8038 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8039 self.pg0.add_stream(pkts)
8040 self.pg_enable_capture(self.pg_interfaces)
8042 capture = self.pg1.get_capture(len(pkts))
8044 ses_num_before_timeout = self.nat64_get_ses_num()
8048 # ICMP and TCP session after timeout
8049 ses_num_after_timeout = self.nat64_get_ses_num()
8050 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8052 def test_icmp_error(self):
8053 """ NAT64 ICMP Error message translation """
8054 self.tcp_port_in = 6303
8055 self.udp_port_in = 6304
8056 self.icmp_id_in = 6305
8058 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8059 end_addr=self.nat_addr,
8062 flags = self.config_flags.NAT_IS_INSIDE
8063 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8064 sw_if_index=self.pg0.sw_if_index)
8065 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8066 sw_if_index=self.pg1.sw_if_index)
8068 # send some packets to create sessions
8069 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8070 self.pg0.add_stream(pkts)
8071 self.pg_enable_capture(self.pg_interfaces)
8073 capture_ip4 = self.pg1.get_capture(len(pkts))
8074 self.verify_capture_out(capture_ip4,
8075 nat_ip=self.nat_addr,
8076 dst_ip=self.pg1.remote_ip4)
8078 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8079 self.pg1.add_stream(pkts)
8080 self.pg_enable_capture(self.pg_interfaces)
8082 capture_ip6 = self.pg0.get_capture(len(pkts))
8083 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8084 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8085 self.pg0.remote_ip6)
8088 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8089 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8090 ICMPv6DestUnreach(code=1) /
8091 packet[IPv6] for packet in capture_ip6]
8092 self.pg0.add_stream(pkts)
8093 self.pg_enable_capture(self.pg_interfaces)
8095 capture = self.pg1.get_capture(len(pkts))
8096 for packet in capture:
8098 self.assertEqual(packet[IP].src, self.nat_addr)
8099 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8100 self.assertEqual(packet[ICMP].type, 3)
8101 self.assertEqual(packet[ICMP].code, 13)
8102 inner = packet[IPerror]
8103 self.assertEqual(inner.src, self.pg1.remote_ip4)
8104 self.assertEqual(inner.dst, self.nat_addr)
8105 self.assert_packet_checksums_valid(packet)
8106 if inner.haslayer(TCPerror):
8107 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8108 elif inner.haslayer(UDPerror):
8109 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8111 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8113 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8117 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8118 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8119 ICMP(type=3, code=13) /
8120 packet[IP] for packet in capture_ip4]
8121 self.pg1.add_stream(pkts)
8122 self.pg_enable_capture(self.pg_interfaces)
8124 capture = self.pg0.get_capture(len(pkts))
8125 for packet in capture:
8127 self.assertEqual(packet[IPv6].src, ip.src)
8128 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8129 icmp = packet[ICMPv6DestUnreach]
8130 self.assertEqual(icmp.code, 1)
8131 inner = icmp[IPerror6]
8132 self.assertEqual(inner.src, self.pg0.remote_ip6)
8133 self.assertEqual(inner.dst, ip.src)
8134 self.assert_icmpv6_checksum_valid(packet)
8135 if inner.haslayer(TCPerror):
8136 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8137 elif inner.haslayer(UDPerror):
8138 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8140 self.assertEqual(inner[ICMPv6EchoRequest].id,
8143 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8146 def test_hairpinning(self):
8147 """ NAT64 hairpinning """
8149 client = self.pg0.remote_hosts[0]
8150 server = self.pg0.remote_hosts[1]
8151 server_tcp_in_port = 22
8152 server_tcp_out_port = 4022
8153 server_udp_in_port = 23
8154 server_udp_out_port = 4023
8155 client_tcp_in_port = 1234
8156 client_udp_in_port = 1235
8157 client_tcp_out_port = 0
8158 client_udp_out_port = 0
8159 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8160 nat_addr_ip6 = ip.src
8162 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8163 end_addr=self.nat_addr,
8166 flags = self.config_flags.NAT_IS_INSIDE
8167 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8168 sw_if_index=self.pg0.sw_if_index)
8169 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8170 sw_if_index=self.pg1.sw_if_index)
8172 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8173 o_addr=self.nat_addr,
8174 i_port=server_tcp_in_port,
8175 o_port=server_tcp_out_port,
8176 proto=IP_PROTOS.tcp, vrf_id=0,
8178 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8179 o_addr=self.nat_addr,
8180 i_port=server_udp_in_port,
8181 o_port=server_udp_out_port,
8182 proto=IP_PROTOS.udp, vrf_id=0,
8187 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8188 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8189 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8191 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8192 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8193 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8195 self.pg0.add_stream(pkts)
8196 self.pg_enable_capture(self.pg_interfaces)
8198 capture = self.pg0.get_capture(len(pkts))
8199 for packet in capture:
8201 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8202 self.assertEqual(packet[IPv6].dst, server.ip6)
8203 self.assert_packet_checksums_valid(packet)
8204 if packet.haslayer(TCP):
8205 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8206 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8207 client_tcp_out_port = packet[TCP].sport
8209 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8210 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8211 client_udp_out_port = packet[UDP].sport
8213 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8218 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8219 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8220 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8222 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8223 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8224 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8226 self.pg0.add_stream(pkts)
8227 self.pg_enable_capture(self.pg_interfaces)
8229 capture = self.pg0.get_capture(len(pkts))
8230 for packet in capture:
8232 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8233 self.assertEqual(packet[IPv6].dst, client.ip6)
8234 self.assert_packet_checksums_valid(packet)
8235 if packet.haslayer(TCP):
8236 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8237 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8239 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8240 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8242 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8247 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8248 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8249 ICMPv6DestUnreach(code=1) /
8250 packet[IPv6] for packet in capture]
8251 self.pg0.add_stream(pkts)
8252 self.pg_enable_capture(self.pg_interfaces)
8254 capture = self.pg0.get_capture(len(pkts))
8255 for packet in capture:
8257 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8258 self.assertEqual(packet[IPv6].dst, server.ip6)
8259 icmp = packet[ICMPv6DestUnreach]
8260 self.assertEqual(icmp.code, 1)
8261 inner = icmp[IPerror6]
8262 self.assertEqual(inner.src, server.ip6)
8263 self.assertEqual(inner.dst, nat_addr_ip6)
8264 self.assert_packet_checksums_valid(packet)
8265 if inner.haslayer(TCPerror):
8266 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8267 self.assertEqual(inner[TCPerror].dport,
8268 client_tcp_out_port)
8270 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8271 self.assertEqual(inner[UDPerror].dport,
8272 client_udp_out_port)
8274 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8277 def test_prefix(self):
8278 """ NAT64 Network-Specific Prefix """
8280 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8281 end_addr=self.nat_addr,
8284 flags = self.config_flags.NAT_IS_INSIDE
8285 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8286 sw_if_index=self.pg0.sw_if_index)
8287 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8288 sw_if_index=self.pg1.sw_if_index)
8289 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8290 end_addr=self.vrf1_nat_addr,
8291 vrf_id=self.vrf1_id, is_add=1)
8292 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8293 sw_if_index=self.pg2.sw_if_index)
8296 global_pref64 = "2001:db8::"
8297 global_pref64_len = 32
8298 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8299 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8302 prefix = self.vapi.nat64_prefix_dump()
8303 self.assertEqual(len(prefix), 1)
8304 self.assertEqual(prefix[0].prefix,
8305 IPv6Network(unicode(global_pref64_str)))
8306 self.assertEqual(prefix[0].vrf_id, 0)
8308 # Add tenant specific prefix
8309 vrf1_pref64 = "2001:db8:122:300::"
8310 vrf1_pref64_len = 56
8311 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8312 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8313 vrf_id=self.vrf1_id, is_add=1)
8315 prefix = self.vapi.nat64_prefix_dump()
8316 self.assertEqual(len(prefix), 2)
8319 pkts = self.create_stream_in_ip6(self.pg0,
8322 plen=global_pref64_len)
8323 self.pg0.add_stream(pkts)
8324 self.pg_enable_capture(self.pg_interfaces)
8326 capture = self.pg1.get_capture(len(pkts))
8327 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8328 dst_ip=self.pg1.remote_ip4)
8330 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8331 self.pg1.add_stream(pkts)
8332 self.pg_enable_capture(self.pg_interfaces)
8334 capture = self.pg0.get_capture(len(pkts))
8335 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8338 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8340 # Tenant specific prefix
8341 pkts = self.create_stream_in_ip6(self.pg2,
8344 plen=vrf1_pref64_len)
8345 self.pg2.add_stream(pkts)
8346 self.pg_enable_capture(self.pg_interfaces)
8348 capture = self.pg1.get_capture(len(pkts))
8349 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8350 dst_ip=self.pg1.remote_ip4)
8352 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8353 self.pg1.add_stream(pkts)
8354 self.pg_enable_capture(self.pg_interfaces)
8356 capture = self.pg2.get_capture(len(pkts))
8357 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8360 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8362 def test_unknown_proto(self):
8363 """ NAT64 translate packet with unknown protocol """
8365 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8366 end_addr=self.nat_addr,
8369 flags = self.config_flags.NAT_IS_INSIDE
8370 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8371 sw_if_index=self.pg0.sw_if_index)
8372 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8373 sw_if_index=self.pg1.sw_if_index)
8374 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8377 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8378 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8379 TCP(sport=self.tcp_port_in, dport=20))
8380 self.pg0.add_stream(p)
8381 self.pg_enable_capture(self.pg_interfaces)
8383 p = self.pg1.get_capture(1)
8385 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8386 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8388 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8389 TCP(sport=1234, dport=1234))
8390 self.pg0.add_stream(p)
8391 self.pg_enable_capture(self.pg_interfaces)
8393 p = self.pg1.get_capture(1)
8396 self.assertEqual(packet[IP].src, self.nat_addr)
8397 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8398 self.assertEqual(packet.haslayer(GRE), 1)
8399 self.assert_packet_checksums_valid(packet)
8401 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8405 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8406 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8408 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8409 TCP(sport=1234, dport=1234))
8410 self.pg1.add_stream(p)
8411 self.pg_enable_capture(self.pg_interfaces)
8413 p = self.pg0.get_capture(1)
8416 self.assertEqual(packet[IPv6].src, remote_ip6)
8417 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8418 self.assertEqual(packet[IPv6].nh, 47)
8420 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8423 def test_hairpinning_unknown_proto(self):
8424 """ NAT64 translate packet with unknown protocol - hairpinning """
8426 client = self.pg0.remote_hosts[0]
8427 server = self.pg0.remote_hosts[1]
8428 server_tcp_in_port = 22
8429 server_tcp_out_port = 4022
8430 client_tcp_in_port = 1234
8431 client_tcp_out_port = 1235
8432 server_nat_ip = "10.0.0.100"
8433 client_nat_ip = "10.0.0.110"
8434 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8435 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8437 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8438 end_addr=client_nat_ip,
8441 flags = self.config_flags.NAT_IS_INSIDE
8442 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8443 sw_if_index=self.pg0.sw_if_index)
8444 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8445 sw_if_index=self.pg1.sw_if_index)
8447 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8448 o_addr=server_nat_ip,
8449 i_port=server_tcp_in_port,
8450 o_port=server_tcp_out_port,
8451 proto=IP_PROTOS.tcp, vrf_id=0,
8454 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8455 o_addr=server_nat_ip, i_port=0,
8457 proto=IP_PROTOS.gre, vrf_id=0,
8460 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8461 o_addr=client_nat_ip,
8462 i_port=client_tcp_in_port,
8463 o_port=client_tcp_out_port,
8464 proto=IP_PROTOS.tcp, vrf_id=0,
8468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8469 IPv6(src=client.ip6, dst=server_nat_ip6) /
8470 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8471 self.pg0.add_stream(p)
8472 self.pg_enable_capture(self.pg_interfaces)
8474 p = self.pg0.get_capture(1)
8476 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8477 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8479 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8480 TCP(sport=1234, dport=1234))
8481 self.pg0.add_stream(p)
8482 self.pg_enable_capture(self.pg_interfaces)
8484 p = self.pg0.get_capture(1)
8487 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8488 self.assertEqual(packet[IPv6].dst, server.ip6)
8489 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8491 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8495 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8496 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8498 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8499 TCP(sport=1234, dport=1234))
8500 self.pg0.add_stream(p)
8501 self.pg_enable_capture(self.pg_interfaces)
8503 p = self.pg0.get_capture(1)
8506 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8507 self.assertEqual(packet[IPv6].dst, client.ip6)
8508 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8510 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8513 def test_one_armed_nat64(self):
8514 """ One armed NAT64 """
8516 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8520 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8521 end_addr=self.nat_addr,
8524 flags = self.config_flags.NAT_IS_INSIDE
8525 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8526 sw_if_index=self.pg3.sw_if_index)
8527 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8528 sw_if_index=self.pg3.sw_if_index)
8531 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8532 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8533 TCP(sport=12345, dport=80))
8534 self.pg3.add_stream(p)
8535 self.pg_enable_capture(self.pg_interfaces)
8537 capture = self.pg3.get_capture(1)
8542 self.assertEqual(ip.src, self.nat_addr)
8543 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8544 self.assertNotEqual(tcp.sport, 12345)
8545 external_port = tcp.sport
8546 self.assertEqual(tcp.dport, 80)
8547 self.assert_packet_checksums_valid(p)
8549 self.logger.error(ppp("Unexpected or invalid packet:", p))
8553 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8554 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8555 TCP(sport=80, dport=external_port))
8556 self.pg3.add_stream(p)
8557 self.pg_enable_capture(self.pg_interfaces)
8559 capture = self.pg3.get_capture(1)
8564 self.assertEqual(ip.src, remote_host_ip6)
8565 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8566 self.assertEqual(tcp.sport, 80)
8567 self.assertEqual(tcp.dport, 12345)
8568 self.assert_packet_checksums_valid(p)
8570 self.logger.error(ppp("Unexpected or invalid packet:", p))
8573 def test_frag_in_order(self):
8574 """ NAT64 translate fragments arriving in order """
8575 self.tcp_port_in = random.randint(1025, 65535)
8577 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8578 end_addr=self.nat_addr,
8581 flags = self.config_flags.NAT_IS_INSIDE
8582 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8583 sw_if_index=self.pg0.sw_if_index)
8584 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8585 sw_if_index=self.pg1.sw_if_index)
8587 reass = self.vapi.nat_reass_dump()
8588 reass_n_start = len(reass)
8592 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8593 self.tcp_port_in, 20, data)
8594 self.pg0.add_stream(pkts)
8595 self.pg_enable_capture(self.pg_interfaces)
8597 frags = self.pg1.get_capture(len(pkts))
8598 p = self.reass_frags_and_verify(frags,
8600 self.pg1.remote_ip4)
8601 self.assertEqual(p[TCP].dport, 20)
8602 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8603 self.tcp_port_out = p[TCP].sport
8604 self.assertEqual(data, p[Raw].load)
8607 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8608 pkts = self.create_stream_frag(self.pg1,
8613 self.pg1.add_stream(pkts)
8614 self.pg_enable_capture(self.pg_interfaces)
8616 frags = self.pg0.get_capture(len(pkts))
8617 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8618 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8619 self.assertEqual(p[TCP].sport, 20)
8620 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8621 self.assertEqual(data, p[Raw].load)
8623 reass = self.vapi.nat_reass_dump()
8624 reass_n_end = len(reass)
8626 self.assertEqual(reass_n_end - reass_n_start, 2)
8628 def test_reass_hairpinning(self):
8629 """ NAT64 fragments hairpinning """
8631 server = self.pg0.remote_hosts[1]
8632 server_in_port = random.randint(1025, 65535)
8633 server_out_port = random.randint(1025, 65535)
8634 client_in_port = random.randint(1025, 65535)
8635 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8636 nat_addr_ip6 = ip.src
8638 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8639 end_addr=self.nat_addr,
8642 flags = self.config_flags.NAT_IS_INSIDE
8643 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8644 sw_if_index=self.pg0.sw_if_index)
8645 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8646 sw_if_index=self.pg1.sw_if_index)
8648 # add static BIB entry for server
8649 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8650 o_addr=self.nat_addr,
8651 i_port=server_in_port,
8652 o_port=server_out_port,
8653 proto=IP_PROTOS.tcp, vrf_id=0,
8656 # send packet from host to server
8657 pkts = self.create_stream_frag_ip6(self.pg0,
8662 self.pg0.add_stream(pkts)
8663 self.pg_enable_capture(self.pg_interfaces)
8665 frags = self.pg0.get_capture(len(pkts))
8666 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8667 self.assertNotEqual(p[TCP].sport, client_in_port)
8668 self.assertEqual(p[TCP].dport, server_in_port)
8669 self.assertEqual(data, p[Raw].load)
8671 def test_frag_out_of_order(self):
8672 """ NAT64 translate fragments arriving out of order """
8673 self.tcp_port_in = random.randint(1025, 65535)
8675 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8676 end_addr=self.nat_addr,
8679 flags = self.config_flags.NAT_IS_INSIDE
8680 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8681 sw_if_index=self.pg0.sw_if_index)
8682 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8683 sw_if_index=self.pg1.sw_if_index)
8687 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8688 self.tcp_port_in, 20, data)
8690 self.pg0.add_stream(pkts)
8691 self.pg_enable_capture(self.pg_interfaces)
8693 frags = self.pg1.get_capture(len(pkts))
8694 p = self.reass_frags_and_verify(frags,
8696 self.pg1.remote_ip4)
8697 self.assertEqual(p[TCP].dport, 20)
8698 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8699 self.tcp_port_out = p[TCP].sport
8700 self.assertEqual(data, p[Raw].load)
8703 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8704 pkts = self.create_stream_frag(self.pg1,
8710 self.pg1.add_stream(pkts)
8711 self.pg_enable_capture(self.pg_interfaces)
8713 frags = self.pg0.get_capture(len(pkts))
8714 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8715 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8716 self.assertEqual(p[TCP].sport, 20)
8717 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8718 self.assertEqual(data, p[Raw].load)
8720 def test_interface_addr(self):
8721 """ Acquire NAT64 pool addresses from interface """
8722 self.vapi.nat64_add_del_interface_addr(
8724 sw_if_index=self.pg4.sw_if_index)
8726 # no address in NAT64 pool
8727 addresses = self.vapi.nat44_address_dump()
8728 self.assertEqual(0, len(addresses))
8730 # configure interface address and check NAT64 address pool
8731 self.pg4.config_ip4()
8732 addresses = self.vapi.nat64_pool_addr_dump()
8733 self.assertEqual(len(addresses), 1)
8735 self.assertEqual(str(addresses[0].address),
8738 # remove interface address and check NAT64 address pool
8739 self.pg4.unconfig_ip4()
8740 addresses = self.vapi.nat64_pool_addr_dump()
8741 self.assertEqual(0, len(addresses))
8743 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8744 def test_ipfix_max_bibs_sessions(self):
8745 """ IPFIX logging maximum session and BIB entries exceeded """
8748 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8752 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8753 end_addr=self.nat_addr,
8756 flags = self.config_flags.NAT_IS_INSIDE
8757 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8758 sw_if_index=self.pg0.sw_if_index)
8759 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8760 sw_if_index=self.pg1.sw_if_index)
8764 for i in range(0, max_bibs):
8765 src = "fd01:aa::%x" % (i)
8766 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8767 IPv6(src=src, dst=remote_host_ip6) /
8768 TCP(sport=12345, dport=80))
8770 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8771 IPv6(src=src, dst=remote_host_ip6) /
8772 TCP(sport=12345, dport=22))
8774 self.pg0.add_stream(pkts)
8775 self.pg_enable_capture(self.pg_interfaces)
8777 self.pg1.get_capture(max_sessions)
8779 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8780 src_address=self.pg3.local_ip4n,
8782 template_interval=10)
8783 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8784 src_port=self.ipfix_src_port,
8787 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8788 IPv6(src=src, dst=remote_host_ip6) /
8789 TCP(sport=12345, dport=25))
8790 self.pg0.add_stream(p)
8791 self.pg_enable_capture(self.pg_interfaces)
8793 self.pg1.assert_nothing_captured()
8795 self.vapi.ipfix_flush()
8796 capture = self.pg3.get_capture(9)
8797 ipfix = IPFIXDecoder()
8798 # first load template
8800 self.assertTrue(p.haslayer(IPFIX))
8801 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8802 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8803 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8804 self.assertEqual(p[UDP].dport, 4739)
8805 self.assertEqual(p[IPFIX].observationDomainID,
8806 self.ipfix_domain_id)
8807 if p.haslayer(Template):
8808 ipfix.add_template(p.getlayer(Template))
8809 # verify events in data set
8811 if p.haslayer(Data):
8812 data = ipfix.decode_data_set(p.getlayer(Set))
8813 self.verify_ipfix_max_sessions(data, max_sessions)
8815 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8816 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8817 TCP(sport=12345, dport=80))
8818 self.pg0.add_stream(p)
8819 self.pg_enable_capture(self.pg_interfaces)
8821 self.pg1.assert_nothing_captured()
8823 self.vapi.ipfix_flush()
8824 capture = self.pg3.get_capture(1)
8825 # verify events in data set
8827 self.assertTrue(p.haslayer(IPFIX))
8828 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8829 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8830 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8831 self.assertEqual(p[UDP].dport, 4739)
8832 self.assertEqual(p[IPFIX].observationDomainID,
8833 self.ipfix_domain_id)
8834 if p.haslayer(Data):
8835 data = ipfix.decode_data_set(p.getlayer(Set))
8836 self.verify_ipfix_max_bibs(data, max_bibs)
8838 def test_ipfix_max_frags(self):
8839 """ IPFIX logging maximum fragments pending reassembly exceeded """
8840 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8841 end_addr=self.nat_addr,
8844 flags = self.config_flags.NAT_IS_INSIDE
8845 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8846 sw_if_index=self.pg0.sw_if_index)
8847 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8848 sw_if_index=self.pg1.sw_if_index)
8849 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8850 drop_frag=0, is_ip6=1)
8851 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8852 src_address=self.pg3.local_ip4n,
8854 template_interval=10)
8855 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8856 src_port=self.ipfix_src_port,
8860 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8861 self.tcp_port_in, 20, data)
8863 self.pg0.add_stream(pkts)
8864 self.pg_enable_capture(self.pg_interfaces)
8866 self.pg1.assert_nothing_captured()
8868 self.vapi.ipfix_flush()
8869 capture = self.pg3.get_capture(9)
8870 ipfix = IPFIXDecoder()
8871 # first load template
8873 self.assertTrue(p.haslayer(IPFIX))
8874 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8875 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8876 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8877 self.assertEqual(p[UDP].dport, 4739)
8878 self.assertEqual(p[IPFIX].observationDomainID,
8879 self.ipfix_domain_id)
8880 if p.haslayer(Template):
8881 ipfix.add_template(p.getlayer(Template))
8882 # verify events in data set
8884 if p.haslayer(Data):
8885 data = ipfix.decode_data_set(p.getlayer(Set))
8886 self.verify_ipfix_max_fragments_ip6(data, 1,
8887 self.pg0.remote_ip6n)
8889 def test_ipfix_bib_ses(self):
8890 """ IPFIX logging NAT64 BIB/session create and delete events """
8891 self.tcp_port_in = random.randint(1025, 65535)
8892 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8896 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8897 end_addr=self.nat_addr,
8900 flags = self.config_flags.NAT_IS_INSIDE
8901 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8902 sw_if_index=self.pg0.sw_if_index)
8903 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8904 sw_if_index=self.pg1.sw_if_index)
8905 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8906 src_address=self.pg3.local_ip4n,
8908 template_interval=10)
8909 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8910 src_port=self.ipfix_src_port,
8914 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8915 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8916 TCP(sport=self.tcp_port_in, dport=25))
8917 self.pg0.add_stream(p)
8918 self.pg_enable_capture(self.pg_interfaces)
8920 p = self.pg1.get_capture(1)
8921 self.tcp_port_out = p[0][TCP].sport
8922 self.vapi.ipfix_flush()
8923 capture = self.pg3.get_capture(10)
8924 ipfix = IPFIXDecoder()
8925 # first load template
8927 self.assertTrue(p.haslayer(IPFIX))
8928 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8929 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8930 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8931 self.assertEqual(p[UDP].dport, 4739)
8932 self.assertEqual(p[IPFIX].observationDomainID,
8933 self.ipfix_domain_id)
8934 if p.haslayer(Template):
8935 ipfix.add_template(p.getlayer(Template))
8936 # verify events in data set
8938 if p.haslayer(Data):
8939 data = ipfix.decode_data_set(p.getlayer(Set))
8940 if scapy.compat.orb(data[0][230]) == 10:
8941 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8942 elif scapy.compat.orb(data[0][230]) == 6:
8943 self.verify_ipfix_nat64_ses(data,
8945 self.pg0.remote_ip6n,
8946 self.pg1.remote_ip4,
8949 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8952 self.pg_enable_capture(self.pg_interfaces)
8953 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8954 end_addr=self.nat_addr,
8957 self.vapi.ipfix_flush()
8958 capture = self.pg3.get_capture(2)
8959 # verify events in data set
8961 self.assertTrue(p.haslayer(IPFIX))
8962 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8963 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8964 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8965 self.assertEqual(p[UDP].dport, 4739)
8966 self.assertEqual(p[IPFIX].observationDomainID,
8967 self.ipfix_domain_id)
8968 if p.haslayer(Data):
8969 data = ipfix.decode_data_set(p.getlayer(Set))
8970 if scapy.compat.orb(data[0][230]) == 11:
8971 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8972 elif scapy.compat.orb(data[0][230]) == 7:
8973 self.verify_ipfix_nat64_ses(data,
8975 self.pg0.remote_ip6n,
8976 self.pg1.remote_ip4,
8979 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8981 def test_syslog_sess(self):
8982 """ Test syslog session creation and deletion """
8983 self.tcp_port_in = random.randint(1025, 65535)
8984 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8988 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8989 end_addr=self.nat_addr,
8992 flags = self.config_flags.NAT_IS_INSIDE
8993 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8994 sw_if_index=self.pg0.sw_if_index)
8995 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8996 sw_if_index=self.pg1.sw_if_index)
8997 self.vapi.syslog_set_filter(
8998 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8999 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9001 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9002 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9003 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9004 self.pg0.add_stream(p)
9005 self.pg_enable_capture(self.pg_interfaces)
9007 p = self.pg1.get_capture(1)
9008 self.tcp_port_out = p[0][TCP].sport
9009 capture = self.pg3.get_capture(1)
9010 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9012 self.pg_enable_capture(self.pg_interfaces)
9014 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9015 end_addr=self.nat_addr,
9018 capture = self.pg3.get_capture(1)
9019 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9021 def nat64_get_ses_num(self):
9023 Return number of active NAT64 sessions.
9025 st = self.vapi.nat64_st_dump(proto=255)
9028 def clear_nat64(self):
9030 Clear NAT64 configuration.
9032 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9033 src_port=self.ipfix_src_port,
9035 self.ipfix_src_port = 4739
9036 self.ipfix_domain_id = 1
9038 self.vapi.syslog_set_filter(
9039 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9041 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9042 tcp_transitory=240, icmp=60)
9044 interfaces = self.vapi.nat64_interface_dump()
9045 for intf in interfaces:
9046 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9047 sw_if_index=intf.sw_if_index)
9049 bib = self.vapi.nat64_bib_dump(proto=255)
9051 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9052 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9060 adresses = self.vapi.nat64_pool_addr_dump()
9061 for addr in adresses:
9062 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9063 end_addr=addr.address,
9067 prefixes = self.vapi.nat64_prefix_dump()
9068 for prefix in prefixes:
9069 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9070 vrf_id=prefix.vrf_id, is_add=0)
9072 bibs = self.statistics.get_counter('/nat64/total-bibs')
9073 self.assertEqual(bibs[0][0], 0)
9074 sessions = self.statistics.get_counter('/nat64/total-sessions')
9075 self.assertEqual(sessions[0][0], 0)
9078 super(TestNAT64, self).tearDown()
9079 if not self.vpp_dead:
9082 def show_commands_at_teardown(self):
9083 self.logger.info(self.vapi.cli("show nat64 pool"))
9084 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9085 self.logger.info(self.vapi.cli("show nat64 prefix"))
9086 self.logger.info(self.vapi.cli("show nat64 bib all"))
9087 self.logger.info(self.vapi.cli("show nat64 session table all"))
9088 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9091 class TestDSlite(MethodHolder):
9092 """ DS-Lite Test Cases """
9095 def setUpClass(cls):
9096 super(TestDSlite, cls).setUpClass()
9099 cls.nat_addr = '10.0.0.3'
9101 cls.create_pg_interfaces(range(3))
9103 cls.pg0.config_ip4()
9104 cls.pg0.resolve_arp()
9106 cls.pg1.config_ip6()
9107 cls.pg1.generate_remote_hosts(2)
9108 cls.pg1.configure_ipv6_neighbors()
9110 cls.pg2.config_ip4()
9111 cls.pg2.resolve_arp()
9114 super(TestDSlite, cls).tearDownClass()
9118 def tearDownClass(cls):
9119 super(TestDSlite, cls).tearDownClass()
9121 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9123 message = data.decode('utf-8')
9125 message = SyslogMessage.parse(message)
9126 except ParseError as e:
9127 self.logger.error(e)
9129 self.assertEqual(message.severity, SyslogSeverity.info)
9130 self.assertEqual(message.appname, 'NAT')
9131 self.assertEqual(message.msgid, 'APMADD')
9132 sd_params = message.sd.get('napmap')
9133 self.assertTrue(sd_params is not None)
9134 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9135 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9136 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9137 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9138 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9139 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9140 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9141 self.assertTrue(sd_params.get('SSUBIX') is not None)
9142 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9144 def test_dslite(self):
9145 """ Test DS-Lite """
9146 nat_config = self.vapi.nat_show_config()
9147 self.assertEqual(0, nat_config.dslite_ce)
9149 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9150 end_addr=self.nat_addr,
9152 aftr_ip4 = '192.0.0.1'
9153 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9154 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9155 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9158 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9159 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9160 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9161 UDP(sport=20000, dport=10000))
9162 self.pg1.add_stream(p)
9163 self.pg_enable_capture(self.pg_interfaces)
9165 capture = self.pg0.get_capture(1)
9166 capture = capture[0]
9167 self.assertFalse(capture.haslayer(IPv6))
9168 self.assertEqual(capture[IP].src, self.nat_addr)
9169 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9170 self.assertNotEqual(capture[UDP].sport, 20000)
9171 self.assertEqual(capture[UDP].dport, 10000)
9172 self.assert_packet_checksums_valid(capture)
9173 out_port = capture[UDP].sport
9174 capture = self.pg2.get_capture(1)
9175 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9176 20000, self.nat_addr, out_port,
9177 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9179 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9180 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9181 UDP(sport=10000, dport=out_port))
9182 self.pg0.add_stream(p)
9183 self.pg_enable_capture(self.pg_interfaces)
9185 capture = self.pg1.get_capture(1)
9186 capture = capture[0]
9187 self.assertEqual(capture[IPv6].src, aftr_ip6)
9188 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9189 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9190 self.assertEqual(capture[IP].dst, '192.168.1.1')
9191 self.assertEqual(capture[UDP].sport, 10000)
9192 self.assertEqual(capture[UDP].dport, 20000)
9193 self.assert_packet_checksums_valid(capture)
9196 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9197 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9198 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9199 TCP(sport=20001, dport=10001))
9200 self.pg1.add_stream(p)
9201 self.pg_enable_capture(self.pg_interfaces)
9203 capture = self.pg0.get_capture(1)
9204 capture = capture[0]
9205 self.assertFalse(capture.haslayer(IPv6))
9206 self.assertEqual(capture[IP].src, self.nat_addr)
9207 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9208 self.assertNotEqual(capture[TCP].sport, 20001)
9209 self.assertEqual(capture[TCP].dport, 10001)
9210 self.assert_packet_checksums_valid(capture)
9211 out_port = capture[TCP].sport
9213 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9214 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9215 TCP(sport=10001, dport=out_port))
9216 self.pg0.add_stream(p)
9217 self.pg_enable_capture(self.pg_interfaces)
9219 capture = self.pg1.get_capture(1)
9220 capture = capture[0]
9221 self.assertEqual(capture[IPv6].src, aftr_ip6)
9222 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9223 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9224 self.assertEqual(capture[IP].dst, '192.168.1.1')
9225 self.assertEqual(capture[TCP].sport, 10001)
9226 self.assertEqual(capture[TCP].dport, 20001)
9227 self.assert_packet_checksums_valid(capture)
9230 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9231 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9232 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9233 ICMP(id=4000, type='echo-request'))
9234 self.pg1.add_stream(p)
9235 self.pg_enable_capture(self.pg_interfaces)
9237 capture = self.pg0.get_capture(1)
9238 capture = capture[0]
9239 self.assertFalse(capture.haslayer(IPv6))
9240 self.assertEqual(capture[IP].src, self.nat_addr)
9241 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9242 self.assertNotEqual(capture[ICMP].id, 4000)
9243 self.assert_packet_checksums_valid(capture)
9244 out_id = capture[ICMP].id
9246 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9247 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9248 ICMP(id=out_id, type='echo-reply'))
9249 self.pg0.add_stream(p)
9250 self.pg_enable_capture(self.pg_interfaces)
9252 capture = self.pg1.get_capture(1)
9253 capture = capture[0]
9254 self.assertEqual(capture[IPv6].src, aftr_ip6)
9255 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9256 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9257 self.assertEqual(capture[IP].dst, '192.168.1.1')
9258 self.assertEqual(capture[ICMP].id, 4000)
9259 self.assert_packet_checksums_valid(capture)
9261 # ping DS-Lite AFTR tunnel endpoint address
9262 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9263 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9264 ICMPv6EchoRequest())
9265 self.pg1.add_stream(p)
9266 self.pg_enable_capture(self.pg_interfaces)
9268 capture = self.pg1.get_capture(1)
9269 capture = capture[0]
9270 self.assertEqual(capture[IPv6].src, aftr_ip6)
9271 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9272 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9274 b4s = self.statistics.get_counter('/dslite/total-b4s')
9275 self.assertEqual(b4s[0][0], 2)
9276 sessions = self.statistics.get_counter('/dslite/total-sessions')
9277 self.assertEqual(sessions[0][0], 3)
9280 super(TestDSlite, self).tearDown()
9282 def show_commands_at_teardown(self):
9283 self.logger.info(self.vapi.cli("show dslite pool"))
9285 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9286 self.logger.info(self.vapi.cli("show dslite sessions"))
9289 class TestDSliteCE(MethodHolder):
9290 """ DS-Lite CE Test Cases """
9293 def setUpConstants(cls):
9294 super(TestDSliteCE, cls).setUpConstants()
9295 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9298 def setUpClass(cls):
9299 super(TestDSliteCE, cls).setUpClass()
9302 cls.create_pg_interfaces(range(2))
9304 cls.pg0.config_ip4()
9305 cls.pg0.resolve_arp()
9307 cls.pg1.config_ip6()
9308 cls.pg1.generate_remote_hosts(1)
9309 cls.pg1.configure_ipv6_neighbors()
9312 super(TestDSliteCE, cls).tearDownClass()
9316 def tearDownClass(cls):
9317 super(TestDSliteCE, cls).tearDownClass()
9319 def test_dslite_ce(self):
9320 """ Test DS-Lite CE """
9322 nat_config = self.vapi.nat_show_config()
9323 self.assertEqual(1, nat_config.dslite_ce)
9325 b4_ip4 = '192.0.0.2'
9326 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9327 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9329 aftr_ip4 = '192.0.0.1'
9330 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9331 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9332 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9334 r1 = VppIpRoute(self, aftr_ip6, 128,
9335 [VppRoutePath(self.pg1.remote_ip6,
9336 self.pg1.sw_if_index)])
9340 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9341 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9342 UDP(sport=10000, dport=20000))
9343 self.pg0.add_stream(p)
9344 self.pg_enable_capture(self.pg_interfaces)
9346 capture = self.pg1.get_capture(1)
9347 capture = capture[0]
9348 self.assertEqual(capture[IPv6].src, b4_ip6)
9349 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9350 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9351 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9352 self.assertEqual(capture[UDP].sport, 10000)
9353 self.assertEqual(capture[UDP].dport, 20000)
9354 self.assert_packet_checksums_valid(capture)
9357 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9358 IPv6(dst=b4_ip6, src=aftr_ip6) /
9359 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9360 UDP(sport=20000, dport=10000))
9361 self.pg1.add_stream(p)
9362 self.pg_enable_capture(self.pg_interfaces)
9364 capture = self.pg0.get_capture(1)
9365 capture = capture[0]
9366 self.assertFalse(capture.haslayer(IPv6))
9367 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9368 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9369 self.assertEqual(capture[UDP].sport, 20000)
9370 self.assertEqual(capture[UDP].dport, 10000)
9371 self.assert_packet_checksums_valid(capture)
9373 # ping DS-Lite B4 tunnel endpoint address
9374 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9375 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9376 ICMPv6EchoRequest())
9377 self.pg1.add_stream(p)
9378 self.pg_enable_capture(self.pg_interfaces)
9380 capture = self.pg1.get_capture(1)
9381 capture = capture[0]
9382 self.assertEqual(capture[IPv6].src, b4_ip6)
9383 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9384 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9387 super(TestDSliteCE, self).tearDown()
9389 def show_commands_at_teardown(self):
9391 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9393 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9396 class TestNAT66(MethodHolder):
9397 """ NAT66 Test Cases """
9400 def setUpClass(cls):
9401 super(TestNAT66, cls).setUpClass()
9404 cls.nat_addr = 'fd01:ff::2'
9406 cls.create_pg_interfaces(range(2))
9407 cls.interfaces = list(cls.pg_interfaces)
9409 for i in cls.interfaces:
9412 i.configure_ipv6_neighbors()
9415 super(TestNAT66, cls).tearDownClass()
9419 def tearDownClass(cls):
9420 super(TestNAT66, cls).tearDownClass()
9422 def test_static(self):
9423 """ 1:1 NAT66 test """
9424 flags = self.config_flags.NAT_IS_INSIDE
9425 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9426 sw_if_index=self.pg0.sw_if_index)
9427 self.vapi.nat66_add_del_interface(is_add=1,
9428 sw_if_index=self.pg1.sw_if_index)
9429 self.vapi.nat66_add_del_static_mapping(
9430 local_ip_address=self.pg0.remote_ip6n,
9431 external_ip_address=self.nat_addr,
9436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9437 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9441 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9445 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9446 ICMPv6EchoRequest())
9448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9449 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9450 GRE() / IP() / TCP())
9452 self.pg0.add_stream(pkts)
9453 self.pg_enable_capture(self.pg_interfaces)
9455 capture = self.pg1.get_capture(len(pkts))
9456 for packet in capture:
9458 self.assertEqual(packet[IPv6].src, self.nat_addr)
9459 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9460 self.assert_packet_checksums_valid(packet)
9462 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9467 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9468 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9471 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9472 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9475 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9476 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9479 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9480 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9481 GRE() / IP() / TCP())
9483 self.pg1.add_stream(pkts)
9484 self.pg_enable_capture(self.pg_interfaces)
9486 capture = self.pg0.get_capture(len(pkts))
9487 for packet in capture:
9489 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9490 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9491 self.assert_packet_checksums_valid(packet)
9493 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9496 sm = self.vapi.nat66_static_mapping_dump()
9497 self.assertEqual(len(sm), 1)
9498 self.assertEqual(sm[0].total_pkts, 8)
9500 def test_check_no_translate(self):
9501 """ NAT66 translate only when egress interface is outside interface """
9502 flags = self.config_flags.NAT_IS_INSIDE
9503 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9504 sw_if_index=self.pg0.sw_if_index)
9505 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9506 sw_if_index=self.pg1.sw_if_index)
9507 self.vapi.nat66_add_del_static_mapping(
9508 local_ip_address=self.pg0.remote_ip6n,
9509 external_ip_address=self.nat_addr,
9513 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9514 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9516 self.pg0.add_stream([p])
9517 self.pg_enable_capture(self.pg_interfaces)
9519 capture = self.pg1.get_capture(1)
9522 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9523 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9525 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9528 def clear_nat66(self):
9530 Clear NAT66 configuration.
9532 interfaces = self.vapi.nat66_interface_dump()
9533 for intf in interfaces:
9534 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9535 sw_if_index=intf.sw_if_index)
9537 static_mappings = self.vapi.nat66_static_mapping_dump()
9538 for sm in static_mappings:
9539 self.vapi.nat66_add_del_static_mapping(
9540 local_ip_address=sm.local_ip_address,
9541 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9545 super(TestNAT66, self).tearDown()
9548 def show_commands_at_teardown(self):
9549 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9550 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9553 if __name__ == '__main__':
9554 unittest.main(testRunner=VppTestRunner)