8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
33 from ipaddress import IPv6Network
36 # NAT HA protocol event data
39 fields_desc = [ByteEnumField("event_type", None,
40 {1: "add", 2: "del", 3: "refresh"}),
41 ByteEnumField("protocol", None,
42 {0: "udp", 1: "tcp", 2: "icmp"}),
43 ShortField("flags", 0),
44 IPField("in_addr", None),
45 IPField("out_addr", None),
46 ShortField("in_port", None),
47 ShortField("out_port", None),
48 IPField("eh_addr", None),
49 IPField("ehn_addr", None),
50 ShortField("eh_port", None),
51 ShortField("ehn_port", None),
52 IntField("fib_index", None),
53 IntField("total_pkts", 0),
54 LongField("total_bytes", 0)]
56 def extract_padding(self, s):
60 # NAT HA protocol header
61 class HANATStateSync(Packet):
62 name = "HA NAT state sync"
63 fields_desc = [XByteField("version", 1),
64 FlagsField("flags", 0, 8, ['ACK']),
65 FieldLenField("count", None, count_of="events"),
66 IntField("sequence_number", 1),
67 IntField("thread_index", 0),
68 PacketListField("events", [], Event,
69 count_from=lambda pkt: pkt.count)]
72 class MethodHolder(VppTestCase):
73 """ NAT create capture and verify method holder """
76 def config_flags(self):
77 return VppEnum.vl_api_nat_config_flags_t
80 def SYSLOG_SEVERITY(self):
81 return VppEnum.vl_api_syslog_severity_t
83 def clear_nat44(self):
85 Clear NAT44 configuration.
87 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
88 if self.pg7.has_ip4_config:
89 self.pg7.unconfig_ip4()
91 self.vapi.nat44_forwarding_enable_disable(enable=0)
93 interfaces = self.vapi.nat44_interface_addr_dump()
94 for intf in interfaces:
95 self.vapi.nat44_add_del_interface_addr(
97 sw_if_index=intf.sw_if_index,
100 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
101 src_port=self.ipfix_src_port,
103 self.ipfix_src_port = 4739
104 self.ipfix_domain_id = 1
106 self.vapi.syslog_set_filter(
107 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
109 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
111 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
112 session_refresh_interval=10)
114 interfaces = self.vapi.nat44_interface_dump()
115 for intf in interfaces:
116 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
117 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
118 self.vapi.nat44_interface_add_del_feature(
119 sw_if_index=intf.sw_if_index)
120 self.vapi.nat44_interface_add_del_feature(
121 sw_if_index=intf.sw_if_index,
124 interfaces = self.vapi.nat44_interface_output_feature_dump()
125 for intf in interfaces:
126 self.vapi.nat44_interface_add_del_output_feature(
129 sw_if_index=intf.sw_if_index)
130 static_mappings = self.vapi.nat44_static_mapping_dump()
131 for sm in static_mappings:
132 self.vapi.nat44_add_del_static_mapping(
134 local_ip_address=sm.local_ip_address,
135 external_ip_address=sm.external_ip_address,
136 external_sw_if_index=sm.external_sw_if_index,
137 local_port=sm.local_port,
138 external_port=sm.external_port,
140 protocol=sm.protocol,
141 flags=sm.flags, tag=sm.tag)
143 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
144 for lb_sm in lb_static_mappings:
145 self.vapi.nat44_add_del_lb_static_mapping(
148 external_addr=lb_sm.external_addr,
149 external_port=lb_sm.external_port,
150 protocol=lb_sm.protocol,
151 local_num=0, locals=[],
154 identity_mappings = self.vapi.nat44_identity_mapping_dump()
155 for id_m in identity_mappings:
156 self.vapi.nat44_add_del_identity_mapping(
157 ip_address=id_m.ip_address,
158 sw_if_index=id_m.sw_if_index,
162 protocol=id_m.protocol)
164 addresses = self.vapi.nat44_address_dump()
165 for addr in addresses:
166 self.vapi.nat44_add_del_address_range(
167 first_ip_address=addr.ip_address,
168 last_ip_address=addr.ip_address,
169 vrf_id=0xFFFFFFFF, flags=addr.flags)
171 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
173 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
174 drop_frag=0, is_ip6=1)
175 self.verify_no_nat44_user()
176 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
177 tcp_transitory=240, icmp=60)
178 self.vapi.nat_set_addr_and_port_alloc_alg()
179 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
181 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
182 local_port=0, external_port=0, vrf_id=0,
183 is_add=1, external_sw_if_index=0xFFFFFFFF,
184 proto=0, tag="", flags=0):
186 Add/delete NAT44 static mapping
188 :param local_ip: Local IP address
189 :param external_ip: External IP address
190 :param local_port: Local port number (Optional)
191 :param external_port: External port number (Optional)
192 :param vrf_id: VRF ID (Default 0)
193 :param is_add: 1 if add, 0 if delete (Default add)
194 :param external_sw_if_index: External interface instead of IP address
195 :param proto: IP protocol (Mandatory if port specified)
196 :param tag: Opaque string tag
197 :param flags: NAT configuration flags
200 if not (local_port and external_port):
201 flags |= self.config_flags.NAT_IS_ADDR_ONLY
203 self.vapi.nat44_add_del_static_mapping(
205 local_ip_address=local_ip,
206 external_ip_address=external_ip,
207 external_sw_if_index=external_sw_if_index,
208 local_port=local_port,
209 external_port=external_port,
210 vrf_id=vrf_id, protocol=proto,
214 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
216 Add/delete NAT44 address
218 :param ip: IP address
219 :param is_add: 1 if add, 0 if delete (Default add)
220 :param twice_nat: twice NAT address for external hosts
222 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
223 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
229 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
231 Create packet stream for inside network
233 :param in_if: Inside interface
234 :param out_if: Outside interface
235 :param dst_ip: Destination address
236 :param ttl: TTL of generated packets
239 dst_ip = out_if.remote_ip4
243 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
244 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
245 TCP(sport=self.tcp_port_in, dport=20))
249 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
250 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
251 UDP(sport=self.udp_port_in, dport=20))
255 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
256 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
257 ICMP(id=self.icmp_id_in, type='echo-request'))
262 def compose_ip6(self, ip4, pref, plen):
264 Compose IPv4-embedded IPv6 addresses
266 :param ip4: IPv4 address
267 :param pref: IPv6 prefix
268 :param plen: IPv6 prefix length
269 :returns: IPv4-embedded IPv6 addresses
271 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
272 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
287 pref_n[10] = ip4_n[3]
291 pref_n[10] = ip4_n[2]
292 pref_n[11] = ip4_n[3]
295 pref_n[10] = ip4_n[1]
296 pref_n[11] = ip4_n[2]
297 pref_n[12] = ip4_n[3]
299 pref_n[12] = ip4_n[0]
300 pref_n[13] = ip4_n[1]
301 pref_n[14] = ip4_n[2]
302 pref_n[15] = ip4_n[3]
303 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
304 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
306 def extract_ip4(self, ip6, plen):
308 Extract IPv4 address embedded in IPv6 addresses
310 :param ip6: IPv6 address
311 :param plen: IPv6 prefix length
312 :returns: extracted IPv4 address
314 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
346 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
348 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
350 Create IPv6 packet stream for inside network
352 :param in_if: Inside interface
353 :param out_if: Outside interface
354 :param ttl: Hop Limit of generated packets
355 :param pref: NAT64 prefix
356 :param plen: NAT64 prefix length
360 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
362 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
365 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
366 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
367 TCP(sport=self.tcp_port_in, dport=20))
371 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
372 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
373 UDP(sport=self.udp_port_in, dport=20))
377 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
378 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
379 ICMPv6EchoRequest(id=self.icmp_id_in))
384 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
385 use_inside_ports=False):
387 Create packet stream for outside network
389 :param out_if: Outside interface
390 :param dst_ip: Destination IP address (Default use global NAT address)
391 :param ttl: TTL of generated packets
392 :param use_inside_ports: Use inside NAT ports as destination ports
393 instead of outside ports
396 dst_ip = self.nat_addr
397 if not use_inside_ports:
398 tcp_port = self.tcp_port_out
399 udp_port = self.udp_port_out
400 icmp_id = self.icmp_id_out
402 tcp_port = self.tcp_port_in
403 udp_port = self.udp_port_in
404 icmp_id = self.icmp_id_in
407 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
408 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
409 TCP(dport=tcp_port, sport=20))
413 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
414 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
415 UDP(dport=udp_port, sport=20))
419 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
420 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
421 ICMP(id=icmp_id, type='echo-reply'))
426 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
428 Create packet stream for outside network
430 :param out_if: Outside interface
431 :param dst_ip: Destination IP address (Default use global NAT address)
432 :param hl: HL of generated packets
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
438 TCP(dport=self.tcp_port_out, sport=20))
442 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
443 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
444 UDP(dport=self.udp_port_out, sport=20))
448 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
449 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
450 ICMPv6EchoReply(id=self.icmp_id_out))
455 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
456 dst_ip=None, is_ip6=False):
458 Verify captured packets on outside network
460 :param capture: Captured packets
461 :param nat_ip: Translated IP address (Default use global NAT address)
462 :param same_port: Source port number is not translated (Default False)
463 :param dst_ip: Destination IP address (Default do not verify)
464 :param is_ip6: If L3 protocol is IPv6 (Default False)
468 ICMP46 = ICMPv6EchoRequest
473 nat_ip = self.nat_addr
474 for packet in capture:
477 self.assert_packet_checksums_valid(packet)
478 self.assertEqual(packet[IP46].src, nat_ip)
479 if dst_ip is not None:
480 self.assertEqual(packet[IP46].dst, dst_ip)
481 if packet.haslayer(TCP):
483 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
486 packet[TCP].sport, self.tcp_port_in)
487 self.tcp_port_out = packet[TCP].sport
488 self.assert_packet_checksums_valid(packet)
489 elif packet.haslayer(UDP):
491 self.assertEqual(packet[UDP].sport, self.udp_port_in)
494 packet[UDP].sport, self.udp_port_in)
495 self.udp_port_out = packet[UDP].sport
498 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
500 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
501 self.icmp_id_out = packet[ICMP46].id
502 self.assert_packet_checksums_valid(packet)
504 self.logger.error(ppp("Unexpected or invalid packet "
505 "(outside network):", packet))
508 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
511 Verify captured packets on outside network
513 :param capture: Captured packets
514 :param nat_ip: Translated IP address
515 :param same_port: Source port number is not translated (Default False)
516 :param dst_ip: Destination IP address (Default do not verify)
518 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
521 def verify_capture_in(self, capture, in_if):
523 Verify captured packets on inside network
525 :param capture: Captured packets
526 :param in_if: Inside interface
528 for packet in capture:
530 self.assert_packet_checksums_valid(packet)
531 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
532 if packet.haslayer(TCP):
533 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
534 elif packet.haslayer(UDP):
535 self.assertEqual(packet[UDP].dport, self.udp_port_in)
537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
539 self.logger.error(ppp("Unexpected or invalid packet "
540 "(inside network):", packet))
543 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
545 Verify captured IPv6 packets on inside network
547 :param capture: Captured packets
548 :param src_ip: Source IP
549 :param dst_ip: Destination IP address
551 for packet in capture:
553 self.assertEqual(packet[IPv6].src, src_ip)
554 self.assertEqual(packet[IPv6].dst, dst_ip)
555 self.assert_packet_checksums_valid(packet)
556 if packet.haslayer(TCP):
557 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
558 elif packet.haslayer(UDP):
559 self.assertEqual(packet[UDP].dport, self.udp_port_in)
561 self.assertEqual(packet[ICMPv6EchoReply].id,
564 self.logger.error(ppp("Unexpected or invalid packet "
565 "(inside network):", packet))
568 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
570 Verify captured packet that don't have to be translated
572 :param capture: Captured packets
573 :param ingress_if: Ingress interface
574 :param egress_if: Egress interface
576 for packet in capture:
578 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
579 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
580 if packet.haslayer(TCP):
581 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
582 elif packet.haslayer(UDP):
583 self.assertEqual(packet[UDP].sport, self.udp_port_in)
585 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(inside network):", packet))
591 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
594 Verify captured packets with ICMP errors on outside network
596 :param capture: Captured packets
597 :param src_ip: Translated IP address or IP address of VPP
598 (Default use global NAT address)
599 :param icmp_type: Type of error ICMP packet
600 we are expecting (Default 11)
603 src_ip = self.nat_addr
604 for packet in capture:
606 self.assertEqual(packet[IP].src, src_ip)
607 self.assertEqual(packet.haslayer(ICMP), 1)
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].dport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].dport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(outside network):", packet))
625 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
627 Verify captured packets with ICMP errors on inside network
629 :param capture: Captured packets
630 :param in_if: Inside interface
631 :param icmp_type: Type of error ICMP packet
632 we are expecting (Default 11)
634 for packet in capture:
636 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
637 self.assertEqual(packet.haslayer(ICMP), 1)
639 self.assertEqual(icmp.type, icmp_type)
640 self.assertTrue(icmp.haslayer(IPerror))
641 inner_ip = icmp[IPerror]
642 if inner_ip.haslayer(TCPerror):
643 self.assertEqual(inner_ip[TCPerror].sport,
645 elif inner_ip.haslayer(UDPerror):
646 self.assertEqual(inner_ip[UDPerror].sport,
649 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
651 self.logger.error(ppp("Unexpected or invalid packet "
652 "(inside network):", packet))
655 def create_stream_frag(self, src_if, dst, sport, dport, data,
656 proto=IP_PROTOS.tcp, echo_reply=False):
658 Create fragmented packet stream
660 :param src_if: Source interface
661 :param dst: Destination IPv4 address
662 :param sport: Source port
663 :param dport: Destination port
664 :param data: Payload data
665 :param proto: protocol (TCP, UDP, ICMP)
666 :param echo_reply: use echo_reply if protocol is ICMP
669 if proto == IP_PROTOS.tcp:
670 p = (IP(src=src_if.remote_ip4, dst=dst) /
671 TCP(sport=sport, dport=dport) /
673 p = p.__class__(scapy.compat.raw(p))
674 chksum = p[TCP].chksum
675 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
676 elif proto == IP_PROTOS.udp:
677 proto_header = UDP(sport=sport, dport=dport)
678 elif proto == IP_PROTOS.icmp:
680 proto_header = ICMP(id=sport, type='echo-request')
682 proto_header = ICMP(id=sport, type='echo-reply')
684 raise Exception("Unsupported protocol")
685 id = random.randint(0, 65535)
687 if proto == IP_PROTOS.tcp:
690 raw = Raw(data[0:16])
691 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
692 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
696 if proto == IP_PROTOS.tcp:
697 raw = Raw(data[4:20])
699 raw = Raw(data[16:32])
700 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
701 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
705 if proto == IP_PROTOS.tcp:
709 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
710 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
716 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
717 pref=None, plen=0, frag_size=128):
719 Create fragmented packet stream
721 :param src_if: Source interface
722 :param dst: Destination IPv4 address
723 :param sport: Source TCP port
724 :param dport: Destination TCP port
725 :param data: Payload data
726 :param pref: NAT64 prefix
727 :param plen: NAT64 prefix length
728 :param fragsize: size of fragments
732 dst_ip6 = ''.join(['64:ff9b::', dst])
734 dst_ip6 = self.compose_ip6(dst, pref, plen)
736 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
737 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
738 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
739 TCP(sport=sport, dport=dport) /
742 return fragment6(p, frag_size)
744 def reass_frags_and_verify(self, frags, src, dst):
746 Reassemble and verify fragmented packet
748 :param frags: Captured fragments
749 :param src: Source IPv4 address to verify
750 :param dst: Destination IPv4 address to verify
752 :returns: Reassembled IPv4 packet
756 self.assertEqual(p[IP].src, src)
757 self.assertEqual(p[IP].dst, dst)
758 self.assert_ip_checksum_valid(p)
759 buffer.seek(p[IP].frag * 8)
760 buffer.write(bytes(p[IP].payload))
761 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
762 proto=frags[0][IP].proto)
763 if ip.proto == IP_PROTOS.tcp:
764 p = (ip / TCP(buffer.getvalue()))
765 self.assert_tcp_checksum_valid(p)
766 elif ip.proto == IP_PROTOS.udp:
767 p = (ip / UDP(buffer.getvalue()[:8]) /
768 Raw(buffer.getvalue()[8:]))
769 elif ip.proto == IP_PROTOS.icmp:
770 p = (ip / ICMP(buffer.getvalue()))
773 def reass_frags_and_verify_ip6(self, frags, src, dst):
775 Reassemble and verify fragmented packet
777 :param frags: Captured fragments
778 :param src: Source IPv6 address to verify
779 :param dst: Destination IPv6 address to verify
781 :returns: Reassembled IPv6 packet
785 self.assertEqual(p[IPv6].src, src)
786 self.assertEqual(p[IPv6].dst, dst)
787 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
788 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
789 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
790 nh=frags[0][IPv6ExtHdrFragment].nh)
791 if ip.nh == IP_PROTOS.tcp:
792 p = (ip / TCP(buffer.getvalue()))
793 elif ip.nh == IP_PROTOS.udp:
794 p = (ip / UDP(buffer.getvalue()))
795 self.assert_packet_checksums_valid(p)
798 def initiate_tcp_session(self, in_if, out_if):
800 Initiates TCP session
802 :param in_if: Inside interface
803 :param out_if: Outside interface
807 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
808 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
809 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
812 self.pg_enable_capture(self.pg_interfaces)
814 capture = out_if.get_capture(1)
816 self.tcp_port_out = p[TCP].sport
818 # SYN + ACK packet out->in
819 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
820 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
821 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
824 self.pg_enable_capture(self.pg_interfaces)
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 out_if.get_capture(1)
839 self.logger.error("TCP 3 way handshake failed")
842 def verify_ipfix_nat44_ses(self, data):
844 Verify IPFIX NAT44 session create/delete event
846 :param data: Decoded IPFIX data records
848 nat44_ses_create_num = 0
849 nat44_ses_delete_num = 0
850 self.assertEqual(6, len(data))
853 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
854 if scapy.compat.orb(record[230]) == 4:
855 nat44_ses_create_num += 1
857 nat44_ses_delete_num += 1
859 self.assertEqual(self.pg0.remote_ip4n, record[8])
860 # postNATSourceIPv4Address
861 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
864 self.assertEqual(struct.pack("!I", 0), record[234])
865 # protocolIdentifier/sourceTransportPort
866 # /postNAPTSourceTransportPort
867 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
868 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
869 self.assertEqual(struct.pack("!H", self.icmp_id_out),
871 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
872 self.assertEqual(struct.pack("!H", self.tcp_port_in),
874 self.assertEqual(struct.pack("!H", self.tcp_port_out),
876 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.udp_port_in),
879 self.assertEqual(struct.pack("!H", self.udp_port_out),
882 self.fail("Invalid protocol")
883 self.assertEqual(3, nat44_ses_create_num)
884 self.assertEqual(3, nat44_ses_delete_num)
886 def verify_ipfix_addr_exhausted(self, data):
888 Verify IPFIX NAT addresses event
890 :param data: Decoded IPFIX data records
892 self.assertEqual(1, len(data))
895 self.assertEqual(scapy.compat.orb(record[230]), 3)
897 self.assertEqual(struct.pack("!I", 0), record[283])
899 def verify_ipfix_max_sessions(self, data, limit):
901 Verify IPFIX maximum session entries exceeded event
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum session entries that can be created.
906 self.assertEqual(1, len(data))
909 self.assertEqual(scapy.compat.orb(record[230]), 13)
910 # natQuotaExceededEvent
911 self.assertEqual(struct.pack("I", 1), record[466])
913 self.assertEqual(struct.pack("I", limit), record[471])
915 def verify_ipfix_max_bibs(self, data, limit):
917 Verify IPFIX maximum BIB entries exceeded event
919 :param data: Decoded IPFIX data records
920 :param limit: Number of maximum BIB entries that can be created.
922 self.assertEqual(1, len(data))
925 self.assertEqual(scapy.compat.orb(record[230]), 13)
926 # natQuotaExceededEvent
927 self.assertEqual(struct.pack("I", 2), record[466])
929 self.assertEqual(struct.pack("I", limit), record[472])
931 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
933 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
935 :param data: Decoded IPFIX data records
936 :param limit: Number of maximum fragments pending reassembly
937 :param src_addr: IPv6 source address
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 5), record[466])
945 # maxFragmentsPendingReassembly
946 self.assertEqual(struct.pack("I", limit), record[475])
948 self.assertEqual(src_addr, record[27])
950 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
952 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
954 :param data: Decoded IPFIX data records
955 :param limit: Number of maximum fragments pending reassembly
956 :param src_addr: IPv4 source address
958 self.assertEqual(1, len(data))
961 self.assertEqual(scapy.compat.orb(record[230]), 13)
962 # natQuotaExceededEvent
963 self.assertEqual(struct.pack("I", 5), record[466])
964 # maxFragmentsPendingReassembly
965 self.assertEqual(struct.pack("I", limit), record[475])
967 self.assertEqual(src_addr, record[8])
969 def verify_ipfix_bib(self, data, is_create, src_addr):
971 Verify IPFIX NAT64 BIB create and delete events
973 :param data: Decoded IPFIX data records
974 :param is_create: Create event if nonzero value otherwise delete event
975 :param src_addr: IPv6 source address
977 self.assertEqual(1, len(data))
981 self.assertEqual(scapy.compat.orb(record[230]), 10)
983 self.assertEqual(scapy.compat.orb(record[230]), 11)
985 self.assertEqual(src_addr, record[27])
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
997 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1000 Verify IPFIX NAT64 session create and delete events
1002 :param data: Decoded IPFIX data records
1003 :param is_create: Create event if nonzero value otherwise delete event
1004 :param src_addr: IPv6 source address
1005 :param dst_addr: IPv4 destination address
1006 :param dst_port: destination TCP port
1008 self.assertEqual(1, len(data))
1012 self.assertEqual(scapy.compat.orb(record[230]), 6)
1014 self.assertEqual(scapy.compat.orb(record[230]), 7)
1016 self.assertEqual(src_addr, record[27])
1017 # destinationIPv6Address
1018 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1019 self.compose_ip6(dst_addr,
1023 # postNATSourceIPv4Address
1024 self.assertEqual(self.nat_addr_n, record[225])
1025 # postNATDestinationIPv4Address
1026 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1028 # protocolIdentifier
1029 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1031 self.assertEqual(struct.pack("!I", 0), record[234])
1032 # sourceTransportPort
1033 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1034 # postNAPTSourceTransportPort
1035 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1036 # destinationTransportPort
1037 self.assertEqual(struct.pack("!H", dst_port), record[11])
1038 # postNAPTDestinationTransportPort
1039 self.assertEqual(struct.pack("!H", dst_port), record[228])
1041 def verify_no_nat44_user(self):
1042 """ Verify that there is no NAT44 user """
1043 users = self.vapi.nat44_user_dump()
1044 self.assertEqual(len(users), 0)
1045 users = self.statistics.get_counter('/nat44/total-users')
1046 self.assertEqual(users[0][0], 0)
1047 sessions = self.statistics.get_counter('/nat44/total-sessions')
1048 self.assertEqual(sessions[0][0], 0)
1050 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1052 Verify IPFIX maximum entries per user exceeded event
1054 :param data: Decoded IPFIX data records
1055 :param limit: Number of maximum entries per user
1056 :param src_addr: IPv4 source address
1058 self.assertEqual(1, len(data))
1061 self.assertEqual(scapy.compat.orb(record[230]), 13)
1062 # natQuotaExceededEvent
1063 self.assertEqual(struct.pack("I", 3), record[466])
1065 self.assertEqual(struct.pack("I", limit), record[473])
1067 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1069 def verify_syslog_apmap(self, data, is_add=True):
1070 message = data.decode('utf-8')
1072 message = SyslogMessage.parse(message)
1073 except ParseError as e:
1074 self.logger.error(e)
1077 self.assertEqual(message.severity, SyslogSeverity.info)
1078 self.assertEqual(message.appname, 'NAT')
1079 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1080 sd_params = message.sd.get('napmap')
1081 self.assertTrue(sd_params is not None)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1085 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1086 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1087 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1088 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1089 self.assertTrue(sd_params.get('SSUBIX') is not None)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1092 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1093 message = data.decode('utf-8')
1095 message = SyslogMessage.parse(message)
1096 except ParseError as e:
1097 self.logger.error(e)
1100 self.assertEqual(message.severity, SyslogSeverity.info)
1101 self.assertEqual(message.appname, 'NAT')
1102 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1103 sd_params = message.sd.get('nsess')
1104 self.assertTrue(sd_params is not None)
1106 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1107 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1109 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1110 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1113 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1114 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1115 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1116 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1117 self.assertEqual(sd_params.get('SVLAN'), '0')
1118 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1119 self.assertEqual(sd_params.get('XDPORT'),
1120 "%d" % self.tcp_external_port)
1122 def verify_mss_value(self, pkt, mss):
1124 Verify TCP MSS value
1129 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1130 raise TypeError("Not a TCP/IP packet")
1132 for option in pkt[TCP].options:
1133 if option[0] == 'MSS':
1134 self.assertEqual(option[1], mss)
1135 self.assert_tcp_checksum_valid(pkt)
1138 def proto2layer(proto):
1139 if proto == IP_PROTOS.tcp:
1141 elif proto == IP_PROTOS.udp:
1143 elif proto == IP_PROTOS.icmp:
1146 raise Exception("Unsupported protocol")
1148 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1149 layer = self.proto2layer(proto)
1151 if proto == IP_PROTOS.tcp:
1152 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1154 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1155 self.port_in = random.randint(1025, 65535)
1157 reass = self.vapi.nat_reass_dump()
1158 reass_n_start = len(reass)
1161 pkts = self.create_stream_frag(self.pg0,
1162 self.pg1.remote_ip4,
1167 self.pg0.add_stream(pkts)
1168 self.pg_enable_capture(self.pg_interfaces)
1170 frags = self.pg1.get_capture(len(pkts))
1171 if not dont_translate:
1172 p = self.reass_frags_and_verify(frags,
1174 self.pg1.remote_ip4)
1176 p = self.reass_frags_and_verify(frags,
1177 self.pg0.remote_ip4,
1178 self.pg1.remote_ip4)
1179 if proto != IP_PROTOS.icmp:
1180 if not dont_translate:
1181 self.assertEqual(p[layer].dport, 20)
1182 self.assertNotEqual(p[layer].sport, self.port_in)
1184 self.assertEqual(p[layer].sport, self.port_in)
1186 if not dont_translate:
1187 self.assertNotEqual(p[layer].id, self.port_in)
1189 self.assertEqual(p[layer].id, self.port_in)
1190 self.assertEqual(data, p[Raw].load)
1193 if not dont_translate:
1194 dst_addr = self.nat_addr
1196 dst_addr = self.pg0.remote_ip4
1197 if proto != IP_PROTOS.icmp:
1199 dport = p[layer].sport
1203 pkts = self.create_stream_frag(self.pg1,
1210 self.pg1.add_stream(pkts)
1211 self.pg_enable_capture(self.pg_interfaces)
1213 frags = self.pg0.get_capture(len(pkts))
1214 p = self.reass_frags_and_verify(frags,
1215 self.pg1.remote_ip4,
1216 self.pg0.remote_ip4)
1217 if proto != IP_PROTOS.icmp:
1218 self.assertEqual(p[layer].sport, 20)
1219 self.assertEqual(p[layer].dport, self.port_in)
1221 self.assertEqual(p[layer].id, self.port_in)
1222 self.assertEqual(data, p[Raw].load)
1224 reass = self.vapi.nat_reass_dump()
1225 reass_n_end = len(reass)
1227 self.assertEqual(reass_n_end - reass_n_start, 2)
1229 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1230 layer = self.proto2layer(proto)
1232 if proto == IP_PROTOS.tcp:
1233 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1235 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1236 self.port_in = random.randint(1025, 65535)
1239 reass = self.vapi.nat_reass_dump()
1240 reass_n_start = len(reass)
1243 pkts = self.create_stream_frag(self.pg0,
1244 self.server_out_addr,
1246 self.server_out_port,
1249 self.pg0.add_stream(pkts)
1250 self.pg_enable_capture(self.pg_interfaces)
1252 frags = self.pg1.get_capture(len(pkts))
1253 p = self.reass_frags_and_verify(frags,
1254 self.pg0.remote_ip4,
1255 self.server_in_addr)
1256 if proto != IP_PROTOS.icmp:
1257 self.assertEqual(p[layer].sport, self.port_in)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1260 self.assertEqual(p[layer].id, self.port_in)
1261 self.assertEqual(data, p[Raw].load)
1264 if proto != IP_PROTOS.icmp:
1265 pkts = self.create_stream_frag(self.pg1,
1266 self.pg0.remote_ip4,
1267 self.server_in_port,
1272 pkts = self.create_stream_frag(self.pg1,
1273 self.pg0.remote_ip4,
1279 self.pg1.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg0.get_capture(len(pkts))
1283 p = self.reass_frags_and_verify(frags,
1284 self.server_out_addr,
1285 self.pg0.remote_ip4)
1286 if proto != IP_PROTOS.icmp:
1287 self.assertEqual(p[layer].sport, self.server_out_port)
1288 self.assertEqual(p[layer].dport, self.port_in)
1290 self.assertEqual(p[layer].id, self.port_in)
1291 self.assertEqual(data, p[Raw].load)
1293 reass = self.vapi.nat_reass_dump()
1294 reass_n_end = len(reass)
1296 self.assertEqual(reass_n_end - reass_n_start, 2)
1298 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1299 layer = self.proto2layer(proto)
1301 if proto == IP_PROTOS.tcp:
1302 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1304 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1306 # send packet from host to server
1307 pkts = self.create_stream_frag(self.pg0,
1310 self.server_out_port,
1313 self.pg0.add_stream(pkts)
1314 self.pg_enable_capture(self.pg_interfaces)
1316 frags = self.pg0.get_capture(len(pkts))
1317 p = self.reass_frags_and_verify(frags,
1320 if proto != IP_PROTOS.icmp:
1321 self.assertNotEqual(p[layer].sport, self.host_in_port)
1322 self.assertEqual(p[layer].dport, self.server_in_port)
1324 self.assertNotEqual(p[layer].id, self.host_in_port)
1325 self.assertEqual(data, p[Raw].load)
1327 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1328 layer = self.proto2layer(proto)
1330 if proto == IP_PROTOS.tcp:
1331 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1333 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1334 self.port_in = random.randint(1025, 65535)
1338 pkts = self.create_stream_frag(self.pg0,
1339 self.pg1.remote_ip4,
1345 self.pg0.add_stream(pkts)
1346 self.pg_enable_capture(self.pg_interfaces)
1348 frags = self.pg1.get_capture(len(pkts))
1349 if not dont_translate:
1350 p = self.reass_frags_and_verify(frags,
1352 self.pg1.remote_ip4)
1354 p = self.reass_frags_and_verify(frags,
1355 self.pg0.remote_ip4,
1356 self.pg1.remote_ip4)
1357 if proto != IP_PROTOS.icmp:
1358 if not dont_translate:
1359 self.assertEqual(p[layer].dport, 20)
1360 self.assertNotEqual(p[layer].sport, self.port_in)
1362 self.assertEqual(p[layer].sport, self.port_in)
1364 if not dont_translate:
1365 self.assertNotEqual(p[layer].id, self.port_in)
1367 self.assertEqual(p[layer].id, self.port_in)
1368 self.assertEqual(data, p[Raw].load)
1371 if not dont_translate:
1372 dst_addr = self.nat_addr
1374 dst_addr = self.pg0.remote_ip4
1375 if proto != IP_PROTOS.icmp:
1377 dport = p[layer].sport
1381 pkts = self.create_stream_frag(self.pg1,
1389 self.pg1.add_stream(pkts)
1390 self.pg_enable_capture(self.pg_interfaces)
1392 frags = self.pg0.get_capture(len(pkts))
1393 p = self.reass_frags_and_verify(frags,
1394 self.pg1.remote_ip4,
1395 self.pg0.remote_ip4)
1396 if proto != IP_PROTOS.icmp:
1397 self.assertEqual(p[layer].sport, 20)
1398 self.assertEqual(p[layer].dport, self.port_in)
1400 self.assertEqual(p[layer].id, self.port_in)
1401 self.assertEqual(data, p[Raw].load)
1403 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1404 layer = self.proto2layer(proto)
1406 if proto == IP_PROTOS.tcp:
1407 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1409 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1410 self.port_in = random.randint(1025, 65535)
1414 pkts = self.create_stream_frag(self.pg0,
1415 self.server_out_addr,
1417 self.server_out_port,
1421 self.pg0.add_stream(pkts)
1422 self.pg_enable_capture(self.pg_interfaces)
1424 frags = self.pg1.get_capture(len(pkts))
1425 p = self.reass_frags_and_verify(frags,
1426 self.pg0.remote_ip4,
1427 self.server_in_addr)
1428 if proto != IP_PROTOS.icmp:
1429 self.assertEqual(p[layer].dport, self.server_in_port)
1430 self.assertEqual(p[layer].sport, self.port_in)
1431 self.assertEqual(p[layer].dport, self.server_in_port)
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1437 if proto != IP_PROTOS.icmp:
1438 pkts = self.create_stream_frag(self.pg1,
1439 self.pg0.remote_ip4,
1440 self.server_in_port,
1445 pkts = self.create_stream_frag(self.pg1,
1446 self.pg0.remote_ip4,
1453 self.pg1.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1456 frags = self.pg0.get_capture(len(pkts))
1457 p = self.reass_frags_and_verify(frags,
1458 self.server_out_addr,
1459 self.pg0.remote_ip4)
1460 if proto != IP_PROTOS.icmp:
1461 self.assertEqual(p[layer].sport, self.server_out_port)
1462 self.assertEqual(p[layer].dport, self.port_in)
1464 self.assertEqual(p[layer].id, self.port_in)
1465 self.assertEqual(data, p[Raw].load)
1468 class TestNAT44(MethodHolder):
1469 """ NAT44 Test Cases """
1472 def setUpClass(cls):
1473 super(TestNAT44, cls).setUpClass()
1474 cls.vapi.cli("set log class nat level debug")
1477 cls.tcp_port_in = 6303
1478 cls.tcp_port_out = 6303
1479 cls.udp_port_in = 6304
1480 cls.udp_port_out = 6304
1481 cls.icmp_id_in = 6305
1482 cls.icmp_id_out = 6305
1483 cls.nat_addr = '10.0.0.3'
1484 cls.ipfix_src_port = 4739
1485 cls.ipfix_domain_id = 1
1486 cls.tcp_external_port = 80
1487 cls.udp_external_port = 69
1489 cls.create_pg_interfaces(range(10))
1490 cls.interfaces = list(cls.pg_interfaces[0:4])
1492 for i in cls.interfaces:
1497 cls.pg0.generate_remote_hosts(3)
1498 cls.pg0.configure_ipv4_neighbors()
1500 cls.pg1.generate_remote_hosts(1)
1501 cls.pg1.configure_ipv4_neighbors()
1503 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1504 cls.vapi.ip_table_add_del(is_add=1, table_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._remote_hosts[0]._ip4 = "172.16.255.2"
1509 cls.pg4.set_table_ip4(10)
1510 cls.pg5._local_ip4 = "172.17.255.3"
1511 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1512 cls.pg5.set_table_ip4(10)
1513 cls.pg6._local_ip4 = "172.16.255.1"
1514 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1515 cls.pg6.set_table_ip4(20)
1516 for i in cls.overlapping_interfaces:
1524 cls.pg9.generate_remote_hosts(2)
1525 cls.pg9.config_ip4()
1526 cls.vapi.sw_interface_add_del_address(
1527 sw_if_index=cls.pg9.sw_if_index,
1528 prefix="10.0.0.1/24")
1531 cls.pg9.resolve_arp()
1532 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1533 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1534 cls.pg9.resolve_arp()
1537 super(TestNAT44, cls).tearDownClass()
1541 def tearDownClass(cls):
1542 super(TestNAT44, cls).tearDownClass()
1544 def test_dynamic(self):
1545 """ NAT44 dynamic translation test """
1546 self.nat44_add_address(self.nat_addr)
1547 flags = self.config_flags.NAT_IS_INSIDE
1548 self.vapi.nat44_interface_add_del_feature(
1549 sw_if_index=self.pg0.sw_if_index,
1550 flags=flags, is_add=1)
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg1.sw_if_index,
1556 tcpn = self.statistics.get_err_counter(
1557 '/err/nat44-in2out-slowpath/TCP packets')
1558 udpn = self.statistics.get_err_counter(
1559 '/err/nat44-in2out-slowpath/UDP packets')
1560 icmpn = self.statistics.get_err_counter(
1561 '/err/nat44-in2out-slowpath/ICMP packets')
1562 totaln = self.statistics.get_err_counter(
1563 '/err/nat44-in2out-slowpath/good in2out packets processed')
1565 pkts = self.create_stream_in(self.pg0, self.pg1)
1566 self.pg0.add_stream(pkts)
1567 self.pg_enable_capture(self.pg_interfaces)
1569 capture = self.pg1.get_capture(len(pkts))
1570 self.verify_capture_out(capture)
1572 err = self.statistics.get_err_counter(
1573 '/err/nat44-in2out-slowpath/TCP packets')
1574 self.assertEqual(err - tcpn, 2)
1575 err = self.statistics.get_err_counter(
1576 '/err/nat44-in2out-slowpath/UDP packets')
1577 self.assertEqual(err - udpn, 1)
1578 err = self.statistics.get_err_counter(
1579 '/err/nat44-in2out-slowpath/ICMP packets')
1580 self.assertEqual(err - icmpn, 1)
1581 err = self.statistics.get_err_counter(
1582 '/err/nat44-in2out-slowpath/good in2out packets processed')
1583 self.assertEqual(err - totaln, 4)
1586 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1587 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1588 icmpn = self.statistics.get_err_counter(
1589 '/err/nat44-out2in/ICMP packets')
1590 totaln = self.statistics.get_err_counter(
1591 '/err/nat44-out2in/good out2in packets processed')
1593 pkts = self.create_stream_out(self.pg1)
1594 self.pg1.add_stream(pkts)
1595 self.pg_enable_capture(self.pg_interfaces)
1597 capture = self.pg0.get_capture(len(pkts))
1598 self.verify_capture_in(capture, self.pg0)
1600 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1601 self.assertEqual(err - tcpn, 2)
1602 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1603 self.assertEqual(err - udpn, 1)
1604 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1605 self.assertEqual(err - icmpn, 1)
1606 err = self.statistics.get_err_counter(
1607 '/err/nat44-out2in/good out2in packets processed')
1608 self.assertEqual(err - totaln, 4)
1610 users = self.statistics.get_counter('/nat44/total-users')
1611 self.assertEqual(users[0][0], 1)
1612 sessions = self.statistics.get_counter('/nat44/total-sessions')
1613 self.assertEqual(sessions[0][0], 3)
1615 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1616 """ NAT44 handling of client packets with TTL=1 """
1618 self.nat44_add_address(self.nat_addr)
1619 flags = self.config_flags.NAT_IS_INSIDE
1620 self.vapi.nat44_interface_add_del_feature(
1621 sw_if_index=self.pg0.sw_if_index,
1622 flags=flags, is_add=1)
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg1.sw_if_index,
1627 # Client side - generate traffic
1628 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1629 self.pg0.add_stream(pkts)
1630 self.pg_enable_capture(self.pg_interfaces)
1633 # Client side - verify ICMP type 11 packets
1634 capture = self.pg0.get_capture(len(pkts))
1635 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1637 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1638 """ NAT44 handling of server packets with TTL=1 """
1640 self.nat44_add_address(self.nat_addr)
1641 flags = self.config_flags.NAT_IS_INSIDE
1642 self.vapi.nat44_interface_add_del_feature(
1643 sw_if_index=self.pg0.sw_if_index,
1644 flags=flags, is_add=1)
1645 self.vapi.nat44_interface_add_del_feature(
1646 sw_if_index=self.pg1.sw_if_index,
1649 # Client side - create sessions
1650 pkts = self.create_stream_in(self.pg0, self.pg1)
1651 self.pg0.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1655 # Server side - generate traffic
1656 capture = self.pg1.get_capture(len(pkts))
1657 self.verify_capture_out(capture)
1658 pkts = self.create_stream_out(self.pg1, ttl=1)
1659 self.pg1.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1663 # Server side - verify ICMP type 11 packets
1664 capture = self.pg1.get_capture(len(pkts))
1665 self.verify_capture_out_with_icmp_errors(capture,
1666 src_ip=self.pg1.local_ip4)
1668 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1669 """ NAT44 handling of error responses to client packets with TTL=2 """
1671 self.nat44_add_address(self.nat_addr)
1672 flags = self.config_flags.NAT_IS_INSIDE
1673 self.vapi.nat44_interface_add_del_feature(
1674 sw_if_index=self.pg0.sw_if_index,
1675 flags=flags, is_add=1)
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg1.sw_if_index,
1680 # Client side - generate traffic
1681 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1682 self.pg0.add_stream(pkts)
1683 self.pg_enable_capture(self.pg_interfaces)
1686 # Server side - simulate ICMP type 11 response
1687 capture = self.pg1.get_capture(len(pkts))
1688 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1689 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1690 ICMP(type=11) / packet[IP] for packet in capture]
1691 self.pg1.add_stream(pkts)
1692 self.pg_enable_capture(self.pg_interfaces)
1695 # Client side - verify ICMP type 11 packets
1696 capture = self.pg0.get_capture(len(pkts))
1697 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1699 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1700 """ NAT44 handling of error responses to server packets with TTL=2 """
1702 self.nat44_add_address(self.nat_addr)
1703 flags = self.config_flags.NAT_IS_INSIDE
1704 self.vapi.nat44_interface_add_del_feature(
1705 sw_if_index=self.pg0.sw_if_index,
1706 flags=flags, is_add=1)
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg1.sw_if_index,
1711 # Client side - create sessions
1712 pkts = self.create_stream_in(self.pg0, self.pg1)
1713 self.pg0.add_stream(pkts)
1714 self.pg_enable_capture(self.pg_interfaces)
1717 # Server side - generate traffic
1718 capture = self.pg1.get_capture(len(pkts))
1719 self.verify_capture_out(capture)
1720 pkts = self.create_stream_out(self.pg1, ttl=2)
1721 self.pg1.add_stream(pkts)
1722 self.pg_enable_capture(self.pg_interfaces)
1725 # Client side - simulate ICMP type 11 response
1726 capture = self.pg0.get_capture(len(pkts))
1727 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1728 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1729 ICMP(type=11) / packet[IP] for packet in capture]
1730 self.pg0.add_stream(pkts)
1731 self.pg_enable_capture(self.pg_interfaces)
1734 # Server side - verify ICMP type 11 packets
1735 capture = self.pg1.get_capture(len(pkts))
1736 self.verify_capture_out_with_icmp_errors(capture)
1738 def test_ping_out_interface_from_outside(self):
1739 """ Ping NAT44 out interface from outside network """
1741 self.nat44_add_address(self.nat_addr)
1742 flags = self.config_flags.NAT_IS_INSIDE
1743 self.vapi.nat44_interface_add_del_feature(
1744 sw_if_index=self.pg0.sw_if_index,
1745 flags=flags, is_add=1)
1746 self.vapi.nat44_interface_add_del_feature(
1747 sw_if_index=self.pg1.sw_if_index,
1750 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1751 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1752 ICMP(id=self.icmp_id_out, type='echo-request'))
1754 self.pg1.add_stream(pkts)
1755 self.pg_enable_capture(self.pg_interfaces)
1757 capture = self.pg1.get_capture(len(pkts))
1760 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1761 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1762 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1763 self.assertEqual(packet[ICMP].type, 0) # echo reply
1765 self.logger.error(ppp("Unexpected or invalid packet "
1766 "(outside network):", packet))
1769 def test_ping_internal_host_from_outside(self):
1770 """ Ping internal host from outside network """
1772 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1773 flags = self.config_flags.NAT_IS_INSIDE
1774 self.vapi.nat44_interface_add_del_feature(
1775 sw_if_index=self.pg0.sw_if_index,
1776 flags=flags, is_add=1)
1777 self.vapi.nat44_interface_add_del_feature(
1778 sw_if_index=self.pg1.sw_if_index,
1782 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1783 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1784 ICMP(id=self.icmp_id_out, type='echo-request'))
1785 self.pg1.add_stream(pkt)
1786 self.pg_enable_capture(self.pg_interfaces)
1788 capture = self.pg0.get_capture(1)
1789 self.verify_capture_in(capture, self.pg0)
1790 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1793 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1794 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1795 ICMP(id=self.icmp_id_in, type='echo-reply'))
1796 self.pg0.add_stream(pkt)
1797 self.pg_enable_capture(self.pg_interfaces)
1799 capture = self.pg1.get_capture(1)
1800 self.verify_capture_out(capture, same_port=True)
1801 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1803 def test_forwarding(self):
1804 """ NAT44 forwarding test """
1806 flags = self.config_flags.NAT_IS_INSIDE
1807 self.vapi.nat44_interface_add_del_feature(
1808 sw_if_index=self.pg0.sw_if_index,
1809 flags=flags, is_add=1)
1810 self.vapi.nat44_interface_add_del_feature(
1811 sw_if_index=self.pg1.sw_if_index,
1813 self.vapi.nat44_forwarding_enable_disable(enable=1)
1815 real_ip = self.pg0.remote_ip4
1816 alias_ip = self.nat_addr
1817 flags = self.config_flags.NAT_IS_ADDR_ONLY
1818 self.vapi.nat44_add_del_static_mapping(is_add=1,
1819 local_ip_address=real_ip,
1820 external_ip_address=alias_ip,
1821 external_sw_if_index=0xFFFFFFFF,
1825 # static mapping match
1827 pkts = self.create_stream_out(self.pg1)
1828 self.pg1.add_stream(pkts)
1829 self.pg_enable_capture(self.pg_interfaces)
1831 capture = self.pg0.get_capture(len(pkts))
1832 self.verify_capture_in(capture, self.pg0)
1834 pkts = self.create_stream_in(self.pg0, self.pg1)
1835 self.pg0.add_stream(pkts)
1836 self.pg_enable_capture(self.pg_interfaces)
1838 capture = self.pg1.get_capture(len(pkts))
1839 self.verify_capture_out(capture, same_port=True)
1841 # no static mapping match
1843 host0 = self.pg0.remote_hosts[0]
1844 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1846 pkts = self.create_stream_out(self.pg1,
1847 dst_ip=self.pg0.remote_ip4,
1848 use_inside_ports=True)
1849 self.pg1.add_stream(pkts)
1850 self.pg_enable_capture(self.pg_interfaces)
1852 capture = self.pg0.get_capture(len(pkts))
1853 self.verify_capture_in(capture, self.pg0)
1855 pkts = self.create_stream_in(self.pg0, self.pg1)
1856 self.pg0.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1859 capture = self.pg1.get_capture(len(pkts))
1860 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1863 self.pg0.remote_hosts[0] = host0
1866 self.vapi.nat44_forwarding_enable_disable(enable=0)
1867 flags = self.config_flags.NAT_IS_ADDR_ONLY
1868 self.vapi.nat44_add_del_static_mapping(
1870 local_ip_address=real_ip,
1871 external_ip_address=alias_ip,
1872 external_sw_if_index=0xFFFFFFFF,
1875 def test_static_in(self):
1876 """ 1:1 NAT initialized from inside network """
1878 nat_ip = "10.0.0.10"
1879 self.tcp_port_out = 6303
1880 self.udp_port_out = 6304
1881 self.icmp_id_out = 6305
1883 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1884 flags = self.config_flags.NAT_IS_INSIDE
1885 self.vapi.nat44_interface_add_del_feature(
1886 sw_if_index=self.pg0.sw_if_index,
1887 flags=flags, is_add=1)
1888 self.vapi.nat44_interface_add_del_feature(
1889 sw_if_index=self.pg1.sw_if_index,
1891 sm = self.vapi.nat44_static_mapping_dump()
1892 self.assertEqual(len(sm), 1)
1893 self.assertEqual(sm[0].tag, '')
1894 self.assertEqual(sm[0].protocol, 0)
1895 self.assertEqual(sm[0].local_port, 0)
1896 self.assertEqual(sm[0].external_port, 0)
1899 pkts = self.create_stream_in(self.pg0, self.pg1)
1900 self.pg0.add_stream(pkts)
1901 self.pg_enable_capture(self.pg_interfaces)
1903 capture = self.pg1.get_capture(len(pkts))
1904 self.verify_capture_out(capture, nat_ip, True)
1907 pkts = self.create_stream_out(self.pg1, nat_ip)
1908 self.pg1.add_stream(pkts)
1909 self.pg_enable_capture(self.pg_interfaces)
1911 capture = self.pg0.get_capture(len(pkts))
1912 self.verify_capture_in(capture, self.pg0)
1914 def test_static_out(self):
1915 """ 1:1 NAT initialized from outside network """
1917 nat_ip = "10.0.0.20"
1918 self.tcp_port_out = 6303
1919 self.udp_port_out = 6304
1920 self.icmp_id_out = 6305
1923 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1924 flags = self.config_flags.NAT_IS_INSIDE
1925 self.vapi.nat44_interface_add_del_feature(
1926 sw_if_index=self.pg0.sw_if_index,
1927 flags=flags, is_add=1)
1928 self.vapi.nat44_interface_add_del_feature(
1929 sw_if_index=self.pg1.sw_if_index,
1931 sm = self.vapi.nat44_static_mapping_dump()
1932 self.assertEqual(len(sm), 1)
1933 self.assertEqual(sm[0].tag, tag)
1936 pkts = self.create_stream_out(self.pg1, nat_ip)
1937 self.pg1.add_stream(pkts)
1938 self.pg_enable_capture(self.pg_interfaces)
1940 capture = self.pg0.get_capture(len(pkts))
1941 self.verify_capture_in(capture, self.pg0)
1944 pkts = self.create_stream_in(self.pg0, self.pg1)
1945 self.pg0.add_stream(pkts)
1946 self.pg_enable_capture(self.pg_interfaces)
1948 capture = self.pg1.get_capture(len(pkts))
1949 self.verify_capture_out(capture, nat_ip, True)
1951 def test_static_with_port_in(self):
1952 """ 1:1 NAPT initialized from inside network """
1954 self.tcp_port_out = 3606
1955 self.udp_port_out = 3607
1956 self.icmp_id_out = 3608
1958 self.nat44_add_address(self.nat_addr)
1959 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1960 self.tcp_port_in, self.tcp_port_out,
1961 proto=IP_PROTOS.tcp)
1962 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1963 self.udp_port_in, self.udp_port_out,
1964 proto=IP_PROTOS.udp)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.icmp_id_in, self.icmp_id_out,
1967 proto=IP_PROTOS.icmp)
1968 flags = self.config_flags.NAT_IS_INSIDE
1969 self.vapi.nat44_interface_add_del_feature(
1970 sw_if_index=self.pg0.sw_if_index,
1971 flags=flags, is_add=1)
1972 self.vapi.nat44_interface_add_del_feature(
1973 sw_if_index=self.pg1.sw_if_index,
1977 pkts = self.create_stream_in(self.pg0, self.pg1)
1978 self.pg0.add_stream(pkts)
1979 self.pg_enable_capture(self.pg_interfaces)
1981 capture = self.pg1.get_capture(len(pkts))
1982 self.verify_capture_out(capture)
1985 pkts = self.create_stream_out(self.pg1)
1986 self.pg1.add_stream(pkts)
1987 self.pg_enable_capture(self.pg_interfaces)
1989 capture = self.pg0.get_capture(len(pkts))
1990 self.verify_capture_in(capture, self.pg0)
1992 def test_static_with_port_out(self):
1993 """ 1:1 NAPT initialized from outside network """
1995 self.tcp_port_out = 30606
1996 self.udp_port_out = 30607
1997 self.icmp_id_out = 30608
1999 self.nat44_add_address(self.nat_addr)
2000 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2001 self.tcp_port_in, self.tcp_port_out,
2002 proto=IP_PROTOS.tcp)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2004 self.udp_port_in, self.udp_port_out,
2005 proto=IP_PROTOS.udp)
2006 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2007 self.icmp_id_in, self.icmp_id_out,
2008 proto=IP_PROTOS.icmp)
2009 flags = self.config_flags.NAT_IS_INSIDE
2010 self.vapi.nat44_interface_add_del_feature(
2011 sw_if_index=self.pg0.sw_if_index,
2012 flags=flags, is_add=1)
2013 self.vapi.nat44_interface_add_del_feature(
2014 sw_if_index=self.pg1.sw_if_index,
2018 pkts = self.create_stream_out(self.pg1)
2019 self.pg1.add_stream(pkts)
2020 self.pg_enable_capture(self.pg_interfaces)
2022 capture = self.pg0.get_capture(len(pkts))
2023 self.verify_capture_in(capture, self.pg0)
2026 pkts = self.create_stream_in(self.pg0, self.pg1)
2027 self.pg0.add_stream(pkts)
2028 self.pg_enable_capture(self.pg_interfaces)
2030 capture = self.pg1.get_capture(len(pkts))
2031 self.verify_capture_out(capture)
2033 def test_static_vrf_aware(self):
2034 """ 1:1 NAT VRF awareness """
2036 nat_ip1 = "10.0.0.30"
2037 nat_ip2 = "10.0.0.40"
2038 self.tcp_port_out = 6303
2039 self.udp_port_out = 6304
2040 self.icmp_id_out = 6305
2042 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2044 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2046 flags = self.config_flags.NAT_IS_INSIDE
2047 self.vapi.nat44_interface_add_del_feature(
2048 sw_if_index=self.pg3.sw_if_index,
2050 self.vapi.nat44_interface_add_del_feature(
2051 sw_if_index=self.pg0.sw_if_index,
2052 flags=flags, is_add=1)
2053 self.vapi.nat44_interface_add_del_feature(
2054 sw_if_index=self.pg4.sw_if_index,
2055 flags=flags, is_add=1)
2057 # inside interface VRF match NAT44 static mapping VRF
2058 pkts = self.create_stream_in(self.pg4, self.pg3)
2059 self.pg4.add_stream(pkts)
2060 self.pg_enable_capture(self.pg_interfaces)
2062 capture = self.pg3.get_capture(len(pkts))
2063 self.verify_capture_out(capture, nat_ip1, True)
2065 # inside interface VRF don't match NAT44 static mapping VRF (packets
2067 pkts = self.create_stream_in(self.pg0, self.pg3)
2068 self.pg0.add_stream(pkts)
2069 self.pg_enable_capture(self.pg_interfaces)
2071 self.pg3.assert_nothing_captured()
2073 def test_dynamic_to_static(self):
2074 """ Switch from dynamic translation to 1:1NAT """
2075 nat_ip = "10.0.0.10"
2076 self.tcp_port_out = 6303
2077 self.udp_port_out = 6304
2078 self.icmp_id_out = 6305
2080 self.nat44_add_address(self.nat_addr)
2081 flags = self.config_flags.NAT_IS_INSIDE
2082 self.vapi.nat44_interface_add_del_feature(
2083 sw_if_index=self.pg0.sw_if_index,
2084 flags=flags, is_add=1)
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg1.sw_if_index,
2090 pkts = self.create_stream_in(self.pg0, self.pg1)
2091 self.pg0.add_stream(pkts)
2092 self.pg_enable_capture(self.pg_interfaces)
2094 capture = self.pg1.get_capture(len(pkts))
2095 self.verify_capture_out(capture)
2098 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2099 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2100 self.assertEqual(len(sessions), 0)
2101 pkts = self.create_stream_in(self.pg0, self.pg1)
2102 self.pg0.add_stream(pkts)
2103 self.pg_enable_capture(self.pg_interfaces)
2105 capture = self.pg1.get_capture(len(pkts))
2106 self.verify_capture_out(capture, nat_ip, True)
2108 def test_identity_nat(self):
2109 """ Identity NAT """
2110 flags = self.config_flags.NAT_IS_ADDR_ONLY
2111 self.vapi.nat44_add_del_identity_mapping(
2112 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2113 flags=flags, is_add=1)
2114 flags = self.config_flags.NAT_IS_INSIDE
2115 self.vapi.nat44_interface_add_del_feature(
2116 sw_if_index=self.pg0.sw_if_index,
2117 flags=flags, is_add=1)
2118 self.vapi.nat44_interface_add_del_feature(
2119 sw_if_index=self.pg1.sw_if_index,
2122 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2123 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2124 TCP(sport=12345, dport=56789))
2125 self.pg1.add_stream(p)
2126 self.pg_enable_capture(self.pg_interfaces)
2128 capture = self.pg0.get_capture(1)
2133 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2134 self.assertEqual(ip.src, self.pg1.remote_ip4)
2135 self.assertEqual(tcp.dport, 56789)
2136 self.assertEqual(tcp.sport, 12345)
2137 self.assert_packet_checksums_valid(p)
2139 self.logger.error(ppp("Unexpected or invalid packet:", p))
2142 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2143 self.assertEqual(len(sessions), 0)
2144 flags = self.config_flags.NAT_IS_ADDR_ONLY
2145 self.vapi.nat44_add_del_identity_mapping(
2146 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2147 flags=flags, vrf_id=1, is_add=1)
2148 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2149 self.assertEqual(len(identity_mappings), 2)
2151 def test_multiple_inside_interfaces(self):
2152 """ NAT44 multiple non-overlapping address space inside interfaces """
2154 self.nat44_add_address(self.nat_addr)
2155 flags = self.config_flags.NAT_IS_INSIDE
2156 self.vapi.nat44_interface_add_del_feature(
2157 sw_if_index=self.pg0.sw_if_index,
2158 flags=flags, is_add=1)
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg1.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg3.sw_if_index,
2166 # between two NAT44 inside interfaces (no translation)
2167 pkts = self.create_stream_in(self.pg0, self.pg1)
2168 self.pg0.add_stream(pkts)
2169 self.pg_enable_capture(self.pg_interfaces)
2171 capture = self.pg1.get_capture(len(pkts))
2172 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2174 # from NAT44 inside to interface without NAT44 feature (no translation)
2175 pkts = self.create_stream_in(self.pg0, self.pg2)
2176 self.pg0.add_stream(pkts)
2177 self.pg_enable_capture(self.pg_interfaces)
2179 capture = self.pg2.get_capture(len(pkts))
2180 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2182 # in2out 1st interface
2183 pkts = self.create_stream_in(self.pg0, self.pg3)
2184 self.pg0.add_stream(pkts)
2185 self.pg_enable_capture(self.pg_interfaces)
2187 capture = self.pg3.get_capture(len(pkts))
2188 self.verify_capture_out(capture)
2190 # out2in 1st interface
2191 pkts = self.create_stream_out(self.pg3)
2192 self.pg3.add_stream(pkts)
2193 self.pg_enable_capture(self.pg_interfaces)
2195 capture = self.pg0.get_capture(len(pkts))
2196 self.verify_capture_in(capture, self.pg0)
2198 # in2out 2nd interface
2199 pkts = self.create_stream_in(self.pg1, self.pg3)
2200 self.pg1.add_stream(pkts)
2201 self.pg_enable_capture(self.pg_interfaces)
2203 capture = self.pg3.get_capture(len(pkts))
2204 self.verify_capture_out(capture)
2206 # out2in 2nd interface
2207 pkts = self.create_stream_out(self.pg3)
2208 self.pg3.add_stream(pkts)
2209 self.pg_enable_capture(self.pg_interfaces)
2211 capture = self.pg1.get_capture(len(pkts))
2212 self.verify_capture_in(capture, self.pg1)
2214 def test_inside_overlapping_interfaces(self):
2215 """ NAT44 multiple inside interfaces with overlapping address space """
2217 static_nat_ip = "10.0.0.10"
2218 self.nat44_add_address(self.nat_addr)
2219 flags = self.config_flags.NAT_IS_INSIDE
2220 self.vapi.nat44_interface_add_del_feature(
2221 sw_if_index=self.pg3.sw_if_index,
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg4.sw_if_index,
2225 flags=flags, is_add=1)
2226 self.vapi.nat44_interface_add_del_feature(
2227 sw_if_index=self.pg5.sw_if_index,
2228 flags=flags, is_add=1)
2229 self.vapi.nat44_interface_add_del_feature(
2230 sw_if_index=self.pg6.sw_if_index,
2231 flags=flags, is_add=1)
2232 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2235 # between NAT44 inside interfaces with same VRF (no translation)
2236 pkts = self.create_stream_in(self.pg4, self.pg5)
2237 self.pg4.add_stream(pkts)
2238 self.pg_enable_capture(self.pg_interfaces)
2240 capture = self.pg5.get_capture(len(pkts))
2241 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2243 # between NAT44 inside interfaces with different VRF (hairpinning)
2244 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2245 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2246 TCP(sport=1234, dport=5678))
2247 self.pg4.add_stream(p)
2248 self.pg_enable_capture(self.pg_interfaces)
2250 capture = self.pg6.get_capture(1)
2255 self.assertEqual(ip.src, self.nat_addr)
2256 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2257 self.assertNotEqual(tcp.sport, 1234)
2258 self.assertEqual(tcp.dport, 5678)
2260 self.logger.error(ppp("Unexpected or invalid packet:", p))
2263 # in2out 1st interface
2264 pkts = self.create_stream_in(self.pg4, self.pg3)
2265 self.pg4.add_stream(pkts)
2266 self.pg_enable_capture(self.pg_interfaces)
2268 capture = self.pg3.get_capture(len(pkts))
2269 self.verify_capture_out(capture)
2271 # out2in 1st interface
2272 pkts = self.create_stream_out(self.pg3)
2273 self.pg3.add_stream(pkts)
2274 self.pg_enable_capture(self.pg_interfaces)
2276 capture = self.pg4.get_capture(len(pkts))
2277 self.verify_capture_in(capture, self.pg4)
2279 # in2out 2nd interface
2280 pkts = self.create_stream_in(self.pg5, self.pg3)
2281 self.pg5.add_stream(pkts)
2282 self.pg_enable_capture(self.pg_interfaces)
2284 capture = self.pg3.get_capture(len(pkts))
2285 self.verify_capture_out(capture)
2287 # out2in 2nd interface
2288 pkts = self.create_stream_out(self.pg3)
2289 self.pg3.add_stream(pkts)
2290 self.pg_enable_capture(self.pg_interfaces)
2292 capture = self.pg5.get_capture(len(pkts))
2293 self.verify_capture_in(capture, self.pg5)
2296 addresses = self.vapi.nat44_address_dump()
2297 self.assertEqual(len(addresses), 1)
2298 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2299 self.assertEqual(len(sessions), 3)
2300 for session in sessions:
2301 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2302 self.assertEqual(str(session.inside_ip_address),
2303 self.pg5.remote_ip4)
2304 self.assertEqual(session.outside_ip_address,
2305 addresses[0].ip_address)
2306 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2307 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2308 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2309 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2310 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2311 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2312 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2313 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2314 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2316 # in2out 3rd interface
2317 pkts = self.create_stream_in(self.pg6, self.pg3)
2318 self.pg6.add_stream(pkts)
2319 self.pg_enable_capture(self.pg_interfaces)
2321 capture = self.pg3.get_capture(len(pkts))
2322 self.verify_capture_out(capture, static_nat_ip, True)
2324 # out2in 3rd interface
2325 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2326 self.pg3.add_stream(pkts)
2327 self.pg_enable_capture(self.pg_interfaces)
2329 capture = self.pg6.get_capture(len(pkts))
2330 self.verify_capture_in(capture, self.pg6)
2332 # general user and session dump verifications
2333 users = self.vapi.nat44_user_dump()
2334 self.assertGreaterEqual(len(users), 3)
2335 addresses = self.vapi.nat44_address_dump()
2336 self.assertEqual(len(addresses), 1)
2338 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2340 for session in sessions:
2341 self.assertEqual(user.ip_address, session.inside_ip_address)
2342 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2343 self.assertTrue(session.protocol in
2344 [IP_PROTOS.tcp, IP_PROTOS.udp,
2346 self.assertFalse(session.flags &
2347 self.config_flags.NAT_IS_EXT_HOST_VALID)
2350 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2351 self.assertGreaterEqual(len(sessions), 4)
2352 for session in sessions:
2353 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2354 self.assertEqual(str(session.inside_ip_address),
2355 self.pg4.remote_ip4)
2356 self.assertEqual(session.outside_ip_address,
2357 addresses[0].ip_address)
2360 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2361 self.assertGreaterEqual(len(sessions), 3)
2362 for session in sessions:
2363 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2364 self.assertEqual(str(session.inside_ip_address),
2365 self.pg6.remote_ip4)
2366 self.assertEqual(str(session.outside_ip_address),
2368 self.assertTrue(session.inside_port in
2369 [self.tcp_port_in, self.udp_port_in,
2372 def test_hairpinning(self):
2373 """ NAT44 hairpinning - 1:1 NAPT """
2375 host = self.pg0.remote_hosts[0]
2376 server = self.pg0.remote_hosts[1]
2379 server_in_port = 5678
2380 server_out_port = 8765
2382 self.nat44_add_address(self.nat_addr)
2383 flags = self.config_flags.NAT_IS_INSIDE
2384 self.vapi.nat44_interface_add_del_feature(
2385 sw_if_index=self.pg0.sw_if_index,
2386 flags=flags, is_add=1)
2387 self.vapi.nat44_interface_add_del_feature(
2388 sw_if_index=self.pg1.sw_if_index,
2391 # add static mapping for server
2392 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2393 server_in_port, server_out_port,
2394 proto=IP_PROTOS.tcp)
2396 # send packet from host to server
2397 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2398 IP(src=host.ip4, dst=self.nat_addr) /
2399 TCP(sport=host_in_port, dport=server_out_port))
2400 self.pg0.add_stream(p)
2401 self.pg_enable_capture(self.pg_interfaces)
2403 capture = self.pg0.get_capture(1)
2408 self.assertEqual(ip.src, self.nat_addr)
2409 self.assertEqual(ip.dst, server.ip4)
2410 self.assertNotEqual(tcp.sport, host_in_port)
2411 self.assertEqual(tcp.dport, server_in_port)
2412 self.assert_packet_checksums_valid(p)
2413 host_out_port = tcp.sport
2415 self.logger.error(ppp("Unexpected or invalid packet:", p))
2418 # send reply from server to host
2419 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2420 IP(src=server.ip4, dst=self.nat_addr) /
2421 TCP(sport=server_in_port, dport=host_out_port))
2422 self.pg0.add_stream(p)
2423 self.pg_enable_capture(self.pg_interfaces)
2425 capture = self.pg0.get_capture(1)
2430 self.assertEqual(ip.src, self.nat_addr)
2431 self.assertEqual(ip.dst, host.ip4)
2432 self.assertEqual(tcp.sport, server_out_port)
2433 self.assertEqual(tcp.dport, host_in_port)
2434 self.assert_packet_checksums_valid(p)
2436 self.logger.error(ppp("Unexpected or invalid packet:", p))
2439 def test_hairpinning2(self):
2440 """ NAT44 hairpinning - 1:1 NAT"""
2442 server1_nat_ip = "10.0.0.10"
2443 server2_nat_ip = "10.0.0.11"
2444 host = self.pg0.remote_hosts[0]
2445 server1 = self.pg0.remote_hosts[1]
2446 server2 = self.pg0.remote_hosts[2]
2447 server_tcp_port = 22
2448 server_udp_port = 20
2450 self.nat44_add_address(self.nat_addr)
2451 flags = self.config_flags.NAT_IS_INSIDE
2452 self.vapi.nat44_interface_add_del_feature(
2453 sw_if_index=self.pg0.sw_if_index,
2454 flags=flags, is_add=1)
2455 self.vapi.nat44_interface_add_del_feature(
2456 sw_if_index=self.pg1.sw_if_index,
2459 # add static mapping for servers
2460 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2461 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2466 IP(src=host.ip4, dst=server1_nat_ip) /
2467 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=host.ip4, dst=server1_nat_ip) /
2471 UDP(sport=self.udp_port_in, dport=server_udp_port))
2473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2474 IP(src=host.ip4, dst=server1_nat_ip) /
2475 ICMP(id=self.icmp_id_in, type='echo-request'))
2477 self.pg0.add_stream(pkts)
2478 self.pg_enable_capture(self.pg_interfaces)
2480 capture = self.pg0.get_capture(len(pkts))
2481 for packet in capture:
2483 self.assertEqual(packet[IP].src, self.nat_addr)
2484 self.assertEqual(packet[IP].dst, server1.ip4)
2485 if packet.haslayer(TCP):
2486 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2487 self.assertEqual(packet[TCP].dport, server_tcp_port)
2488 self.tcp_port_out = packet[TCP].sport
2489 self.assert_packet_checksums_valid(packet)
2490 elif packet.haslayer(UDP):
2491 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2492 self.assertEqual(packet[UDP].dport, server_udp_port)
2493 self.udp_port_out = packet[UDP].sport
2495 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2496 self.icmp_id_out = packet[ICMP].id
2498 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2503 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2504 IP(src=server1.ip4, dst=self.nat_addr) /
2505 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server1.ip4, dst=self.nat_addr) /
2509 UDP(sport=server_udp_port, dport=self.udp_port_out))
2511 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2512 IP(src=server1.ip4, dst=self.nat_addr) /
2513 ICMP(id=self.icmp_id_out, type='echo-reply'))
2515 self.pg0.add_stream(pkts)
2516 self.pg_enable_capture(self.pg_interfaces)
2518 capture = self.pg0.get_capture(len(pkts))
2519 for packet in capture:
2521 self.assertEqual(packet[IP].src, server1_nat_ip)
2522 self.assertEqual(packet[IP].dst, host.ip4)
2523 if packet.haslayer(TCP):
2524 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2525 self.assertEqual(packet[TCP].sport, server_tcp_port)
2526 self.assert_packet_checksums_valid(packet)
2527 elif packet.haslayer(UDP):
2528 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2529 self.assertEqual(packet[UDP].sport, server_udp_port)
2531 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2533 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2536 # server2 to server1
2538 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2539 IP(src=server2.ip4, dst=server1_nat_ip) /
2540 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2542 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2543 IP(src=server2.ip4, dst=server1_nat_ip) /
2544 UDP(sport=self.udp_port_in, dport=server_udp_port))
2546 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2547 IP(src=server2.ip4, dst=server1_nat_ip) /
2548 ICMP(id=self.icmp_id_in, type='echo-request'))
2550 self.pg0.add_stream(pkts)
2551 self.pg_enable_capture(self.pg_interfaces)
2553 capture = self.pg0.get_capture(len(pkts))
2554 for packet in capture:
2556 self.assertEqual(packet[IP].src, server2_nat_ip)
2557 self.assertEqual(packet[IP].dst, server1.ip4)
2558 if packet.haslayer(TCP):
2559 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2560 self.assertEqual(packet[TCP].dport, server_tcp_port)
2561 self.tcp_port_out = packet[TCP].sport
2562 self.assert_packet_checksums_valid(packet)
2563 elif packet.haslayer(UDP):
2564 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2565 self.assertEqual(packet[UDP].dport, server_udp_port)
2566 self.udp_port_out = packet[UDP].sport
2568 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2569 self.icmp_id_out = packet[ICMP].id
2571 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2574 # server1 to server2
2576 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2577 IP(src=server1.ip4, dst=server2_nat_ip) /
2578 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2581 IP(src=server1.ip4, dst=server2_nat_ip) /
2582 UDP(sport=server_udp_port, dport=self.udp_port_out))
2584 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2585 IP(src=server1.ip4, dst=server2_nat_ip) /
2586 ICMP(id=self.icmp_id_out, type='echo-reply'))
2588 self.pg0.add_stream(pkts)
2589 self.pg_enable_capture(self.pg_interfaces)
2591 capture = self.pg0.get_capture(len(pkts))
2592 for packet in capture:
2594 self.assertEqual(packet[IP].src, server1_nat_ip)
2595 self.assertEqual(packet[IP].dst, server2.ip4)
2596 if packet.haslayer(TCP):
2597 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2598 self.assertEqual(packet[TCP].sport, server_tcp_port)
2599 self.assert_packet_checksums_valid(packet)
2600 elif packet.haslayer(UDP):
2601 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2602 self.assertEqual(packet[UDP].sport, server_udp_port)
2604 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2606 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2609 def test_max_translations_per_user(self):
2610 """ MAX translations per user - recycle the least recently used """
2612 self.nat44_add_address(self.nat_addr)
2613 flags = self.config_flags.NAT_IS_INSIDE
2614 self.vapi.nat44_interface_add_del_feature(
2615 sw_if_index=self.pg0.sw_if_index,
2616 flags=flags, is_add=1)
2617 self.vapi.nat44_interface_add_del_feature(
2618 sw_if_index=self.pg1.sw_if_index,
2621 # get maximum number of translations per user
2622 nat44_config = self.vapi.nat_show_config()
2624 # send more than maximum number of translations per user packets
2625 pkts_num = nat44_config.max_translations_per_user + 5
2627 for port in range(0, pkts_num):
2628 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2629 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2630 TCP(sport=1025 + port))
2632 self.pg0.add_stream(pkts)
2633 self.pg_enable_capture(self.pg_interfaces)
2636 # verify number of translated packet
2637 self.pg1.get_capture(pkts_num)
2639 users = self.vapi.nat44_user_dump()
2641 if user.ip_address == self.pg0.remote_ip4:
2642 self.assertEqual(user.nsessions,
2643 nat44_config.max_translations_per_user)
2644 self.assertEqual(user.nstaticsessions, 0)
2647 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2649 proto=IP_PROTOS.tcp)
2650 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2651 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2652 TCP(sport=tcp_port))
2653 self.pg0.add_stream(p)
2654 self.pg_enable_capture(self.pg_interfaces)
2656 self.pg1.get_capture(1)
2657 users = self.vapi.nat44_user_dump()
2659 if user.ip_address == self.pg0.remote_ip4:
2660 self.assertEqual(user.nsessions,
2661 nat44_config.max_translations_per_user - 1)
2662 self.assertEqual(user.nstaticsessions, 1)
2664 def test_interface_addr(self):
2665 """ Acquire NAT44 addresses from interface """
2666 self.vapi.nat44_add_del_interface_addr(
2668 sw_if_index=self.pg7.sw_if_index)
2670 # no address in NAT pool
2671 addresses = self.vapi.nat44_address_dump()
2672 self.assertEqual(0, len(addresses))
2674 # configure interface address and check NAT address pool
2675 self.pg7.config_ip4()
2676 addresses = self.vapi.nat44_address_dump()
2677 self.assertEqual(1, len(addresses))
2678 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2680 # remove interface address and check NAT address pool
2681 self.pg7.unconfig_ip4()
2682 addresses = self.vapi.nat44_address_dump()
2683 self.assertEqual(0, len(addresses))
2685 def test_interface_addr_static_mapping(self):
2686 """ Static mapping with addresses from interface """
2689 self.vapi.nat44_add_del_interface_addr(
2691 sw_if_index=self.pg7.sw_if_index)
2692 self.nat44_add_static_mapping(
2694 external_sw_if_index=self.pg7.sw_if_index,
2697 # static mappings with external interface
2698 static_mappings = self.vapi.nat44_static_mapping_dump()
2699 self.assertEqual(1, len(static_mappings))
2700 self.assertEqual(self.pg7.sw_if_index,
2701 static_mappings[0].external_sw_if_index)
2702 self.assertEqual(static_mappings[0].tag, tag)
2704 # configure interface address and check static mappings
2705 self.pg7.config_ip4()
2706 static_mappings = self.vapi.nat44_static_mapping_dump()
2707 self.assertEqual(2, len(static_mappings))
2709 for sm in static_mappings:
2710 if sm.external_sw_if_index == 0xFFFFFFFF:
2711 self.assertEqual(str(sm.external_ip_address),
2713 self.assertEqual(sm.tag, tag)
2715 self.assertTrue(resolved)
2717 # remove interface address and check static mappings
2718 self.pg7.unconfig_ip4()
2719 static_mappings = self.vapi.nat44_static_mapping_dump()
2720 self.assertEqual(1, len(static_mappings))
2721 self.assertEqual(self.pg7.sw_if_index,
2722 static_mappings[0].external_sw_if_index)
2723 self.assertEqual(static_mappings[0].tag, tag)
2725 # configure interface address again and check static mappings
2726 self.pg7.config_ip4()
2727 static_mappings = self.vapi.nat44_static_mapping_dump()
2728 self.assertEqual(2, len(static_mappings))
2730 for sm in static_mappings:
2731 if sm.external_sw_if_index == 0xFFFFFFFF:
2732 self.assertEqual(str(sm.external_ip_address),
2734 self.assertEqual(sm.tag, tag)
2736 self.assertTrue(resolved)
2738 # remove static mapping
2739 self.nat44_add_static_mapping(
2741 external_sw_if_index=self.pg7.sw_if_index,
2744 static_mappings = self.vapi.nat44_static_mapping_dump()
2745 self.assertEqual(0, len(static_mappings))
2747 def test_interface_addr_identity_nat(self):
2748 """ Identity NAT with addresses from interface """
2751 self.vapi.nat44_add_del_interface_addr(
2753 sw_if_index=self.pg7.sw_if_index)
2754 self.vapi.nat44_add_del_identity_mapping(
2756 sw_if_index=self.pg7.sw_if_index,
2758 protocol=IP_PROTOS.tcp,
2761 # identity mappings with external interface
2762 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2763 self.assertEqual(1, len(identity_mappings))
2764 self.assertEqual(self.pg7.sw_if_index,
2765 identity_mappings[0].sw_if_index)
2767 # configure interface address and check identity mappings
2768 self.pg7.config_ip4()
2769 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2771 self.assertEqual(2, len(identity_mappings))
2772 for sm in identity_mappings:
2773 if sm.sw_if_index == 0xFFFFFFFF:
2774 self.assertEqual(str(identity_mappings[0].ip_address),
2776 self.assertEqual(port, identity_mappings[0].port)
2777 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2779 self.assertTrue(resolved)
2781 # remove interface address and check identity mappings
2782 self.pg7.unconfig_ip4()
2783 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2784 self.assertEqual(1, len(identity_mappings))
2785 self.assertEqual(self.pg7.sw_if_index,
2786 identity_mappings[0].sw_if_index)
2788 def test_ipfix_nat44_sess(self):
2789 """ IPFIX logging NAT44 session created/deleted """
2790 self.ipfix_domain_id = 10
2791 self.ipfix_src_port = 20202
2792 collector_port = 30303
2793 bind_layers(UDP, IPFIX, dport=30303)
2794 self.nat44_add_address(self.nat_addr)
2795 flags = self.config_flags.NAT_IS_INSIDE
2796 self.vapi.nat44_interface_add_del_feature(
2797 sw_if_index=self.pg0.sw_if_index,
2798 flags=flags, is_add=1)
2799 self.vapi.nat44_interface_add_del_feature(
2800 sw_if_index=self.pg1.sw_if_index,
2802 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2803 src_address=self.pg3.local_ip4,
2805 template_interval=10,
2806 collector_port=collector_port)
2807 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2808 src_port=self.ipfix_src_port,
2811 pkts = self.create_stream_in(self.pg0, self.pg1)
2812 self.pg0.add_stream(pkts)
2813 self.pg_enable_capture(self.pg_interfaces)
2815 capture = self.pg1.get_capture(len(pkts))
2816 self.verify_capture_out(capture)
2817 self.nat44_add_address(self.nat_addr, is_add=0)
2818 self.vapi.ipfix_flush()
2819 capture = self.pg3.get_capture(9)
2820 ipfix = IPFIXDecoder()
2821 # first load template
2823 self.assertTrue(p.haslayer(IPFIX))
2824 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2825 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2826 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2827 self.assertEqual(p[UDP].dport, collector_port)
2828 self.assertEqual(p[IPFIX].observationDomainID,
2829 self.ipfix_domain_id)
2830 if p.haslayer(Template):
2831 ipfix.add_template(p.getlayer(Template))
2832 # verify events in data set
2834 if p.haslayer(Data):
2835 data = ipfix.decode_data_set(p.getlayer(Set))
2836 self.verify_ipfix_nat44_ses(data)
2838 def test_ipfix_addr_exhausted(self):
2839 """ IPFIX logging NAT addresses exhausted """
2840 flags = self.config_flags.NAT_IS_INSIDE
2841 self.vapi.nat44_interface_add_del_feature(
2842 sw_if_index=self.pg0.sw_if_index,
2843 flags=flags, is_add=1)
2844 self.vapi.nat44_interface_add_del_feature(
2845 sw_if_index=self.pg1.sw_if_index,
2847 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2848 src_address=self.pg3.local_ip4,
2850 template_interval=10)
2851 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2852 src_port=self.ipfix_src_port,
2855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2856 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2858 self.pg0.add_stream(p)
2859 self.pg_enable_capture(self.pg_interfaces)
2861 self.pg1.assert_nothing_captured()
2863 self.vapi.ipfix_flush()
2864 capture = self.pg3.get_capture(9)
2865 ipfix = IPFIXDecoder()
2866 # first load template
2868 self.assertTrue(p.haslayer(IPFIX))
2869 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2870 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2871 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2872 self.assertEqual(p[UDP].dport, 4739)
2873 self.assertEqual(p[IPFIX].observationDomainID,
2874 self.ipfix_domain_id)
2875 if p.haslayer(Template):
2876 ipfix.add_template(p.getlayer(Template))
2877 # verify events in data set
2879 if p.haslayer(Data):
2880 data = ipfix.decode_data_set(p.getlayer(Set))
2881 self.verify_ipfix_addr_exhausted(data)
2883 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2884 def test_ipfix_max_sessions(self):
2885 """ IPFIX logging maximum session entries exceeded """
2886 self.nat44_add_address(self.nat_addr)
2887 flags = self.config_flags.NAT_IS_INSIDE
2888 self.vapi.nat44_interface_add_del_feature(
2889 sw_if_index=self.pg0.sw_if_index,
2890 flags=flags, is_add=1)
2891 self.vapi.nat44_interface_add_del_feature(
2892 sw_if_index=self.pg1.sw_if_index,
2895 nat44_config = self.vapi.nat_show_config()
2896 max_sessions = 10 * nat44_config.translation_buckets
2899 for i in range(0, max_sessions):
2900 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2901 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2902 IP(src=src, dst=self.pg1.remote_ip4) /
2905 self.pg0.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2909 self.pg1.get_capture(max_sessions)
2910 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2911 src_address=self.pg3.local_ip4,
2913 template_interval=10)
2914 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2915 src_port=self.ipfix_src_port,
2918 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2919 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2921 self.pg0.add_stream(p)
2922 self.pg_enable_capture(self.pg_interfaces)
2924 self.pg1.assert_nothing_captured()
2926 self.vapi.ipfix_flush()
2927 capture = self.pg3.get_capture(9)
2928 ipfix = IPFIXDecoder()
2929 # first load template
2931 self.assertTrue(p.haslayer(IPFIX))
2932 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2933 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2934 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2935 self.assertEqual(p[UDP].dport, 4739)
2936 self.assertEqual(p[IPFIX].observationDomainID,
2937 self.ipfix_domain_id)
2938 if p.haslayer(Template):
2939 ipfix.add_template(p.getlayer(Template))
2940 # verify events in data set
2942 if p.haslayer(Data):
2943 data = ipfix.decode_data_set(p.getlayer(Set))
2944 self.verify_ipfix_max_sessions(data, max_sessions)
2946 def test_syslog_apmap(self):
2947 """ Test syslog address and port mapping creation and deletion """
2948 self.vapi.syslog_set_filter(
2949 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2950 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2951 self.nat44_add_address(self.nat_addr)
2952 flags = self.config_flags.NAT_IS_INSIDE
2953 self.vapi.nat44_interface_add_del_feature(
2954 sw_if_index=self.pg0.sw_if_index,
2955 flags=flags, is_add=1)
2956 self.vapi.nat44_interface_add_del_feature(
2957 sw_if_index=self.pg1.sw_if_index,
2960 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2961 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2962 TCP(sport=self.tcp_port_in, dport=20))
2963 self.pg0.add_stream(p)
2964 self.pg_enable_capture(self.pg_interfaces)
2966 capture = self.pg1.get_capture(1)
2967 self.tcp_port_out = capture[0][TCP].sport
2968 capture = self.pg3.get_capture(1)
2969 self.verify_syslog_apmap(capture[0][Raw].load)
2971 self.pg_enable_capture(self.pg_interfaces)
2973 self.nat44_add_address(self.nat_addr, is_add=0)
2974 capture = self.pg3.get_capture(1)
2975 self.verify_syslog_apmap(capture[0][Raw].load, False)
2977 def test_pool_addr_fib(self):
2978 """ NAT44 add pool addresses to FIB """
2979 static_addr = '10.0.0.10'
2980 self.nat44_add_address(self.nat_addr)
2981 flags = self.config_flags.NAT_IS_INSIDE
2982 self.vapi.nat44_interface_add_del_feature(
2983 sw_if_index=self.pg0.sw_if_index,
2984 flags=flags, is_add=1)
2985 self.vapi.nat44_interface_add_del_feature(
2986 sw_if_index=self.pg1.sw_if_index,
2988 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2991 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2992 ARP(op=ARP.who_has, pdst=self.nat_addr,
2993 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2994 self.pg1.add_stream(p)
2995 self.pg_enable_capture(self.pg_interfaces)
2997 capture = self.pg1.get_capture(1)
2998 self.assertTrue(capture[0].haslayer(ARP))
2999 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3002 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3003 ARP(op=ARP.who_has, pdst=static_addr,
3004 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3005 self.pg1.add_stream(p)
3006 self.pg_enable_capture(self.pg_interfaces)
3008 capture = self.pg1.get_capture(1)
3009 self.assertTrue(capture[0].haslayer(ARP))
3010 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3012 # send ARP to non-NAT44 interface
3013 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3014 ARP(op=ARP.who_has, pdst=self.nat_addr,
3015 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3016 self.pg2.add_stream(p)
3017 self.pg_enable_capture(self.pg_interfaces)
3019 self.pg1.assert_nothing_captured()
3021 # remove addresses and verify
3022 self.nat44_add_address(self.nat_addr, is_add=0)
3023 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3026 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3027 ARP(op=ARP.who_has, pdst=self.nat_addr,
3028 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3029 self.pg1.add_stream(p)
3030 self.pg_enable_capture(self.pg_interfaces)
3032 self.pg1.assert_nothing_captured()
3034 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3035 ARP(op=ARP.who_has, pdst=static_addr,
3036 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3037 self.pg1.add_stream(p)
3038 self.pg_enable_capture(self.pg_interfaces)
3040 self.pg1.assert_nothing_captured()
3042 def test_vrf_mode(self):
3043 """ NAT44 tenant VRF aware address pool mode """
3047 nat_ip1 = "10.0.0.10"
3048 nat_ip2 = "10.0.0.11"
3050 self.pg0.unconfig_ip4()
3051 self.pg1.unconfig_ip4()
3052 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3053 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3054 self.pg0.set_table_ip4(vrf_id1)
3055 self.pg1.set_table_ip4(vrf_id2)
3056 self.pg0.config_ip4()
3057 self.pg1.config_ip4()
3058 self.pg0.resolve_arp()
3059 self.pg1.resolve_arp()
3061 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3062 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3063 flags = self.config_flags.NAT_IS_INSIDE
3064 self.vapi.nat44_interface_add_del_feature(
3065 sw_if_index=self.pg0.sw_if_index,
3066 flags=flags, is_add=1)
3067 self.vapi.nat44_interface_add_del_feature(
3068 sw_if_index=self.pg1.sw_if_index,
3069 flags=flags, is_add=1)
3070 self.vapi.nat44_interface_add_del_feature(
3071 sw_if_index=self.pg2.sw_if_index,
3076 pkts = self.create_stream_in(self.pg0, self.pg2)
3077 self.pg0.add_stream(pkts)
3078 self.pg_enable_capture(self.pg_interfaces)
3080 capture = self.pg2.get_capture(len(pkts))
3081 self.verify_capture_out(capture, nat_ip1)
3084 pkts = self.create_stream_in(self.pg1, self.pg2)
3085 self.pg1.add_stream(pkts)
3086 self.pg_enable_capture(self.pg_interfaces)
3088 capture = self.pg2.get_capture(len(pkts))
3089 self.verify_capture_out(capture, nat_ip2)
3092 self.pg0.unconfig_ip4()
3093 self.pg1.unconfig_ip4()
3094 self.pg0.set_table_ip4(0)
3095 self.pg1.set_table_ip4(0)
3096 self.pg0.config_ip4()
3097 self.pg1.config_ip4()
3098 self.pg0.resolve_arp()
3099 self.pg1.resolve_arp()
3100 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3101 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3103 def test_vrf_feature_independent(self):
3104 """ NAT44 tenant VRF independent address pool mode """
3106 nat_ip1 = "10.0.0.10"
3107 nat_ip2 = "10.0.0.11"
3109 self.nat44_add_address(nat_ip1)
3110 self.nat44_add_address(nat_ip2, vrf_id=99)
3111 flags = self.config_flags.NAT_IS_INSIDE
3112 self.vapi.nat44_interface_add_del_feature(
3113 sw_if_index=self.pg0.sw_if_index,
3114 flags=flags, is_add=1)
3115 self.vapi.nat44_interface_add_del_feature(
3116 sw_if_index=self.pg1.sw_if_index,
3117 flags=flags, is_add=1)
3118 self.vapi.nat44_interface_add_del_feature(
3119 sw_if_index=self.pg2.sw_if_index,
3123 pkts = self.create_stream_in(self.pg0, self.pg2)
3124 self.pg0.add_stream(pkts)
3125 self.pg_enable_capture(self.pg_interfaces)
3127 capture = self.pg2.get_capture(len(pkts))
3128 self.verify_capture_out(capture, nat_ip1)
3131 pkts = self.create_stream_in(self.pg1, self.pg2)
3132 self.pg1.add_stream(pkts)
3133 self.pg_enable_capture(self.pg_interfaces)
3135 capture = self.pg2.get_capture(len(pkts))
3136 self.verify_capture_out(capture, nat_ip1)
3138 def create_routes_and_neigbors(self):
3139 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3140 [VppRoutePath(self.pg7.remote_ip4,
3141 self.pg7.sw_if_index)])
3142 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3143 [VppRoutePath(self.pg8.remote_ip4,
3144 self.pg8.sw_if_index)])
3148 n1 = VppNeighbor(self,
3149 self.pg7.sw_if_index,
3150 self.pg7.remote_mac,
3151 self.pg7.remote_ip4,
3153 n2 = VppNeighbor(self,
3154 self.pg8.sw_if_index,
3155 self.pg8.remote_mac,
3156 self.pg8.remote_ip4,
3161 def test_dynamic_ipless_interfaces(self):
3162 """ NAT44 interfaces without configured IP address """
3163 self.create_routes_and_neigbors()
3164 self.nat44_add_address(self.nat_addr)
3165 flags = self.config_flags.NAT_IS_INSIDE
3166 self.vapi.nat44_interface_add_del_feature(
3167 sw_if_index=self.pg7.sw_if_index,
3168 flags=flags, is_add=1)
3169 self.vapi.nat44_interface_add_del_feature(
3170 sw_if_index=self.pg8.sw_if_index,
3174 pkts = self.create_stream_in(self.pg7, self.pg8)
3175 self.pg7.add_stream(pkts)
3176 self.pg_enable_capture(self.pg_interfaces)
3178 capture = self.pg8.get_capture(len(pkts))
3179 self.verify_capture_out(capture)
3182 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3183 self.pg8.add_stream(pkts)
3184 self.pg_enable_capture(self.pg_interfaces)
3186 capture = self.pg7.get_capture(len(pkts))
3187 self.verify_capture_in(capture, self.pg7)
3189 def test_static_ipless_interfaces(self):
3190 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3192 self.create_routes_and_neigbors()
3193 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3194 flags = self.config_flags.NAT_IS_INSIDE
3195 self.vapi.nat44_interface_add_del_feature(
3196 sw_if_index=self.pg7.sw_if_index,
3197 flags=flags, is_add=1)
3198 self.vapi.nat44_interface_add_del_feature(
3199 sw_if_index=self.pg8.sw_if_index,
3203 pkts = self.create_stream_out(self.pg8)
3204 self.pg8.add_stream(pkts)
3205 self.pg_enable_capture(self.pg_interfaces)
3207 capture = self.pg7.get_capture(len(pkts))
3208 self.verify_capture_in(capture, self.pg7)
3211 pkts = self.create_stream_in(self.pg7, self.pg8)
3212 self.pg7.add_stream(pkts)
3213 self.pg_enable_capture(self.pg_interfaces)
3215 capture = self.pg8.get_capture(len(pkts))
3216 self.verify_capture_out(capture, self.nat_addr, True)
3218 def test_static_with_port_ipless_interfaces(self):
3219 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3221 self.tcp_port_out = 30606
3222 self.udp_port_out = 30607
3223 self.icmp_id_out = 30608
3225 self.create_routes_and_neigbors()
3226 self.nat44_add_address(self.nat_addr)
3227 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3228 self.tcp_port_in, self.tcp_port_out,
3229 proto=IP_PROTOS.tcp)
3230 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3231 self.udp_port_in, self.udp_port_out,
3232 proto=IP_PROTOS.udp)
3233 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3234 self.icmp_id_in, self.icmp_id_out,
3235 proto=IP_PROTOS.icmp)
3236 flags = self.config_flags.NAT_IS_INSIDE
3237 self.vapi.nat44_interface_add_del_feature(
3238 sw_if_index=self.pg7.sw_if_index,
3239 flags=flags, is_add=1)
3240 self.vapi.nat44_interface_add_del_feature(
3241 sw_if_index=self.pg8.sw_if_index,
3245 pkts = self.create_stream_out(self.pg8)
3246 self.pg8.add_stream(pkts)
3247 self.pg_enable_capture(self.pg_interfaces)
3249 capture = self.pg7.get_capture(len(pkts))
3250 self.verify_capture_in(capture, self.pg7)
3253 pkts = self.create_stream_in(self.pg7, self.pg8)
3254 self.pg7.add_stream(pkts)
3255 self.pg_enable_capture(self.pg_interfaces)
3257 capture = self.pg8.get_capture(len(pkts))
3258 self.verify_capture_out(capture)
3260 def test_static_unknown_proto(self):
3261 """ 1:1 NAT translate packet with unknown protocol """
3262 nat_ip = "10.0.0.10"
3263 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3264 flags = self.config_flags.NAT_IS_INSIDE
3265 self.vapi.nat44_interface_add_del_feature(
3266 sw_if_index=self.pg0.sw_if_index,
3267 flags=flags, is_add=1)
3268 self.vapi.nat44_interface_add_del_feature(
3269 sw_if_index=self.pg1.sw_if_index,
3273 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3274 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3276 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3277 TCP(sport=1234, dport=1234))
3278 self.pg0.add_stream(p)
3279 self.pg_enable_capture(self.pg_interfaces)
3281 p = self.pg1.get_capture(1)
3284 self.assertEqual(packet[IP].src, nat_ip)
3285 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3286 self.assertEqual(packet.haslayer(GRE), 1)
3287 self.assert_packet_checksums_valid(packet)
3289 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3293 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3294 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3296 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3297 TCP(sport=1234, dport=1234))
3298 self.pg1.add_stream(p)
3299 self.pg_enable_capture(self.pg_interfaces)
3301 p = self.pg0.get_capture(1)
3304 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3305 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3306 self.assertEqual(packet.haslayer(GRE), 1)
3307 self.assert_packet_checksums_valid(packet)
3309 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3312 def test_hairpinning_static_unknown_proto(self):
3313 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3315 host = self.pg0.remote_hosts[0]
3316 server = self.pg0.remote_hosts[1]
3318 host_nat_ip = "10.0.0.10"
3319 server_nat_ip = "10.0.0.11"
3321 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3322 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3323 flags = self.config_flags.NAT_IS_INSIDE
3324 self.vapi.nat44_interface_add_del_feature(
3325 sw_if_index=self.pg0.sw_if_index,
3326 flags=flags, is_add=1)
3327 self.vapi.nat44_interface_add_del_feature(
3328 sw_if_index=self.pg1.sw_if_index,
3332 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3333 IP(src=host.ip4, dst=server_nat_ip) /
3335 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3336 TCP(sport=1234, dport=1234))
3337 self.pg0.add_stream(p)
3338 self.pg_enable_capture(self.pg_interfaces)
3340 p = self.pg0.get_capture(1)
3343 self.assertEqual(packet[IP].src, host_nat_ip)
3344 self.assertEqual(packet[IP].dst, server.ip4)
3345 self.assertEqual(packet.haslayer(GRE), 1)
3346 self.assert_packet_checksums_valid(packet)
3348 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3352 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3353 IP(src=server.ip4, dst=host_nat_ip) /
3355 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3356 TCP(sport=1234, dport=1234))
3357 self.pg0.add_stream(p)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 p = self.pg0.get_capture(1)
3363 self.assertEqual(packet[IP].src, server_nat_ip)
3364 self.assertEqual(packet[IP].dst, host.ip4)
3365 self.assertEqual(packet.haslayer(GRE), 1)
3366 self.assert_packet_checksums_valid(packet)
3368 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3371 def test_output_feature(self):
3372 """ NAT44 interface output feature (in2out postrouting) """
3373 self.nat44_add_address(self.nat_addr)
3374 flags = self.config_flags.NAT_IS_INSIDE
3375 self.vapi.nat44_interface_add_del_output_feature(
3376 is_add=1, flags=flags,
3377 sw_if_index=self.pg0.sw_if_index)
3378 self.vapi.nat44_interface_add_del_output_feature(
3379 is_add=1, flags=flags,
3380 sw_if_index=self.pg1.sw_if_index)
3381 self.vapi.nat44_interface_add_del_output_feature(
3383 sw_if_index=self.pg3.sw_if_index)
3386 pkts = self.create_stream_in(self.pg0, self.pg3)
3387 self.pg0.add_stream(pkts)
3388 self.pg_enable_capture(self.pg_interfaces)
3390 capture = self.pg3.get_capture(len(pkts))
3391 self.verify_capture_out(capture)
3394 pkts = self.create_stream_out(self.pg3)
3395 self.pg3.add_stream(pkts)
3396 self.pg_enable_capture(self.pg_interfaces)
3398 capture = self.pg0.get_capture(len(pkts))
3399 self.verify_capture_in(capture, self.pg0)
3401 # from non-NAT interface to NAT inside interface
3402 pkts = self.create_stream_in(self.pg2, self.pg0)
3403 self.pg2.add_stream(pkts)
3404 self.pg_enable_capture(self.pg_interfaces)
3406 capture = self.pg0.get_capture(len(pkts))
3407 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3409 def test_output_feature_vrf_aware(self):
3410 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3411 nat_ip_vrf10 = "10.0.0.10"
3412 nat_ip_vrf20 = "10.0.0.20"
3414 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3415 [VppRoutePath(self.pg3.remote_ip4,
3416 self.pg3.sw_if_index)],
3418 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3419 [VppRoutePath(self.pg3.remote_ip4,
3420 self.pg3.sw_if_index)],
3425 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3426 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3427 flags = self.config_flags.NAT_IS_INSIDE
3428 self.vapi.nat44_interface_add_del_output_feature(
3429 is_add=1, flags=flags,
3430 sw_if_index=self.pg4.sw_if_index)
3431 self.vapi.nat44_interface_add_del_output_feature(
3432 is_add=1, flags=flags,
3433 sw_if_index=self.pg6.sw_if_index)
3434 self.vapi.nat44_interface_add_del_output_feature(
3436 sw_if_index=self.pg3.sw_if_index)
3439 pkts = self.create_stream_in(self.pg4, self.pg3)
3440 self.pg4.add_stream(pkts)
3441 self.pg_enable_capture(self.pg_interfaces)
3443 capture = self.pg3.get_capture(len(pkts))
3444 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3447 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3448 self.pg3.add_stream(pkts)
3449 self.pg_enable_capture(self.pg_interfaces)
3451 capture = self.pg4.get_capture(len(pkts))
3452 self.verify_capture_in(capture, self.pg4)
3455 pkts = self.create_stream_in(self.pg6, self.pg3)
3456 self.pg6.add_stream(pkts)
3457 self.pg_enable_capture(self.pg_interfaces)
3459 capture = self.pg3.get_capture(len(pkts))
3460 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3463 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3464 self.pg3.add_stream(pkts)
3465 self.pg_enable_capture(self.pg_interfaces)
3467 capture = self.pg6.get_capture(len(pkts))
3468 self.verify_capture_in(capture, self.pg6)
3470 def test_output_feature_hairpinning(self):
3471 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3472 host = self.pg0.remote_hosts[0]
3473 server = self.pg0.remote_hosts[1]
3476 server_in_port = 5678
3477 server_out_port = 8765
3479 self.nat44_add_address(self.nat_addr)
3480 flags = self.config_flags.NAT_IS_INSIDE
3481 self.vapi.nat44_interface_add_del_output_feature(
3482 is_add=1, flags=flags,
3483 sw_if_index=self.pg0.sw_if_index)
3484 self.vapi.nat44_interface_add_del_output_feature(
3486 sw_if_index=self.pg1.sw_if_index)
3488 # add static mapping for server
3489 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3490 server_in_port, server_out_port,
3491 proto=IP_PROTOS.tcp)
3493 # send packet from host to server
3494 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3495 IP(src=host.ip4, dst=self.nat_addr) /
3496 TCP(sport=host_in_port, dport=server_out_port))
3497 self.pg0.add_stream(p)
3498 self.pg_enable_capture(self.pg_interfaces)
3500 capture = self.pg0.get_capture(1)
3505 self.assertEqual(ip.src, self.nat_addr)
3506 self.assertEqual(ip.dst, server.ip4)
3507 self.assertNotEqual(tcp.sport, host_in_port)
3508 self.assertEqual(tcp.dport, server_in_port)
3509 self.assert_packet_checksums_valid(p)
3510 host_out_port = tcp.sport
3512 self.logger.error(ppp("Unexpected or invalid packet:", p))
3515 # send reply from server to host
3516 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3517 IP(src=server.ip4, dst=self.nat_addr) /
3518 TCP(sport=server_in_port, dport=host_out_port))
3519 self.pg0.add_stream(p)
3520 self.pg_enable_capture(self.pg_interfaces)
3522 capture = self.pg0.get_capture(1)
3527 self.assertEqual(ip.src, self.nat_addr)
3528 self.assertEqual(ip.dst, host.ip4)
3529 self.assertEqual(tcp.sport, server_out_port)
3530 self.assertEqual(tcp.dport, host_in_port)
3531 self.assert_packet_checksums_valid(p)
3533 self.logger.error(ppp("Unexpected or invalid packet:", p))
3536 def test_one_armed_nat44(self):
3537 """ One armed NAT44 """
3538 remote_host = self.pg9.remote_hosts[0]
3539 local_host = self.pg9.remote_hosts[1]
3542 self.nat44_add_address(self.nat_addr)
3543 flags = self.config_flags.NAT_IS_INSIDE
3544 self.vapi.nat44_interface_add_del_feature(
3545 sw_if_index=self.pg9.sw_if_index,
3547 self.vapi.nat44_interface_add_del_feature(
3548 sw_if_index=self.pg9.sw_if_index,
3549 flags=flags, is_add=1)
3552 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3553 IP(src=local_host.ip4, dst=remote_host.ip4) /
3554 TCP(sport=12345, dport=80))
3555 self.pg9.add_stream(p)
3556 self.pg_enable_capture(self.pg_interfaces)
3558 capture = self.pg9.get_capture(1)
3563 self.assertEqual(ip.src, self.nat_addr)
3564 self.assertEqual(ip.dst, remote_host.ip4)
3565 self.assertNotEqual(tcp.sport, 12345)
3566 external_port = tcp.sport
3567 self.assertEqual(tcp.dport, 80)
3568 self.assert_packet_checksums_valid(p)
3570 self.logger.error(ppp("Unexpected or invalid packet:", p))
3574 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3575 IP(src=remote_host.ip4, dst=self.nat_addr) /
3576 TCP(sport=80, dport=external_port))
3577 self.pg9.add_stream(p)
3578 self.pg_enable_capture(self.pg_interfaces)
3580 capture = self.pg9.get_capture(1)
3585 self.assertEqual(ip.src, remote_host.ip4)
3586 self.assertEqual(ip.dst, local_host.ip4)
3587 self.assertEqual(tcp.sport, 80)
3588 self.assertEqual(tcp.dport, 12345)
3589 self.assert_packet_checksums_valid(p)
3591 self.logger.error(ppp("Unexpected or invalid packet:", p))
3594 err = self.statistics.get_err_counter(
3595 '/err/nat44-classify/next in2out')
3596 self.assertEqual(err, 1)
3597 err = self.statistics.get_err_counter(
3598 '/err/nat44-classify/next out2in')
3599 self.assertEqual(err, 1)
3601 def test_del_session(self):
3602 """ Delete NAT44 session """
3603 self.nat44_add_address(self.nat_addr)
3604 flags = self.config_flags.NAT_IS_INSIDE
3605 self.vapi.nat44_interface_add_del_feature(
3606 sw_if_index=self.pg0.sw_if_index,
3607 flags=flags, is_add=1)
3608 self.vapi.nat44_interface_add_del_feature(
3609 sw_if_index=self.pg1.sw_if_index,
3612 pkts = self.create_stream_in(self.pg0, self.pg1)
3613 self.pg0.add_stream(pkts)
3614 self.pg_enable_capture(self.pg_interfaces)
3616 self.pg1.get_capture(len(pkts))
3618 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3619 nsessions = len(sessions)
3621 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3622 port=sessions[0].inside_port,
3623 protocol=sessions[0].protocol,
3624 flags=self.config_flags.NAT_IS_INSIDE)
3625 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3626 port=sessions[1].outside_port,
3627 protocol=sessions[1].protocol)
3629 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3630 self.assertEqual(nsessions - len(sessions), 2)
3632 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3633 port=sessions[0].inside_port,
3634 protocol=sessions[0].protocol,
3635 flags=self.config_flags.NAT_IS_INSIDE)
3637 self.verify_no_nat44_user()
3639 def test_set_get_reass(self):
3640 """ NAT44 set/get virtual fragmentation reassembly """
3641 reas_cfg1 = self.vapi.nat_get_reass()
3643 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3644 max_reass=reas_cfg1.ip4_max_reass * 2,
3645 max_frag=reas_cfg1.ip4_max_frag * 2,
3648 reas_cfg2 = self.vapi.nat_get_reass()
3650 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3651 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3652 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3654 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3656 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3658 def test_frag_in_order(self):
3659 """ NAT44 translate fragments arriving in order """
3661 self.nat44_add_address(self.nat_addr)
3662 flags = self.config_flags.NAT_IS_INSIDE
3663 self.vapi.nat44_interface_add_del_feature(
3664 sw_if_index=self.pg0.sw_if_index,
3665 flags=flags, is_add=1)
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg1.sw_if_index,
3670 reas_cfg1 = self.vapi.nat_get_reass()
3671 # this test was intermittently failing in some cases
3672 # until we temporarily bump the reassembly timeouts
3673 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
3676 self.frag_in_order(proto=IP_PROTOS.tcp)
3677 self.frag_in_order(proto=IP_PROTOS.udp)
3678 self.frag_in_order(proto=IP_PROTOS.icmp)
3680 # restore the reassembly timeouts
3681 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
3682 max_reass=reas_cfg1.ip4_max_reass,
3683 max_frag=reas_cfg1.ip4_max_frag,
3684 drop_frag=reas_cfg1.ip4_drop_frag)
3686 def test_frag_forwarding(self):
3687 """ NAT44 forwarding fragment test """
3688 self.vapi.nat44_add_del_interface_addr(
3690 sw_if_index=self.pg1.sw_if_index)
3691 flags = self.config_flags.NAT_IS_INSIDE
3692 self.vapi.nat44_interface_add_del_feature(
3693 sw_if_index=self.pg0.sw_if_index,
3694 flags=flags, is_add=1)
3695 self.vapi.nat44_interface_add_del_feature(
3696 sw_if_index=self.pg1.sw_if_index,
3698 self.vapi.nat44_forwarding_enable_disable(enable=1)
3700 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3701 pkts = self.create_stream_frag(self.pg1,
3702 self.pg0.remote_ip4,
3706 proto=IP_PROTOS.udp)
3707 self.pg1.add_stream(pkts)
3708 self.pg_enable_capture(self.pg_interfaces)
3710 frags = self.pg0.get_capture(len(pkts))
3711 p = self.reass_frags_and_verify(frags,
3712 self.pg1.remote_ip4,
3713 self.pg0.remote_ip4)
3714 self.assertEqual(p[UDP].sport, 4789)
3715 self.assertEqual(p[UDP].dport, 4789)
3716 self.assertEqual(data, p[Raw].load)
3718 def test_reass_hairpinning(self):
3719 """ NAT44 fragments hairpinning """
3721 self.server = self.pg0.remote_hosts[1]
3722 self.host_in_port = random.randint(1025, 65535)
3723 self.server_in_port = random.randint(1025, 65535)
3724 self.server_out_port = random.randint(1025, 65535)
3726 self.nat44_add_address(self.nat_addr)
3727 flags = self.config_flags.NAT_IS_INSIDE
3728 self.vapi.nat44_interface_add_del_feature(
3729 sw_if_index=self.pg0.sw_if_index,
3730 flags=flags, is_add=1)
3731 self.vapi.nat44_interface_add_del_feature(
3732 sw_if_index=self.pg1.sw_if_index,
3734 # add static mapping for server
3735 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3736 self.server_in_port,
3737 self.server_out_port,
3738 proto=IP_PROTOS.tcp)
3739 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3740 self.server_in_port,
3741 self.server_out_port,
3742 proto=IP_PROTOS.udp)
3743 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3745 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3746 self.reass_hairpinning(proto=IP_PROTOS.udp)
3747 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3749 def test_frag_out_of_order(self):
3750 """ NAT44 translate fragments arriving out of order """
3752 self.nat44_add_address(self.nat_addr)
3753 flags = self.config_flags.NAT_IS_INSIDE
3754 self.vapi.nat44_interface_add_del_feature(
3755 sw_if_index=self.pg0.sw_if_index,
3756 flags=flags, is_add=1)
3757 self.vapi.nat44_interface_add_del_feature(
3758 sw_if_index=self.pg1.sw_if_index,
3761 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3762 self.frag_out_of_order(proto=IP_PROTOS.udp)
3763 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3765 def test_port_restricted(self):
3766 """ Port restricted NAT44 (MAP-E CE) """
3767 self.nat44_add_address(self.nat_addr)
3768 flags = self.config_flags.NAT_IS_INSIDE
3769 self.vapi.nat44_interface_add_del_feature(
3770 sw_if_index=self.pg0.sw_if_index,
3771 flags=flags, is_add=1)
3772 self.vapi.nat44_interface_add_del_feature(
3773 sw_if_index=self.pg1.sw_if_index,
3775 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3780 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3781 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3782 TCP(sport=4567, dport=22))
3783 self.pg0.add_stream(p)
3784 self.pg_enable_capture(self.pg_interfaces)
3786 capture = self.pg1.get_capture(1)
3791 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3792 self.assertEqual(ip.src, self.nat_addr)
3793 self.assertEqual(tcp.dport, 22)
3794 self.assertNotEqual(tcp.sport, 4567)
3795 self.assertEqual((tcp.sport >> 6) & 63, 10)
3796 self.assert_packet_checksums_valid(p)
3798 self.logger.error(ppp("Unexpected or invalid packet:", p))
3801 def test_port_range(self):
3802 """ External address port range """
3803 self.nat44_add_address(self.nat_addr)
3804 flags = self.config_flags.NAT_IS_INSIDE
3805 self.vapi.nat44_interface_add_del_feature(
3806 sw_if_index=self.pg0.sw_if_index,
3807 flags=flags, is_add=1)
3808 self.vapi.nat44_interface_add_del_feature(
3809 sw_if_index=self.pg1.sw_if_index,
3811 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3816 for port in range(0, 5):
3817 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3818 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3819 TCP(sport=1125 + port))
3821 self.pg0.add_stream(pkts)
3822 self.pg_enable_capture(self.pg_interfaces)
3824 capture = self.pg1.get_capture(3)
3827 self.assertGreaterEqual(tcp.sport, 1025)
3828 self.assertLessEqual(tcp.sport, 1027)
3830 def test_ipfix_max_frags(self):
3831 """ IPFIX logging maximum fragments pending reassembly exceeded """
3832 self.nat44_add_address(self.nat_addr)
3833 flags = self.config_flags.NAT_IS_INSIDE
3834 self.vapi.nat44_interface_add_del_feature(
3835 sw_if_index=self.pg0.sw_if_index,
3836 flags=flags, is_add=1)
3837 self.vapi.nat44_interface_add_del_feature(
3838 sw_if_index=self.pg1.sw_if_index,
3840 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3842 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
3843 src_address=self.pg3.local_ip4,
3845 template_interval=10)
3846 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3847 src_port=self.ipfix_src_port,
3850 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3851 self.tcp_port_in = random.randint(1025, 65535)
3852 pkts = self.create_stream_frag(self.pg0,
3853 self.pg1.remote_ip4,
3858 self.pg0.add_stream(pkts)
3859 self.pg_enable_capture(self.pg_interfaces)
3861 self.pg1.assert_nothing_captured()
3863 self.vapi.ipfix_flush()
3864 capture = self.pg3.get_capture(9)
3865 ipfix = IPFIXDecoder()
3866 # first load template
3868 self.assertTrue(p.haslayer(IPFIX))
3869 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3870 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3871 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3872 self.assertEqual(p[UDP].dport, 4739)
3873 self.assertEqual(p[IPFIX].observationDomainID,
3874 self.ipfix_domain_id)
3875 if p.haslayer(Template):
3876 ipfix.add_template(p.getlayer(Template))
3877 # verify events in data set
3879 if p.haslayer(Data):
3880 data = ipfix.decode_data_set(p.getlayer(Set))
3881 self.verify_ipfix_max_fragments_ip4(data, 1,
3882 self.pg0.remote_ip4n)
3884 def test_multiple_outside_vrf(self):
3885 """ Multiple outside VRF """
3889 self.pg1.unconfig_ip4()
3890 self.pg2.unconfig_ip4()
3891 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3892 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3893 self.pg1.set_table_ip4(vrf_id1)
3894 self.pg2.set_table_ip4(vrf_id2)
3895 self.pg1.config_ip4()
3896 self.pg2.config_ip4()
3897 self.pg1.resolve_arp()
3898 self.pg2.resolve_arp()
3900 self.nat44_add_address(self.nat_addr)
3901 flags = self.config_flags.NAT_IS_INSIDE
3902 self.vapi.nat44_interface_add_del_feature(
3903 sw_if_index=self.pg0.sw_if_index,
3904 flags=flags, is_add=1)
3905 self.vapi.nat44_interface_add_del_feature(
3906 sw_if_index=self.pg1.sw_if_index,
3908 self.vapi.nat44_interface_add_del_feature(
3909 sw_if_index=self.pg2.sw_if_index,
3914 pkts = self.create_stream_in(self.pg0, self.pg1)
3915 self.pg0.add_stream(pkts)
3916 self.pg_enable_capture(self.pg_interfaces)
3918 capture = self.pg1.get_capture(len(pkts))
3919 self.verify_capture_out(capture, self.nat_addr)
3921 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3922 self.pg1.add_stream(pkts)
3923 self.pg_enable_capture(self.pg_interfaces)
3925 capture = self.pg0.get_capture(len(pkts))
3926 self.verify_capture_in(capture, self.pg0)
3928 self.tcp_port_in = 60303
3929 self.udp_port_in = 60304
3930 self.icmp_id_in = 60305
3933 pkts = self.create_stream_in(self.pg0, self.pg2)
3934 self.pg0.add_stream(pkts)
3935 self.pg_enable_capture(self.pg_interfaces)
3937 capture = self.pg2.get_capture(len(pkts))
3938 self.verify_capture_out(capture, self.nat_addr)
3940 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3941 self.pg2.add_stream(pkts)
3942 self.pg_enable_capture(self.pg_interfaces)
3944 capture = self.pg0.get_capture(len(pkts))
3945 self.verify_capture_in(capture, self.pg0)
3948 self.nat44_add_address(self.nat_addr, is_add=0)
3949 self.pg1.unconfig_ip4()
3950 self.pg2.unconfig_ip4()
3951 self.pg1.set_table_ip4(0)
3952 self.pg2.set_table_ip4(0)
3953 self.pg1.config_ip4()
3954 self.pg2.config_ip4()
3955 self.pg1.resolve_arp()
3956 self.pg2.resolve_arp()
3958 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3959 def test_session_timeout(self):
3960 """ NAT44 session timeouts """
3961 self.nat44_add_address(self.nat_addr)
3962 flags = self.config_flags.NAT_IS_INSIDE
3963 self.vapi.nat44_interface_add_del_feature(
3964 sw_if_index=self.pg0.sw_if_index,
3965 flags=flags, is_add=1)
3966 self.vapi.nat44_interface_add_del_feature(
3967 sw_if_index=self.pg1.sw_if_index,
3969 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3970 tcp_transitory=240, icmp=60)
3974 for i in range(0, max_sessions):
3975 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3976 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3977 IP(src=src, dst=self.pg1.remote_ip4) /
3978 UDP(sport=1025, dport=53))
3980 self.pg0.add_stream(pkts)
3981 self.pg_enable_capture(self.pg_interfaces)
3983 self.pg1.get_capture(max_sessions)
3988 for i in range(0, max_sessions):
3989 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3990 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3991 IP(src=src, dst=self.pg1.remote_ip4) /
3992 UDP(sport=1026, dport=53))
3994 self.pg0.add_stream(pkts)
3995 self.pg_enable_capture(self.pg_interfaces)
3997 self.pg1.get_capture(max_sessions)
4000 users = self.vapi.nat44_user_dump()
4002 nsessions = nsessions + user.nsessions
4003 self.assertLess(nsessions, 2 * max_sessions)
4005 def test_mss_clamping(self):
4006 """ TCP MSS clamping """
4007 self.nat44_add_address(self.nat_addr)
4008 flags = self.config_flags.NAT_IS_INSIDE
4009 self.vapi.nat44_interface_add_del_feature(
4010 sw_if_index=self.pg0.sw_if_index,
4011 flags=flags, is_add=1)
4012 self.vapi.nat44_interface_add_del_feature(
4013 sw_if_index=self.pg1.sw_if_index,
4016 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4017 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4018 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4019 flags="S", options=[('MSS', 1400)]))
4021 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4022 self.pg0.add_stream(p)
4023 self.pg_enable_capture(self.pg_interfaces)
4025 capture = self.pg1.get_capture(1)
4026 # Negotiated MSS value greater than configured - changed
4027 self.verify_mss_value(capture[0], 1000)
4029 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4030 self.pg0.add_stream(p)
4031 self.pg_enable_capture(self.pg_interfaces)
4033 capture = self.pg1.get_capture(1)
4034 # MSS clamping disabled - negotiated MSS unchanged
4035 self.verify_mss_value(capture[0], 1400)
4037 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4038 self.pg0.add_stream(p)
4039 self.pg_enable_capture(self.pg_interfaces)
4041 capture = self.pg1.get_capture(1)
4042 # Negotiated MSS value smaller than configured - unchanged
4043 self.verify_mss_value(capture[0], 1400)
4045 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4046 def test_ha_send(self):
4047 """ Send HA session synchronization events (active) """
4048 self.nat44_add_address(self.nat_addr)
4049 flags = self.config_flags.NAT_IS_INSIDE
4050 self.vapi.nat44_interface_add_del_feature(
4051 sw_if_index=self.pg0.sw_if_index,
4052 flags=flags, is_add=1)
4053 self.vapi.nat44_interface_add_del_feature(
4054 sw_if_index=self.pg1.sw_if_index,
4056 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4059 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4060 port=12346, session_refresh_interval=10)
4061 bind_layers(UDP, HANATStateSync, sport=12345)
4064 pkts = self.create_stream_in(self.pg0, self.pg1)
4065 self.pg0.add_stream(pkts)
4066 self.pg_enable_capture(self.pg_interfaces)
4068 capture = self.pg1.get_capture(len(pkts))
4069 self.verify_capture_out(capture)
4070 # active send HA events
4071 self.vapi.nat_ha_flush()
4072 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4073 self.assertEqual(stats[0][0], 3)
4074 capture = self.pg3.get_capture(1)
4076 self.assert_packet_checksums_valid(p)
4080 hanat = p[HANATStateSync]
4082 self.logger.error(ppp("Invalid packet:", p))
4085 self.assertEqual(ip.src, self.pg3.local_ip4)
4086 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4087 self.assertEqual(udp.sport, 12345)
4088 self.assertEqual(udp.dport, 12346)
4089 self.assertEqual(hanat.version, 1)
4090 self.assertEqual(hanat.thread_index, 0)
4091 self.assertEqual(hanat.count, 3)
4092 seq = hanat.sequence_number
4093 for event in hanat.events:
4094 self.assertEqual(event.event_type, 1)
4095 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4096 self.assertEqual(event.out_addr, self.nat_addr)
4097 self.assertEqual(event.fib_index, 0)
4099 # ACK received events
4100 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4101 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4102 UDP(sport=12346, dport=12345) /
4103 HANATStateSync(sequence_number=seq, flags='ACK'))
4104 self.pg3.add_stream(ack)
4106 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4107 self.assertEqual(stats[0][0], 1)
4109 # delete one session
4110 self.pg_enable_capture(self.pg_interfaces)
4111 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
4112 port=self.tcp_port_in,
4113 protocol=IP_PROTOS.tcp,
4114 flags=self.config_flags.NAT_IS_INSIDE)
4115 self.vapi.nat_ha_flush()
4116 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4117 self.assertEqual(stats[0][0], 1)
4118 capture = self.pg3.get_capture(1)
4121 hanat = p[HANATStateSync]
4123 self.logger.error(ppp("Invalid packet:", p))
4126 self.assertGreater(hanat.sequence_number, seq)
4128 # do not send ACK, active retry send HA event again
4129 self.pg_enable_capture(self.pg_interfaces)
4131 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4132 self.assertEqual(stats[0][0], 3)
4133 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4134 self.assertEqual(stats[0][0], 1)
4135 capture = self.pg3.get_capture(3)
4136 for packet in capture:
4137 self.assertEqual(packet, p)
4139 # session counters refresh
4140 pkts = self.create_stream_out(self.pg1)
4141 self.pg1.add_stream(pkts)
4142 self.pg_enable_capture(self.pg_interfaces)
4144 self.pg0.get_capture(2)
4145 self.vapi.nat_ha_flush()
4146 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4147 self.assertEqual(stats[0][0], 2)
4148 capture = self.pg3.get_capture(1)
4150 self.assert_packet_checksums_valid(p)
4154 hanat = p[HANATStateSync]
4156 self.logger.error(ppp("Invalid packet:", p))
4159 self.assertEqual(ip.src, self.pg3.local_ip4)
4160 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4161 self.assertEqual(udp.sport, 12345)
4162 self.assertEqual(udp.dport, 12346)
4163 self.assertEqual(hanat.version, 1)
4164 self.assertEqual(hanat.count, 2)
4165 seq = hanat.sequence_number
4166 for event in hanat.events:
4167 self.assertEqual(event.event_type, 3)
4168 self.assertEqual(event.out_addr, self.nat_addr)
4169 self.assertEqual(event.fib_index, 0)
4170 self.assertEqual(event.total_pkts, 2)
4171 self.assertGreater(event.total_bytes, 0)
4173 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4174 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4175 UDP(sport=12346, dport=12345) /
4176 HANATStateSync(sequence_number=seq, flags='ACK'))
4177 self.pg3.add_stream(ack)
4179 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4180 self.assertEqual(stats[0][0], 2)
4182 def test_ha_recv(self):
4183 """ Receive HA session synchronization events (passive) """
4184 self.nat44_add_address(self.nat_addr)
4185 flags = self.config_flags.NAT_IS_INSIDE
4186 self.vapi.nat44_interface_add_del_feature(
4187 sw_if_index=self.pg0.sw_if_index,
4188 flags=flags, is_add=1)
4189 self.vapi.nat44_interface_add_del_feature(
4190 sw_if_index=self.pg1.sw_if_index,
4192 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4195 bind_layers(UDP, HANATStateSync, sport=12345)
4197 self.tcp_port_out = random.randint(1025, 65535)
4198 self.udp_port_out = random.randint(1025, 65535)
4200 # send HA session add events to failover/passive
4201 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4202 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4203 UDP(sport=12346, dport=12345) /
4204 HANATStateSync(sequence_number=1, events=[
4205 Event(event_type='add', protocol='tcp',
4206 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4207 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4208 eh_addr=self.pg1.remote_ip4,
4209 ehn_addr=self.pg1.remote_ip4,
4210 eh_port=self.tcp_external_port,
4211 ehn_port=self.tcp_external_port, fib_index=0),
4212 Event(event_type='add', protocol='udp',
4213 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4214 in_port=self.udp_port_in, out_port=self.udp_port_out,
4215 eh_addr=self.pg1.remote_ip4,
4216 ehn_addr=self.pg1.remote_ip4,
4217 eh_port=self.udp_external_port,
4218 ehn_port=self.udp_external_port, fib_index=0)]))
4220 self.pg3.add_stream(p)
4221 self.pg_enable_capture(self.pg_interfaces)
4224 capture = self.pg3.get_capture(1)
4227 hanat = p[HANATStateSync]
4229 self.logger.error(ppp("Invalid packet:", p))
4232 self.assertEqual(hanat.sequence_number, 1)
4233 self.assertEqual(hanat.flags, 'ACK')
4234 self.assertEqual(hanat.version, 1)
4235 self.assertEqual(hanat.thread_index, 0)
4236 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4237 self.assertEqual(stats[0][0], 1)
4238 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4239 self.assertEqual(stats[0][0], 2)
4240 users = self.statistics.get_counter('/nat44/total-users')
4241 self.assertEqual(users[0][0], 1)
4242 sessions = self.statistics.get_counter('/nat44/total-sessions')
4243 self.assertEqual(sessions[0][0], 2)
4244 users = self.vapi.nat44_user_dump()
4245 self.assertEqual(len(users), 1)
4246 self.assertEqual(str(users[0].ip_address),
4247 self.pg0.remote_ip4)
4248 # there should be 2 sessions created by HA
4249 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4251 self.assertEqual(len(sessions), 2)
4252 for session in sessions:
4253 self.assertEqual(str(session.inside_ip_address),
4254 self.pg0.remote_ip4)
4255 self.assertEqual(str(session.outside_ip_address),
4257 self.assertIn(session.inside_port,
4258 [self.tcp_port_in, self.udp_port_in])
4259 self.assertIn(session.outside_port,
4260 [self.tcp_port_out, self.udp_port_out])
4261 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4263 # send HA session delete event to failover/passive
4264 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4265 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4266 UDP(sport=12346, dport=12345) /
4267 HANATStateSync(sequence_number=2, events=[
4268 Event(event_type='del', protocol='udp',
4269 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4270 in_port=self.udp_port_in, out_port=self.udp_port_out,
4271 eh_addr=self.pg1.remote_ip4,
4272 ehn_addr=self.pg1.remote_ip4,
4273 eh_port=self.udp_external_port,
4274 ehn_port=self.udp_external_port, fib_index=0)]))
4276 self.pg3.add_stream(p)
4277 self.pg_enable_capture(self.pg_interfaces)
4280 capture = self.pg3.get_capture(1)
4283 hanat = p[HANATStateSync]
4285 self.logger.error(ppp("Invalid packet:", p))
4288 self.assertEqual(hanat.sequence_number, 2)
4289 self.assertEqual(hanat.flags, 'ACK')
4290 self.assertEqual(hanat.version, 1)
4291 users = self.vapi.nat44_user_dump()
4292 self.assertEqual(len(users), 1)
4293 self.assertEqual(str(users[0].ip_address),
4294 self.pg0.remote_ip4)
4295 # now we should have only 1 session, 1 deleted by HA
4296 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4298 self.assertEqual(len(sessions), 1)
4299 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4300 self.assertEqual(stats[0][0], 1)
4302 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4303 self.assertEqual(stats, 2)
4305 # send HA session refresh event to failover/passive
4306 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4307 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4308 UDP(sport=12346, dport=12345) /
4309 HANATStateSync(sequence_number=3, events=[
4310 Event(event_type='refresh', protocol='tcp',
4311 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4312 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4313 eh_addr=self.pg1.remote_ip4,
4314 ehn_addr=self.pg1.remote_ip4,
4315 eh_port=self.tcp_external_port,
4316 ehn_port=self.tcp_external_port, fib_index=0,
4317 total_bytes=1024, total_pkts=2)]))
4318 self.pg3.add_stream(p)
4319 self.pg_enable_capture(self.pg_interfaces)
4322 capture = self.pg3.get_capture(1)
4325 hanat = p[HANATStateSync]
4327 self.logger.error(ppp("Invalid packet:", p))
4330 self.assertEqual(hanat.sequence_number, 3)
4331 self.assertEqual(hanat.flags, 'ACK')
4332 self.assertEqual(hanat.version, 1)
4333 users = self.vapi.nat44_user_dump()
4334 self.assertEqual(len(users), 1)
4335 self.assertEqual(str(users[0].ip_address),
4336 self.pg0.remote_ip4)
4337 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4339 self.assertEqual(len(sessions), 1)
4340 session = sessions[0]
4341 self.assertEqual(session.total_bytes, 1024)
4342 self.assertEqual(session.total_pkts, 2)
4343 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4344 self.assertEqual(stats[0][0], 1)
4346 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4347 self.assertEqual(stats, 3)
4349 # send packet to test session created by HA
4350 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4351 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4352 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4353 self.pg1.add_stream(p)
4354 self.pg_enable_capture(self.pg_interfaces)
4356 capture = self.pg0.get_capture(1)
4362 self.logger.error(ppp("Invalid packet:", p))
4365 self.assertEqual(ip.src, self.pg1.remote_ip4)
4366 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4367 self.assertEqual(tcp.sport, self.tcp_external_port)
4368 self.assertEqual(tcp.dport, self.tcp_port_in)
4371 super(TestNAT44, self).tearDown()
4373 self.vapi.cli("clear logging")
4375 def show_commands_at_teardown(self):
4376 self.logger.info(self.vapi.cli("show nat44 addresses"))
4377 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4378 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4379 self.logger.info(self.vapi.cli("show nat44 interface address"))
4380 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4381 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4382 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4383 self.logger.info(self.vapi.cli("show nat timeouts"))
4385 self.vapi.cli("show nat addr-port-assignment-alg"))
4386 self.logger.info(self.vapi.cli("show nat ha"))
4389 class TestNAT44EndpointDependent(MethodHolder):
4390 """ Endpoint-Dependent mapping and filtering test cases """
4393 def setUpConstants(cls):
4394 super(TestNAT44EndpointDependent, cls).setUpConstants()
4395 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4398 def setUpClass(cls):
4399 super(TestNAT44EndpointDependent, cls).setUpClass()
4400 cls.vapi.cli("set log class nat level debug")
4402 cls.tcp_port_in = 6303
4403 cls.tcp_port_out = 6303
4404 cls.udp_port_in = 6304
4405 cls.udp_port_out = 6304
4406 cls.icmp_id_in = 6305
4407 cls.icmp_id_out = 6305
4408 cls.nat_addr = '10.0.0.3'
4409 cls.ipfix_src_port = 4739
4410 cls.ipfix_domain_id = 1
4411 cls.tcp_external_port = 80
4413 cls.create_pg_interfaces(range(9))
4414 cls.interfaces = list(cls.pg_interfaces[0:3])
4416 for i in cls.interfaces:
4421 cls.pg0.generate_remote_hosts(3)
4422 cls.pg0.configure_ipv4_neighbors()
4426 cls.pg4.generate_remote_hosts(2)
4427 cls.pg4.config_ip4()
4428 cls.vapi.sw_interface_add_del_address(
4429 sw_if_index=cls.pg4.sw_if_index,
4430 prefix="10.0.0.1/24")
4433 cls.pg4.resolve_arp()
4434 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4435 cls.pg4.resolve_arp()
4437 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4438 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4440 cls.pg5._local_ip4 = "10.1.1.1"
4441 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4442 cls.pg5.set_table_ip4(1)
4443 cls.pg5.config_ip4()
4445 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4446 [VppRoutePath("0.0.0.0",
4447 cls.pg5.sw_if_index)],
4452 cls.pg6._local_ip4 = "10.1.2.1"
4453 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4454 cls.pg6.set_table_ip4(1)
4455 cls.pg6.config_ip4()
4458 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4459 [VppRoutePath("0.0.0.0",
4460 cls.pg6.sw_if_index)],
4463 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4464 [VppRoutePath("0.0.0.0",
4469 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4470 [VppRoutePath("0.0.0.0", 0xffffffff,
4474 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4475 [VppRoutePath(cls.pg1.local_ip4,
4476 cls.pg1.sw_if_index)],
4483 cls.pg5.resolve_arp()
4484 cls.pg6.resolve_arp()
4487 cls.pg7.config_ip4()
4488 cls.pg7.resolve_arp()
4489 cls.pg7.generate_remote_hosts(3)
4490 cls.pg7.configure_ipv4_neighbors()
4493 cls.pg8.config_ip4()
4494 cls.pg8.resolve_arp()
4497 super(TestNAT44EndpointDependent, cls).tearDownClass()
4501 def tearDownClass(cls):
4502 super(TestNAT44EndpointDependent, cls).tearDownClass()
4504 def test_frag_in_order(self):
4505 """ NAT44 translate fragments arriving in order """
4506 self.nat44_add_address(self.nat_addr)
4507 flags = self.config_flags.NAT_IS_INSIDE
4508 self.vapi.nat44_interface_add_del_feature(
4509 sw_if_index=self.pg0.sw_if_index,
4510 flags=flags, is_add=1)
4511 self.vapi.nat44_interface_add_del_feature(
4512 sw_if_index=self.pg1.sw_if_index,
4514 self.frag_in_order(proto=IP_PROTOS.tcp)
4515 self.frag_in_order(proto=IP_PROTOS.udp)
4516 self.frag_in_order(proto=IP_PROTOS.icmp)
4518 def test_frag_in_order_dont_translate(self):
4519 """ NAT44 don't translate fragments arriving in order """
4520 flags = self.config_flags.NAT_IS_INSIDE
4521 self.vapi.nat44_interface_add_del_feature(
4522 sw_if_index=self.pg0.sw_if_index,
4523 flags=flags, is_add=1)
4524 self.vapi.nat44_interface_add_del_feature(
4525 sw_if_index=self.pg1.sw_if_index,
4527 self.vapi.nat44_forwarding_enable_disable(enable=True)
4528 reas_cfg1 = self.vapi.nat_get_reass()
4529 # this test was intermittently failing in some cases
4530 # until we temporarily bump the reassembly timeouts
4531 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4533 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4534 # restore the reassembly timeouts
4535 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4536 max_reass=reas_cfg1.ip4_max_reass,
4537 max_frag=reas_cfg1.ip4_max_frag,
4538 drop_frag=reas_cfg1.ip4_drop_frag)
4540 def test_frag_out_of_order(self):
4541 """ NAT44 translate fragments arriving out of order """
4542 self.nat44_add_address(self.nat_addr)
4543 flags = self.config_flags.NAT_IS_INSIDE
4544 self.vapi.nat44_interface_add_del_feature(
4545 sw_if_index=self.pg0.sw_if_index,
4546 flags=flags, is_add=1)
4547 self.vapi.nat44_interface_add_del_feature(
4548 sw_if_index=self.pg1.sw_if_index,
4550 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4551 self.frag_out_of_order(proto=IP_PROTOS.udp)
4552 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4554 def test_frag_out_of_order_dont_translate(self):
4555 """ NAT44 don't translate fragments arriving out of order """
4556 flags = self.config_flags.NAT_IS_INSIDE
4557 self.vapi.nat44_interface_add_del_feature(
4558 sw_if_index=self.pg0.sw_if_index,
4559 flags=flags, is_add=1)
4560 self.vapi.nat44_interface_add_del_feature(
4561 sw_if_index=self.pg1.sw_if_index,
4563 self.vapi.nat44_forwarding_enable_disable(enable=True)
4564 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4566 def test_frag_in_order_in_plus_out(self):
4567 """ in+out interface fragments in order """
4568 flags = self.config_flags.NAT_IS_INSIDE
4569 self.vapi.nat44_interface_add_del_feature(
4570 sw_if_index=self.pg0.sw_if_index,
4572 self.vapi.nat44_interface_add_del_feature(
4573 sw_if_index=self.pg0.sw_if_index,
4574 flags=flags, is_add=1)
4575 self.vapi.nat44_interface_add_del_feature(
4576 sw_if_index=self.pg1.sw_if_index,
4578 self.vapi.nat44_interface_add_del_feature(
4579 sw_if_index=self.pg1.sw_if_index,
4580 flags=flags, is_add=1)
4582 self.server = self.pg1.remote_hosts[0]
4584 self.server_in_addr = self.server.ip4
4585 self.server_out_addr = '11.11.11.11'
4586 self.server_in_port = random.randint(1025, 65535)
4587 self.server_out_port = random.randint(1025, 65535)
4589 self.nat44_add_address(self.server_out_addr)
4591 # add static mappings for server
4592 self.nat44_add_static_mapping(self.server_in_addr,
4593 self.server_out_addr,
4594 self.server_in_port,
4595 self.server_out_port,
4596 proto=IP_PROTOS.tcp)
4597 self.nat44_add_static_mapping(self.server_in_addr,
4598 self.server_out_addr,
4599 self.server_in_port,
4600 self.server_out_port,
4601 proto=IP_PROTOS.udp)
4602 self.nat44_add_static_mapping(self.server_in_addr,
4603 self.server_out_addr,
4604 proto=IP_PROTOS.icmp)
4606 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4609 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4610 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4611 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4613 def test_frag_out_of_order_in_plus_out(self):
4614 """ in+out interface fragments out of order """
4615 flags = self.config_flags.NAT_IS_INSIDE
4616 self.vapi.nat44_interface_add_del_feature(
4617 sw_if_index=self.pg0.sw_if_index,
4619 self.vapi.nat44_interface_add_del_feature(
4620 sw_if_index=self.pg0.sw_if_index,
4621 flags=flags, is_add=1)
4622 self.vapi.nat44_interface_add_del_feature(
4623 sw_if_index=self.pg1.sw_if_index,
4625 self.vapi.nat44_interface_add_del_feature(
4626 sw_if_index=self.pg1.sw_if_index,
4627 flags=flags, is_add=1)
4629 self.server = self.pg1.remote_hosts[0]
4631 self.server_in_addr = self.server.ip4
4632 self.server_out_addr = '11.11.11.11'
4633 self.server_in_port = random.randint(1025, 65535)
4634 self.server_out_port = random.randint(1025, 65535)
4636 self.nat44_add_address(self.server_out_addr)
4638 # add static mappings for server
4639 self.nat44_add_static_mapping(self.server_in_addr,
4640 self.server_out_addr,
4641 self.server_in_port,
4642 self.server_out_port,
4643 proto=IP_PROTOS.tcp)
4644 self.nat44_add_static_mapping(self.server_in_addr,
4645 self.server_out_addr,
4646 self.server_in_port,
4647 self.server_out_port,
4648 proto=IP_PROTOS.udp)
4649 self.nat44_add_static_mapping(self.server_in_addr,
4650 self.server_out_addr,
4651 proto=IP_PROTOS.icmp)
4653 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4656 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4657 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4658 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4660 def test_reass_hairpinning(self):
4661 """ NAT44 fragments hairpinning """
4662 self.server = self.pg0.remote_hosts[1]
4663 self.host_in_port = random.randint(1025, 65535)
4664 self.server_in_port = random.randint(1025, 65535)
4665 self.server_out_port = random.randint(1025, 65535)
4667 self.nat44_add_address(self.nat_addr)
4668 flags = self.config_flags.NAT_IS_INSIDE
4669 self.vapi.nat44_interface_add_del_feature(
4670 sw_if_index=self.pg0.sw_if_index,
4671 flags=flags, is_add=1)
4672 self.vapi.nat44_interface_add_del_feature(
4673 sw_if_index=self.pg1.sw_if_index,
4675 # add static mapping for server
4676 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4677 self.server_in_port,
4678 self.server_out_port,
4679 proto=IP_PROTOS.tcp)
4680 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4681 self.server_in_port,
4682 self.server_out_port,
4683 proto=IP_PROTOS.udp)
4684 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4686 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4687 self.reass_hairpinning(proto=IP_PROTOS.udp)
4688 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4690 def test_dynamic(self):
4691 """ NAT44 dynamic translation test """
4693 self.nat44_add_address(self.nat_addr)
4694 flags = self.config_flags.NAT_IS_INSIDE
4695 self.vapi.nat44_interface_add_del_feature(
4696 sw_if_index=self.pg0.sw_if_index,
4697 flags=flags, is_add=1)
4698 self.vapi.nat44_interface_add_del_feature(
4699 sw_if_index=self.pg1.sw_if_index,
4702 nat_config = self.vapi.nat_show_config()
4703 self.assertEqual(1, nat_config.endpoint_dependent)
4706 tcpn = self.statistics.get_err_counter(
4707 '/err/nat44-ed-in2out-slowpath/TCP packets')
4708 udpn = self.statistics.get_err_counter(
4709 '/err/nat44-ed-in2out-slowpath/UDP packets')
4710 icmpn = self.statistics.get_err_counter(
4711 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4712 totaln = self.statistics.get_err_counter(
4713 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4715 pkts = self.create_stream_in(self.pg0, self.pg1)
4716 self.pg0.add_stream(pkts)
4717 self.pg_enable_capture(self.pg_interfaces)
4719 capture = self.pg1.get_capture(len(pkts))
4720 self.verify_capture_out(capture)
4722 err = self.statistics.get_err_counter(
4723 '/err/nat44-ed-in2out-slowpath/TCP packets')
4724 self.assertEqual(err - tcpn, 2)
4725 err = self.statistics.get_err_counter(
4726 '/err/nat44-ed-in2out-slowpath/UDP packets')
4727 self.assertEqual(err - udpn, 1)
4728 err = self.statistics.get_err_counter(
4729 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4730 self.assertEqual(err - icmpn, 1)
4731 err = self.statistics.get_err_counter(
4732 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4733 self.assertEqual(err - totaln, 4)
4736 tcpn = self.statistics.get_err_counter(
4737 '/err/nat44-ed-out2in/TCP packets')
4738 udpn = self.statistics.get_err_counter(
4739 '/err/nat44-ed-out2in/UDP packets')
4740 icmpn = self.statistics.get_err_counter(
4741 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4742 totaln = self.statistics.get_err_counter(
4743 '/err/nat44-ed-out2in/good out2in packets processed')
4745 pkts = self.create_stream_out(self.pg1)
4746 self.pg1.add_stream(pkts)
4747 self.pg_enable_capture(self.pg_interfaces)
4749 capture = self.pg0.get_capture(len(pkts))
4750 self.verify_capture_in(capture, self.pg0)
4752 err = self.statistics.get_err_counter(
4753 '/err/nat44-ed-out2in/TCP packets')
4754 self.assertEqual(err - tcpn, 2)
4755 err = self.statistics.get_err_counter(
4756 '/err/nat44-ed-out2in/UDP packets')
4757 self.assertEqual(err - udpn, 1)
4758 err = self.statistics.get_err_counter(
4759 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4760 self.assertEqual(err - icmpn, 1)
4761 err = self.statistics.get_err_counter(
4762 '/err/nat44-ed-out2in/good out2in packets processed')
4763 self.assertEqual(err - totaln, 3)
4765 users = self.statistics.get_counter('/nat44/total-users')
4766 self.assertEqual(users[0][0], 1)
4767 sessions = self.statistics.get_counter('/nat44/total-sessions')
4768 self.assertEqual(sessions[0][0], 3)
4770 def test_dynamic_output_feature_vrf(self):
4771 """ NAT44 dynamic translation test: output-feature, VRF"""
4773 # other then default (0)
4776 self.nat44_add_address(self.nat_addr)
4777 flags = self.config_flags.NAT_IS_INSIDE
4778 self.vapi.nat44_interface_add_del_output_feature(
4779 sw_if_index=self.pg7.sw_if_index,
4780 flags=flags, is_add=1)
4781 self.vapi.nat44_interface_add_del_output_feature(
4782 sw_if_index=self.pg8.sw_if_index,
4786 self.vapi.ip_table_add_del(is_add=1, table_id=new_vrf_id)
4788 self.pg7.unconfig_ip4()
4789 self.pg7.set_table_ip4(new_vrf_id)
4790 self.pg7.config_ip4()
4791 self.pg7.resolve_arp()
4793 self.pg8.unconfig_ip4()
4794 self.pg8.set_table_ip4(new_vrf_id)
4795 self.pg8.config_ip4()
4796 self.pg8.resolve_arp()
4798 nat_config = self.vapi.nat_show_config()
4799 self.assertEqual(1, nat_config.endpoint_dependent)
4802 tcpn = self.statistics.get_err_counter(
4803 '/err/nat44-ed-in2out-slowpath/TCP packets')
4804 udpn = self.statistics.get_err_counter(
4805 '/err/nat44-ed-in2out-slowpath/UDP packets')
4806 icmpn = self.statistics.get_err_counter(
4807 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4808 totaln = self.statistics.get_err_counter(
4809 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4811 pkts = self.create_stream_in(self.pg7, self.pg8)
4812 self.pg7.add_stream(pkts)
4813 self.pg_enable_capture(self.pg_interfaces)
4815 capture = self.pg8.get_capture(len(pkts))
4816 self.verify_capture_out(capture)
4818 err = self.statistics.get_err_counter(
4819 '/err/nat44-ed-in2out-slowpath/TCP packets')
4820 self.assertEqual(err - tcpn, 2)
4821 err = self.statistics.get_err_counter(
4822 '/err/nat44-ed-in2out-slowpath/UDP packets')
4823 self.assertEqual(err - udpn, 1)
4824 err = self.statistics.get_err_counter(
4825 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4826 self.assertEqual(err - icmpn, 1)
4827 err = self.statistics.get_err_counter(
4828 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4829 self.assertEqual(err - totaln, 4)
4832 tcpn = self.statistics.get_err_counter(
4833 '/err/nat44-ed-out2in/TCP packets')
4834 udpn = self.statistics.get_err_counter(
4835 '/err/nat44-ed-out2in/UDP packets')
4836 icmpn = self.statistics.get_err_counter(
4837 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4838 totaln = self.statistics.get_err_counter(
4839 '/err/nat44-ed-out2in/good out2in packets processed')
4841 pkts = self.create_stream_out(self.pg8)
4842 self.pg8.add_stream(pkts)
4843 self.pg_enable_capture(self.pg_interfaces)
4845 capture = self.pg7.get_capture(len(pkts))
4846 self.verify_capture_in(capture, self.pg7)
4848 err = self.statistics.get_err_counter(
4849 '/err/nat44-ed-out2in/TCP packets')
4850 self.assertEqual(err - tcpn, 2)
4851 err = self.statistics.get_err_counter(
4852 '/err/nat44-ed-out2in/UDP packets')
4853 self.assertEqual(err - udpn, 1)
4854 err = self.statistics.get_err_counter(
4855 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4856 self.assertEqual(err - icmpn, 1)
4857 err = self.statistics.get_err_counter(
4858 '/err/nat44-ed-out2in/good out2in packets processed')
4859 self.assertEqual(err - totaln, 3)
4861 users = self.statistics.get_counter('/nat44/total-users')
4862 self.assertEqual(users[0][0], 1)
4863 sessions = self.statistics.get_counter('/nat44/total-sessions')
4864 self.assertEqual(sessions[0][0], 3)
4867 self.pg7.unconfig_ip4()
4868 self.pg7.set_table_ip4(1)
4869 self.pg7.config_ip4()
4870 self.pg7.resolve_arp()
4872 self.pg8.unconfig_ip4()
4873 self.pg8.set_table_ip4(1)
4874 self.pg8.config_ip4()
4875 self.pg8.resolve_arp()
4877 self.vapi.ip_table_add_del(is_add=0, table_id=new_vrf_id)
4879 def test_forwarding(self):
4880 """ NAT44 forwarding test """
4882 flags = self.config_flags.NAT_IS_INSIDE
4883 self.vapi.nat44_interface_add_del_feature(
4884 sw_if_index=self.pg0.sw_if_index,
4885 flags=flags, is_add=1)
4886 self.vapi.nat44_interface_add_del_feature(
4887 sw_if_index=self.pg1.sw_if_index,
4889 self.vapi.nat44_forwarding_enable_disable(enable=1)
4891 real_ip = self.pg0.remote_ip4
4892 alias_ip = self.nat_addr
4893 flags = self.config_flags.NAT_IS_ADDR_ONLY
4894 self.vapi.nat44_add_del_static_mapping(is_add=1,
4895 local_ip_address=real_ip,
4896 external_ip_address=alias_ip,
4897 external_sw_if_index=0xFFFFFFFF,
4901 # in2out - static mapping match
4903 pkts = self.create_stream_out(self.pg1)
4904 self.pg1.add_stream(pkts)
4905 self.pg_enable_capture(self.pg_interfaces)
4907 capture = self.pg0.get_capture(len(pkts))
4908 self.verify_capture_in(capture, self.pg0)
4910 pkts = self.create_stream_in(self.pg0, self.pg1)
4911 self.pg0.add_stream(pkts)
4912 self.pg_enable_capture(self.pg_interfaces)
4914 capture = self.pg1.get_capture(len(pkts))
4915 self.verify_capture_out(capture, same_port=True)
4917 # in2out - no static mapping match
4919 host0 = self.pg0.remote_hosts[0]
4920 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4922 pkts = self.create_stream_out(self.pg1,
4923 dst_ip=self.pg0.remote_ip4,
4924 use_inside_ports=True)
4925 self.pg1.add_stream(pkts)
4926 self.pg_enable_capture(self.pg_interfaces)
4928 capture = self.pg0.get_capture(len(pkts))
4929 self.verify_capture_in(capture, self.pg0)
4931 pkts = self.create_stream_in(self.pg0, self.pg1)
4932 self.pg0.add_stream(pkts)
4933 self.pg_enable_capture(self.pg_interfaces)
4935 capture = self.pg1.get_capture(len(pkts))
4936 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4939 self.pg0.remote_hosts[0] = host0
4941 user = self.pg0.remote_hosts[1]
4942 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4943 self.assertEqual(len(sessions), 3)
4944 self.assertTrue(sessions[0].flags &
4945 self.config_flags.NAT_IS_EXT_HOST_VALID)
4946 self.vapi.nat44_del_session(
4947 address=sessions[0].inside_ip_address,
4948 port=sessions[0].inside_port,
4949 protocol=sessions[0].protocol,
4950 flags=(self.config_flags.NAT_IS_INSIDE |
4951 self.config_flags.NAT_IS_EXT_HOST_VALID),
4952 ext_host_address=sessions[0].ext_host_address,
4953 ext_host_port=sessions[0].ext_host_port)
4954 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4955 self.assertEqual(len(sessions), 2)
4958 self.vapi.nat44_forwarding_enable_disable(enable=0)
4959 flags = self.config_flags.NAT_IS_ADDR_ONLY
4960 self.vapi.nat44_add_del_static_mapping(
4962 local_ip_address=real_ip,
4963 external_ip_address=alias_ip,
4964 external_sw_if_index=0xFFFFFFFF,
4967 def test_static_lb(self):
4968 """ NAT44 local service load balancing """
4969 external_addr_n = self.nat_addr
4972 server1 = self.pg0.remote_hosts[0]
4973 server2 = self.pg0.remote_hosts[1]
4975 locals = [{'addr': server1.ip4,
4979 {'addr': server2.ip4,
4984 self.nat44_add_address(self.nat_addr)
4985 self.vapi.nat44_add_del_lb_static_mapping(
4987 external_addr=external_addr_n,
4988 external_port=external_port,
4989 protocol=IP_PROTOS.tcp,
4990 local_num=len(locals),
4992 flags = self.config_flags.NAT_IS_INSIDE
4993 self.vapi.nat44_interface_add_del_feature(
4994 sw_if_index=self.pg0.sw_if_index,
4995 flags=flags, is_add=1)
4996 self.vapi.nat44_interface_add_del_feature(
4997 sw_if_index=self.pg1.sw_if_index,
5000 # from client to service
5001 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5002 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5003 TCP(sport=12345, dport=external_port))
5004 self.pg1.add_stream(p)
5005 self.pg_enable_capture(self.pg_interfaces)
5007 capture = self.pg0.get_capture(1)
5013 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5014 if ip.dst == server1.ip4:
5018 self.assertEqual(tcp.dport, local_port)
5019 self.assert_packet_checksums_valid(p)
5021 self.logger.error(ppp("Unexpected or invalid packet:", p))
5024 # from service back to client
5025 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5026 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5027 TCP(sport=local_port, dport=12345))
5028 self.pg0.add_stream(p)
5029 self.pg_enable_capture(self.pg_interfaces)
5031 capture = self.pg1.get_capture(1)
5036 self.assertEqual(ip.src, self.nat_addr)
5037 self.assertEqual(tcp.sport, external_port)
5038 self.assert_packet_checksums_valid(p)
5040 self.logger.error(ppp("Unexpected or invalid packet:", p))
5043 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5044 self.assertEqual(len(sessions), 1)
5045 self.assertTrue(sessions[0].flags &
5046 self.config_flags.NAT_IS_EXT_HOST_VALID)
5047 self.vapi.nat44_del_session(
5048 address=sessions[0].inside_ip_address,
5049 port=sessions[0].inside_port,
5050 protocol=sessions[0].protocol,
5051 flags=(self.config_flags.NAT_IS_INSIDE |
5052 self.config_flags.NAT_IS_EXT_HOST_VALID),
5053 ext_host_address=sessions[0].ext_host_address,
5054 ext_host_port=sessions[0].ext_host_port)
5055 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5056 self.assertEqual(len(sessions), 0)
5058 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5059 def test_static_lb_multi_clients(self):
5060 """ NAT44 local service load balancing - multiple clients"""
5062 external_addr = self.nat_addr
5065 server1 = self.pg0.remote_hosts[0]
5066 server2 = self.pg0.remote_hosts[1]
5067 server3 = self.pg0.remote_hosts[2]
5069 locals = [{'addr': server1.ip4,
5073 {'addr': server2.ip4,
5078 self.nat44_add_address(self.nat_addr)
5079 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5080 external_addr=external_addr,
5081 external_port=external_port,
5082 protocol=IP_PROTOS.tcp,
5083 local_num=len(locals),
5085 flags = self.config_flags.NAT_IS_INSIDE
5086 self.vapi.nat44_interface_add_del_feature(
5087 sw_if_index=self.pg0.sw_if_index,
5088 flags=flags, is_add=1)
5089 self.vapi.nat44_interface_add_del_feature(
5090 sw_if_index=self.pg1.sw_if_index,
5095 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5097 for client in clients:
5098 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5099 IP(src=client, dst=self.nat_addr) /
5100 TCP(sport=12345, dport=external_port))
5102 self.pg1.add_stream(pkts)
5103 self.pg_enable_capture(self.pg_interfaces)
5105 capture = self.pg0.get_capture(len(pkts))
5107 if p[IP].dst == server1.ip4:
5111 self.assertGreater(server1_n, server2_n)
5114 'addr': server3.ip4,
5121 self.vapi.nat44_lb_static_mapping_add_del_local(
5123 external_addr=external_addr,
5124 external_port=external_port,
5126 protocol=IP_PROTOS.tcp)
5130 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5132 for client in clients:
5133 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5134 IP(src=client, dst=self.nat_addr) /
5135 TCP(sport=12346, dport=external_port))
5137 self.assertGreater(len(pkts), 0)
5138 self.pg1.add_stream(pkts)
5139 self.pg_enable_capture(self.pg_interfaces)
5141 capture = self.pg0.get_capture(len(pkts))
5143 if p[IP].dst == server1.ip4:
5145 elif p[IP].dst == server2.ip4:
5149 self.assertGreater(server1_n, 0)
5150 self.assertGreater(server2_n, 0)
5151 self.assertGreater(server3_n, 0)
5154 'addr': server2.ip4,
5160 # remove one back-end
5161 self.vapi.nat44_lb_static_mapping_add_del_local(
5163 external_addr=external_addr,
5164 external_port=external_port,
5166 protocol=IP_PROTOS.tcp)
5170 self.pg1.add_stream(pkts)
5171 self.pg_enable_capture(self.pg_interfaces)
5173 capture = self.pg0.get_capture(len(pkts))
5175 if p[IP].dst == server1.ip4:
5177 elif p[IP].dst == server2.ip4:
5181 self.assertGreater(server1_n, 0)
5182 self.assertEqual(server2_n, 0)
5183 self.assertGreater(server3_n, 0)
5185 def test_static_lb_2(self):
5186 """ NAT44 local service load balancing (asymmetrical rule) """
5187 external_addr = self.nat_addr
5190 server1 = self.pg0.remote_hosts[0]
5191 server2 = self.pg0.remote_hosts[1]
5193 locals = [{'addr': server1.ip4,
5197 {'addr': server2.ip4,
5202 self.vapi.nat44_forwarding_enable_disable(enable=1)
5203 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5204 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5205 external_addr=external_addr,
5206 external_port=external_port,
5207 protocol=IP_PROTOS.tcp,
5208 local_num=len(locals),
5210 flags = self.config_flags.NAT_IS_INSIDE
5211 self.vapi.nat44_interface_add_del_feature(
5212 sw_if_index=self.pg0.sw_if_index,
5213 flags=flags, is_add=1)
5214 self.vapi.nat44_interface_add_del_feature(
5215 sw_if_index=self.pg1.sw_if_index,
5218 # from client to service
5219 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5220 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5221 TCP(sport=12345, dport=external_port))
5222 self.pg1.add_stream(p)
5223 self.pg_enable_capture(self.pg_interfaces)
5225 capture = self.pg0.get_capture(1)
5231 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5232 if ip.dst == server1.ip4:
5236 self.assertEqual(tcp.dport, local_port)
5237 self.assert_packet_checksums_valid(p)
5239 self.logger.error(ppp("Unexpected or invalid packet:", p))
5242 # from service back to client
5243 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5244 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5245 TCP(sport=local_port, dport=12345))
5246 self.pg0.add_stream(p)
5247 self.pg_enable_capture(self.pg_interfaces)
5249 capture = self.pg1.get_capture(1)
5254 self.assertEqual(ip.src, self.nat_addr)
5255 self.assertEqual(tcp.sport, external_port)
5256 self.assert_packet_checksums_valid(p)
5258 self.logger.error(ppp("Unexpected or invalid packet:", p))
5261 # from client to server (no translation)
5262 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5263 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5264 TCP(sport=12346, dport=local_port))
5265 self.pg1.add_stream(p)
5266 self.pg_enable_capture(self.pg_interfaces)
5268 capture = self.pg0.get_capture(1)
5274 self.assertEqual(ip.dst, server1.ip4)
5275 self.assertEqual(tcp.dport, local_port)
5276 self.assert_packet_checksums_valid(p)
5278 self.logger.error(ppp("Unexpected or invalid packet:", p))
5281 # from service back to client (no translation)
5282 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5283 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5284 TCP(sport=local_port, dport=12346))
5285 self.pg0.add_stream(p)
5286 self.pg_enable_capture(self.pg_interfaces)
5288 capture = self.pg1.get_capture(1)
5293 self.assertEqual(ip.src, server1.ip4)
5294 self.assertEqual(tcp.sport, local_port)
5295 self.assert_packet_checksums_valid(p)
5297 self.logger.error(ppp("Unexpected or invalid packet:", p))
5300 def test_lb_affinity(self):
5301 """ NAT44 local service load balancing affinity """
5302 external_addr = self.nat_addr
5305 server1 = self.pg0.remote_hosts[0]
5306 server2 = self.pg0.remote_hosts[1]
5308 locals = [{'addr': server1.ip4,
5312 {'addr': server2.ip4,
5317 self.nat44_add_address(self.nat_addr)
5318 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5319 external_addr=external_addr,
5320 external_port=external_port,
5321 protocol=IP_PROTOS.tcp,
5323 local_num=len(locals),
5325 flags = self.config_flags.NAT_IS_INSIDE
5326 self.vapi.nat44_interface_add_del_feature(
5327 sw_if_index=self.pg0.sw_if_index,
5328 flags=flags, is_add=1)
5329 self.vapi.nat44_interface_add_del_feature(
5330 sw_if_index=self.pg1.sw_if_index,
5333 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5334 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5335 TCP(sport=1025, dport=external_port))
5336 self.pg1.add_stream(p)
5337 self.pg_enable_capture(self.pg_interfaces)
5339 capture = self.pg0.get_capture(1)
5340 backend = capture[0][IP].dst
5342 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5343 self.assertEqual(len(sessions), 1)
5344 self.assertTrue(sessions[0].flags &
5345 self.config_flags.NAT_IS_EXT_HOST_VALID)
5346 self.vapi.nat44_del_session(
5347 address=sessions[0].inside_ip_address,
5348 port=sessions[0].inside_port,
5349 protocol=sessions[0].protocol,
5350 flags=(self.config_flags.NAT_IS_INSIDE |
5351 self.config_flags.NAT_IS_EXT_HOST_VALID),
5352 ext_host_address=sessions[0].ext_host_address,
5353 ext_host_port=sessions[0].ext_host_port)
5356 for port in range(1030, 1100):
5357 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5358 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5359 TCP(sport=port, dport=external_port))
5361 self.pg1.add_stream(pkts)
5362 self.pg_enable_capture(self.pg_interfaces)
5364 capture = self.pg0.get_capture(len(pkts))
5366 self.assertEqual(p[IP].dst, backend)
5368 def test_unknown_proto(self):
5369 """ NAT44 translate packet with unknown protocol """
5370 self.nat44_add_address(self.nat_addr)
5371 flags = self.config_flags.NAT_IS_INSIDE
5372 self.vapi.nat44_interface_add_del_feature(
5373 sw_if_index=self.pg0.sw_if_index,
5374 flags=flags, is_add=1)
5375 self.vapi.nat44_interface_add_del_feature(
5376 sw_if_index=self.pg1.sw_if_index,
5380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5381 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5382 TCP(sport=self.tcp_port_in, dport=20))
5383 self.pg0.add_stream(p)
5384 self.pg_enable_capture(self.pg_interfaces)
5386 p = self.pg1.get_capture(1)
5388 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5389 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5391 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5392 TCP(sport=1234, dport=1234))
5393 self.pg0.add_stream(p)
5394 self.pg_enable_capture(self.pg_interfaces)
5396 p = self.pg1.get_capture(1)
5399 self.assertEqual(packet[IP].src, self.nat_addr)
5400 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5401 self.assertEqual(packet.haslayer(GRE), 1)
5402 self.assert_packet_checksums_valid(packet)
5404 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5408 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5409 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5411 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5412 TCP(sport=1234, dport=1234))
5413 self.pg1.add_stream(p)
5414 self.pg_enable_capture(self.pg_interfaces)
5416 p = self.pg0.get_capture(1)
5419 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5420 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5421 self.assertEqual(packet.haslayer(GRE), 1)
5422 self.assert_packet_checksums_valid(packet)
5424 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5427 def test_hairpinning_unknown_proto(self):
5428 """ NAT44 translate packet with unknown protocol - hairpinning """
5429 host = self.pg0.remote_hosts[0]
5430 server = self.pg0.remote_hosts[1]
5432 server_out_port = 8765
5433 server_nat_ip = "10.0.0.11"
5435 self.nat44_add_address(self.nat_addr)
5436 flags = self.config_flags.NAT_IS_INSIDE
5437 self.vapi.nat44_interface_add_del_feature(
5438 sw_if_index=self.pg0.sw_if_index,
5439 flags=flags, is_add=1)
5440 self.vapi.nat44_interface_add_del_feature(
5441 sw_if_index=self.pg1.sw_if_index,
5444 # add static mapping for server
5445 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5448 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5449 IP(src=host.ip4, dst=server_nat_ip) /
5450 TCP(sport=host_in_port, dport=server_out_port))
5451 self.pg0.add_stream(p)
5452 self.pg_enable_capture(self.pg_interfaces)
5454 self.pg0.get_capture(1)
5456 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5457 IP(src=host.ip4, dst=server_nat_ip) /
5459 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5460 TCP(sport=1234, dport=1234))
5461 self.pg0.add_stream(p)
5462 self.pg_enable_capture(self.pg_interfaces)
5464 p = self.pg0.get_capture(1)
5467 self.assertEqual(packet[IP].src, self.nat_addr)
5468 self.assertEqual(packet[IP].dst, server.ip4)
5469 self.assertEqual(packet.haslayer(GRE), 1)
5470 self.assert_packet_checksums_valid(packet)
5472 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5476 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5477 IP(src=server.ip4, dst=self.nat_addr) /
5479 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5480 TCP(sport=1234, dport=1234))
5481 self.pg0.add_stream(p)
5482 self.pg_enable_capture(self.pg_interfaces)
5484 p = self.pg0.get_capture(1)
5487 self.assertEqual(packet[IP].src, server_nat_ip)
5488 self.assertEqual(packet[IP].dst, host.ip4)
5489 self.assertEqual(packet.haslayer(GRE), 1)
5490 self.assert_packet_checksums_valid(packet)
5492 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5495 def test_output_feature_and_service(self):
5496 """ NAT44 interface output feature and services """
5497 external_addr = '1.2.3.4'
5501 self.vapi.nat44_forwarding_enable_disable(enable=1)
5502 self.nat44_add_address(self.nat_addr)
5503 flags = self.config_flags.NAT_IS_ADDR_ONLY
5504 self.vapi.nat44_add_del_identity_mapping(
5505 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5506 flags=flags, is_add=1)
5507 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5508 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5509 local_port, external_port,
5510 proto=IP_PROTOS.tcp, flags=flags)
5511 flags = self.config_flags.NAT_IS_INSIDE
5512 self.vapi.nat44_interface_add_del_feature(
5513 sw_if_index=self.pg0.sw_if_index,
5515 self.vapi.nat44_interface_add_del_feature(
5516 sw_if_index=self.pg0.sw_if_index,
5517 flags=flags, is_add=1)
5518 self.vapi.nat44_interface_add_del_output_feature(
5520 sw_if_index=self.pg1.sw_if_index)
5522 # from client to service
5523 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5524 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5525 TCP(sport=12345, dport=external_port))
5526 self.pg1.add_stream(p)
5527 self.pg_enable_capture(self.pg_interfaces)
5529 capture = self.pg0.get_capture(1)
5534 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5535 self.assertEqual(tcp.dport, local_port)
5536 self.assert_packet_checksums_valid(p)
5538 self.logger.error(ppp("Unexpected or invalid packet:", p))
5541 # from service back to client
5542 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5543 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5544 TCP(sport=local_port, dport=12345))
5545 self.pg0.add_stream(p)
5546 self.pg_enable_capture(self.pg_interfaces)
5548 capture = self.pg1.get_capture(1)
5553 self.assertEqual(ip.src, external_addr)
5554 self.assertEqual(tcp.sport, external_port)
5555 self.assert_packet_checksums_valid(p)
5557 self.logger.error(ppp("Unexpected or invalid packet:", p))
5560 # from local network host to external network
5561 pkts = self.create_stream_in(self.pg0, self.pg1)
5562 self.pg0.add_stream(pkts)
5563 self.pg_enable_capture(self.pg_interfaces)
5565 capture = self.pg1.get_capture(len(pkts))
5566 self.verify_capture_out(capture)
5567 pkts = self.create_stream_in(self.pg0, self.pg1)
5568 self.pg0.add_stream(pkts)
5569 self.pg_enable_capture(self.pg_interfaces)
5571 capture = self.pg1.get_capture(len(pkts))
5572 self.verify_capture_out(capture)
5574 # from external network back to local network host
5575 pkts = self.create_stream_out(self.pg1)
5576 self.pg1.add_stream(pkts)
5577 self.pg_enable_capture(self.pg_interfaces)
5579 capture = self.pg0.get_capture(len(pkts))
5580 self.verify_capture_in(capture, self.pg0)
5582 def test_output_feature_and_service2(self):
5583 """ NAT44 interface output feature and service host direct access """
5584 self.vapi.nat44_forwarding_enable_disable(enable=1)
5585 self.nat44_add_address(self.nat_addr)
5586 self.vapi.nat44_interface_add_del_output_feature(
5588 sw_if_index=self.pg1.sw_if_index)
5590 # session initiated from service host - translate
5591 pkts = self.create_stream_in(self.pg0, self.pg1)
5592 self.pg0.add_stream(pkts)
5593 self.pg_enable_capture(self.pg_interfaces)
5595 capture = self.pg1.get_capture(len(pkts))
5596 self.verify_capture_out(capture)
5598 pkts = self.create_stream_out(self.pg1)
5599 self.pg1.add_stream(pkts)
5600 self.pg_enable_capture(self.pg_interfaces)
5602 capture = self.pg0.get_capture(len(pkts))
5603 self.verify_capture_in(capture, self.pg0)
5605 # session initiated from remote host - do not translate
5606 self.tcp_port_in = 60303
5607 self.udp_port_in = 60304
5608 self.icmp_id_in = 60305
5609 pkts = self.create_stream_out(self.pg1,
5610 self.pg0.remote_ip4,
5611 use_inside_ports=True)
5612 self.pg1.add_stream(pkts)
5613 self.pg_enable_capture(self.pg_interfaces)
5615 capture = self.pg0.get_capture(len(pkts))
5616 self.verify_capture_in(capture, self.pg0)
5618 pkts = self.create_stream_in(self.pg0, self.pg1)
5619 self.pg0.add_stream(pkts)
5620 self.pg_enable_capture(self.pg_interfaces)
5622 capture = self.pg1.get_capture(len(pkts))
5623 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5626 def test_output_feature_and_service3(self):
5627 """ NAT44 interface output feature and DST NAT """
5628 external_addr = '1.2.3.4'
5632 self.vapi.nat44_forwarding_enable_disable(enable=1)
5633 self.nat44_add_address(self.nat_addr)
5634 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5635 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5636 local_port, external_port,
5637 proto=IP_PROTOS.tcp, flags=flags)
5638 flags = self.config_flags.NAT_IS_INSIDE
5639 self.vapi.nat44_interface_add_del_feature(
5640 sw_if_index=self.pg0.sw_if_index,
5642 self.vapi.nat44_interface_add_del_feature(
5643 sw_if_index=self.pg0.sw_if_index,
5644 flags=flags, is_add=1)
5645 self.vapi.nat44_interface_add_del_output_feature(
5647 sw_if_index=self.pg1.sw_if_index)
5649 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5650 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5651 TCP(sport=12345, dport=external_port))
5652 self.pg0.add_stream(p)
5653 self.pg_enable_capture(self.pg_interfaces)
5655 capture = self.pg1.get_capture(1)
5660 self.assertEqual(ip.src, self.pg0.remote_ip4)
5661 self.assertEqual(tcp.sport, 12345)
5662 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5663 self.assertEqual(tcp.dport, local_port)
5664 self.assert_packet_checksums_valid(p)
5666 self.logger.error(ppp("Unexpected or invalid packet:", p))
5669 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5670 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5671 TCP(sport=local_port, dport=12345))
5672 self.pg1.add_stream(p)
5673 self.pg_enable_capture(self.pg_interfaces)
5675 capture = self.pg0.get_capture(1)
5680 self.assertEqual(ip.src, external_addr)
5681 self.assertEqual(tcp.sport, external_port)
5682 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5683 self.assertEqual(tcp.dport, 12345)
5684 self.assert_packet_checksums_valid(p)
5686 self.logger.error(ppp("Unexpected or invalid packet:", p))
5689 def test_next_src_nat(self):
5690 """ On way back forward packet to nat44-in2out node. """
5691 twice_nat_addr = '10.0.1.3'
5694 post_twice_nat_port = 0
5696 self.vapi.nat44_forwarding_enable_disable(enable=1)
5697 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5698 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5699 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5700 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5701 local_port, external_port,
5702 proto=IP_PROTOS.tcp, vrf_id=1,
5704 self.vapi.nat44_interface_add_del_feature(
5705 sw_if_index=self.pg6.sw_if_index,
5708 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5709 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5710 TCP(sport=12345, dport=external_port))
5711 self.pg6.add_stream(p)
5712 self.pg_enable_capture(self.pg_interfaces)
5714 capture = self.pg6.get_capture(1)
5719 self.assertEqual(ip.src, twice_nat_addr)
5720 self.assertNotEqual(tcp.sport, 12345)
5721 post_twice_nat_port = tcp.sport
5722 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5723 self.assertEqual(tcp.dport, local_port)
5724 self.assert_packet_checksums_valid(p)
5726 self.logger.error(ppp("Unexpected or invalid packet:", p))
5729 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5730 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5731 TCP(sport=local_port, dport=post_twice_nat_port))
5732 self.pg6.add_stream(p)
5733 self.pg_enable_capture(self.pg_interfaces)
5735 capture = self.pg6.get_capture(1)
5740 self.assertEqual(ip.src, self.pg1.remote_ip4)
5741 self.assertEqual(tcp.sport, external_port)
5742 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5743 self.assertEqual(tcp.dport, 12345)
5744 self.assert_packet_checksums_valid(p)
5746 self.logger.error(ppp("Unexpected or invalid packet:", p))
5749 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5751 twice_nat_addr = '10.0.1.3'
5759 port_in1 = port_in + 1
5760 port_in2 = port_in + 2
5765 server1 = self.pg0.remote_hosts[0]
5766 server2 = self.pg0.remote_hosts[1]
5778 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5781 self.nat44_add_address(self.nat_addr)
5782 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5786 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5788 flags |= self.config_flags.NAT_IS_TWICE_NAT
5791 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5793 proto=IP_PROTOS.tcp,
5796 locals = [{'addr': server1.ip4,
5800 {'addr': server2.ip4,
5804 out_addr = self.nat_addr
5806 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5807 external_addr=out_addr,
5808 external_port=port_out,
5809 protocol=IP_PROTOS.tcp,
5810 local_num=len(locals),
5812 flags = self.config_flags.NAT_IS_INSIDE
5813 self.vapi.nat44_interface_add_del_feature(
5814 sw_if_index=pg0.sw_if_index,
5815 flags=flags, is_add=1)
5816 self.vapi.nat44_interface_add_del_feature(
5817 sw_if_index=pg1.sw_if_index,
5824 assert client_id is not None
5826 client = self.pg0.remote_hosts[0]
5827 elif client_id == 2:
5828 client = self.pg0.remote_hosts[1]
5830 client = pg1.remote_hosts[0]
5831 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5832 IP(src=client.ip4, dst=self.nat_addr) /
5833 TCP(sport=eh_port_out, dport=port_out))
5835 self.pg_enable_capture(self.pg_interfaces)
5837 capture = pg0.get_capture(1)
5843 if ip.dst == server1.ip4:
5849 self.assertEqual(ip.dst, server.ip4)
5851 self.assertIn(tcp.dport, [port_in1, port_in2])
5853 self.assertEqual(tcp.dport, port_in)
5855 self.assertEqual(ip.src, twice_nat_addr)
5856 self.assertNotEqual(tcp.sport, eh_port_out)
5858 self.assertEqual(ip.src, client.ip4)
5859 self.assertEqual(tcp.sport, eh_port_out)
5861 eh_port_in = tcp.sport
5862 saved_port_in = tcp.dport
5863 self.assert_packet_checksums_valid(p)
5865 self.logger.error(ppp("Unexpected or invalid packet:", p))
5868 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5869 IP(src=server.ip4, dst=eh_addr_in) /
5870 TCP(sport=saved_port_in, dport=eh_port_in))
5872 self.pg_enable_capture(self.pg_interfaces)
5874 capture = pg1.get_capture(1)
5879 self.assertEqual(ip.dst, client.ip4)
5880 self.assertEqual(ip.src, self.nat_addr)
5881 self.assertEqual(tcp.dport, eh_port_out)
5882 self.assertEqual(tcp.sport, port_out)
5883 self.assert_packet_checksums_valid(p)
5885 self.logger.error(ppp("Unexpected or invalid packet:", p))
5889 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5890 self.assertEqual(len(sessions), 1)
5891 self.assertTrue(sessions[0].flags &
5892 self.config_flags.NAT_IS_EXT_HOST_VALID)
5893 self.assertTrue(sessions[0].flags &
5894 self.config_flags.NAT_IS_TWICE_NAT)
5895 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5896 self.vapi.nat44_del_session(
5897 address=sessions[0].inside_ip_address,
5898 port=sessions[0].inside_port,
5899 protocol=sessions[0].protocol,
5900 flags=(self.config_flags.NAT_IS_INSIDE |
5901 self.config_flags.NAT_IS_EXT_HOST_VALID),
5902 ext_host_address=sessions[0].ext_host_nat_address,
5903 ext_host_port=sessions[0].ext_host_nat_port)
5904 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5905 self.assertEqual(len(sessions), 0)
5907 def test_twice_nat(self):
5909 self.twice_nat_common()
5911 def test_self_twice_nat_positive(self):
5912 """ Self Twice NAT44 (positive test) """
5913 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5915 def test_self_twice_nat_negative(self):
5916 """ Self Twice NAT44 (negative test) """
5917 self.twice_nat_common(self_twice_nat=True)
5919 def test_twice_nat_lb(self):
5920 """ Twice NAT44 local service load balancing """
5921 self.twice_nat_common(lb=True)
5923 def test_self_twice_nat_lb_positive(self):
5924 """ Self Twice NAT44 local service load balancing (positive test) """
5925 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5928 def test_self_twice_nat_lb_negative(self):
5929 """ Self Twice NAT44 local service load balancing (negative test) """
5930 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5933 def test_twice_nat_interface_addr(self):
5934 """ Acquire twice NAT44 addresses from interface """
5935 flags = self.config_flags.NAT_IS_TWICE_NAT
5936 self.vapi.nat44_add_del_interface_addr(
5938 sw_if_index=self.pg3.sw_if_index,
5941 # no address in NAT pool
5942 adresses = self.vapi.nat44_address_dump()
5943 self.assertEqual(0, len(adresses))
5945 # configure interface address and check NAT address pool
5946 self.pg3.config_ip4()
5947 adresses = self.vapi.nat44_address_dump()
5948 self.assertEqual(1, len(adresses))
5949 self.assertEqual(str(adresses[0].ip_address),
5951 self.assertEqual(adresses[0].flags, flags)
5953 # remove interface address and check NAT address pool
5954 self.pg3.unconfig_ip4()
5955 adresses = self.vapi.nat44_address_dump()
5956 self.assertEqual(0, len(adresses))
5958 def test_tcp_close(self):
5959 """ Close TCP session from inside network - output feature """
5960 self.vapi.nat44_forwarding_enable_disable(enable=1)
5961 self.nat44_add_address(self.pg1.local_ip4)
5962 twice_nat_addr = '10.0.1.3'
5963 service_ip = '192.168.16.150'
5964 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5965 flags = self.config_flags.NAT_IS_INSIDE
5966 self.vapi.nat44_interface_add_del_feature(
5967 sw_if_index=self.pg0.sw_if_index,
5969 self.vapi.nat44_interface_add_del_feature(
5970 sw_if_index=self.pg0.sw_if_index,
5971 flags=flags, is_add=1)
5972 self.vapi.nat44_interface_add_del_output_feature(
5974 sw_if_index=self.pg1.sw_if_index)
5975 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5976 self.config_flags.NAT_IS_TWICE_NAT)
5977 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5981 proto=IP_PROTOS.tcp,
5983 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5984 start_sessnum = len(sessions)
5986 # SYN packet out->in
5987 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5988 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5989 TCP(sport=33898, dport=80, flags="S"))
5990 self.pg1.add_stream(p)
5991 self.pg_enable_capture(self.pg_interfaces)
5993 capture = self.pg0.get_capture(1)
5995 tcp_port = p[TCP].sport
5997 # SYN + ACK packet in->out
5998 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5999 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6000 TCP(sport=80, dport=tcp_port, flags="SA"))
6001 self.pg0.add_stream(p)
6002 self.pg_enable_capture(self.pg_interfaces)
6004 self.pg1.get_capture(1)
6006 # ACK packet out->in
6007 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6008 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6009 TCP(sport=33898, dport=80, flags="A"))
6010 self.pg1.add_stream(p)
6011 self.pg_enable_capture(self.pg_interfaces)
6013 self.pg0.get_capture(1)
6015 # FIN packet in -> out
6016 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6017 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6018 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6019 self.pg0.add_stream(p)
6020 self.pg_enable_capture(self.pg_interfaces)
6022 self.pg1.get_capture(1)
6024 # FIN+ACK packet out -> in
6025 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6026 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6027 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6028 self.pg1.add_stream(p)
6029 self.pg_enable_capture(self.pg_interfaces)
6031 self.pg0.get_capture(1)
6033 # ACK packet in -> out
6034 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6035 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6036 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6037 self.pg0.add_stream(p)
6038 self.pg_enable_capture(self.pg_interfaces)
6040 self.pg1.get_capture(1)
6042 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6044 self.assertEqual(len(sessions) - start_sessnum, 0)
6046 def test_tcp_session_close_in(self):
6047 """ Close TCP session from inside network """
6048 self.tcp_port_out = 10505
6049 self.nat44_add_address(self.nat_addr)
6050 flags = self.config_flags.NAT_IS_TWICE_NAT
6051 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6055 proto=IP_PROTOS.tcp,
6057 flags = self.config_flags.NAT_IS_INSIDE
6058 self.vapi.nat44_interface_add_del_feature(
6059 sw_if_index=self.pg0.sw_if_index,
6060 flags=flags, is_add=1)
6061 self.vapi.nat44_interface_add_del_feature(
6062 sw_if_index=self.pg1.sw_if_index,
6065 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6066 start_sessnum = len(sessions)
6068 self.initiate_tcp_session(self.pg0, self.pg1)
6070 # FIN packet in -> out
6071 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6072 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6073 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6074 flags="FA", seq=100, ack=300))
6075 self.pg0.add_stream(p)
6076 self.pg_enable_capture(self.pg_interfaces)
6078 self.pg1.get_capture(1)
6082 # ACK packet out -> in
6083 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6084 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6085 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6086 flags="A", seq=300, ack=101))
6089 # FIN packet out -> in
6090 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6091 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6092 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6093 flags="FA", seq=300, ack=101))
6096 self.pg1.add_stream(pkts)
6097 self.pg_enable_capture(self.pg_interfaces)
6099 self.pg0.get_capture(2)
6101 # ACK packet in -> out
6102 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6103 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6104 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6105 flags="A", seq=101, ack=301))
6106 self.pg0.add_stream(p)
6107 self.pg_enable_capture(self.pg_interfaces)
6109 self.pg1.get_capture(1)
6111 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6113 self.assertEqual(len(sessions) - start_sessnum, 0)
6115 def test_tcp_session_close_out(self):
6116 """ Close TCP session from outside network """
6117 self.tcp_port_out = 10505
6118 self.nat44_add_address(self.nat_addr)
6119 flags = self.config_flags.NAT_IS_TWICE_NAT
6120 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6124 proto=IP_PROTOS.tcp,
6126 flags = self.config_flags.NAT_IS_INSIDE
6127 self.vapi.nat44_interface_add_del_feature(
6128 sw_if_index=self.pg0.sw_if_index,
6129 flags=flags, is_add=1)
6130 self.vapi.nat44_interface_add_del_feature(
6131 sw_if_index=self.pg1.sw_if_index,
6134 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6135 start_sessnum = len(sessions)
6137 self.initiate_tcp_session(self.pg0, self.pg1)
6139 # FIN packet out -> in
6140 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6141 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6142 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6143 flags="FA", seq=100, ack=300))
6144 self.pg1.add_stream(p)
6145 self.pg_enable_capture(self.pg_interfaces)
6147 self.pg0.get_capture(1)
6149 # FIN+ACK packet in -> out
6150 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6151 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6152 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6153 flags="FA", seq=300, ack=101))
6155 self.pg0.add_stream(p)
6156 self.pg_enable_capture(self.pg_interfaces)
6158 self.pg1.get_capture(1)
6160 # ACK packet out -> in
6161 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6162 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6163 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6164 flags="A", seq=101, ack=301))
6165 self.pg1.add_stream(p)
6166 self.pg_enable_capture(self.pg_interfaces)
6168 self.pg0.get_capture(1)
6170 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6172 self.assertEqual(len(sessions) - start_sessnum, 0)
6174 def test_tcp_session_close_simultaneous(self):
6175 """ Close TCP session from inside network """
6176 self.tcp_port_out = 10505
6177 self.nat44_add_address(self.nat_addr)
6178 flags = self.config_flags.NAT_IS_TWICE_NAT
6179 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6183 proto=IP_PROTOS.tcp,
6185 flags = self.config_flags.NAT_IS_INSIDE
6186 self.vapi.nat44_interface_add_del_feature(
6187 sw_if_index=self.pg0.sw_if_index,
6188 flags=flags, is_add=1)
6189 self.vapi.nat44_interface_add_del_feature(
6190 sw_if_index=self.pg1.sw_if_index,
6193 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6194 start_sessnum = len(sessions)
6196 self.initiate_tcp_session(self.pg0, self.pg1)
6198 # FIN packet in -> out
6199 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6200 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6201 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6202 flags="FA", seq=100, ack=300))
6203 self.pg0.add_stream(p)
6204 self.pg_enable_capture(self.pg_interfaces)
6206 self.pg1.get_capture(1)
6208 # FIN packet out -> in
6209 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6210 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6211 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6212 flags="FA", seq=300, ack=100))
6213 self.pg1.add_stream(p)
6214 self.pg_enable_capture(self.pg_interfaces)
6216 self.pg0.get_capture(1)
6218 # ACK packet in -> out
6219 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6220 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6221 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6222 flags="A", seq=101, ack=301))
6223 self.pg0.add_stream(p)
6224 self.pg_enable_capture(self.pg_interfaces)
6226 self.pg1.get_capture(1)
6228 # ACK packet out -> in
6229 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6230 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6231 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6232 flags="A", seq=301, ack=101))
6233 self.pg1.add_stream(p)
6234 self.pg_enable_capture(self.pg_interfaces)
6236 self.pg0.get_capture(1)
6238 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6240 self.assertEqual(len(sessions) - start_sessnum, 0)
6242 def test_one_armed_nat44_static(self):
6243 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6244 remote_host = self.pg4.remote_hosts[0]
6245 local_host = self.pg4.remote_hosts[1]
6250 self.vapi.nat44_forwarding_enable_disable(enable=1)
6251 self.nat44_add_address(self.nat_addr, twice_nat=1)
6252 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6253 self.config_flags.NAT_IS_TWICE_NAT)
6254 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6255 local_port, external_port,
6256 proto=IP_PROTOS.tcp, flags=flags)
6257 flags = self.config_flags.NAT_IS_INSIDE
6258 self.vapi.nat44_interface_add_del_feature(
6259 sw_if_index=self.pg4.sw_if_index,
6261 self.vapi.nat44_interface_add_del_feature(
6262 sw_if_index=self.pg4.sw_if_index,
6263 flags=flags, is_add=1)
6265 # from client to service
6266 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6267 IP(src=remote_host.ip4, dst=self.nat_addr) /
6268 TCP(sport=12345, dport=external_port))
6269 self.pg4.add_stream(p)
6270 self.pg_enable_capture(self.pg_interfaces)
6272 capture = self.pg4.get_capture(1)
6277 self.assertEqual(ip.dst, local_host.ip4)
6278 self.assertEqual(ip.src, self.nat_addr)
6279 self.assertEqual(tcp.dport, local_port)
6280 self.assertNotEqual(tcp.sport, 12345)
6281 eh_port_in = tcp.sport
6282 self.assert_packet_checksums_valid(p)
6284 self.logger.error(ppp("Unexpected or invalid packet:", p))
6287 # from service back to client
6288 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6289 IP(src=local_host.ip4, dst=self.nat_addr) /
6290 TCP(sport=local_port, dport=eh_port_in))
6291 self.pg4.add_stream(p)
6292 self.pg_enable_capture(self.pg_interfaces)
6294 capture = self.pg4.get_capture(1)
6299 self.assertEqual(ip.src, self.nat_addr)
6300 self.assertEqual(ip.dst, remote_host.ip4)
6301 self.assertEqual(tcp.sport, external_port)
6302 self.assertEqual(tcp.dport, 12345)
6303 self.assert_packet_checksums_valid(p)
6305 self.logger.error(ppp("Unexpected or invalid packet:", p))
6308 def test_static_with_port_out2(self):
6309 """ 1:1 NAPT asymmetrical rule """
6314 self.vapi.nat44_forwarding_enable_disable(enable=1)
6315 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6316 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6317 local_port, external_port,
6318 proto=IP_PROTOS.tcp, flags=flags)
6319 flags = self.config_flags.NAT_IS_INSIDE
6320 self.vapi.nat44_interface_add_del_feature(
6321 sw_if_index=self.pg0.sw_if_index,
6322 flags=flags, is_add=1)
6323 self.vapi.nat44_interface_add_del_feature(
6324 sw_if_index=self.pg1.sw_if_index,
6327 # from client to service
6328 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6329 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6330 TCP(sport=12345, dport=external_port))
6331 self.pg1.add_stream(p)
6332 self.pg_enable_capture(self.pg_interfaces)
6334 capture = self.pg0.get_capture(1)
6339 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6340 self.assertEqual(tcp.dport, local_port)
6341 self.assert_packet_checksums_valid(p)
6343 self.logger.error(ppp("Unexpected or invalid packet:", p))
6347 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6348 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6349 ICMP(type=11) / capture[0][IP])
6350 self.pg0.add_stream(p)
6351 self.pg_enable_capture(self.pg_interfaces)
6353 capture = self.pg1.get_capture(1)
6356 self.assertEqual(p[IP].src, self.nat_addr)
6358 self.assertEqual(inner.dst, self.nat_addr)
6359 self.assertEqual(inner[TCPerror].dport, external_port)
6361 self.logger.error(ppp("Unexpected or invalid packet:", p))
6364 # from service back to client
6365 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6366 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6367 TCP(sport=local_port, dport=12345))
6368 self.pg0.add_stream(p)
6369 self.pg_enable_capture(self.pg_interfaces)
6371 capture = self.pg1.get_capture(1)
6376 self.assertEqual(ip.src, self.nat_addr)
6377 self.assertEqual(tcp.sport, external_port)
6378 self.assert_packet_checksums_valid(p)
6380 self.logger.error(ppp("Unexpected or invalid packet:", p))
6384 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6385 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6386 ICMP(type=11) / capture[0][IP])
6387 self.pg1.add_stream(p)
6388 self.pg_enable_capture(self.pg_interfaces)
6390 capture = self.pg0.get_capture(1)
6393 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6395 self.assertEqual(inner.src, self.pg0.remote_ip4)
6396 self.assertEqual(inner[TCPerror].sport, local_port)
6398 self.logger.error(ppp("Unexpected or invalid packet:", p))
6401 # from client to server (no translation)
6402 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6403 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6404 TCP(sport=12346, dport=local_port))
6405 self.pg1.add_stream(p)
6406 self.pg_enable_capture(self.pg_interfaces)
6408 capture = self.pg0.get_capture(1)
6413 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6414 self.assertEqual(tcp.dport, local_port)
6415 self.assert_packet_checksums_valid(p)
6417 self.logger.error(ppp("Unexpected or invalid packet:", p))
6420 # from service back to client (no translation)
6421 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6422 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6423 TCP(sport=local_port, dport=12346))
6424 self.pg0.add_stream(p)
6425 self.pg_enable_capture(self.pg_interfaces)
6427 capture = self.pg1.get_capture(1)
6432 self.assertEqual(ip.src, self.pg0.remote_ip4)
6433 self.assertEqual(tcp.sport, local_port)
6434 self.assert_packet_checksums_valid(p)
6436 self.logger.error(ppp("Unexpected or invalid packet:", p))
6439 def test_output_feature(self):
6440 """ NAT44 interface output feature (in2out postrouting) """
6441 self.vapi.nat44_forwarding_enable_disable(enable=1)
6442 self.nat44_add_address(self.nat_addr)
6443 self.vapi.nat44_interface_add_del_feature(
6444 sw_if_index=self.pg0.sw_if_index,
6446 self.vapi.nat44_interface_add_del_output_feature(
6448 sw_if_index=self.pg1.sw_if_index)
6451 pkts = self.create_stream_in(self.pg0, self.pg1)
6452 self.pg0.add_stream(pkts)
6453 self.pg_enable_capture(self.pg_interfaces)
6455 capture = self.pg1.get_capture(len(pkts))
6456 self.verify_capture_out(capture)
6459 pkts = self.create_stream_out(self.pg1)
6460 self.pg1.add_stream(pkts)
6461 self.pg_enable_capture(self.pg_interfaces)
6463 capture = self.pg0.get_capture(len(pkts))
6464 self.verify_capture_in(capture, self.pg0)
6466 def test_multiple_vrf(self):
6467 """ Multiple VRF setup """
6468 external_addr = '1.2.3.4'
6473 self.vapi.nat44_forwarding_enable_disable(enable=1)
6474 self.nat44_add_address(self.nat_addr)
6475 flags = self.config_flags.NAT_IS_INSIDE
6476 self.vapi.nat44_interface_add_del_feature(
6477 sw_if_index=self.pg0.sw_if_index,
6479 self.vapi.nat44_interface_add_del_feature(
6480 sw_if_index=self.pg0.sw_if_index,
6481 flags=flags, is_add=1)
6482 self.vapi.nat44_interface_add_del_output_feature(
6484 sw_if_index=self.pg1.sw_if_index)
6485 self.vapi.nat44_interface_add_del_feature(
6486 sw_if_index=self.pg5.sw_if_index,
6488 self.vapi.nat44_interface_add_del_feature(
6489 sw_if_index=self.pg5.sw_if_index,
6490 flags=flags, is_add=1)
6491 self.vapi.nat44_interface_add_del_feature(
6492 sw_if_index=self.pg6.sw_if_index,
6494 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6495 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6496 local_port, external_port, vrf_id=1,
6497 proto=IP_PROTOS.tcp, flags=flags)
6498 self.nat44_add_static_mapping(
6499 self.pg0.remote_ip4,
6500 external_sw_if_index=self.pg0.sw_if_index,
6501 local_port=local_port,
6503 external_port=external_port,
6504 proto=IP_PROTOS.tcp,
6508 # from client to service (both VRF1)
6509 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6510 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6511 TCP(sport=12345, dport=external_port))
6512 self.pg6.add_stream(p)
6513 self.pg_enable_capture(self.pg_interfaces)
6515 capture = self.pg5.get_capture(1)
6520 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6521 self.assertEqual(tcp.dport, local_port)
6522 self.assert_packet_checksums_valid(p)
6524 self.logger.error(ppp("Unexpected or invalid packet:", p))
6527 # from service back to client (both VRF1)
6528 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6529 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6530 TCP(sport=local_port, dport=12345))
6531 self.pg5.add_stream(p)
6532 self.pg_enable_capture(self.pg_interfaces)
6534 capture = self.pg6.get_capture(1)
6539 self.assertEqual(ip.src, external_addr)
6540 self.assertEqual(tcp.sport, external_port)
6541 self.assert_packet_checksums_valid(p)
6543 self.logger.error(ppp("Unexpected or invalid packet:", p))
6546 # dynamic NAT from VRF1 to VRF0 (output-feature)
6547 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6548 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6549 TCP(sport=2345, dport=22))
6550 self.pg5.add_stream(p)
6551 self.pg_enable_capture(self.pg_interfaces)
6553 capture = self.pg1.get_capture(1)
6558 self.assertEqual(ip.src, self.nat_addr)
6559 self.assertNotEqual(tcp.sport, 2345)
6560 self.assert_packet_checksums_valid(p)
6563 self.logger.error(ppp("Unexpected or invalid packet:", p))
6566 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6567 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6568 TCP(sport=22, dport=port))
6569 self.pg1.add_stream(p)
6570 self.pg_enable_capture(self.pg_interfaces)
6572 capture = self.pg5.get_capture(1)
6577 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6578 self.assertEqual(tcp.dport, 2345)
6579 self.assert_packet_checksums_valid(p)
6581 self.logger.error(ppp("Unexpected or invalid packet:", p))
6584 # from client VRF1 to service VRF0
6585 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6586 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6587 TCP(sport=12346, dport=external_port))
6588 self.pg6.add_stream(p)
6589 self.pg_enable_capture(self.pg_interfaces)
6591 capture = self.pg0.get_capture(1)
6596 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6597 self.assertEqual(tcp.dport, local_port)
6598 self.assert_packet_checksums_valid(p)
6600 self.logger.error(ppp("Unexpected or invalid packet:", p))
6603 # from service VRF0 back to client VRF1
6604 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6605 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6606 TCP(sport=local_port, dport=12346))
6607 self.pg0.add_stream(p)
6608 self.pg_enable_capture(self.pg_interfaces)
6610 capture = self.pg6.get_capture(1)
6615 self.assertEqual(ip.src, self.pg0.local_ip4)
6616 self.assertEqual(tcp.sport, external_port)
6617 self.assert_packet_checksums_valid(p)
6619 self.logger.error(ppp("Unexpected or invalid packet:", p))
6622 # from client VRF0 to service VRF1
6623 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6624 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6625 TCP(sport=12347, dport=external_port))
6626 self.pg0.add_stream(p)
6627 self.pg_enable_capture(self.pg_interfaces)
6629 capture = self.pg5.get_capture(1)
6634 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6635 self.assertEqual(tcp.dport, local_port)
6636 self.assert_packet_checksums_valid(p)
6638 self.logger.error(ppp("Unexpected or invalid packet:", p))
6641 # from service VRF1 back to client VRF0
6642 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6643 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6644 TCP(sport=local_port, dport=12347))
6645 self.pg5.add_stream(p)
6646 self.pg_enable_capture(self.pg_interfaces)
6648 capture = self.pg0.get_capture(1)
6653 self.assertEqual(ip.src, external_addr)
6654 self.assertEqual(tcp.sport, external_port)
6655 self.assert_packet_checksums_valid(p)
6657 self.logger.error(ppp("Unexpected or invalid packet:", p))
6660 # from client to server (both VRF1, no translation)
6661 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6662 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6663 TCP(sport=12348, dport=local_port))
6664 self.pg6.add_stream(p)
6665 self.pg_enable_capture(self.pg_interfaces)
6667 capture = self.pg5.get_capture(1)
6672 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6673 self.assertEqual(tcp.dport, local_port)
6674 self.assert_packet_checksums_valid(p)
6676 self.logger.error(ppp("Unexpected or invalid packet:", p))
6679 # from server back to client (both VRF1, no translation)
6680 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6681 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6682 TCP(sport=local_port, dport=12348))
6683 self.pg5.add_stream(p)
6684 self.pg_enable_capture(self.pg_interfaces)
6686 capture = self.pg6.get_capture(1)
6691 self.assertEqual(ip.src, self.pg5.remote_ip4)
6692 self.assertEqual(tcp.sport, local_port)
6693 self.assert_packet_checksums_valid(p)
6695 self.logger.error(ppp("Unexpected or invalid packet:", p))
6698 # from client VRF1 to server VRF0 (no translation)
6699 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6700 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6701 TCP(sport=local_port, dport=12349))
6702 self.pg0.add_stream(p)
6703 self.pg_enable_capture(self.pg_interfaces)
6705 capture = self.pg6.get_capture(1)
6710 self.assertEqual(ip.src, self.pg0.remote_ip4)
6711 self.assertEqual(tcp.sport, local_port)
6712 self.assert_packet_checksums_valid(p)
6714 self.logger.error(ppp("Unexpected or invalid packet:", p))
6717 # from server VRF0 back to client VRF1 (no translation)
6718 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6719 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6720 TCP(sport=local_port, dport=12349))
6721 self.pg0.add_stream(p)
6722 self.pg_enable_capture(self.pg_interfaces)
6724 capture = self.pg6.get_capture(1)
6729 self.assertEqual(ip.src, self.pg0.remote_ip4)
6730 self.assertEqual(tcp.sport, local_port)
6731 self.assert_packet_checksums_valid(p)
6733 self.logger.error(ppp("Unexpected or invalid packet:", p))
6736 # from client VRF0 to server VRF1 (no translation)
6737 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6738 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6739 TCP(sport=12344, dport=local_port))
6740 self.pg0.add_stream(p)
6741 self.pg_enable_capture(self.pg_interfaces)
6743 capture = self.pg5.get_capture(1)
6748 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6749 self.assertEqual(tcp.dport, local_port)
6750 self.assert_packet_checksums_valid(p)
6752 self.logger.error(ppp("Unexpected or invalid packet:", p))
6755 # from server VRF1 back to client VRF0 (no translation)
6756 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6757 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6758 TCP(sport=local_port, dport=12344))
6759 self.pg5.add_stream(p)
6760 self.pg_enable_capture(self.pg_interfaces)
6762 capture = self.pg0.get_capture(1)
6767 self.assertEqual(ip.src, self.pg5.remote_ip4)
6768 self.assertEqual(tcp.sport, local_port)
6769 self.assert_packet_checksums_valid(p)
6771 self.logger.error(ppp("Unexpected or invalid packet:", p))
6774 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6775 def test_session_timeout(self):
6776 """ NAT44 session timeouts """
6777 self.nat44_add_address(self.nat_addr)
6778 flags = self.config_flags.NAT_IS_INSIDE
6779 self.vapi.nat44_interface_add_del_feature(
6780 sw_if_index=self.pg0.sw_if_index,
6781 flags=flags, is_add=1)
6782 self.vapi.nat44_interface_add_del_feature(
6783 sw_if_index=self.pg1.sw_if_index,
6785 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6786 tcp_transitory=240, icmp=5)
6790 for i in range(0, max_sessions):
6791 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6792 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6793 IP(src=src, dst=self.pg1.remote_ip4) /
6794 ICMP(id=1025, type='echo-request'))
6796 self.pg0.add_stream(pkts)
6797 self.pg_enable_capture(self.pg_interfaces)
6799 self.pg1.get_capture(max_sessions)
6804 for i in range(0, max_sessions):
6805 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6806 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6807 IP(src=src, dst=self.pg1.remote_ip4) /
6808 ICMP(id=1026, type='echo-request'))
6810 self.pg0.add_stream(pkts)
6811 self.pg_enable_capture(self.pg_interfaces)
6813 self.pg1.get_capture(max_sessions)
6816 users = self.vapi.nat44_user_dump()
6818 nsessions = nsessions + user.nsessions
6819 self.assertLess(nsessions, 2 * max_sessions)
6821 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6822 def test_session_rst_timeout(self):
6823 """ NAT44 session RST timeouts """
6824 self.nat44_add_address(self.nat_addr)
6825 flags = self.config_flags.NAT_IS_INSIDE
6826 self.vapi.nat44_interface_add_del_feature(
6827 sw_if_index=self.pg0.sw_if_index,
6828 flags=flags, is_add=1)
6829 self.vapi.nat44_interface_add_del_feature(
6830 sw_if_index=self.pg1.sw_if_index,
6832 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6833 tcp_transitory=5, icmp=60)
6835 self.initiate_tcp_session(self.pg0, self.pg1)
6836 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6837 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6838 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6840 self.pg0.add_stream(p)
6841 self.pg_enable_capture(self.pg_interfaces)
6843 self.pg1.get_capture(1)
6847 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6848 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6849 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6851 self.pg0.add_stream(p)
6852 self.pg_enable_capture(self.pg_interfaces)
6854 self.pg1.get_capture(1)
6857 users = self.vapi.nat44_user_dump()
6858 self.assertEqual(len(users), 1)
6859 self.assertEqual(str(users[0].ip_address),
6860 self.pg0.remote_ip4)
6861 self.assertEqual(users[0].nsessions, 1)
6863 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6864 def test_session_limit_per_user(self):
6865 """ Maximum sessions per user limit """
6866 self.nat44_add_address(self.nat_addr)
6867 flags = self.config_flags.NAT_IS_INSIDE
6868 self.vapi.nat44_interface_add_del_feature(
6869 sw_if_index=self.pg0.sw_if_index,
6870 flags=flags, is_add=1)
6871 self.vapi.nat44_interface_add_del_feature(
6872 sw_if_index=self.pg1.sw_if_index,
6874 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
6875 src_address=self.pg2.local_ip4,
6877 template_interval=10)
6878 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6879 tcp_transitory=240, icmp=60)
6881 # get maximum number of translations per user
6882 nat44_config = self.vapi.nat_show_config()
6885 for port in range(0, nat44_config.max_translations_per_user):
6886 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6887 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6888 UDP(sport=1025 + port, dport=1025 + port))
6891 self.pg0.add_stream(pkts)
6892 self.pg_enable_capture(self.pg_interfaces)
6894 capture = self.pg1.get_capture(len(pkts))
6896 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6897 src_port=self.ipfix_src_port,
6900 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6901 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6902 UDP(sport=3001, dport=3002))
6903 self.pg0.add_stream(p)
6904 self.pg_enable_capture(self.pg_interfaces)
6906 capture = self.pg1.assert_nothing_captured()
6908 # verify IPFIX logging
6909 self.vapi.ipfix_flush()
6911 capture = self.pg2.get_capture(10)
6912 ipfix = IPFIXDecoder()
6913 # first load template
6915 self.assertTrue(p.haslayer(IPFIX))
6916 if p.haslayer(Template):
6917 ipfix.add_template(p.getlayer(Template))
6918 # verify events in data set
6920 if p.haslayer(Data):
6921 data = ipfix.decode_data_set(p.getlayer(Set))
6922 self.verify_ipfix_max_entries_per_user(
6924 nat44_config.max_translations_per_user,
6925 self.pg0.remote_ip4)
6928 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6929 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6930 UDP(sport=3001, dport=3002))
6931 self.pg0.add_stream(p)
6932 self.pg_enable_capture(self.pg_interfaces)
6934 self.pg1.get_capture(1)
6936 def test_syslog_sess(self):
6937 """ Test syslog session creation and deletion """
6938 self.vapi.syslog_set_filter(
6939 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6940 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6941 self.nat44_add_address(self.nat_addr)
6942 flags = self.config_flags.NAT_IS_INSIDE
6943 self.vapi.nat44_interface_add_del_feature(
6944 sw_if_index=self.pg0.sw_if_index,
6945 flags=flags, is_add=1)
6946 self.vapi.nat44_interface_add_del_feature(
6947 sw_if_index=self.pg1.sw_if_index,
6950 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6951 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6952 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6953 self.pg0.add_stream(p)
6954 self.pg_enable_capture(self.pg_interfaces)
6956 capture = self.pg1.get_capture(1)
6957 self.tcp_port_out = capture[0][TCP].sport
6958 capture = self.pg2.get_capture(1)
6959 self.verify_syslog_sess(capture[0][Raw].load)
6961 self.pg_enable_capture(self.pg_interfaces)
6963 self.nat44_add_address(self.nat_addr, is_add=0)
6964 capture = self.pg2.get_capture(1)
6965 self.verify_syslog_sess(capture[0][Raw].load, False)
6968 super(TestNAT44EndpointDependent, self).tearDown()
6969 if not self.vpp_dead:
6971 self.vapi.cli("clear logging")
6973 def show_commands_at_teardown(self):
6974 self.logger.info(self.vapi.cli("show nat44 addresses"))
6975 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6976 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6977 self.logger.info(self.vapi.cli("show nat44 interface address"))
6978 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6979 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6980 self.logger.info(self.vapi.cli("show nat timeouts"))
6983 class TestNAT44Out2InDPO(MethodHolder):
6984 """ NAT44 Test Cases using out2in DPO """
6987 def setUpConstants(cls):
6988 super(TestNAT44Out2InDPO, cls).setUpConstants()
6989 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6992 def setUpClass(cls):
6993 super(TestNAT44Out2InDPO, cls).setUpClass()
6994 cls.vapi.cli("set log class nat level debug")
6997 cls.tcp_port_in = 6303
6998 cls.tcp_port_out = 6303
6999 cls.udp_port_in = 6304
7000 cls.udp_port_out = 6304
7001 cls.icmp_id_in = 6305
7002 cls.icmp_id_out = 6305
7003 cls.nat_addr = '10.0.0.3'
7004 cls.dst_ip4 = '192.168.70.1'
7006 cls.create_pg_interfaces(range(2))
7009 cls.pg0.config_ip4()
7010 cls.pg0.resolve_arp()
7013 cls.pg1.config_ip6()
7014 cls.pg1.resolve_ndp()
7016 r1 = VppIpRoute(cls, "::", 0,
7017 [VppRoutePath(cls.pg1.remote_ip6,
7018 cls.pg1.sw_if_index)],
7023 super(TestNAT44Out2InDPO, cls).tearDownClass()
7027 def tearDownClass(cls):
7028 super(TestNAT44Out2InDPO, cls).tearDownClass()
7030 def configure_xlat(self):
7031 self.dst_ip6_pfx = '1:2:3::'
7032 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7034 self.dst_ip6_pfx_len = 96
7035 self.src_ip6_pfx = '4:5:6::'
7036 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7038 self.src_ip6_pfx_len = 96
7039 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7040 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7041 '\x00\x00\x00\x00', 0)
7043 @unittest.skip('Temporary disabled')
7044 def test_464xlat_ce(self):
7045 """ Test 464XLAT CE with NAT44 """
7047 nat_config = self.vapi.nat_show_config()
7048 self.assertEqual(1, nat_config.out2in_dpo)
7050 self.configure_xlat()
7052 flags = self.config_flags.NAT_IS_INSIDE
7053 self.vapi.nat44_interface_add_del_feature(
7054 sw_if_index=self.pg0.sw_if_index,
7055 flags=flags, is_add=1)
7056 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7057 last_ip_address=self.nat_addr_n,
7058 vrf_id=0xFFFFFFFF, is_add=1)
7060 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7061 self.dst_ip6_pfx_len)
7062 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7063 self.src_ip6_pfx_len)
7066 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7067 self.pg0.add_stream(pkts)
7068 self.pg_enable_capture(self.pg_interfaces)
7070 capture = self.pg1.get_capture(len(pkts))
7071 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7074 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7076 self.pg1.add_stream(pkts)
7077 self.pg_enable_capture(self.pg_interfaces)
7079 capture = self.pg0.get_capture(len(pkts))
7080 self.verify_capture_in(capture, self.pg0)
7082 self.vapi.nat44_interface_add_del_feature(
7083 sw_if_index=self.pg0.sw_if_index,
7085 self.vapi.nat44_add_del_address_range(
7086 first_ip_address=self.nat_addr_n,
7087 last_ip_address=self.nat_addr_n,
7090 @unittest.skip('Temporary disabled')
7091 def test_464xlat_ce_no_nat(self):
7092 """ Test 464XLAT CE without NAT44 """
7094 self.configure_xlat()
7096 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7097 self.dst_ip6_pfx_len)
7098 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7099 self.src_ip6_pfx_len)
7101 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7102 self.pg0.add_stream(pkts)
7103 self.pg_enable_capture(self.pg_interfaces)
7105 capture = self.pg1.get_capture(len(pkts))
7106 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7107 nat_ip=out_dst_ip6, same_port=True)
7109 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7110 self.pg1.add_stream(pkts)
7111 self.pg_enable_capture(self.pg_interfaces)
7113 capture = self.pg0.get_capture(len(pkts))
7114 self.verify_capture_in(capture, self.pg0)
7117 class TestDeterministicNAT(MethodHolder):
7118 """ Deterministic NAT Test Cases """
7121 def setUpConstants(cls):
7122 super(TestDeterministicNAT, cls).setUpConstants()
7123 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7126 def setUpClass(cls):
7127 super(TestDeterministicNAT, cls).setUpClass()
7128 cls.vapi.cli("set log class nat level debug")
7131 cls.tcp_port_in = 6303
7132 cls.tcp_external_port = 6303
7133 cls.udp_port_in = 6304
7134 cls.udp_external_port = 6304
7135 cls.icmp_id_in = 6305
7136 cls.nat_addr = '10.0.0.3'
7138 cls.create_pg_interfaces(range(3))
7139 cls.interfaces = list(cls.pg_interfaces)
7141 for i in cls.interfaces:
7146 cls.pg0.generate_remote_hosts(2)
7147 cls.pg0.configure_ipv4_neighbors()
7150 super(TestDeterministicNAT, cls).tearDownClass()
7154 def tearDownClass(cls):
7155 super(TestDeterministicNAT, cls).tearDownClass()
7157 def create_stream_in(self, in_if, out_if, ttl=64):
7159 Create packet stream for inside network
7161 :param in_if: Inside interface
7162 :param out_if: Outside interface
7163 :param ttl: TTL of generated packets
7167 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7168 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7169 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7173 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7174 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7175 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7179 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7180 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7181 ICMP(id=self.icmp_id_in, type='echo-request'))
7186 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7188 Create packet stream for outside network
7190 :param out_if: Outside interface
7191 :param dst_ip: Destination IP address (Default use global NAT address)
7192 :param ttl: TTL of generated packets
7195 dst_ip = self.nat_addr
7198 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7199 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7200 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7204 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7205 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7206 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7210 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7211 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7212 ICMP(id=self.icmp_external_id, type='echo-reply'))
7217 def verify_capture_out(self, capture, nat_ip=None):
7219 Verify captured packets on outside network
7221 :param capture: Captured packets
7222 :param nat_ip: Translated IP address (Default use global NAT address)
7223 :param same_port: Source port number is not translated (Default False)
7226 nat_ip = self.nat_addr
7227 for packet in capture:
7229 self.assertEqual(packet[IP].src, nat_ip)
7230 if packet.haslayer(TCP):
7231 self.tcp_port_out = packet[TCP].sport
7232 elif packet.haslayer(UDP):
7233 self.udp_port_out = packet[UDP].sport
7235 self.icmp_external_id = packet[ICMP].id
7237 self.logger.error(ppp("Unexpected or invalid packet "
7238 "(outside network):", packet))
7241 def test_deterministic_mode(self):
7242 """ NAT plugin run deterministic mode """
7243 in_addr = '172.16.255.0'
7244 out_addr = '172.17.255.50'
7245 in_addr_t = '172.16.255.20'
7249 nat_config = self.vapi.nat_show_config()
7250 self.assertEqual(1, nat_config.deterministic)
7252 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7253 in_plen=in_plen, out_addr=out_addr,
7256 rep1 = self.vapi.nat_det_forward(in_addr_t)
7257 self.assertEqual(str(rep1.out_addr), out_addr)
7258 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7260 self.assertEqual(str(rep2.in_addr), in_addr_t)
7262 deterministic_mappings = self.vapi.nat_det_map_dump()
7263 self.assertEqual(len(deterministic_mappings), 1)
7264 dsm = deterministic_mappings[0]
7265 self.assertEqual(in_addr, str(dsm.in_addr))
7266 self.assertEqual(in_plen, dsm.in_plen)
7267 self.assertEqual(out_addr, str(dsm.out_addr))
7268 self.assertEqual(out_plen, dsm.out_plen)
7270 self.clear_nat_det()
7271 deterministic_mappings = self.vapi.nat_det_map_dump()
7272 self.assertEqual(len(deterministic_mappings), 0)
7274 def test_set_timeouts(self):
7275 """ Set deterministic NAT timeouts """
7276 timeouts_before = self.vapi.nat_get_timeouts()
7278 self.vapi.nat_set_timeouts(
7279 udp=timeouts_before.udp + 10,
7280 tcp_established=timeouts_before.tcp_established + 10,
7281 tcp_transitory=timeouts_before.tcp_transitory + 10,
7282 icmp=timeouts_before.icmp + 10)
7284 timeouts_after = self.vapi.nat_get_timeouts()
7286 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7287 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7288 self.assertNotEqual(timeouts_before.tcp_established,
7289 timeouts_after.tcp_established)
7290 self.assertNotEqual(timeouts_before.tcp_transitory,
7291 timeouts_after.tcp_transitory)
7293 def test_det_in(self):
7294 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7296 nat_ip = "10.0.0.10"
7298 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7300 out_addr=socket.inet_aton(nat_ip),
7303 flags = self.config_flags.NAT_IS_INSIDE
7304 self.vapi.nat44_interface_add_del_feature(
7305 sw_if_index=self.pg0.sw_if_index,
7306 flags=flags, is_add=1)
7307 self.vapi.nat44_interface_add_del_feature(
7308 sw_if_index=self.pg1.sw_if_index,
7312 pkts = self.create_stream_in(self.pg0, self.pg1)
7313 self.pg0.add_stream(pkts)
7314 self.pg_enable_capture(self.pg_interfaces)
7316 capture = self.pg1.get_capture(len(pkts))
7317 self.verify_capture_out(capture, nat_ip)
7320 pkts = self.create_stream_out(self.pg1, nat_ip)
7321 self.pg1.add_stream(pkts)
7322 self.pg_enable_capture(self.pg_interfaces)
7324 capture = self.pg0.get_capture(len(pkts))
7325 self.verify_capture_in(capture, self.pg0)
7328 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7329 self.assertEqual(len(sessions), 3)
7333 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7334 self.assertEqual(s.in_port, self.tcp_port_in)
7335 self.assertEqual(s.out_port, self.tcp_port_out)
7336 self.assertEqual(s.ext_port, self.tcp_external_port)
7340 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7341 self.assertEqual(s.in_port, self.udp_port_in)
7342 self.assertEqual(s.out_port, self.udp_port_out)
7343 self.assertEqual(s.ext_port, self.udp_external_port)
7347 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7348 self.assertEqual(s.in_port, self.icmp_id_in)
7349 self.assertEqual(s.out_port, self.icmp_external_id)
7351 def test_multiple_users(self):
7352 """ Deterministic NAT multiple users """
7354 nat_ip = "10.0.0.10"
7356 external_port = 6303
7358 host0 = self.pg0.remote_hosts[0]
7359 host1 = self.pg0.remote_hosts[1]
7361 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7362 out_addr=socket.inet_aton(nat_ip),
7364 flags = self.config_flags.NAT_IS_INSIDE
7365 self.vapi.nat44_interface_add_del_feature(
7366 sw_if_index=self.pg0.sw_if_index,
7367 flags=flags, is_add=1)
7368 self.vapi.nat44_interface_add_del_feature(
7369 sw_if_index=self.pg1.sw_if_index,
7373 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7374 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7375 TCP(sport=port_in, dport=external_port))
7376 self.pg0.add_stream(p)
7377 self.pg_enable_capture(self.pg_interfaces)
7379 capture = self.pg1.get_capture(1)
7384 self.assertEqual(ip.src, nat_ip)
7385 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7386 self.assertEqual(tcp.dport, external_port)
7387 port_out0 = tcp.sport
7389 self.logger.error(ppp("Unexpected or invalid packet:", p))
7393 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7394 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7395 TCP(sport=port_in, dport=external_port))
7396 self.pg0.add_stream(p)
7397 self.pg_enable_capture(self.pg_interfaces)
7399 capture = self.pg1.get_capture(1)
7404 self.assertEqual(ip.src, nat_ip)
7405 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7406 self.assertEqual(tcp.dport, external_port)
7407 port_out1 = tcp.sport
7409 self.logger.error(ppp("Unexpected or invalid packet:", p))
7412 dms = self.vapi.nat_det_map_dump()
7413 self.assertEqual(1, len(dms))
7414 self.assertEqual(2, dms[0].ses_num)
7417 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7418 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7419 TCP(sport=external_port, dport=port_out0))
7420 self.pg1.add_stream(p)
7421 self.pg_enable_capture(self.pg_interfaces)
7423 capture = self.pg0.get_capture(1)
7428 self.assertEqual(ip.src, self.pg1.remote_ip4)
7429 self.assertEqual(ip.dst, host0.ip4)
7430 self.assertEqual(tcp.dport, port_in)
7431 self.assertEqual(tcp.sport, external_port)
7433 self.logger.error(ppp("Unexpected or invalid packet:", p))
7437 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7438 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7439 TCP(sport=external_port, dport=port_out1))
7440 self.pg1.add_stream(p)
7441 self.pg_enable_capture(self.pg_interfaces)
7443 capture = self.pg0.get_capture(1)
7448 self.assertEqual(ip.src, self.pg1.remote_ip4)
7449 self.assertEqual(ip.dst, host1.ip4)
7450 self.assertEqual(tcp.dport, port_in)
7451 self.assertEqual(tcp.sport, external_port)
7453 self.logger.error(ppp("Unexpected or invalid packet", p))
7456 # session close api test
7457 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7459 self.pg1.remote_ip4,
7461 dms = self.vapi.nat_det_map_dump()
7462 self.assertEqual(dms[0].ses_num, 1)
7464 self.vapi.nat_det_close_session_in(host0.ip4,
7466 self.pg1.remote_ip4,
7468 dms = self.vapi.nat_det_map_dump()
7469 self.assertEqual(dms[0].ses_num, 0)
7471 def test_tcp_session_close_detection_in(self):
7472 """ Deterministic NAT TCP session close from inside network """
7473 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7475 out_addr=socket.inet_aton(self.nat_addr),
7477 flags = self.config_flags.NAT_IS_INSIDE
7478 self.vapi.nat44_interface_add_del_feature(
7479 sw_if_index=self.pg0.sw_if_index,
7480 flags=flags, is_add=1)
7481 self.vapi.nat44_interface_add_del_feature(
7482 sw_if_index=self.pg1.sw_if_index,
7485 self.initiate_tcp_session(self.pg0, self.pg1)
7487 # close the session from inside
7489 # FIN packet in -> out
7490 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7491 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7492 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7494 self.pg0.add_stream(p)
7495 self.pg_enable_capture(self.pg_interfaces)
7497 self.pg1.get_capture(1)
7501 # ACK packet out -> in
7502 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7503 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7504 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7508 # FIN packet out -> in
7509 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7510 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7511 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7515 self.pg1.add_stream(pkts)
7516 self.pg_enable_capture(self.pg_interfaces)
7518 self.pg0.get_capture(2)
7520 # ACK packet in -> out
7521 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7522 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7523 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7525 self.pg0.add_stream(p)
7526 self.pg_enable_capture(self.pg_interfaces)
7528 self.pg1.get_capture(1)
7530 # Check if deterministic NAT44 closed the session
7531 dms = self.vapi.nat_det_map_dump()
7532 self.assertEqual(0, dms[0].ses_num)
7534 self.logger.error("TCP session termination failed")
7537 def test_tcp_session_close_detection_out(self):
7538 """ Deterministic NAT TCP session close from outside network """
7539 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7541 out_addr=socket.inet_aton(self.nat_addr),
7543 flags = self.config_flags.NAT_IS_INSIDE
7544 self.vapi.nat44_interface_add_del_feature(
7545 sw_if_index=self.pg0.sw_if_index,
7546 flags=flags, is_add=1)
7547 self.vapi.nat44_interface_add_del_feature(
7548 sw_if_index=self.pg1.sw_if_index,
7551 self.initiate_tcp_session(self.pg0, self.pg1)
7553 # close the session from outside
7555 # FIN packet out -> in
7556 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7557 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7558 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7560 self.pg1.add_stream(p)
7561 self.pg_enable_capture(self.pg_interfaces)
7563 self.pg0.get_capture(1)
7567 # ACK packet in -> out
7568 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7569 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7570 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7574 # ACK packet in -> out
7575 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7576 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7577 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7581 self.pg0.add_stream(pkts)
7582 self.pg_enable_capture(self.pg_interfaces)
7584 self.pg1.get_capture(2)
7586 # ACK packet out -> in
7587 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7588 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7589 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7591 self.pg1.add_stream(p)
7592 self.pg_enable_capture(self.pg_interfaces)
7594 self.pg0.get_capture(1)
7596 # Check if deterministic NAT44 closed the session
7597 dms = self.vapi.nat_det_map_dump()
7598 self.assertEqual(0, dms[0].ses_num)
7600 self.logger.error("TCP session termination failed")
7603 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7604 def test_session_timeout(self):
7605 """ Deterministic NAT session timeouts """
7606 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7608 out_addr=socket.inet_aton(self.nat_addr),
7610 flags = self.config_flags.NAT_IS_INSIDE
7611 self.vapi.nat44_interface_add_del_feature(
7612 sw_if_index=self.pg0.sw_if_index,
7613 flags=flags, is_add=1)
7614 self.vapi.nat44_interface_add_del_feature(
7615 sw_if_index=self.pg1.sw_if_index,
7618 self.initiate_tcp_session(self.pg0, self.pg1)
7619 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7621 pkts = self.create_stream_in(self.pg0, self.pg1)
7622 self.pg0.add_stream(pkts)
7623 self.pg_enable_capture(self.pg_interfaces)
7625 capture = self.pg1.get_capture(len(pkts))
7628 dms = self.vapi.nat_det_map_dump()
7629 self.assertEqual(0, dms[0].ses_num)
7631 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7632 def test_session_limit_per_user(self):
7633 """ Deterministic NAT maximum sessions per user limit """
7634 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7636 out_addr=socket.inet_aton(self.nat_addr),
7638 flags = self.config_flags.NAT_IS_INSIDE
7639 self.vapi.nat44_interface_add_del_feature(
7640 sw_if_index=self.pg0.sw_if_index,
7641 flags=flags, is_add=1)
7642 self.vapi.nat44_interface_add_del_feature(
7643 sw_if_index=self.pg1.sw_if_index,
7645 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7646 src_address=self.pg2.local_ip4,
7648 template_interval=10)
7649 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7653 for port in range(1025, 2025):
7654 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7655 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7656 UDP(sport=port, dport=port))
7659 self.pg0.add_stream(pkts)
7660 self.pg_enable_capture(self.pg_interfaces)
7662 capture = self.pg1.get_capture(len(pkts))
7664 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7665 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7666 UDP(sport=3001, dport=3002))
7667 self.pg0.add_stream(p)
7668 self.pg_enable_capture(self.pg_interfaces)
7670 capture = self.pg1.assert_nothing_captured()
7672 # verify ICMP error packet
7673 capture = self.pg0.get_capture(1)
7675 self.assertTrue(p.haslayer(ICMP))
7677 self.assertEqual(icmp.type, 3)
7678 self.assertEqual(icmp.code, 1)
7679 self.assertTrue(icmp.haslayer(IPerror))
7680 inner_ip = icmp[IPerror]
7681 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7682 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7684 dms = self.vapi.nat_det_map_dump()
7686 self.assertEqual(1000, dms[0].ses_num)
7688 # verify IPFIX logging
7689 self.vapi.ipfix_flush()
7691 capture = self.pg2.get_capture(2)
7692 ipfix = IPFIXDecoder()
7693 # first load template
7695 self.assertTrue(p.haslayer(IPFIX))
7696 if p.haslayer(Template):
7697 ipfix.add_template(p.getlayer(Template))
7698 # verify events in data set
7700 if p.haslayer(Data):
7701 data = ipfix.decode_data_set(p.getlayer(Set))
7702 self.verify_ipfix_max_entries_per_user(data,
7704 self.pg0.remote_ip4)
7706 def clear_nat_det(self):
7708 Clear deterministic NAT configuration.
7710 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7712 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7713 tcp_transitory=240, icmp=60)
7714 deterministic_mappings = self.vapi.nat_det_map_dump()
7715 for dsm in deterministic_mappings:
7716 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7717 in_plen=dsm.in_plen,
7718 out_addr=dsm.out_addr,
7719 out_plen=dsm.out_plen)
7721 interfaces = self.vapi.nat44_interface_dump()
7722 for intf in interfaces:
7723 self.vapi.nat44_interface_add_del_feature(
7724 sw_if_index=intf.sw_if_index,
7728 super(TestDeterministicNAT, self).tearDown()
7729 if not self.vpp_dead:
7730 self.clear_nat_det()
7732 def show_commands_at_teardown(self):
7733 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7734 self.logger.info(self.vapi.cli("show nat timeouts"))
7736 self.vapi.cli("show nat44 deterministic mappings"))
7738 self.vapi.cli("show nat44 deterministic sessions"))
7741 class TestNAT64(MethodHolder):
7742 """ NAT64 Test Cases """
7745 def setUpConstants(cls):
7746 super(TestNAT64, cls).setUpConstants()
7747 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7748 "nat64 st hash buckets 256", "}"])
7751 def setUpClass(cls):
7752 super(TestNAT64, cls).setUpClass()
7755 cls.tcp_port_in = 6303
7756 cls.tcp_port_out = 6303
7757 cls.udp_port_in = 6304
7758 cls.udp_port_out = 6304
7759 cls.icmp_id_in = 6305
7760 cls.icmp_id_out = 6305
7761 cls.tcp_external_port = 80
7762 cls.nat_addr = '10.0.0.3'
7763 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7765 cls.vrf1_nat_addr = '10.0.10.3'
7766 cls.ipfix_src_port = 4739
7767 cls.ipfix_domain_id = 1
7769 cls.create_pg_interfaces(range(6))
7770 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7771 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7772 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7774 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7775 table_id=cls.vrf1_id)
7777 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7779 cls.pg0.generate_remote_hosts(2)
7781 for i in cls.ip6_interfaces:
7784 i.configure_ipv6_neighbors()
7786 for i in cls.ip4_interfaces:
7792 cls.pg3.config_ip4()
7793 cls.pg3.resolve_arp()
7794 cls.pg3.config_ip6()
7795 cls.pg3.configure_ipv6_neighbors()
7798 cls.pg5.config_ip6()
7801 super(TestNAT64, cls).tearDownClass()
7805 def tearDownClass(cls):
7806 super(TestNAT64, cls).tearDownClass()
7808 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7809 """ NAT64 inside interface handles Neighbor Advertisement """
7811 flags = self.config_flags.NAT_IS_INSIDE
7812 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7813 sw_if_index=self.pg5.sw_if_index)
7816 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7817 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7818 ICMPv6EchoRequest())
7820 self.pg5.add_stream(pkts)
7821 self.pg_enable_capture(self.pg_interfaces)
7824 # Wait for Neighbor Solicitation
7825 capture = self.pg5.get_capture(len(pkts))
7828 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7829 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7830 tgt = packet[ICMPv6ND_NS].tgt
7832 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7835 # Send Neighbor Advertisement
7836 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7837 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7838 ICMPv6ND_NA(tgt=tgt) /
7839 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7841 self.pg5.add_stream(pkts)
7842 self.pg_enable_capture(self.pg_interfaces)
7845 # Try to send ping again
7847 self.pg5.add_stream(pkts)
7848 self.pg_enable_capture(self.pg_interfaces)
7851 # Wait for ping reply
7852 capture = self.pg5.get_capture(len(pkts))
7855 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7856 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7857 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7859 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7862 def test_pool(self):
7863 """ Add/delete address to NAT64 pool """
7864 nat_addr = '1.2.3.4'
7866 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7868 vrf_id=0xFFFFFFFF, is_add=1)
7870 addresses = self.vapi.nat64_pool_addr_dump()
7871 self.assertEqual(len(addresses), 1)
7872 self.assertEqual(str(addresses[0].address), nat_addr)
7874 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7876 vrf_id=0xFFFFFFFF, is_add=0)
7878 addresses = self.vapi.nat64_pool_addr_dump()
7879 self.assertEqual(len(addresses), 0)
7881 def test_interface(self):
7882 """ Enable/disable NAT64 feature on the interface """
7883 flags = self.config_flags.NAT_IS_INSIDE
7884 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7885 sw_if_index=self.pg0.sw_if_index)
7886 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7887 sw_if_index=self.pg1.sw_if_index)
7889 interfaces = self.vapi.nat64_interface_dump()
7890 self.assertEqual(len(interfaces), 2)
7893 for intf in interfaces:
7894 if intf.sw_if_index == self.pg0.sw_if_index:
7895 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7897 elif intf.sw_if_index == self.pg1.sw_if_index:
7898 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7900 self.assertTrue(pg0_found)
7901 self.assertTrue(pg1_found)
7903 features = self.vapi.cli("show interface features pg0")
7904 self.assertIn('nat64-in2out', features)
7905 features = self.vapi.cli("show interface features pg1")
7906 self.assertIn('nat64-out2in', features)
7908 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7909 sw_if_index=self.pg0.sw_if_index)
7910 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7911 sw_if_index=self.pg1.sw_if_index)
7913 interfaces = self.vapi.nat64_interface_dump()
7914 self.assertEqual(len(interfaces), 0)
7916 def test_static_bib(self):
7917 """ Add/delete static BIB entry """
7918 in_addr = '2001:db8:85a3::8a2e:370:7334'
7919 out_addr = '10.1.1.3'
7922 proto = IP_PROTOS.tcp
7924 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7925 i_port=in_port, o_port=out_port,
7926 proto=proto, vrf_id=0, is_add=1)
7927 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7930 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7932 self.assertEqual(str(bibe.i_addr), in_addr)
7933 self.assertEqual(str(bibe.o_addr), out_addr)
7934 self.assertEqual(bibe.i_port, in_port)
7935 self.assertEqual(bibe.o_port, out_port)
7936 self.assertEqual(static_bib_num, 1)
7937 bibs = self.statistics.get_counter('/nat64/total-bibs')
7938 self.assertEqual(bibs[0][0], 1)
7940 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7941 i_port=in_port, o_port=out_port,
7942 proto=proto, vrf_id=0, is_add=0)
7943 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7946 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7948 self.assertEqual(static_bib_num, 0)
7949 bibs = self.statistics.get_counter('/nat64/total-bibs')
7950 self.assertEqual(bibs[0][0], 0)
7952 def test_set_timeouts(self):
7953 """ Set NAT64 timeouts """
7954 # verify default values
7955 timeouts = self.vapi.nat_get_timeouts()
7956 self.assertEqual(timeouts.udp, 300)
7957 self.assertEqual(timeouts.icmp, 60)
7958 self.assertEqual(timeouts.tcp_transitory, 240)
7959 self.assertEqual(timeouts.tcp_established, 7440)
7961 # set and verify custom values
7962 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7963 tcp_transitory=250, icmp=30)
7964 timeouts = self.vapi.nat_get_timeouts()
7965 self.assertEqual(timeouts.udp, 200)
7966 self.assertEqual(timeouts.icmp, 30)
7967 self.assertEqual(timeouts.tcp_transitory, 250)
7968 self.assertEqual(timeouts.tcp_established, 7450)
7970 def test_dynamic(self):
7971 """ NAT64 dynamic translation test """
7972 self.tcp_port_in = 6303
7973 self.udp_port_in = 6304
7974 self.icmp_id_in = 6305
7976 ses_num_start = self.nat64_get_ses_num()
7978 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7979 end_addr=self.nat_addr,
7982 flags = self.config_flags.NAT_IS_INSIDE
7983 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7984 sw_if_index=self.pg0.sw_if_index)
7985 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7986 sw_if_index=self.pg1.sw_if_index)
7989 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7990 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7991 icmpn = self.statistics.get_err_counter(
7992 '/err/nat64-in2out/ICMP packets')
7993 totaln = self.statistics.get_err_counter(
7994 '/err/nat64-in2out/good in2out packets processed')
7996 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7997 self.pg0.add_stream(pkts)
7998 self.pg_enable_capture(self.pg_interfaces)
8000 capture = self.pg1.get_capture(len(pkts))
8001 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8002 dst_ip=self.pg1.remote_ip4)
8004 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8005 self.assertEqual(err - tcpn, 1)
8006 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8007 self.assertEqual(err - udpn, 1)
8008 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8009 self.assertEqual(err - icmpn, 1)
8010 err = self.statistics.get_err_counter(
8011 '/err/nat64-in2out/good in2out packets processed')
8012 self.assertEqual(err - totaln, 3)
8015 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8016 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8017 icmpn = self.statistics.get_err_counter(
8018 '/err/nat64-out2in/ICMP packets')
8019 totaln = self.statistics.get_err_counter(
8020 '/err/nat64-out2in/good out2in packets processed')
8022 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8023 self.pg1.add_stream(pkts)
8024 self.pg_enable_capture(self.pg_interfaces)
8026 capture = self.pg0.get_capture(len(pkts))
8027 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8028 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8030 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8031 self.assertEqual(err - tcpn, 2)
8032 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8033 self.assertEqual(err - udpn, 1)
8034 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8035 self.assertEqual(err - icmpn, 1)
8036 err = self.statistics.get_err_counter(
8037 '/err/nat64-out2in/good out2in packets processed')
8038 self.assertEqual(err - totaln, 4)
8040 bibs = self.statistics.get_counter('/nat64/total-bibs')
8041 self.assertEqual(bibs[0][0], 3)
8042 sessions = self.statistics.get_counter('/nat64/total-sessions')
8043 self.assertEqual(sessions[0][0], 3)
8046 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8047 self.pg0.add_stream(pkts)
8048 self.pg_enable_capture(self.pg_interfaces)
8050 capture = self.pg1.get_capture(len(pkts))
8051 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8052 dst_ip=self.pg1.remote_ip4)
8055 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8056 self.pg1.add_stream(pkts)
8057 self.pg_enable_capture(self.pg_interfaces)
8059 capture = self.pg0.get_capture(len(pkts))
8060 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8062 ses_num_end = self.nat64_get_ses_num()
8064 self.assertEqual(ses_num_end - ses_num_start, 3)
8066 # tenant with specific VRF
8067 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8068 end_addr=self.vrf1_nat_addr,
8069 vrf_id=self.vrf1_id, is_add=1)
8070 flags = self.config_flags.NAT_IS_INSIDE
8071 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8072 sw_if_index=self.pg2.sw_if_index)
8074 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8075 self.pg2.add_stream(pkts)
8076 self.pg_enable_capture(self.pg_interfaces)
8078 capture = self.pg1.get_capture(len(pkts))
8079 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8080 dst_ip=self.pg1.remote_ip4)
8082 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8083 self.pg1.add_stream(pkts)
8084 self.pg_enable_capture(self.pg_interfaces)
8086 capture = self.pg2.get_capture(len(pkts))
8087 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8089 def test_static(self):
8090 """ NAT64 static translation test """
8091 self.tcp_port_in = 60303
8092 self.udp_port_in = 60304
8093 self.icmp_id_in = 60305
8094 self.tcp_port_out = 60303
8095 self.udp_port_out = 60304
8096 self.icmp_id_out = 60305
8098 ses_num_start = self.nat64_get_ses_num()
8100 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8101 end_addr=self.nat_addr,
8104 flags = self.config_flags.NAT_IS_INSIDE
8105 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8106 sw_if_index=self.pg0.sw_if_index)
8107 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8108 sw_if_index=self.pg1.sw_if_index)
8110 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8111 o_addr=self.nat_addr,
8112 i_port=self.tcp_port_in,
8113 o_port=self.tcp_port_out,
8114 proto=IP_PROTOS.tcp, vrf_id=0,
8116 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8117 o_addr=self.nat_addr,
8118 i_port=self.udp_port_in,
8119 o_port=self.udp_port_out,
8120 proto=IP_PROTOS.udp, vrf_id=0,
8122 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8123 o_addr=self.nat_addr,
8124 i_port=self.icmp_id_in,
8125 o_port=self.icmp_id_out,
8126 proto=IP_PROTOS.icmp, vrf_id=0,
8130 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8131 self.pg0.add_stream(pkts)
8132 self.pg_enable_capture(self.pg_interfaces)
8134 capture = self.pg1.get_capture(len(pkts))
8135 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8136 dst_ip=self.pg1.remote_ip4, same_port=True)
8139 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8140 self.pg1.add_stream(pkts)
8141 self.pg_enable_capture(self.pg_interfaces)
8143 capture = self.pg0.get_capture(len(pkts))
8144 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8145 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8147 ses_num_end = self.nat64_get_ses_num()
8149 self.assertEqual(ses_num_end - ses_num_start, 3)
8151 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8152 def test_session_timeout(self):
8153 """ NAT64 session timeout """
8154 self.icmp_id_in = 1234
8155 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8156 end_addr=self.nat_addr,
8159 flags = self.config_flags.NAT_IS_INSIDE
8160 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8161 sw_if_index=self.pg0.sw_if_index)
8162 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8163 sw_if_index=self.pg1.sw_if_index)
8164 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8168 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8169 self.pg0.add_stream(pkts)
8170 self.pg_enable_capture(self.pg_interfaces)
8172 capture = self.pg1.get_capture(len(pkts))
8174 ses_num_before_timeout = self.nat64_get_ses_num()
8178 # ICMP and TCP session after timeout
8179 ses_num_after_timeout = self.nat64_get_ses_num()
8180 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8182 def test_icmp_error(self):
8183 """ NAT64 ICMP Error message translation """
8184 self.tcp_port_in = 6303
8185 self.udp_port_in = 6304
8186 self.icmp_id_in = 6305
8188 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8189 end_addr=self.nat_addr,
8192 flags = self.config_flags.NAT_IS_INSIDE
8193 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8194 sw_if_index=self.pg0.sw_if_index)
8195 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8196 sw_if_index=self.pg1.sw_if_index)
8198 # send some packets to create sessions
8199 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8200 self.pg0.add_stream(pkts)
8201 self.pg_enable_capture(self.pg_interfaces)
8203 capture_ip4 = self.pg1.get_capture(len(pkts))
8204 self.verify_capture_out(capture_ip4,
8205 nat_ip=self.nat_addr,
8206 dst_ip=self.pg1.remote_ip4)
8208 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8209 self.pg1.add_stream(pkts)
8210 self.pg_enable_capture(self.pg_interfaces)
8212 capture_ip6 = self.pg0.get_capture(len(pkts))
8213 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8214 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8215 self.pg0.remote_ip6)
8218 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8219 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8220 ICMPv6DestUnreach(code=1) /
8221 packet[IPv6] for packet in capture_ip6]
8222 self.pg0.add_stream(pkts)
8223 self.pg_enable_capture(self.pg_interfaces)
8225 capture = self.pg1.get_capture(len(pkts))
8226 for packet in capture:
8228 self.assertEqual(packet[IP].src, self.nat_addr)
8229 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8230 self.assertEqual(packet[ICMP].type, 3)
8231 self.assertEqual(packet[ICMP].code, 13)
8232 inner = packet[IPerror]
8233 self.assertEqual(inner.src, self.pg1.remote_ip4)
8234 self.assertEqual(inner.dst, self.nat_addr)
8235 self.assert_packet_checksums_valid(packet)
8236 if inner.haslayer(TCPerror):
8237 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8238 elif inner.haslayer(UDPerror):
8239 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8241 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8243 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8247 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8248 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8249 ICMP(type=3, code=13) /
8250 packet[IP] for packet in capture_ip4]
8251 self.pg1.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, ip.src)
8258 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8259 icmp = packet[ICMPv6DestUnreach]
8260 self.assertEqual(icmp.code, 1)
8261 inner = icmp[IPerror6]
8262 self.assertEqual(inner.src, self.pg0.remote_ip6)
8263 self.assertEqual(inner.dst, ip.src)
8264 self.assert_icmpv6_checksum_valid(packet)
8265 if inner.haslayer(TCPerror):
8266 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8267 elif inner.haslayer(UDPerror):
8268 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8270 self.assertEqual(inner[ICMPv6EchoRequest].id,
8273 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8276 def test_hairpinning(self):
8277 """ NAT64 hairpinning """
8279 client = self.pg0.remote_hosts[0]
8280 server = self.pg0.remote_hosts[1]
8281 server_tcp_in_port = 22
8282 server_tcp_out_port = 4022
8283 server_udp_in_port = 23
8284 server_udp_out_port = 4023
8285 client_tcp_in_port = 1234
8286 client_udp_in_port = 1235
8287 client_tcp_out_port = 0
8288 client_udp_out_port = 0
8289 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8290 nat_addr_ip6 = ip.src
8292 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8293 end_addr=self.nat_addr,
8296 flags = self.config_flags.NAT_IS_INSIDE
8297 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8298 sw_if_index=self.pg0.sw_if_index)
8299 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8300 sw_if_index=self.pg1.sw_if_index)
8302 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8303 o_addr=self.nat_addr,
8304 i_port=server_tcp_in_port,
8305 o_port=server_tcp_out_port,
8306 proto=IP_PROTOS.tcp, vrf_id=0,
8308 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8309 o_addr=self.nat_addr,
8310 i_port=server_udp_in_port,
8311 o_port=server_udp_out_port,
8312 proto=IP_PROTOS.udp, vrf_id=0,
8317 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8318 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8319 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8321 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8322 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8323 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8325 self.pg0.add_stream(pkts)
8326 self.pg_enable_capture(self.pg_interfaces)
8328 capture = self.pg0.get_capture(len(pkts))
8329 for packet in capture:
8331 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8332 self.assertEqual(packet[IPv6].dst, server.ip6)
8333 self.assert_packet_checksums_valid(packet)
8334 if packet.haslayer(TCP):
8335 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8336 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8337 client_tcp_out_port = packet[TCP].sport
8339 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8340 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8341 client_udp_out_port = packet[UDP].sport
8343 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8348 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8349 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8350 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8352 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8353 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8354 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8356 self.pg0.add_stream(pkts)
8357 self.pg_enable_capture(self.pg_interfaces)
8359 capture = self.pg0.get_capture(len(pkts))
8360 for packet in capture:
8362 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8363 self.assertEqual(packet[IPv6].dst, client.ip6)
8364 self.assert_packet_checksums_valid(packet)
8365 if packet.haslayer(TCP):
8366 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8367 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8369 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8370 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8372 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8377 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8378 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8379 ICMPv6DestUnreach(code=1) /
8380 packet[IPv6] for packet in capture]
8381 self.pg0.add_stream(pkts)
8382 self.pg_enable_capture(self.pg_interfaces)
8384 capture = self.pg0.get_capture(len(pkts))
8385 for packet in capture:
8387 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8388 self.assertEqual(packet[IPv6].dst, server.ip6)
8389 icmp = packet[ICMPv6DestUnreach]
8390 self.assertEqual(icmp.code, 1)
8391 inner = icmp[IPerror6]
8392 self.assertEqual(inner.src, server.ip6)
8393 self.assertEqual(inner.dst, nat_addr_ip6)
8394 self.assert_packet_checksums_valid(packet)
8395 if inner.haslayer(TCPerror):
8396 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8397 self.assertEqual(inner[TCPerror].dport,
8398 client_tcp_out_port)
8400 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8401 self.assertEqual(inner[UDPerror].dport,
8402 client_udp_out_port)
8404 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8407 def test_prefix(self):
8408 """ NAT64 Network-Specific Prefix """
8410 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8411 end_addr=self.nat_addr,
8414 flags = self.config_flags.NAT_IS_INSIDE
8415 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8416 sw_if_index=self.pg0.sw_if_index)
8417 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8418 sw_if_index=self.pg1.sw_if_index)
8419 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8420 end_addr=self.vrf1_nat_addr,
8421 vrf_id=self.vrf1_id, is_add=1)
8422 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8423 sw_if_index=self.pg2.sw_if_index)
8426 global_pref64 = "2001:db8::"
8427 global_pref64_len = 32
8428 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8429 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8432 prefix = self.vapi.nat64_prefix_dump()
8433 self.assertEqual(len(prefix), 1)
8434 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8435 self.assertEqual(prefix[0].vrf_id, 0)
8437 # Add tenant specific prefix
8438 vrf1_pref64 = "2001:db8:122:300::"
8439 vrf1_pref64_len = 56
8440 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8441 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8442 vrf_id=self.vrf1_id, is_add=1)
8444 prefix = self.vapi.nat64_prefix_dump()
8445 self.assertEqual(len(prefix), 2)
8448 pkts = self.create_stream_in_ip6(self.pg0,
8451 plen=global_pref64_len)
8452 self.pg0.add_stream(pkts)
8453 self.pg_enable_capture(self.pg_interfaces)
8455 capture = self.pg1.get_capture(len(pkts))
8456 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8457 dst_ip=self.pg1.remote_ip4)
8459 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8460 self.pg1.add_stream(pkts)
8461 self.pg_enable_capture(self.pg_interfaces)
8463 capture = self.pg0.get_capture(len(pkts))
8464 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8467 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8469 # Tenant specific prefix
8470 pkts = self.create_stream_in_ip6(self.pg2,
8473 plen=vrf1_pref64_len)
8474 self.pg2.add_stream(pkts)
8475 self.pg_enable_capture(self.pg_interfaces)
8477 capture = self.pg1.get_capture(len(pkts))
8478 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8479 dst_ip=self.pg1.remote_ip4)
8481 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8482 self.pg1.add_stream(pkts)
8483 self.pg_enable_capture(self.pg_interfaces)
8485 capture = self.pg2.get_capture(len(pkts))
8486 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8489 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8491 def test_unknown_proto(self):
8492 """ NAT64 translate packet with unknown protocol """
8494 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8495 end_addr=self.nat_addr,
8498 flags = self.config_flags.NAT_IS_INSIDE
8499 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8500 sw_if_index=self.pg0.sw_if_index)
8501 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8502 sw_if_index=self.pg1.sw_if_index)
8503 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8507 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8508 TCP(sport=self.tcp_port_in, dport=20))
8509 self.pg0.add_stream(p)
8510 self.pg_enable_capture(self.pg_interfaces)
8512 p = self.pg1.get_capture(1)
8514 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8515 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8517 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8518 TCP(sport=1234, dport=1234))
8519 self.pg0.add_stream(p)
8520 self.pg_enable_capture(self.pg_interfaces)
8522 p = self.pg1.get_capture(1)
8525 self.assertEqual(packet[IP].src, self.nat_addr)
8526 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8527 self.assertEqual(packet.haslayer(GRE), 1)
8528 self.assert_packet_checksums_valid(packet)
8530 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8534 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8535 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8537 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8538 TCP(sport=1234, dport=1234))
8539 self.pg1.add_stream(p)
8540 self.pg_enable_capture(self.pg_interfaces)
8542 p = self.pg0.get_capture(1)
8545 self.assertEqual(packet[IPv6].src, remote_ip6)
8546 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8547 self.assertEqual(packet[IPv6].nh, 47)
8549 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8552 def test_hairpinning_unknown_proto(self):
8553 """ NAT64 translate packet with unknown protocol - hairpinning """
8555 client = self.pg0.remote_hosts[0]
8556 server = self.pg0.remote_hosts[1]
8557 server_tcp_in_port = 22
8558 server_tcp_out_port = 4022
8559 client_tcp_in_port = 1234
8560 client_tcp_out_port = 1235
8561 server_nat_ip = "10.0.0.100"
8562 client_nat_ip = "10.0.0.110"
8563 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8564 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8566 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8567 end_addr=client_nat_ip,
8570 flags = self.config_flags.NAT_IS_INSIDE
8571 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8572 sw_if_index=self.pg0.sw_if_index)
8573 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8574 sw_if_index=self.pg1.sw_if_index)
8576 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8577 o_addr=server_nat_ip,
8578 i_port=server_tcp_in_port,
8579 o_port=server_tcp_out_port,
8580 proto=IP_PROTOS.tcp, vrf_id=0,
8583 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8584 o_addr=server_nat_ip, i_port=0,
8586 proto=IP_PROTOS.gre, vrf_id=0,
8589 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8590 o_addr=client_nat_ip,
8591 i_port=client_tcp_in_port,
8592 o_port=client_tcp_out_port,
8593 proto=IP_PROTOS.tcp, vrf_id=0,
8597 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8598 IPv6(src=client.ip6, dst=server_nat_ip6) /
8599 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8600 self.pg0.add_stream(p)
8601 self.pg_enable_capture(self.pg_interfaces)
8603 p = self.pg0.get_capture(1)
8605 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8606 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8608 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8609 TCP(sport=1234, dport=1234))
8610 self.pg0.add_stream(p)
8611 self.pg_enable_capture(self.pg_interfaces)
8613 p = self.pg0.get_capture(1)
8616 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8617 self.assertEqual(packet[IPv6].dst, server.ip6)
8618 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8620 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8624 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8625 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8627 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8628 TCP(sport=1234, dport=1234))
8629 self.pg0.add_stream(p)
8630 self.pg_enable_capture(self.pg_interfaces)
8632 p = self.pg0.get_capture(1)
8635 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8636 self.assertEqual(packet[IPv6].dst, client.ip6)
8637 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8639 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8642 def test_one_armed_nat64(self):
8643 """ One armed NAT64 """
8645 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8649 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8650 end_addr=self.nat_addr,
8653 flags = self.config_flags.NAT_IS_INSIDE
8654 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8655 sw_if_index=self.pg3.sw_if_index)
8656 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8657 sw_if_index=self.pg3.sw_if_index)
8660 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8661 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8662 TCP(sport=12345, dport=80))
8663 self.pg3.add_stream(p)
8664 self.pg_enable_capture(self.pg_interfaces)
8666 capture = self.pg3.get_capture(1)
8671 self.assertEqual(ip.src, self.nat_addr)
8672 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8673 self.assertNotEqual(tcp.sport, 12345)
8674 external_port = tcp.sport
8675 self.assertEqual(tcp.dport, 80)
8676 self.assert_packet_checksums_valid(p)
8678 self.logger.error(ppp("Unexpected or invalid packet:", p))
8682 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8683 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8684 TCP(sport=80, dport=external_port))
8685 self.pg3.add_stream(p)
8686 self.pg_enable_capture(self.pg_interfaces)
8688 capture = self.pg3.get_capture(1)
8693 self.assertEqual(ip.src, remote_host_ip6)
8694 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8695 self.assertEqual(tcp.sport, 80)
8696 self.assertEqual(tcp.dport, 12345)
8697 self.assert_packet_checksums_valid(p)
8699 self.logger.error(ppp("Unexpected or invalid packet:", p))
8702 def test_frag_in_order(self):
8703 """ NAT64 translate fragments arriving in order """
8704 self.tcp_port_in = random.randint(1025, 65535)
8706 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8707 end_addr=self.nat_addr,
8710 flags = self.config_flags.NAT_IS_INSIDE
8711 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8712 sw_if_index=self.pg0.sw_if_index)
8713 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8714 sw_if_index=self.pg1.sw_if_index)
8716 reass = self.vapi.nat_reass_dump()
8717 reass_n_start = len(reass)
8721 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8722 self.tcp_port_in, 20, data)
8723 self.pg0.add_stream(pkts)
8724 self.pg_enable_capture(self.pg_interfaces)
8726 frags = self.pg1.get_capture(len(pkts))
8727 p = self.reass_frags_and_verify(frags,
8729 self.pg1.remote_ip4)
8730 self.assertEqual(p[TCP].dport, 20)
8731 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8732 self.tcp_port_out = p[TCP].sport
8733 self.assertEqual(data, p[Raw].load)
8736 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8737 pkts = self.create_stream_frag(self.pg1,
8742 self.pg1.add_stream(pkts)
8743 self.pg_enable_capture(self.pg_interfaces)
8745 frags = self.pg0.get_capture(len(pkts))
8746 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8747 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8748 self.assertEqual(p[TCP].sport, 20)
8749 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8750 self.assertEqual(data, p[Raw].load)
8752 reass = self.vapi.nat_reass_dump()
8753 reass_n_end = len(reass)
8755 self.assertEqual(reass_n_end - reass_n_start, 2)
8757 def test_reass_hairpinning(self):
8758 """ NAT64 fragments hairpinning """
8760 server = self.pg0.remote_hosts[1]
8761 server_in_port = random.randint(1025, 65535)
8762 server_out_port = random.randint(1025, 65535)
8763 client_in_port = random.randint(1025, 65535)
8764 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8765 nat_addr_ip6 = ip.src
8767 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8768 end_addr=self.nat_addr,
8771 flags = self.config_flags.NAT_IS_INSIDE
8772 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8773 sw_if_index=self.pg0.sw_if_index)
8774 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8775 sw_if_index=self.pg1.sw_if_index)
8777 # add static BIB entry for server
8778 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8779 o_addr=self.nat_addr,
8780 i_port=server_in_port,
8781 o_port=server_out_port,
8782 proto=IP_PROTOS.tcp, vrf_id=0,
8785 # send packet from host to server
8786 pkts = self.create_stream_frag_ip6(self.pg0,
8791 self.pg0.add_stream(pkts)
8792 self.pg_enable_capture(self.pg_interfaces)
8794 frags = self.pg0.get_capture(len(pkts))
8795 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8796 self.assertNotEqual(p[TCP].sport, client_in_port)
8797 self.assertEqual(p[TCP].dport, server_in_port)
8798 self.assertEqual(data, p[Raw].load)
8800 def test_frag_out_of_order(self):
8801 """ NAT64 translate fragments arriving out of order """
8802 self.tcp_port_in = random.randint(1025, 65535)
8804 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8805 end_addr=self.nat_addr,
8808 flags = self.config_flags.NAT_IS_INSIDE
8809 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8810 sw_if_index=self.pg0.sw_if_index)
8811 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8812 sw_if_index=self.pg1.sw_if_index)
8816 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8817 self.tcp_port_in, 20, data)
8819 self.pg0.add_stream(pkts)
8820 self.pg_enable_capture(self.pg_interfaces)
8822 frags = self.pg1.get_capture(len(pkts))
8823 p = self.reass_frags_and_verify(frags,
8825 self.pg1.remote_ip4)
8826 self.assertEqual(p[TCP].dport, 20)
8827 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8828 self.tcp_port_out = p[TCP].sport
8829 self.assertEqual(data, p[Raw].load)
8832 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8833 pkts = self.create_stream_frag(self.pg1,
8839 self.pg1.add_stream(pkts)
8840 self.pg_enable_capture(self.pg_interfaces)
8842 frags = self.pg0.get_capture(len(pkts))
8843 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8844 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8845 self.assertEqual(p[TCP].sport, 20)
8846 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8847 self.assertEqual(data, p[Raw].load)
8849 def test_interface_addr(self):
8850 """ Acquire NAT64 pool addresses from interface """
8851 self.vapi.nat64_add_del_interface_addr(
8853 sw_if_index=self.pg4.sw_if_index)
8855 # no address in NAT64 pool
8856 addresses = self.vapi.nat44_address_dump()
8857 self.assertEqual(0, len(addresses))
8859 # configure interface address and check NAT64 address pool
8860 self.pg4.config_ip4()
8861 addresses = self.vapi.nat64_pool_addr_dump()
8862 self.assertEqual(len(addresses), 1)
8864 self.assertEqual(str(addresses[0].address),
8867 # remove interface address and check NAT64 address pool
8868 self.pg4.unconfig_ip4()
8869 addresses = self.vapi.nat64_pool_addr_dump()
8870 self.assertEqual(0, len(addresses))
8872 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8873 def test_ipfix_max_bibs_sessions(self):
8874 """ IPFIX logging maximum session and BIB entries exceeded """
8877 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8881 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8882 end_addr=self.nat_addr,
8885 flags = self.config_flags.NAT_IS_INSIDE
8886 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8887 sw_if_index=self.pg0.sw_if_index)
8888 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8889 sw_if_index=self.pg1.sw_if_index)
8893 for i in range(0, max_bibs):
8894 src = "fd01:aa::%x" % (i)
8895 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8896 IPv6(src=src, dst=remote_host_ip6) /
8897 TCP(sport=12345, dport=80))
8899 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8900 IPv6(src=src, dst=remote_host_ip6) /
8901 TCP(sport=12345, dport=22))
8903 self.pg0.add_stream(pkts)
8904 self.pg_enable_capture(self.pg_interfaces)
8906 self.pg1.get_capture(max_sessions)
8908 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8909 src_address=self.pg3.local_ip4,
8911 template_interval=10)
8912 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8913 src_port=self.ipfix_src_port,
8916 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8917 IPv6(src=src, dst=remote_host_ip6) /
8918 TCP(sport=12345, dport=25))
8919 self.pg0.add_stream(p)
8920 self.pg_enable_capture(self.pg_interfaces)
8922 self.pg1.assert_nothing_captured()
8924 self.vapi.ipfix_flush()
8925 capture = self.pg3.get_capture(9)
8926 ipfix = IPFIXDecoder()
8927 # first load template
8929 self.assertTrue(p.haslayer(IPFIX))
8930 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8931 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8932 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8933 self.assertEqual(p[UDP].dport, 4739)
8934 self.assertEqual(p[IPFIX].observationDomainID,
8935 self.ipfix_domain_id)
8936 if p.haslayer(Template):
8937 ipfix.add_template(p.getlayer(Template))
8938 # verify events in data set
8940 if p.haslayer(Data):
8941 data = ipfix.decode_data_set(p.getlayer(Set))
8942 self.verify_ipfix_max_sessions(data, max_sessions)
8944 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8945 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8946 TCP(sport=12345, dport=80))
8947 self.pg0.add_stream(p)
8948 self.pg_enable_capture(self.pg_interfaces)
8950 self.pg1.assert_nothing_captured()
8952 self.vapi.ipfix_flush()
8953 capture = self.pg3.get_capture(1)
8954 # verify events in data set
8956 self.assertTrue(p.haslayer(IPFIX))
8957 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8958 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8959 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8960 self.assertEqual(p[UDP].dport, 4739)
8961 self.assertEqual(p[IPFIX].observationDomainID,
8962 self.ipfix_domain_id)
8963 if p.haslayer(Data):
8964 data = ipfix.decode_data_set(p.getlayer(Set))
8965 self.verify_ipfix_max_bibs(data, max_bibs)
8967 def test_ipfix_max_frags(self):
8968 """ IPFIX logging maximum fragments pending reassembly exceeded """
8969 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8970 end_addr=self.nat_addr,
8973 flags = self.config_flags.NAT_IS_INSIDE
8974 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8975 sw_if_index=self.pg0.sw_if_index)
8976 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8977 sw_if_index=self.pg1.sw_if_index)
8978 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8979 drop_frag=0, is_ip6=1)
8980 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8981 src_address=self.pg3.local_ip4,
8983 template_interval=10)
8984 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8985 src_port=self.ipfix_src_port,
8989 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8990 self.tcp_port_in, 20, data)
8992 self.pg0.add_stream(pkts)
8993 self.pg_enable_capture(self.pg_interfaces)
8995 self.pg1.assert_nothing_captured()
8997 self.vapi.ipfix_flush()
8998 capture = self.pg3.get_capture(9)
8999 ipfix = IPFIXDecoder()
9000 # first load template
9002 self.assertTrue(p.haslayer(IPFIX))
9003 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9004 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9005 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9006 self.assertEqual(p[UDP].dport, 4739)
9007 self.assertEqual(p[IPFIX].observationDomainID,
9008 self.ipfix_domain_id)
9009 if p.haslayer(Template):
9010 ipfix.add_template(p.getlayer(Template))
9011 # verify events in data set
9013 if p.haslayer(Data):
9014 data = ipfix.decode_data_set(p.getlayer(Set))
9015 self.verify_ipfix_max_fragments_ip6(data, 1,
9016 self.pg0.remote_ip6n)
9018 def test_ipfix_bib_ses(self):
9019 """ IPFIX logging NAT64 BIB/session create and delete events """
9020 self.tcp_port_in = random.randint(1025, 65535)
9021 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9025 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9026 end_addr=self.nat_addr,
9029 flags = self.config_flags.NAT_IS_INSIDE
9030 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9031 sw_if_index=self.pg0.sw_if_index)
9032 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9033 sw_if_index=self.pg1.sw_if_index)
9034 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9035 src_address=self.pg3.local_ip4,
9037 template_interval=10)
9038 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9039 src_port=self.ipfix_src_port,
9043 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9044 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9045 TCP(sport=self.tcp_port_in, dport=25))
9046 self.pg0.add_stream(p)
9047 self.pg_enable_capture(self.pg_interfaces)
9049 p = self.pg1.get_capture(1)
9050 self.tcp_port_out = p[0][TCP].sport
9051 self.vapi.ipfix_flush()
9052 capture = self.pg3.get_capture(10)
9053 ipfix = IPFIXDecoder()
9054 # first load template
9056 self.assertTrue(p.haslayer(IPFIX))
9057 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9058 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9059 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9060 self.assertEqual(p[UDP].dport, 4739)
9061 self.assertEqual(p[IPFIX].observationDomainID,
9062 self.ipfix_domain_id)
9063 if p.haslayer(Template):
9064 ipfix.add_template(p.getlayer(Template))
9065 # verify events in data set
9067 if p.haslayer(Data):
9068 data = ipfix.decode_data_set(p.getlayer(Set))
9069 if scapy.compat.orb(data[0][230]) == 10:
9070 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
9071 elif scapy.compat.orb(data[0][230]) == 6:
9072 self.verify_ipfix_nat64_ses(data,
9074 self.pg0.remote_ip6n,
9075 self.pg1.remote_ip4,
9078 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9081 self.pg_enable_capture(self.pg_interfaces)
9082 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9083 end_addr=self.nat_addr,
9086 self.vapi.ipfix_flush()
9087 capture = self.pg3.get_capture(2)
9088 # verify events in data set
9090 self.assertTrue(p.haslayer(IPFIX))
9091 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9092 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9093 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9094 self.assertEqual(p[UDP].dport, 4739)
9095 self.assertEqual(p[IPFIX].observationDomainID,
9096 self.ipfix_domain_id)
9097 if p.haslayer(Data):
9098 data = ipfix.decode_data_set(p.getlayer(Set))
9099 if scapy.compat.orb(data[0][230]) == 11:
9100 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9101 elif scapy.compat.orb(data[0][230]) == 7:
9102 self.verify_ipfix_nat64_ses(data,
9104 self.pg0.remote_ip6n,
9105 self.pg1.remote_ip4,
9108 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9110 def test_syslog_sess(self):
9111 """ Test syslog session creation and deletion """
9112 self.tcp_port_in = random.randint(1025, 65535)
9113 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9117 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9118 end_addr=self.nat_addr,
9121 flags = self.config_flags.NAT_IS_INSIDE
9122 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9123 sw_if_index=self.pg0.sw_if_index)
9124 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9125 sw_if_index=self.pg1.sw_if_index)
9126 self.vapi.syslog_set_filter(
9127 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9128 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9130 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9131 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9132 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9133 self.pg0.add_stream(p)
9134 self.pg_enable_capture(self.pg_interfaces)
9136 p = self.pg1.get_capture(1)
9137 self.tcp_port_out = p[0][TCP].sport
9138 capture = self.pg3.get_capture(1)
9139 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9141 self.pg_enable_capture(self.pg_interfaces)
9143 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9144 end_addr=self.nat_addr,
9147 capture = self.pg3.get_capture(1)
9148 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9150 def nat64_get_ses_num(self):
9152 Return number of active NAT64 sessions.
9154 st = self.vapi.nat64_st_dump(proto=255)
9157 def clear_nat64(self):
9159 Clear NAT64 configuration.
9161 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9162 src_port=self.ipfix_src_port,
9164 self.ipfix_src_port = 4739
9165 self.ipfix_domain_id = 1
9167 self.vapi.syslog_set_filter(
9168 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9170 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9171 tcp_transitory=240, icmp=60)
9173 interfaces = self.vapi.nat64_interface_dump()
9174 for intf in interfaces:
9175 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9176 sw_if_index=intf.sw_if_index)
9178 bib = self.vapi.nat64_bib_dump(proto=255)
9180 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9181 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9189 adresses = self.vapi.nat64_pool_addr_dump()
9190 for addr in adresses:
9191 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9192 end_addr=addr.address,
9196 prefixes = self.vapi.nat64_prefix_dump()
9197 for prefix in prefixes:
9198 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9199 vrf_id=prefix.vrf_id, is_add=0)
9201 bibs = self.statistics.get_counter('/nat64/total-bibs')
9202 self.assertEqual(bibs[0][0], 0)
9203 sessions = self.statistics.get_counter('/nat64/total-sessions')
9204 self.assertEqual(sessions[0][0], 0)
9207 super(TestNAT64, self).tearDown()
9208 if not self.vpp_dead:
9211 def show_commands_at_teardown(self):
9212 self.logger.info(self.vapi.cli("show nat64 pool"))
9213 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9214 self.logger.info(self.vapi.cli("show nat64 prefix"))
9215 self.logger.info(self.vapi.cli("show nat64 bib all"))
9216 self.logger.info(self.vapi.cli("show nat64 session table all"))
9217 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9220 class TestDSlite(MethodHolder):
9221 """ DS-Lite Test Cases """
9224 def setUpClass(cls):
9225 super(TestDSlite, cls).setUpClass()
9228 cls.nat_addr = '10.0.0.3'
9230 cls.create_pg_interfaces(range(3))
9232 cls.pg0.config_ip4()
9233 cls.pg0.resolve_arp()
9235 cls.pg1.config_ip6()
9236 cls.pg1.generate_remote_hosts(2)
9237 cls.pg1.configure_ipv6_neighbors()
9239 cls.pg2.config_ip4()
9240 cls.pg2.resolve_arp()
9243 super(TestDSlite, cls).tearDownClass()
9247 def tearDownClass(cls):
9248 super(TestDSlite, cls).tearDownClass()
9250 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9252 message = data.decode('utf-8')
9254 message = SyslogMessage.parse(message)
9255 except ParseError as e:
9256 self.logger.error(e)
9258 self.assertEqual(message.severity, SyslogSeverity.info)
9259 self.assertEqual(message.appname, 'NAT')
9260 self.assertEqual(message.msgid, 'APMADD')
9261 sd_params = message.sd.get('napmap')
9262 self.assertTrue(sd_params is not None)
9263 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9264 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9265 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9266 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9267 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9268 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9269 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9270 self.assertTrue(sd_params.get('SSUBIX') is not None)
9271 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9273 def test_dslite(self):
9274 """ Test DS-Lite """
9275 nat_config = self.vapi.nat_show_config()
9276 self.assertEqual(0, nat_config.dslite_ce)
9278 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9279 end_addr=self.nat_addr,
9281 aftr_ip4 = '192.0.0.1'
9282 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9283 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9284 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
9287 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9288 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9289 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9290 UDP(sport=20000, dport=10000))
9291 self.pg1.add_stream(p)
9292 self.pg_enable_capture(self.pg_interfaces)
9294 capture = self.pg0.get_capture(1)
9295 capture = capture[0]
9296 self.assertFalse(capture.haslayer(IPv6))
9297 self.assertEqual(capture[IP].src, self.nat_addr)
9298 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9299 self.assertNotEqual(capture[UDP].sport, 20000)
9300 self.assertEqual(capture[UDP].dport, 10000)
9301 self.assert_packet_checksums_valid(capture)
9302 out_port = capture[UDP].sport
9303 capture = self.pg2.get_capture(1)
9304 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9305 20000, self.nat_addr, out_port,
9306 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9309 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9310 UDP(sport=10000, dport=out_port))
9311 self.pg0.add_stream(p)
9312 self.pg_enable_capture(self.pg_interfaces)
9314 capture = self.pg1.get_capture(1)
9315 capture = capture[0]
9316 self.assertEqual(capture[IPv6].src, aftr_ip6)
9317 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9318 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9319 self.assertEqual(capture[IP].dst, '192.168.1.1')
9320 self.assertEqual(capture[UDP].sport, 10000)
9321 self.assertEqual(capture[UDP].dport, 20000)
9322 self.assert_packet_checksums_valid(capture)
9325 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9326 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9327 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9328 TCP(sport=20001, dport=10001))
9329 self.pg1.add_stream(p)
9330 self.pg_enable_capture(self.pg_interfaces)
9332 capture = self.pg0.get_capture(1)
9333 capture = capture[0]
9334 self.assertFalse(capture.haslayer(IPv6))
9335 self.assertEqual(capture[IP].src, self.nat_addr)
9336 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9337 self.assertNotEqual(capture[TCP].sport, 20001)
9338 self.assertEqual(capture[TCP].dport, 10001)
9339 self.assert_packet_checksums_valid(capture)
9340 out_port = capture[TCP].sport
9342 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9343 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9344 TCP(sport=10001, dport=out_port))
9345 self.pg0.add_stream(p)
9346 self.pg_enable_capture(self.pg_interfaces)
9348 capture = self.pg1.get_capture(1)
9349 capture = capture[0]
9350 self.assertEqual(capture[IPv6].src, aftr_ip6)
9351 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9352 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9353 self.assertEqual(capture[IP].dst, '192.168.1.1')
9354 self.assertEqual(capture[TCP].sport, 10001)
9355 self.assertEqual(capture[TCP].dport, 20001)
9356 self.assert_packet_checksums_valid(capture)
9359 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9360 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9361 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9362 ICMP(id=4000, type='echo-request'))
9363 self.pg1.add_stream(p)
9364 self.pg_enable_capture(self.pg_interfaces)
9366 capture = self.pg0.get_capture(1)
9367 capture = capture[0]
9368 self.assertFalse(capture.haslayer(IPv6))
9369 self.assertEqual(capture[IP].src, self.nat_addr)
9370 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9371 self.assertNotEqual(capture[ICMP].id, 4000)
9372 self.assert_packet_checksums_valid(capture)
9373 out_id = capture[ICMP].id
9375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9376 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9377 ICMP(id=out_id, type='echo-reply'))
9378 self.pg0.add_stream(p)
9379 self.pg_enable_capture(self.pg_interfaces)
9381 capture = self.pg1.get_capture(1)
9382 capture = capture[0]
9383 self.assertEqual(capture[IPv6].src, aftr_ip6)
9384 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9385 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9386 self.assertEqual(capture[IP].dst, '192.168.1.1')
9387 self.assertEqual(capture[ICMP].id, 4000)
9388 self.assert_packet_checksums_valid(capture)
9390 # ping DS-Lite AFTR tunnel endpoint address
9391 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9392 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9393 ICMPv6EchoRequest())
9394 self.pg1.add_stream(p)
9395 self.pg_enable_capture(self.pg_interfaces)
9397 capture = self.pg1.get_capture(1)
9398 capture = capture[0]
9399 self.assertEqual(capture[IPv6].src, aftr_ip6)
9400 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9401 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9403 b4s = self.statistics.get_counter('/dslite/total-b4s')
9404 self.assertEqual(b4s[0][0], 2)
9405 sessions = self.statistics.get_counter('/dslite/total-sessions')
9406 self.assertEqual(sessions[0][0], 3)
9409 super(TestDSlite, self).tearDown()
9411 def show_commands_at_teardown(self):
9412 self.logger.info(self.vapi.cli("show dslite pool"))
9414 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9415 self.logger.info(self.vapi.cli("show dslite sessions"))
9418 class TestDSliteCE(MethodHolder):
9419 """ DS-Lite CE Test Cases """
9422 def setUpConstants(cls):
9423 super(TestDSliteCE, cls).setUpConstants()
9424 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9427 def setUpClass(cls):
9428 super(TestDSliteCE, cls).setUpClass()
9431 cls.create_pg_interfaces(range(2))
9433 cls.pg0.config_ip4()
9434 cls.pg0.resolve_arp()
9436 cls.pg1.config_ip6()
9437 cls.pg1.generate_remote_hosts(1)
9438 cls.pg1.configure_ipv6_neighbors()
9441 super(TestDSliteCE, cls).tearDownClass()
9445 def tearDownClass(cls):
9446 super(TestDSliteCE, cls).tearDownClass()
9448 def test_dslite_ce(self):
9449 """ Test DS-Lite CE """
9451 nat_config = self.vapi.nat_show_config()
9452 self.assertEqual(1, nat_config.dslite_ce)
9454 b4_ip4 = '192.0.0.2'
9455 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9456 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9458 aftr_ip4 = '192.0.0.1'
9459 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9460 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9461 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9463 r1 = VppIpRoute(self, aftr_ip6, 128,
9464 [VppRoutePath(self.pg1.remote_ip6,
9465 self.pg1.sw_if_index)])
9469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9470 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9471 UDP(sport=10000, dport=20000))
9472 self.pg0.add_stream(p)
9473 self.pg_enable_capture(self.pg_interfaces)
9475 capture = self.pg1.get_capture(1)
9476 capture = capture[0]
9477 self.assertEqual(capture[IPv6].src, b4_ip6)
9478 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9479 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9480 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9481 self.assertEqual(capture[UDP].sport, 10000)
9482 self.assertEqual(capture[UDP].dport, 20000)
9483 self.assert_packet_checksums_valid(capture)
9486 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9487 IPv6(dst=b4_ip6, src=aftr_ip6) /
9488 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9489 UDP(sport=20000, dport=10000))
9490 self.pg1.add_stream(p)
9491 self.pg_enable_capture(self.pg_interfaces)
9493 capture = self.pg0.get_capture(1)
9494 capture = capture[0]
9495 self.assertFalse(capture.haslayer(IPv6))
9496 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9497 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9498 self.assertEqual(capture[UDP].sport, 20000)
9499 self.assertEqual(capture[UDP].dport, 10000)
9500 self.assert_packet_checksums_valid(capture)
9502 # ping DS-Lite B4 tunnel endpoint address
9503 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9504 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9505 ICMPv6EchoRequest())
9506 self.pg1.add_stream(p)
9507 self.pg_enable_capture(self.pg_interfaces)
9509 capture = self.pg1.get_capture(1)
9510 capture = capture[0]
9511 self.assertEqual(capture[IPv6].src, b4_ip6)
9512 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9513 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9516 super(TestDSliteCE, self).tearDown()
9518 def show_commands_at_teardown(self):
9520 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9522 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9525 class TestNAT66(MethodHolder):
9526 """ NAT66 Test Cases """
9529 def setUpClass(cls):
9530 super(TestNAT66, cls).setUpClass()
9533 cls.nat_addr = 'fd01:ff::2'
9535 cls.create_pg_interfaces(range(2))
9536 cls.interfaces = list(cls.pg_interfaces)
9538 for i in cls.interfaces:
9541 i.configure_ipv6_neighbors()
9544 super(TestNAT66, cls).tearDownClass()
9548 def tearDownClass(cls):
9549 super(TestNAT66, cls).tearDownClass()
9551 def test_static(self):
9552 """ 1:1 NAT66 test """
9553 flags = self.config_flags.NAT_IS_INSIDE
9554 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9555 sw_if_index=self.pg0.sw_if_index)
9556 self.vapi.nat66_add_del_interface(is_add=1,
9557 sw_if_index=self.pg1.sw_if_index)
9558 self.vapi.nat66_add_del_static_mapping(
9559 local_ip_address=self.pg0.remote_ip6n,
9560 external_ip_address=self.nat_addr,
9565 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9566 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9569 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9570 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9573 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9574 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9575 ICMPv6EchoRequest())
9577 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9578 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9579 GRE() / IP() / TCP())
9581 self.pg0.add_stream(pkts)
9582 self.pg_enable_capture(self.pg_interfaces)
9584 capture = self.pg1.get_capture(len(pkts))
9585 for packet in capture:
9587 self.assertEqual(packet[IPv6].src, self.nat_addr)
9588 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9589 self.assert_packet_checksums_valid(packet)
9591 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9596 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9597 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9600 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9601 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9604 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9605 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9608 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9609 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9610 GRE() / IP() / TCP())
9612 self.pg1.add_stream(pkts)
9613 self.pg_enable_capture(self.pg_interfaces)
9615 capture = self.pg0.get_capture(len(pkts))
9616 for packet in capture:
9618 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9619 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9620 self.assert_packet_checksums_valid(packet)
9622 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9625 sm = self.vapi.nat66_static_mapping_dump()
9626 self.assertEqual(len(sm), 1)
9627 self.assertEqual(sm[0].total_pkts, 8)
9629 def test_check_no_translate(self):
9630 """ NAT66 translate only when egress interface is outside interface """
9631 flags = self.config_flags.NAT_IS_INSIDE
9632 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9633 sw_if_index=self.pg0.sw_if_index)
9634 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9635 sw_if_index=self.pg1.sw_if_index)
9636 self.vapi.nat66_add_del_static_mapping(
9637 local_ip_address=self.pg0.remote_ip6n,
9638 external_ip_address=self.nat_addr,
9642 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9643 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9645 self.pg0.add_stream([p])
9646 self.pg_enable_capture(self.pg_interfaces)
9648 capture = self.pg1.get_capture(1)
9651 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9652 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9654 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9657 def clear_nat66(self):
9659 Clear NAT66 configuration.
9661 interfaces = self.vapi.nat66_interface_dump()
9662 for intf in interfaces:
9663 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9664 sw_if_index=intf.sw_if_index)
9666 static_mappings = self.vapi.nat66_static_mapping_dump()
9667 for sm in static_mappings:
9668 self.vapi.nat66_add_del_static_mapping(
9669 local_ip_address=sm.local_ip_address,
9670 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9674 super(TestNAT66, self).tearDown()
9677 def show_commands_at_teardown(self):
9678 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9679 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9682 if __name__ == '__main__':
9683 unittest.main(testRunner=VppTestRunner)