8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
33 from ipaddress import IPv6Network
36 # NAT HA protocol event data
39 fields_desc = [ByteEnumField("event_type", None,
40 {1: "add", 2: "del", 3: "refresh"}),
41 ByteEnumField("protocol", None,
42 {0: "udp", 1: "tcp", 2: "icmp"}),
43 ShortField("flags", 0),
44 IPField("in_addr", None),
45 IPField("out_addr", None),
46 ShortField("in_port", None),
47 ShortField("out_port", None),
48 IPField("eh_addr", None),
49 IPField("ehn_addr", None),
50 ShortField("eh_port", None),
51 ShortField("ehn_port", None),
52 IntField("fib_index", None),
53 IntField("total_pkts", 0),
54 LongField("total_bytes", 0)]
56 def extract_padding(self, s):
60 # NAT HA protocol header
61 class HANATStateSync(Packet):
62 name = "HA NAT state sync"
63 fields_desc = [XByteField("version", 1),
64 FlagsField("flags", 0, 8, ['ACK']),
65 FieldLenField("count", None, count_of="events"),
66 IntField("sequence_number", 1),
67 IntField("thread_index", 0),
68 PacketListField("events", [], Event,
69 count_from=lambda pkt: pkt.count)]
72 class MethodHolder(VppTestCase):
73 """ NAT create capture and verify method holder """
76 def config_flags(self):
77 return VppEnum.vl_api_nat_config_flags_t
80 def SYSLOG_SEVERITY(self):
81 return VppEnum.vl_api_syslog_severity_t
83 def clear_nat44(self):
85 Clear NAT44 configuration.
87 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
88 if self.pg7.has_ip4_config:
89 self.pg7.unconfig_ip4()
91 self.vapi.nat44_forwarding_enable_disable(enable=0)
93 interfaces = self.vapi.nat44_interface_addr_dump()
94 for intf in interfaces:
95 self.vapi.nat44_add_del_interface_addr(
97 sw_if_index=intf.sw_if_index,
100 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
101 src_port=self.ipfix_src_port,
103 self.ipfix_src_port = 4739
104 self.ipfix_domain_id = 1
106 self.vapi.syslog_set_filter(
107 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
109 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
111 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
112 session_refresh_interval=10)
114 interfaces = self.vapi.nat44_interface_dump()
115 for intf in interfaces:
116 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
117 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
118 self.vapi.nat44_interface_add_del_feature(
119 sw_if_index=intf.sw_if_index)
120 self.vapi.nat44_interface_add_del_feature(
121 sw_if_index=intf.sw_if_index,
124 interfaces = self.vapi.nat44_interface_output_feature_dump()
125 for intf in interfaces:
126 self.vapi.nat44_interface_add_del_output_feature(
129 sw_if_index=intf.sw_if_index)
130 static_mappings = self.vapi.nat44_static_mapping_dump()
131 for sm in static_mappings:
132 self.vapi.nat44_add_del_static_mapping(
134 local_ip_address=sm.local_ip_address,
135 external_ip_address=sm.external_ip_address,
136 external_sw_if_index=sm.external_sw_if_index,
137 local_port=sm.local_port,
138 external_port=sm.external_port,
140 protocol=sm.protocol,
141 flags=sm.flags, tag=sm.tag)
143 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
144 for lb_sm in lb_static_mappings:
145 self.vapi.nat44_add_del_lb_static_mapping(
148 external_addr=lb_sm.external_addr,
149 external_port=lb_sm.external_port,
150 protocol=lb_sm.protocol,
151 local_num=0, locals=[],
154 identity_mappings = self.vapi.nat44_identity_mapping_dump()
155 for id_m in identity_mappings:
156 self.vapi.nat44_add_del_identity_mapping(
157 ip_address=id_m.ip_address,
158 sw_if_index=id_m.sw_if_index,
162 protocol=id_m.protocol)
164 addresses = self.vapi.nat44_address_dump()
165 for addr in addresses:
166 self.vapi.nat44_add_del_address_range(
167 first_ip_address=addr.ip_address,
168 last_ip_address=addr.ip_address,
169 vrf_id=0xFFFFFFFF, flags=addr.flags)
171 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
173 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
174 drop_frag=0, is_ip6=1)
175 self.verify_no_nat44_user()
176 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
177 tcp_transitory=240, icmp=60)
178 self.vapi.nat_set_addr_and_port_alloc_alg()
179 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
181 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
182 local_port=0, external_port=0, vrf_id=0,
183 is_add=1, external_sw_if_index=0xFFFFFFFF,
184 proto=0, tag="", flags=0):
186 Add/delete NAT44 static mapping
188 :param local_ip: Local IP address
189 :param external_ip: External IP address
190 :param local_port: Local port number (Optional)
191 :param external_port: External port number (Optional)
192 :param vrf_id: VRF ID (Default 0)
193 :param is_add: 1 if add, 0 if delete (Default add)
194 :param external_sw_if_index: External interface instead of IP address
195 :param proto: IP protocol (Mandatory if port specified)
196 :param tag: Opaque string tag
197 :param flags: NAT configuration flags
200 if not (local_port and external_port):
201 flags |= self.config_flags.NAT_IS_ADDR_ONLY
203 self.vapi.nat44_add_del_static_mapping(
205 local_ip_address=local_ip,
206 external_ip_address=external_ip,
207 external_sw_if_index=external_sw_if_index,
208 local_port=local_port,
209 external_port=external_port,
210 vrf_id=vrf_id, protocol=proto,
214 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
216 Add/delete NAT44 address
218 :param ip: IP address
219 :param is_add: 1 if add, 0 if delete (Default add)
220 :param twice_nat: twice NAT address for external hosts
222 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
223 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
229 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
231 Create packet stream for inside network
233 :param in_if: Inside interface
234 :param out_if: Outside interface
235 :param dst_ip: Destination address
236 :param ttl: TTL of generated packets
239 dst_ip = out_if.remote_ip4
243 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
244 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
245 TCP(sport=self.tcp_port_in, dport=20))
249 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
250 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
251 UDP(sport=self.udp_port_in, dport=20))
255 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
256 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
257 ICMP(id=self.icmp_id_in, type='echo-request'))
262 def compose_ip6(self, ip4, pref, plen):
264 Compose IPv4-embedded IPv6 addresses
266 :param ip4: IPv4 address
267 :param pref: IPv6 prefix
268 :param plen: IPv6 prefix length
269 :returns: IPv4-embedded IPv6 addresses
271 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
272 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
287 pref_n[10] = ip4_n[3]
291 pref_n[10] = ip4_n[2]
292 pref_n[11] = ip4_n[3]
295 pref_n[10] = ip4_n[1]
296 pref_n[11] = ip4_n[2]
297 pref_n[12] = ip4_n[3]
299 pref_n[12] = ip4_n[0]
300 pref_n[13] = ip4_n[1]
301 pref_n[14] = ip4_n[2]
302 pref_n[15] = ip4_n[3]
303 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
304 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
306 def extract_ip4(self, ip6, plen):
308 Extract IPv4 address embedded in IPv6 addresses
310 :param ip6: IPv6 address
311 :param plen: IPv6 prefix length
312 :returns: extracted IPv4 address
314 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
346 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
348 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
350 Create IPv6 packet stream for inside network
352 :param in_if: Inside interface
353 :param out_if: Outside interface
354 :param ttl: Hop Limit of generated packets
355 :param pref: NAT64 prefix
356 :param plen: NAT64 prefix length
360 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
362 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
365 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
366 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
367 TCP(sport=self.tcp_port_in, dport=20))
371 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
372 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
373 UDP(sport=self.udp_port_in, dport=20))
377 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
378 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
379 ICMPv6EchoRequest(id=self.icmp_id_in))
384 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
385 use_inside_ports=False):
387 Create packet stream for outside network
389 :param out_if: Outside interface
390 :param dst_ip: Destination IP address (Default use global NAT address)
391 :param ttl: TTL of generated packets
392 :param use_inside_ports: Use inside NAT ports as destination ports
393 instead of outside ports
396 dst_ip = self.nat_addr
397 if not use_inside_ports:
398 tcp_port = self.tcp_port_out
399 udp_port = self.udp_port_out
400 icmp_id = self.icmp_id_out
402 tcp_port = self.tcp_port_in
403 udp_port = self.udp_port_in
404 icmp_id = self.icmp_id_in
407 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
408 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
409 TCP(dport=tcp_port, sport=20))
413 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
414 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
415 UDP(dport=udp_port, sport=20))
419 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
420 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
421 ICMP(id=icmp_id, type='echo-reply'))
426 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
428 Create packet stream for outside network
430 :param out_if: Outside interface
431 :param dst_ip: Destination IP address (Default use global NAT address)
432 :param hl: HL of generated packets
436 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
437 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
438 TCP(dport=self.tcp_port_out, sport=20))
442 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
443 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
444 UDP(dport=self.udp_port_out, sport=20))
448 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
449 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
450 ICMPv6EchoReply(id=self.icmp_id_out))
455 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
456 dst_ip=None, is_ip6=False):
458 Verify captured packets on outside network
460 :param capture: Captured packets
461 :param nat_ip: Translated IP address (Default use global NAT address)
462 :param same_port: Source port number is not translated (Default False)
463 :param dst_ip: Destination IP address (Default do not verify)
464 :param is_ip6: If L3 protocol is IPv6 (Default False)
468 ICMP46 = ICMPv6EchoRequest
473 nat_ip = self.nat_addr
474 for packet in capture:
477 self.assert_packet_checksums_valid(packet)
478 self.assertEqual(packet[IP46].src, nat_ip)
479 if dst_ip is not None:
480 self.assertEqual(packet[IP46].dst, dst_ip)
481 if packet.haslayer(TCP):
483 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
486 packet[TCP].sport, self.tcp_port_in)
487 self.tcp_port_out = packet[TCP].sport
488 self.assert_packet_checksums_valid(packet)
489 elif packet.haslayer(UDP):
491 self.assertEqual(packet[UDP].sport, self.udp_port_in)
494 packet[UDP].sport, self.udp_port_in)
495 self.udp_port_out = packet[UDP].sport
498 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
500 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
501 self.icmp_id_out = packet[ICMP46].id
502 self.assert_packet_checksums_valid(packet)
504 self.logger.error(ppp("Unexpected or invalid packet "
505 "(outside network):", packet))
508 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
511 Verify captured packets on outside network
513 :param capture: Captured packets
514 :param nat_ip: Translated IP address
515 :param same_port: Source port number is not translated (Default False)
516 :param dst_ip: Destination IP address (Default do not verify)
518 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
521 def verify_capture_in(self, capture, in_if):
523 Verify captured packets on inside network
525 :param capture: Captured packets
526 :param in_if: Inside interface
528 for packet in capture:
530 self.assert_packet_checksums_valid(packet)
531 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
532 if packet.haslayer(TCP):
533 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
534 elif packet.haslayer(UDP):
535 self.assertEqual(packet[UDP].dport, self.udp_port_in)
537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
539 self.logger.error(ppp("Unexpected or invalid packet "
540 "(inside network):", packet))
543 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
545 Verify captured IPv6 packets on inside network
547 :param capture: Captured packets
548 :param src_ip: Source IP
549 :param dst_ip: Destination IP address
551 for packet in capture:
553 self.assertEqual(packet[IPv6].src, src_ip)
554 self.assertEqual(packet[IPv6].dst, dst_ip)
555 self.assert_packet_checksums_valid(packet)
556 if packet.haslayer(TCP):
557 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
558 elif packet.haslayer(UDP):
559 self.assertEqual(packet[UDP].dport, self.udp_port_in)
561 self.assertEqual(packet[ICMPv6EchoReply].id,
564 self.logger.error(ppp("Unexpected or invalid packet "
565 "(inside network):", packet))
568 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
570 Verify captured packet that don't have to be translated
572 :param capture: Captured packets
573 :param ingress_if: Ingress interface
574 :param egress_if: Egress interface
576 for packet in capture:
578 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
579 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
580 if packet.haslayer(TCP):
581 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
582 elif packet.haslayer(UDP):
583 self.assertEqual(packet[UDP].sport, self.udp_port_in)
585 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
587 self.logger.error(ppp("Unexpected or invalid packet "
588 "(inside network):", packet))
591 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
594 Verify captured packets with ICMP errors on outside network
596 :param capture: Captured packets
597 :param src_ip: Translated IP address or IP address of VPP
598 (Default use global NAT address)
599 :param icmp_type: Type of error ICMP packet
600 we are expecting (Default 11)
603 src_ip = self.nat_addr
604 for packet in capture:
606 self.assertEqual(packet[IP].src, src_ip)
607 self.assertEqual(packet.haslayer(ICMP), 1)
609 self.assertEqual(icmp.type, icmp_type)
610 self.assertTrue(icmp.haslayer(IPerror))
611 inner_ip = icmp[IPerror]
612 if inner_ip.haslayer(TCPerror):
613 self.assertEqual(inner_ip[TCPerror].dport,
615 elif inner_ip.haslayer(UDPerror):
616 self.assertEqual(inner_ip[UDPerror].dport,
619 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
621 self.logger.error(ppp("Unexpected or invalid packet "
622 "(outside network):", packet))
625 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
627 Verify captured packets with ICMP errors on inside network
629 :param capture: Captured packets
630 :param in_if: Inside interface
631 :param icmp_type: Type of error ICMP packet
632 we are expecting (Default 11)
634 for packet in capture:
636 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
637 self.assertEqual(packet.haslayer(ICMP), 1)
639 self.assertEqual(icmp.type, icmp_type)
640 self.assertTrue(icmp.haslayer(IPerror))
641 inner_ip = icmp[IPerror]
642 if inner_ip.haslayer(TCPerror):
643 self.assertEqual(inner_ip[TCPerror].sport,
645 elif inner_ip.haslayer(UDPerror):
646 self.assertEqual(inner_ip[UDPerror].sport,
649 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
651 self.logger.error(ppp("Unexpected or invalid packet "
652 "(inside network):", packet))
655 def create_stream_frag(self, src_if, dst, sport, dport, data,
656 proto=IP_PROTOS.tcp, echo_reply=False):
658 Create fragmented packet stream
660 :param src_if: Source interface
661 :param dst: Destination IPv4 address
662 :param sport: Source port
663 :param dport: Destination port
664 :param data: Payload data
665 :param proto: protocol (TCP, UDP, ICMP)
666 :param echo_reply: use echo_reply if protocol is ICMP
669 if proto == IP_PROTOS.tcp:
670 p = (IP(src=src_if.remote_ip4, dst=dst) /
671 TCP(sport=sport, dport=dport) /
673 p = p.__class__(scapy.compat.raw(p))
674 chksum = p[TCP].chksum
675 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
676 elif proto == IP_PROTOS.udp:
677 proto_header = UDP(sport=sport, dport=dport)
678 elif proto == IP_PROTOS.icmp:
680 proto_header = ICMP(id=sport, type='echo-request')
682 proto_header = ICMP(id=sport, type='echo-reply')
684 raise Exception("Unsupported protocol")
685 id = random.randint(0, 65535)
687 if proto == IP_PROTOS.tcp:
690 raw = Raw(data[0:16])
691 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
692 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
696 if proto == IP_PROTOS.tcp:
697 raw = Raw(data[4:20])
699 raw = Raw(data[16:32])
700 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
701 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
705 if proto == IP_PROTOS.tcp:
709 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
710 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
716 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
717 pref=None, plen=0, frag_size=128):
719 Create fragmented packet stream
721 :param src_if: Source interface
722 :param dst: Destination IPv4 address
723 :param sport: Source TCP port
724 :param dport: Destination TCP port
725 :param data: Payload data
726 :param pref: NAT64 prefix
727 :param plen: NAT64 prefix length
728 :param fragsize: size of fragments
732 dst_ip6 = ''.join(['64:ff9b::', dst])
734 dst_ip6 = self.compose_ip6(dst, pref, plen)
736 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
737 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
738 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
739 TCP(sport=sport, dport=dport) /
742 return fragment6(p, frag_size)
744 def reass_frags_and_verify(self, frags, src, dst):
746 Reassemble and verify fragmented packet
748 :param frags: Captured fragments
749 :param src: Source IPv4 address to verify
750 :param dst: Destination IPv4 address to verify
752 :returns: Reassembled IPv4 packet
756 self.assertEqual(p[IP].src, src)
757 self.assertEqual(p[IP].dst, dst)
758 self.assert_ip_checksum_valid(p)
759 buffer.seek(p[IP].frag * 8)
760 buffer.write(bytes(p[IP].payload))
761 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
762 proto=frags[0][IP].proto)
763 if ip.proto == IP_PROTOS.tcp:
764 p = (ip / TCP(buffer.getvalue()))
765 self.assert_tcp_checksum_valid(p)
766 elif ip.proto == IP_PROTOS.udp:
767 p = (ip / UDP(buffer.getvalue()[:8]) /
768 Raw(buffer.getvalue()[8:]))
769 elif ip.proto == IP_PROTOS.icmp:
770 p = (ip / ICMP(buffer.getvalue()))
773 def reass_frags_and_verify_ip6(self, frags, src, dst):
775 Reassemble and verify fragmented packet
777 :param frags: Captured fragments
778 :param src: Source IPv6 address to verify
779 :param dst: Destination IPv6 address to verify
781 :returns: Reassembled IPv6 packet
785 self.assertEqual(p[IPv6].src, src)
786 self.assertEqual(p[IPv6].dst, dst)
787 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
788 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
789 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
790 nh=frags[0][IPv6ExtHdrFragment].nh)
791 if ip.nh == IP_PROTOS.tcp:
792 p = (ip / TCP(buffer.getvalue()))
793 elif ip.nh == IP_PROTOS.udp:
794 p = (ip / UDP(buffer.getvalue()))
795 self.assert_packet_checksums_valid(p)
798 def initiate_tcp_session(self, in_if, out_if):
800 Initiates TCP session
802 :param in_if: Inside interface
803 :param out_if: Outside interface
807 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
808 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
809 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
812 self.pg_enable_capture(self.pg_interfaces)
814 capture = out_if.get_capture(1)
816 self.tcp_port_out = p[TCP].sport
818 # SYN + ACK packet out->in
819 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
820 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
821 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
824 self.pg_enable_capture(self.pg_interfaces)
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 out_if.get_capture(1)
839 self.logger.error("TCP 3 way handshake failed")
842 def verify_ipfix_nat44_ses(self, data):
844 Verify IPFIX NAT44 session create/delete event
846 :param data: Decoded IPFIX data records
848 nat44_ses_create_num = 0
849 nat44_ses_delete_num = 0
850 self.assertEqual(6, len(data))
853 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
854 if scapy.compat.orb(record[230]) == 4:
855 nat44_ses_create_num += 1
857 nat44_ses_delete_num += 1
859 self.assertEqual(self.pg0.remote_ip4n, record[8])
860 # postNATSourceIPv4Address
861 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
864 self.assertEqual(struct.pack("!I", 0), record[234])
865 # protocolIdentifier/sourceTransportPort
866 # /postNAPTSourceTransportPort
867 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
868 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
869 self.assertEqual(struct.pack("!H", self.icmp_id_out),
871 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
872 self.assertEqual(struct.pack("!H", self.tcp_port_in),
874 self.assertEqual(struct.pack("!H", self.tcp_port_out),
876 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.udp_port_in),
879 self.assertEqual(struct.pack("!H", self.udp_port_out),
882 self.fail("Invalid protocol")
883 self.assertEqual(3, nat44_ses_create_num)
884 self.assertEqual(3, nat44_ses_delete_num)
886 def verify_ipfix_addr_exhausted(self, data):
888 Verify IPFIX NAT addresses event
890 :param data: Decoded IPFIX data records
892 self.assertEqual(1, len(data))
895 self.assertEqual(scapy.compat.orb(record[230]), 3)
897 self.assertEqual(struct.pack("!I", 0), record[283])
899 def verify_ipfix_max_sessions(self, data, limit):
901 Verify IPFIX maximum session entries exceeded event
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum session entries that can be created.
906 self.assertEqual(1, len(data))
909 self.assertEqual(scapy.compat.orb(record[230]), 13)
910 # natQuotaExceededEvent
911 self.assertEqual(struct.pack("I", 1), record[466])
913 self.assertEqual(struct.pack("I", limit), record[471])
915 def verify_ipfix_max_bibs(self, data, limit):
917 Verify IPFIX maximum BIB entries exceeded event
919 :param data: Decoded IPFIX data records
920 :param limit: Number of maximum BIB entries that can be created.
922 self.assertEqual(1, len(data))
925 self.assertEqual(scapy.compat.orb(record[230]), 13)
926 # natQuotaExceededEvent
927 self.assertEqual(struct.pack("I", 2), record[466])
929 self.assertEqual(struct.pack("I", limit), record[472])
931 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
933 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
935 :param data: Decoded IPFIX data records
936 :param limit: Number of maximum fragments pending reassembly
937 :param src_addr: IPv6 source address
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 5), record[466])
945 # maxFragmentsPendingReassembly
946 self.assertEqual(struct.pack("I", limit), record[475])
948 self.assertEqual(src_addr, record[27])
950 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
952 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
954 :param data: Decoded IPFIX data records
955 :param limit: Number of maximum fragments pending reassembly
956 :param src_addr: IPv4 source address
958 self.assertEqual(1, len(data))
961 self.assertEqual(scapy.compat.orb(record[230]), 13)
962 # natQuotaExceededEvent
963 self.assertEqual(struct.pack("I", 5), record[466])
964 # maxFragmentsPendingReassembly
965 self.assertEqual(struct.pack("I", limit), record[475])
967 self.assertEqual(src_addr, record[8])
969 def verify_ipfix_bib(self, data, is_create, src_addr):
971 Verify IPFIX NAT64 BIB create and delete events
973 :param data: Decoded IPFIX data records
974 :param is_create: Create event if nonzero value otherwise delete event
975 :param src_addr: IPv6 source address
977 self.assertEqual(1, len(data))
981 self.assertEqual(scapy.compat.orb(record[230]), 10)
983 self.assertEqual(scapy.compat.orb(record[230]), 11)
985 self.assertEqual(src_addr, record[27])
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
997 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1000 Verify IPFIX NAT64 session create and delete events
1002 :param data: Decoded IPFIX data records
1003 :param is_create: Create event if nonzero value otherwise delete event
1004 :param src_addr: IPv6 source address
1005 :param dst_addr: IPv4 destination address
1006 :param dst_port: destination TCP port
1008 self.assertEqual(1, len(data))
1012 self.assertEqual(scapy.compat.orb(record[230]), 6)
1014 self.assertEqual(scapy.compat.orb(record[230]), 7)
1016 self.assertEqual(src_addr, record[27])
1017 # destinationIPv6Address
1018 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1019 self.compose_ip6(dst_addr,
1023 # postNATSourceIPv4Address
1024 self.assertEqual(self.nat_addr_n, record[225])
1025 # postNATDestinationIPv4Address
1026 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1028 # protocolIdentifier
1029 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1031 self.assertEqual(struct.pack("!I", 0), record[234])
1032 # sourceTransportPort
1033 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1034 # postNAPTSourceTransportPort
1035 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1036 # destinationTransportPort
1037 self.assertEqual(struct.pack("!H", dst_port), record[11])
1038 # postNAPTDestinationTransportPort
1039 self.assertEqual(struct.pack("!H", dst_port), record[228])
1041 def verify_no_nat44_user(self):
1042 """ Verify that there is no NAT44 user """
1043 users = self.vapi.nat44_user_dump()
1044 self.assertEqual(len(users), 0)
1045 users = self.statistics.get_counter('/nat44/total-users')
1046 self.assertEqual(users[0][0], 0)
1047 sessions = self.statistics.get_counter('/nat44/total-sessions')
1048 self.assertEqual(sessions[0][0], 0)
1050 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1052 Verify IPFIX maximum entries per user exceeded event
1054 :param data: Decoded IPFIX data records
1055 :param limit: Number of maximum entries per user
1056 :param src_addr: IPv4 source address
1058 self.assertEqual(1, len(data))
1061 self.assertEqual(scapy.compat.orb(record[230]), 13)
1062 # natQuotaExceededEvent
1063 self.assertEqual(struct.pack("I", 3), record[466])
1065 self.assertEqual(struct.pack("I", limit), record[473])
1067 self.assertEqual(src_addr, record[8])
1069 def verify_syslog_apmap(self, data, is_add=True):
1070 message = data.decode('utf-8')
1072 message = SyslogMessage.parse(message)
1073 except ParseError as e:
1074 self.logger.error(e)
1077 self.assertEqual(message.severity, SyslogSeverity.info)
1078 self.assertEqual(message.appname, 'NAT')
1079 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1080 sd_params = message.sd.get('napmap')
1081 self.assertTrue(sd_params is not None)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1085 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1086 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1087 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1088 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1089 self.assertTrue(sd_params.get('SSUBIX') is not None)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1092 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1093 message = data.decode('utf-8')
1095 message = SyslogMessage.parse(message)
1096 except ParseError as e:
1097 self.logger.error(e)
1100 self.assertEqual(message.severity, SyslogSeverity.info)
1101 self.assertEqual(message.appname, 'NAT')
1102 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1103 sd_params = message.sd.get('nsess')
1104 self.assertTrue(sd_params is not None)
1106 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1107 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1109 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1110 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1113 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1114 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1115 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1116 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1117 self.assertEqual(sd_params.get('SVLAN'), '0')
1118 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1119 self.assertEqual(sd_params.get('XDPORT'),
1120 "%d" % self.tcp_external_port)
1122 def verify_mss_value(self, pkt, mss):
1124 Verify TCP MSS value
1129 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1130 raise TypeError("Not a TCP/IP packet")
1132 for option in pkt[TCP].options:
1133 if option[0] == 'MSS':
1134 self.assertEqual(option[1], mss)
1135 self.assert_tcp_checksum_valid(pkt)
1138 def proto2layer(proto):
1139 if proto == IP_PROTOS.tcp:
1141 elif proto == IP_PROTOS.udp:
1143 elif proto == IP_PROTOS.icmp:
1146 raise Exception("Unsupported protocol")
1148 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1149 layer = self.proto2layer(proto)
1151 if proto == IP_PROTOS.tcp:
1152 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1154 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1155 self.port_in = random.randint(1025, 65535)
1157 reass = self.vapi.nat_reass_dump()
1158 reass_n_start = len(reass)
1161 pkts = self.create_stream_frag(self.pg0,
1162 self.pg1.remote_ip4,
1167 self.pg0.add_stream(pkts)
1168 self.pg_enable_capture(self.pg_interfaces)
1170 frags = self.pg1.get_capture(len(pkts))
1171 if not dont_translate:
1172 p = self.reass_frags_and_verify(frags,
1174 self.pg1.remote_ip4)
1176 p = self.reass_frags_and_verify(frags,
1177 self.pg0.remote_ip4,
1178 self.pg1.remote_ip4)
1179 if proto != IP_PROTOS.icmp:
1180 if not dont_translate:
1181 self.assertEqual(p[layer].dport, 20)
1182 self.assertNotEqual(p[layer].sport, self.port_in)
1184 self.assertEqual(p[layer].sport, self.port_in)
1186 if not dont_translate:
1187 self.assertNotEqual(p[layer].id, self.port_in)
1189 self.assertEqual(p[layer].id, self.port_in)
1190 self.assertEqual(data, p[Raw].load)
1193 if not dont_translate:
1194 dst_addr = self.nat_addr
1196 dst_addr = self.pg0.remote_ip4
1197 if proto != IP_PROTOS.icmp:
1199 dport = p[layer].sport
1203 pkts = self.create_stream_frag(self.pg1,
1210 self.pg1.add_stream(pkts)
1211 self.pg_enable_capture(self.pg_interfaces)
1213 frags = self.pg0.get_capture(len(pkts))
1214 p = self.reass_frags_and_verify(frags,
1215 self.pg1.remote_ip4,
1216 self.pg0.remote_ip4)
1217 if proto != IP_PROTOS.icmp:
1218 self.assertEqual(p[layer].sport, 20)
1219 self.assertEqual(p[layer].dport, self.port_in)
1221 self.assertEqual(p[layer].id, self.port_in)
1222 self.assertEqual(data, p[Raw].load)
1224 reass = self.vapi.nat_reass_dump()
1225 reass_n_end = len(reass)
1227 self.assertEqual(reass_n_end - reass_n_start, 2)
1229 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1230 layer = self.proto2layer(proto)
1232 if proto == IP_PROTOS.tcp:
1233 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1235 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1236 self.port_in = random.randint(1025, 65535)
1239 reass = self.vapi.nat_reass_dump()
1240 reass_n_start = len(reass)
1243 pkts = self.create_stream_frag(self.pg0,
1244 self.server_out_addr,
1246 self.server_out_port,
1249 self.pg0.add_stream(pkts)
1250 self.pg_enable_capture(self.pg_interfaces)
1252 frags = self.pg1.get_capture(len(pkts))
1253 p = self.reass_frags_and_verify(frags,
1254 self.pg0.remote_ip4,
1255 self.server_in_addr)
1256 if proto != IP_PROTOS.icmp:
1257 self.assertEqual(p[layer].sport, self.port_in)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1260 self.assertEqual(p[layer].id, self.port_in)
1261 self.assertEqual(data, p[Raw].load)
1264 if proto != IP_PROTOS.icmp:
1265 pkts = self.create_stream_frag(self.pg1,
1266 self.pg0.remote_ip4,
1267 self.server_in_port,
1272 pkts = self.create_stream_frag(self.pg1,
1273 self.pg0.remote_ip4,
1279 self.pg1.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg0.get_capture(len(pkts))
1283 p = self.reass_frags_and_verify(frags,
1284 self.server_out_addr,
1285 self.pg0.remote_ip4)
1286 if proto != IP_PROTOS.icmp:
1287 self.assertEqual(p[layer].sport, self.server_out_port)
1288 self.assertEqual(p[layer].dport, self.port_in)
1290 self.assertEqual(p[layer].id, self.port_in)
1291 self.assertEqual(data, p[Raw].load)
1293 reass = self.vapi.nat_reass_dump()
1294 reass_n_end = len(reass)
1296 self.assertEqual(reass_n_end - reass_n_start, 2)
1298 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1299 layer = self.proto2layer(proto)
1301 if proto == IP_PROTOS.tcp:
1302 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1304 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1306 # send packet from host to server
1307 pkts = self.create_stream_frag(self.pg0,
1310 self.server_out_port,
1313 self.pg0.add_stream(pkts)
1314 self.pg_enable_capture(self.pg_interfaces)
1316 frags = self.pg0.get_capture(len(pkts))
1317 p = self.reass_frags_and_verify(frags,
1320 if proto != IP_PROTOS.icmp:
1321 self.assertNotEqual(p[layer].sport, self.host_in_port)
1322 self.assertEqual(p[layer].dport, self.server_in_port)
1324 self.assertNotEqual(p[layer].id, self.host_in_port)
1325 self.assertEqual(data, p[Raw].load)
1327 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1328 layer = self.proto2layer(proto)
1330 if proto == IP_PROTOS.tcp:
1331 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1333 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1334 self.port_in = random.randint(1025, 65535)
1338 pkts = self.create_stream_frag(self.pg0,
1339 self.pg1.remote_ip4,
1345 self.pg0.add_stream(pkts)
1346 self.pg_enable_capture(self.pg_interfaces)
1348 frags = self.pg1.get_capture(len(pkts))
1349 if not dont_translate:
1350 p = self.reass_frags_and_verify(frags,
1352 self.pg1.remote_ip4)
1354 p = self.reass_frags_and_verify(frags,
1355 self.pg0.remote_ip4,
1356 self.pg1.remote_ip4)
1357 if proto != IP_PROTOS.icmp:
1358 if not dont_translate:
1359 self.assertEqual(p[layer].dport, 20)
1360 self.assertNotEqual(p[layer].sport, self.port_in)
1362 self.assertEqual(p[layer].sport, self.port_in)
1364 if not dont_translate:
1365 self.assertNotEqual(p[layer].id, self.port_in)
1367 self.assertEqual(p[layer].id, self.port_in)
1368 self.assertEqual(data, p[Raw].load)
1371 if not dont_translate:
1372 dst_addr = self.nat_addr
1374 dst_addr = self.pg0.remote_ip4
1375 if proto != IP_PROTOS.icmp:
1377 dport = p[layer].sport
1381 pkts = self.create_stream_frag(self.pg1,
1389 self.pg1.add_stream(pkts)
1390 self.pg_enable_capture(self.pg_interfaces)
1392 frags = self.pg0.get_capture(len(pkts))
1393 p = self.reass_frags_and_verify(frags,
1394 self.pg1.remote_ip4,
1395 self.pg0.remote_ip4)
1396 if proto != IP_PROTOS.icmp:
1397 self.assertEqual(p[layer].sport, 20)
1398 self.assertEqual(p[layer].dport, self.port_in)
1400 self.assertEqual(p[layer].id, self.port_in)
1401 self.assertEqual(data, p[Raw].load)
1403 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1404 layer = self.proto2layer(proto)
1406 if proto == IP_PROTOS.tcp:
1407 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1409 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1410 self.port_in = random.randint(1025, 65535)
1414 pkts = self.create_stream_frag(self.pg0,
1415 self.server_out_addr,
1417 self.server_out_port,
1421 self.pg0.add_stream(pkts)
1422 self.pg_enable_capture(self.pg_interfaces)
1424 frags = self.pg1.get_capture(len(pkts))
1425 p = self.reass_frags_and_verify(frags,
1426 self.pg0.remote_ip4,
1427 self.server_in_addr)
1428 if proto != IP_PROTOS.icmp:
1429 self.assertEqual(p[layer].dport, self.server_in_port)
1430 self.assertEqual(p[layer].sport, self.port_in)
1431 self.assertEqual(p[layer].dport, self.server_in_port)
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1437 if proto != IP_PROTOS.icmp:
1438 pkts = self.create_stream_frag(self.pg1,
1439 self.pg0.remote_ip4,
1440 self.server_in_port,
1445 pkts = self.create_stream_frag(self.pg1,
1446 self.pg0.remote_ip4,
1453 self.pg1.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1456 frags = self.pg0.get_capture(len(pkts))
1457 p = self.reass_frags_and_verify(frags,
1458 self.server_out_addr,
1459 self.pg0.remote_ip4)
1460 if proto != IP_PROTOS.icmp:
1461 self.assertEqual(p[layer].sport, self.server_out_port)
1462 self.assertEqual(p[layer].dport, self.port_in)
1464 self.assertEqual(p[layer].id, self.port_in)
1465 self.assertEqual(data, p[Raw].load)
1468 class TestNAT44(MethodHolder):
1469 """ NAT44 Test Cases """
1472 def setUpClass(cls):
1473 super(TestNAT44, cls).setUpClass()
1474 cls.vapi.cli("set log class nat level debug")
1477 cls.tcp_port_in = 6303
1478 cls.tcp_port_out = 6303
1479 cls.udp_port_in = 6304
1480 cls.udp_port_out = 6304
1481 cls.icmp_id_in = 6305
1482 cls.icmp_id_out = 6305
1483 cls.nat_addr = '10.0.0.3'
1484 cls.ipfix_src_port = 4739
1485 cls.ipfix_domain_id = 1
1486 cls.tcp_external_port = 80
1487 cls.udp_external_port = 69
1489 cls.create_pg_interfaces(range(10))
1490 cls.interfaces = list(cls.pg_interfaces[0:4])
1492 for i in cls.interfaces:
1497 cls.pg0.generate_remote_hosts(3)
1498 cls.pg0.configure_ipv4_neighbors()
1500 cls.pg1.generate_remote_hosts(1)
1501 cls.pg1.configure_ipv4_neighbors()
1503 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1504 cls.vapi.ip_table_add_del(is_add=1, table_id=10)
1505 cls.vapi.ip_table_add_del(is_add=1, table_id=20)
1507 cls.pg4._local_ip4 = "172.16.255.1"
1508 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1509 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1510 cls.pg4.set_table_ip4(10)
1511 cls.pg5._local_ip4 = "172.17.255.3"
1512 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1513 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1514 cls.pg5.set_table_ip4(10)
1515 cls.pg6._local_ip4 = "172.16.255.1"
1516 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1517 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1518 cls.pg6.set_table_ip4(20)
1519 for i in cls.overlapping_interfaces:
1527 cls.pg9.generate_remote_hosts(2)
1528 cls.pg9.config_ip4()
1529 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1530 cls.vapi.sw_interface_add_del_address(
1531 sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
1534 cls.pg9.resolve_arp()
1535 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1536 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1537 cls.pg9.resolve_arp()
1540 super(TestNAT44, cls).tearDownClass()
1544 def tearDownClass(cls):
1545 super(TestNAT44, cls).tearDownClass()
1547 def test_dynamic(self):
1548 """ NAT44 dynamic translation test """
1549 self.nat44_add_address(self.nat_addr)
1550 flags = self.config_flags.NAT_IS_INSIDE
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg0.sw_if_index,
1553 flags=flags, is_add=1)
1554 self.vapi.nat44_interface_add_del_feature(
1555 sw_if_index=self.pg1.sw_if_index,
1559 tcpn = self.statistics.get_err_counter(
1560 '/err/nat44-in2out-slowpath/TCP packets')
1561 udpn = self.statistics.get_err_counter(
1562 '/err/nat44-in2out-slowpath/UDP packets')
1563 icmpn = self.statistics.get_err_counter(
1564 '/err/nat44-in2out-slowpath/ICMP packets')
1565 totaln = self.statistics.get_err_counter(
1566 '/err/nat44-in2out-slowpath/good in2out packets processed')
1568 pkts = self.create_stream_in(self.pg0, self.pg1)
1569 self.pg0.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1572 capture = self.pg1.get_capture(len(pkts))
1573 self.verify_capture_out(capture)
1575 err = self.statistics.get_err_counter(
1576 '/err/nat44-in2out-slowpath/TCP packets')
1577 self.assertEqual(err - tcpn, 2)
1578 err = self.statistics.get_err_counter(
1579 '/err/nat44-in2out-slowpath/UDP packets')
1580 self.assertEqual(err - udpn, 1)
1581 err = self.statistics.get_err_counter(
1582 '/err/nat44-in2out-slowpath/ICMP packets')
1583 self.assertEqual(err - icmpn, 1)
1584 err = self.statistics.get_err_counter(
1585 '/err/nat44-in2out-slowpath/good in2out packets processed')
1586 self.assertEqual(err - totaln, 4)
1589 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1590 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1591 icmpn = self.statistics.get_err_counter(
1592 '/err/nat44-out2in/ICMP packets')
1593 totaln = self.statistics.get_err_counter(
1594 '/err/nat44-out2in/good out2in packets processed')
1596 pkts = self.create_stream_out(self.pg1)
1597 self.pg1.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1600 capture = self.pg0.get_capture(len(pkts))
1601 self.verify_capture_in(capture, self.pg0)
1603 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1604 self.assertEqual(err - tcpn, 2)
1605 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1606 self.assertEqual(err - udpn, 1)
1607 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1608 self.assertEqual(err - icmpn, 1)
1609 err = self.statistics.get_err_counter(
1610 '/err/nat44-out2in/good out2in packets processed')
1611 self.assertEqual(err - totaln, 4)
1613 users = self.statistics.get_counter('/nat44/total-users')
1614 self.assertEqual(users[0][0], 1)
1615 sessions = self.statistics.get_counter('/nat44/total-sessions')
1616 self.assertEqual(sessions[0][0], 3)
1618 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1619 """ NAT44 handling of client packets with TTL=1 """
1621 self.nat44_add_address(self.nat_addr)
1622 flags = self.config_flags.NAT_IS_INSIDE
1623 self.vapi.nat44_interface_add_del_feature(
1624 sw_if_index=self.pg0.sw_if_index,
1625 flags=flags, is_add=1)
1626 self.vapi.nat44_interface_add_del_feature(
1627 sw_if_index=self.pg1.sw_if_index,
1630 # Client side - generate traffic
1631 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1632 self.pg0.add_stream(pkts)
1633 self.pg_enable_capture(self.pg_interfaces)
1636 # Client side - verify ICMP type 11 packets
1637 capture = self.pg0.get_capture(len(pkts))
1638 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1640 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1641 """ NAT44 handling of server packets with TTL=1 """
1643 self.nat44_add_address(self.nat_addr)
1644 flags = self.config_flags.NAT_IS_INSIDE
1645 self.vapi.nat44_interface_add_del_feature(
1646 sw_if_index=self.pg0.sw_if_index,
1647 flags=flags, is_add=1)
1648 self.vapi.nat44_interface_add_del_feature(
1649 sw_if_index=self.pg1.sw_if_index,
1652 # Client side - create sessions
1653 pkts = self.create_stream_in(self.pg0, self.pg1)
1654 self.pg0.add_stream(pkts)
1655 self.pg_enable_capture(self.pg_interfaces)
1658 # Server side - generate traffic
1659 capture = self.pg1.get_capture(len(pkts))
1660 self.verify_capture_out(capture)
1661 pkts = self.create_stream_out(self.pg1, ttl=1)
1662 self.pg1.add_stream(pkts)
1663 self.pg_enable_capture(self.pg_interfaces)
1666 # Server side - verify ICMP type 11 packets
1667 capture = self.pg1.get_capture(len(pkts))
1668 self.verify_capture_out_with_icmp_errors(capture,
1669 src_ip=self.pg1.local_ip4)
1671 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1672 """ NAT44 handling of error responses to client packets with TTL=2 """
1674 self.nat44_add_address(self.nat_addr)
1675 flags = self.config_flags.NAT_IS_INSIDE
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg0.sw_if_index,
1678 flags=flags, is_add=1)
1679 self.vapi.nat44_interface_add_del_feature(
1680 sw_if_index=self.pg1.sw_if_index,
1683 # Client side - generate traffic
1684 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1685 self.pg0.add_stream(pkts)
1686 self.pg_enable_capture(self.pg_interfaces)
1689 # Server side - simulate ICMP type 11 response
1690 capture = self.pg1.get_capture(len(pkts))
1691 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1692 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1693 ICMP(type=11) / packet[IP] for packet in capture]
1694 self.pg1.add_stream(pkts)
1695 self.pg_enable_capture(self.pg_interfaces)
1698 # Client side - verify ICMP type 11 packets
1699 capture = self.pg0.get_capture(len(pkts))
1700 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1702 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1703 """ NAT44 handling of error responses to server packets with TTL=2 """
1705 self.nat44_add_address(self.nat_addr)
1706 flags = self.config_flags.NAT_IS_INSIDE
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg0.sw_if_index,
1709 flags=flags, is_add=1)
1710 self.vapi.nat44_interface_add_del_feature(
1711 sw_if_index=self.pg1.sw_if_index,
1714 # Client side - create sessions
1715 pkts = self.create_stream_in(self.pg0, self.pg1)
1716 self.pg0.add_stream(pkts)
1717 self.pg_enable_capture(self.pg_interfaces)
1720 # Server side - generate traffic
1721 capture = self.pg1.get_capture(len(pkts))
1722 self.verify_capture_out(capture)
1723 pkts = self.create_stream_out(self.pg1, ttl=2)
1724 self.pg1.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1728 # Client side - simulate ICMP type 11 response
1729 capture = self.pg0.get_capture(len(pkts))
1730 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1731 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1732 ICMP(type=11) / packet[IP] for packet in capture]
1733 self.pg0.add_stream(pkts)
1734 self.pg_enable_capture(self.pg_interfaces)
1737 # Server side - verify ICMP type 11 packets
1738 capture = self.pg1.get_capture(len(pkts))
1739 self.verify_capture_out_with_icmp_errors(capture)
1741 def test_ping_out_interface_from_outside(self):
1742 """ Ping NAT44 out interface from outside network """
1744 self.nat44_add_address(self.nat_addr)
1745 flags = self.config_flags.NAT_IS_INSIDE
1746 self.vapi.nat44_interface_add_del_feature(
1747 sw_if_index=self.pg0.sw_if_index,
1748 flags=flags, is_add=1)
1749 self.vapi.nat44_interface_add_del_feature(
1750 sw_if_index=self.pg1.sw_if_index,
1753 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1754 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1755 ICMP(id=self.icmp_id_out, type='echo-request'))
1757 self.pg1.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1760 capture = self.pg1.get_capture(len(pkts))
1763 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1764 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1765 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1766 self.assertEqual(packet[ICMP].type, 0) # echo reply
1768 self.logger.error(ppp("Unexpected or invalid packet "
1769 "(outside network):", packet))
1772 def test_ping_internal_host_from_outside(self):
1773 """ Ping internal host from outside network """
1775 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1776 flags = self.config_flags.NAT_IS_INSIDE
1777 self.vapi.nat44_interface_add_del_feature(
1778 sw_if_index=self.pg0.sw_if_index,
1779 flags=flags, is_add=1)
1780 self.vapi.nat44_interface_add_del_feature(
1781 sw_if_index=self.pg1.sw_if_index,
1785 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1786 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1787 ICMP(id=self.icmp_id_out, type='echo-request'))
1788 self.pg1.add_stream(pkt)
1789 self.pg_enable_capture(self.pg_interfaces)
1791 capture = self.pg0.get_capture(1)
1792 self.verify_capture_in(capture, self.pg0)
1793 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1796 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1797 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1798 ICMP(id=self.icmp_id_in, type='echo-reply'))
1799 self.pg0.add_stream(pkt)
1800 self.pg_enable_capture(self.pg_interfaces)
1802 capture = self.pg1.get_capture(1)
1803 self.verify_capture_out(capture, same_port=True)
1804 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1806 def test_forwarding(self):
1807 """ NAT44 forwarding test """
1809 flags = self.config_flags.NAT_IS_INSIDE
1810 self.vapi.nat44_interface_add_del_feature(
1811 sw_if_index=self.pg0.sw_if_index,
1812 flags=flags, is_add=1)
1813 self.vapi.nat44_interface_add_del_feature(
1814 sw_if_index=self.pg1.sw_if_index,
1816 self.vapi.nat44_forwarding_enable_disable(enable=1)
1818 real_ip = self.pg0.remote_ip4n
1819 alias_ip = self.nat_addr
1820 flags = self.config_flags.NAT_IS_ADDR_ONLY
1821 self.vapi.nat44_add_del_static_mapping(is_add=1,
1822 local_ip_address=real_ip,
1823 external_ip_address=alias_ip,
1824 external_sw_if_index=0xFFFFFFFF,
1828 # static mapping match
1830 pkts = self.create_stream_out(self.pg1)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1834 capture = self.pg0.get_capture(len(pkts))
1835 self.verify_capture_in(capture, self.pg0)
1837 pkts = self.create_stream_in(self.pg0, self.pg1)
1838 self.pg0.add_stream(pkts)
1839 self.pg_enable_capture(self.pg_interfaces)
1841 capture = self.pg1.get_capture(len(pkts))
1842 self.verify_capture_out(capture, same_port=True)
1844 # no static mapping match
1846 host0 = self.pg0.remote_hosts[0]
1847 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1849 pkts = self.create_stream_out(self.pg1,
1850 dst_ip=self.pg0.remote_ip4,
1851 use_inside_ports=True)
1852 self.pg1.add_stream(pkts)
1853 self.pg_enable_capture(self.pg_interfaces)
1855 capture = self.pg0.get_capture(len(pkts))
1856 self.verify_capture_in(capture, self.pg0)
1858 pkts = self.create_stream_in(self.pg0, self.pg1)
1859 self.pg0.add_stream(pkts)
1860 self.pg_enable_capture(self.pg_interfaces)
1862 capture = self.pg1.get_capture(len(pkts))
1863 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1866 self.pg0.remote_hosts[0] = host0
1869 self.vapi.nat44_forwarding_enable_disable(enable=0)
1870 flags = self.config_flags.NAT_IS_ADDR_ONLY
1871 self.vapi.nat44_add_del_static_mapping(
1873 local_ip_address=real_ip,
1874 external_ip_address=alias_ip,
1875 external_sw_if_index=0xFFFFFFFF,
1878 def test_static_in(self):
1879 """ 1:1 NAT initialized from inside network """
1881 nat_ip = "10.0.0.10"
1882 self.tcp_port_out = 6303
1883 self.udp_port_out = 6304
1884 self.icmp_id_out = 6305
1886 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1887 flags = self.config_flags.NAT_IS_INSIDE
1888 self.vapi.nat44_interface_add_del_feature(
1889 sw_if_index=self.pg0.sw_if_index,
1890 flags=flags, is_add=1)
1891 self.vapi.nat44_interface_add_del_feature(
1892 sw_if_index=self.pg1.sw_if_index,
1894 sm = self.vapi.nat44_static_mapping_dump()
1895 self.assertEqual(len(sm), 1)
1896 self.assertEqual(sm[0].tag, '')
1897 self.assertEqual(sm[0].protocol, 0)
1898 self.assertEqual(sm[0].local_port, 0)
1899 self.assertEqual(sm[0].external_port, 0)
1902 pkts = self.create_stream_in(self.pg0, self.pg1)
1903 self.pg0.add_stream(pkts)
1904 self.pg_enable_capture(self.pg_interfaces)
1906 capture = self.pg1.get_capture(len(pkts))
1907 self.verify_capture_out(capture, nat_ip, True)
1910 pkts = self.create_stream_out(self.pg1, nat_ip)
1911 self.pg1.add_stream(pkts)
1912 self.pg_enable_capture(self.pg_interfaces)
1914 capture = self.pg0.get_capture(len(pkts))
1915 self.verify_capture_in(capture, self.pg0)
1917 def test_static_out(self):
1918 """ 1:1 NAT initialized from outside network """
1920 nat_ip = "10.0.0.20"
1921 self.tcp_port_out = 6303
1922 self.udp_port_out = 6304
1923 self.icmp_id_out = 6305
1926 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1927 flags = self.config_flags.NAT_IS_INSIDE
1928 self.vapi.nat44_interface_add_del_feature(
1929 sw_if_index=self.pg0.sw_if_index,
1930 flags=flags, is_add=1)
1931 self.vapi.nat44_interface_add_del_feature(
1932 sw_if_index=self.pg1.sw_if_index,
1934 sm = self.vapi.nat44_static_mapping_dump()
1935 self.assertEqual(len(sm), 1)
1936 self.assertEqual((sm[0].tag).split(b'\0', 1)[0], tag)
1939 pkts = self.create_stream_out(self.pg1, nat_ip)
1940 self.pg1.add_stream(pkts)
1941 self.pg_enable_capture(self.pg_interfaces)
1943 capture = self.pg0.get_capture(len(pkts))
1944 self.verify_capture_in(capture, self.pg0)
1947 pkts = self.create_stream_in(self.pg0, self.pg1)
1948 self.pg0.add_stream(pkts)
1949 self.pg_enable_capture(self.pg_interfaces)
1951 capture = self.pg1.get_capture(len(pkts))
1952 self.verify_capture_out(capture, nat_ip, True)
1954 def test_static_with_port_in(self):
1955 """ 1:1 NAPT initialized from inside network """
1957 self.tcp_port_out = 3606
1958 self.udp_port_out = 3607
1959 self.icmp_id_out = 3608
1961 self.nat44_add_address(self.nat_addr)
1962 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1963 self.tcp_port_in, self.tcp_port_out,
1964 proto=IP_PROTOS.tcp)
1965 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1966 self.udp_port_in, self.udp_port_out,
1967 proto=IP_PROTOS.udp)
1968 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1969 self.icmp_id_in, self.icmp_id_out,
1970 proto=IP_PROTOS.icmp)
1971 flags = self.config_flags.NAT_IS_INSIDE
1972 self.vapi.nat44_interface_add_del_feature(
1973 sw_if_index=self.pg0.sw_if_index,
1974 flags=flags, is_add=1)
1975 self.vapi.nat44_interface_add_del_feature(
1976 sw_if_index=self.pg1.sw_if_index,
1980 pkts = self.create_stream_in(self.pg0, self.pg1)
1981 self.pg0.add_stream(pkts)
1982 self.pg_enable_capture(self.pg_interfaces)
1984 capture = self.pg1.get_capture(len(pkts))
1985 self.verify_capture_out(capture)
1988 pkts = self.create_stream_out(self.pg1)
1989 self.pg1.add_stream(pkts)
1990 self.pg_enable_capture(self.pg_interfaces)
1992 capture = self.pg0.get_capture(len(pkts))
1993 self.verify_capture_in(capture, self.pg0)
1995 def test_static_with_port_out(self):
1996 """ 1:1 NAPT initialized from outside network """
1998 self.tcp_port_out = 30606
1999 self.udp_port_out = 30607
2000 self.icmp_id_out = 30608
2002 self.nat44_add_address(self.nat_addr)
2003 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2004 self.tcp_port_in, self.tcp_port_out,
2005 proto=IP_PROTOS.tcp)
2006 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2007 self.udp_port_in, self.udp_port_out,
2008 proto=IP_PROTOS.udp)
2009 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2010 self.icmp_id_in, self.icmp_id_out,
2011 proto=IP_PROTOS.icmp)
2012 flags = self.config_flags.NAT_IS_INSIDE
2013 self.vapi.nat44_interface_add_del_feature(
2014 sw_if_index=self.pg0.sw_if_index,
2015 flags=flags, is_add=1)
2016 self.vapi.nat44_interface_add_del_feature(
2017 sw_if_index=self.pg1.sw_if_index,
2021 pkts = self.create_stream_out(self.pg1)
2022 self.pg1.add_stream(pkts)
2023 self.pg_enable_capture(self.pg_interfaces)
2025 capture = self.pg0.get_capture(len(pkts))
2026 self.verify_capture_in(capture, self.pg0)
2029 pkts = self.create_stream_in(self.pg0, self.pg1)
2030 self.pg0.add_stream(pkts)
2031 self.pg_enable_capture(self.pg_interfaces)
2033 capture = self.pg1.get_capture(len(pkts))
2034 self.verify_capture_out(capture)
2036 def test_static_vrf_aware(self):
2037 """ 1:1 NAT VRF awareness """
2039 nat_ip1 = "10.0.0.30"
2040 nat_ip2 = "10.0.0.40"
2041 self.tcp_port_out = 6303
2042 self.udp_port_out = 6304
2043 self.icmp_id_out = 6305
2045 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2047 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2049 flags = self.config_flags.NAT_IS_INSIDE
2050 self.vapi.nat44_interface_add_del_feature(
2051 sw_if_index=self.pg3.sw_if_index,
2053 self.vapi.nat44_interface_add_del_feature(
2054 sw_if_index=self.pg0.sw_if_index,
2055 flags=flags, is_add=1)
2056 self.vapi.nat44_interface_add_del_feature(
2057 sw_if_index=self.pg4.sw_if_index,
2058 flags=flags, is_add=1)
2060 # inside interface VRF match NAT44 static mapping VRF
2061 pkts = self.create_stream_in(self.pg4, self.pg3)
2062 self.pg4.add_stream(pkts)
2063 self.pg_enable_capture(self.pg_interfaces)
2065 capture = self.pg3.get_capture(len(pkts))
2066 self.verify_capture_out(capture, nat_ip1, True)
2068 # inside interface VRF don't match NAT44 static mapping VRF (packets
2070 pkts = self.create_stream_in(self.pg0, self.pg3)
2071 self.pg0.add_stream(pkts)
2072 self.pg_enable_capture(self.pg_interfaces)
2074 self.pg3.assert_nothing_captured()
2076 def test_dynamic_to_static(self):
2077 """ Switch from dynamic translation to 1:1NAT """
2078 nat_ip = "10.0.0.10"
2079 self.tcp_port_out = 6303
2080 self.udp_port_out = 6304
2081 self.icmp_id_out = 6305
2083 self.nat44_add_address(self.nat_addr)
2084 flags = self.config_flags.NAT_IS_INSIDE
2085 self.vapi.nat44_interface_add_del_feature(
2086 sw_if_index=self.pg0.sw_if_index,
2087 flags=flags, is_add=1)
2088 self.vapi.nat44_interface_add_del_feature(
2089 sw_if_index=self.pg1.sw_if_index,
2093 pkts = self.create_stream_in(self.pg0, self.pg1)
2094 self.pg0.add_stream(pkts)
2095 self.pg_enable_capture(self.pg_interfaces)
2097 capture = self.pg1.get_capture(len(pkts))
2098 self.verify_capture_out(capture)
2101 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2102 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2103 self.assertEqual(len(sessions), 0)
2104 pkts = self.create_stream_in(self.pg0, self.pg1)
2105 self.pg0.add_stream(pkts)
2106 self.pg_enable_capture(self.pg_interfaces)
2108 capture = self.pg1.get_capture(len(pkts))
2109 self.verify_capture_out(capture, nat_ip, True)
2111 def test_identity_nat(self):
2112 """ Identity NAT """
2113 flags = self.config_flags.NAT_IS_ADDR_ONLY
2114 self.vapi.nat44_add_del_identity_mapping(
2115 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2116 flags=flags, is_add=1)
2117 flags = self.config_flags.NAT_IS_INSIDE
2118 self.vapi.nat44_interface_add_del_feature(
2119 sw_if_index=self.pg0.sw_if_index,
2120 flags=flags, is_add=1)
2121 self.vapi.nat44_interface_add_del_feature(
2122 sw_if_index=self.pg1.sw_if_index,
2125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2126 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2127 TCP(sport=12345, dport=56789))
2128 self.pg1.add_stream(p)
2129 self.pg_enable_capture(self.pg_interfaces)
2131 capture = self.pg0.get_capture(1)
2136 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2137 self.assertEqual(ip.src, self.pg1.remote_ip4)
2138 self.assertEqual(tcp.dport, 56789)
2139 self.assertEqual(tcp.sport, 12345)
2140 self.assert_packet_checksums_valid(p)
2142 self.logger.error(ppp("Unexpected or invalid packet:", p))
2145 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2146 self.assertEqual(len(sessions), 0)
2147 flags = self.config_flags.NAT_IS_ADDR_ONLY
2148 self.vapi.nat44_add_del_identity_mapping(
2149 ip_address=self.pg0.remote_ip4n, sw_if_index=0xFFFFFFFF,
2150 flags=flags, vrf_id=1, is_add=1)
2151 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2152 self.assertEqual(len(identity_mappings), 2)
2154 def test_multiple_inside_interfaces(self):
2155 """ NAT44 multiple non-overlapping address space inside interfaces """
2157 self.nat44_add_address(self.nat_addr)
2158 flags = self.config_flags.NAT_IS_INSIDE
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg0.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg1.sw_if_index,
2164 flags=flags, is_add=1)
2165 self.vapi.nat44_interface_add_del_feature(
2166 sw_if_index=self.pg3.sw_if_index,
2169 # between two NAT44 inside interfaces (no translation)
2170 pkts = self.create_stream_in(self.pg0, self.pg1)
2171 self.pg0.add_stream(pkts)
2172 self.pg_enable_capture(self.pg_interfaces)
2174 capture = self.pg1.get_capture(len(pkts))
2175 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2177 # from NAT44 inside to interface without NAT44 feature (no translation)
2178 pkts = self.create_stream_in(self.pg0, self.pg2)
2179 self.pg0.add_stream(pkts)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg2.get_capture(len(pkts))
2183 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2185 # in2out 1st interface
2186 pkts = self.create_stream_in(self.pg0, self.pg3)
2187 self.pg0.add_stream(pkts)
2188 self.pg_enable_capture(self.pg_interfaces)
2190 capture = self.pg3.get_capture(len(pkts))
2191 self.verify_capture_out(capture)
2193 # out2in 1st interface
2194 pkts = self.create_stream_out(self.pg3)
2195 self.pg3.add_stream(pkts)
2196 self.pg_enable_capture(self.pg_interfaces)
2198 capture = self.pg0.get_capture(len(pkts))
2199 self.verify_capture_in(capture, self.pg0)
2201 # in2out 2nd interface
2202 pkts = self.create_stream_in(self.pg1, self.pg3)
2203 self.pg1.add_stream(pkts)
2204 self.pg_enable_capture(self.pg_interfaces)
2206 capture = self.pg3.get_capture(len(pkts))
2207 self.verify_capture_out(capture)
2209 # out2in 2nd interface
2210 pkts = self.create_stream_out(self.pg3)
2211 self.pg3.add_stream(pkts)
2212 self.pg_enable_capture(self.pg_interfaces)
2214 capture = self.pg1.get_capture(len(pkts))
2215 self.verify_capture_in(capture, self.pg1)
2217 def test_inside_overlapping_interfaces(self):
2218 """ NAT44 multiple inside interfaces with overlapping address space """
2220 static_nat_ip = "10.0.0.10"
2221 self.nat44_add_address(self.nat_addr)
2222 flags = self.config_flags.NAT_IS_INSIDE
2223 self.vapi.nat44_interface_add_del_feature(
2224 sw_if_index=self.pg3.sw_if_index,
2226 self.vapi.nat44_interface_add_del_feature(
2227 sw_if_index=self.pg4.sw_if_index,
2228 flags=flags, is_add=1)
2229 self.vapi.nat44_interface_add_del_feature(
2230 sw_if_index=self.pg5.sw_if_index,
2231 flags=flags, is_add=1)
2232 self.vapi.nat44_interface_add_del_feature(
2233 sw_if_index=self.pg6.sw_if_index,
2234 flags=flags, is_add=1)
2235 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2238 # between NAT44 inside interfaces with same VRF (no translation)
2239 pkts = self.create_stream_in(self.pg4, self.pg5)
2240 self.pg4.add_stream(pkts)
2241 self.pg_enable_capture(self.pg_interfaces)
2243 capture = self.pg5.get_capture(len(pkts))
2244 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2246 # between NAT44 inside interfaces with different VRF (hairpinning)
2247 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2248 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2249 TCP(sport=1234, dport=5678))
2250 self.pg4.add_stream(p)
2251 self.pg_enable_capture(self.pg_interfaces)
2253 capture = self.pg6.get_capture(1)
2258 self.assertEqual(ip.src, self.nat_addr)
2259 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2260 self.assertNotEqual(tcp.sport, 1234)
2261 self.assertEqual(tcp.dport, 5678)
2263 self.logger.error(ppp("Unexpected or invalid packet:", p))
2266 # in2out 1st interface
2267 pkts = self.create_stream_in(self.pg4, self.pg3)
2268 self.pg4.add_stream(pkts)
2269 self.pg_enable_capture(self.pg_interfaces)
2271 capture = self.pg3.get_capture(len(pkts))
2272 self.verify_capture_out(capture)
2274 # out2in 1st interface
2275 pkts = self.create_stream_out(self.pg3)
2276 self.pg3.add_stream(pkts)
2277 self.pg_enable_capture(self.pg_interfaces)
2279 capture = self.pg4.get_capture(len(pkts))
2280 self.verify_capture_in(capture, self.pg4)
2282 # in2out 2nd interface
2283 pkts = self.create_stream_in(self.pg5, self.pg3)
2284 self.pg5.add_stream(pkts)
2285 self.pg_enable_capture(self.pg_interfaces)
2287 capture = self.pg3.get_capture(len(pkts))
2288 self.verify_capture_out(capture)
2290 # out2in 2nd interface
2291 pkts = self.create_stream_out(self.pg3)
2292 self.pg3.add_stream(pkts)
2293 self.pg_enable_capture(self.pg_interfaces)
2295 capture = self.pg5.get_capture(len(pkts))
2296 self.verify_capture_in(capture, self.pg5)
2299 addresses = self.vapi.nat44_address_dump()
2300 self.assertEqual(len(addresses), 1)
2301 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
2302 self.assertEqual(len(sessions), 3)
2303 for session in sessions:
2304 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2305 self.assertEqual(str(session.inside_ip_address),
2306 self.pg5.remote_ip4)
2307 self.assertEqual(session.outside_ip_address,
2308 addresses[0].ip_address)
2309 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2310 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2311 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2312 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2313 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2314 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2315 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2316 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2317 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2319 # in2out 3rd interface
2320 pkts = self.create_stream_in(self.pg6, self.pg3)
2321 self.pg6.add_stream(pkts)
2322 self.pg_enable_capture(self.pg_interfaces)
2324 capture = self.pg3.get_capture(len(pkts))
2325 self.verify_capture_out(capture, static_nat_ip, True)
2327 # out2in 3rd interface
2328 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2329 self.pg3.add_stream(pkts)
2330 self.pg_enable_capture(self.pg_interfaces)
2332 capture = self.pg6.get_capture(len(pkts))
2333 self.verify_capture_in(capture, self.pg6)
2335 # general user and session dump verifications
2336 users = self.vapi.nat44_user_dump()
2337 self.assertGreaterEqual(len(users), 3)
2338 addresses = self.vapi.nat44_address_dump()
2339 self.assertEqual(len(addresses), 1)
2341 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2343 for session in sessions:
2344 self.assertEqual(user.ip_address, session.inside_ip_address)
2345 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2346 self.assertTrue(session.protocol in
2347 [IP_PROTOS.tcp, IP_PROTOS.udp,
2349 self.assertFalse(session.flags &
2350 self.config_flags.NAT_IS_EXT_HOST_VALID)
2353 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
2354 self.assertGreaterEqual(len(sessions), 4)
2355 for session in sessions:
2356 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2357 self.assertEqual(str(session.inside_ip_address),
2358 self.pg4.remote_ip4)
2359 self.assertEqual(session.outside_ip_address,
2360 addresses[0].ip_address)
2363 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
2364 self.assertGreaterEqual(len(sessions), 3)
2365 for session in sessions:
2366 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2367 self.assertEqual(str(session.inside_ip_address),
2368 self.pg6.remote_ip4)
2369 self.assertEqual(str(session.outside_ip_address),
2371 self.assertTrue(session.inside_port in
2372 [self.tcp_port_in, self.udp_port_in,
2375 def test_hairpinning(self):
2376 """ NAT44 hairpinning - 1:1 NAPT """
2378 host = self.pg0.remote_hosts[0]
2379 server = self.pg0.remote_hosts[1]
2382 server_in_port = 5678
2383 server_out_port = 8765
2385 self.nat44_add_address(self.nat_addr)
2386 flags = self.config_flags.NAT_IS_INSIDE
2387 self.vapi.nat44_interface_add_del_feature(
2388 sw_if_index=self.pg0.sw_if_index,
2389 flags=flags, is_add=1)
2390 self.vapi.nat44_interface_add_del_feature(
2391 sw_if_index=self.pg1.sw_if_index,
2394 # add static mapping for server
2395 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2396 server_in_port, server_out_port,
2397 proto=IP_PROTOS.tcp)
2399 # send packet from host to server
2400 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2401 IP(src=host.ip4, dst=self.nat_addr) /
2402 TCP(sport=host_in_port, dport=server_out_port))
2403 self.pg0.add_stream(p)
2404 self.pg_enable_capture(self.pg_interfaces)
2406 capture = self.pg0.get_capture(1)
2411 self.assertEqual(ip.src, self.nat_addr)
2412 self.assertEqual(ip.dst, server.ip4)
2413 self.assertNotEqual(tcp.sport, host_in_port)
2414 self.assertEqual(tcp.dport, server_in_port)
2415 self.assert_packet_checksums_valid(p)
2416 host_out_port = tcp.sport
2418 self.logger.error(ppp("Unexpected or invalid packet:", p))
2421 # send reply from server to host
2422 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2423 IP(src=server.ip4, dst=self.nat_addr) /
2424 TCP(sport=server_in_port, dport=host_out_port))
2425 self.pg0.add_stream(p)
2426 self.pg_enable_capture(self.pg_interfaces)
2428 capture = self.pg0.get_capture(1)
2433 self.assertEqual(ip.src, self.nat_addr)
2434 self.assertEqual(ip.dst, host.ip4)
2435 self.assertEqual(tcp.sport, server_out_port)
2436 self.assertEqual(tcp.dport, host_in_port)
2437 self.assert_packet_checksums_valid(p)
2439 self.logger.error(ppp("Unexpected or invalid packet:", p))
2442 def test_hairpinning2(self):
2443 """ NAT44 hairpinning - 1:1 NAT"""
2445 server1_nat_ip = "10.0.0.10"
2446 server2_nat_ip = "10.0.0.11"
2447 host = self.pg0.remote_hosts[0]
2448 server1 = self.pg0.remote_hosts[1]
2449 server2 = self.pg0.remote_hosts[2]
2450 server_tcp_port = 22
2451 server_udp_port = 20
2453 self.nat44_add_address(self.nat_addr)
2454 flags = self.config_flags.NAT_IS_INSIDE
2455 self.vapi.nat44_interface_add_del_feature(
2456 sw_if_index=self.pg0.sw_if_index,
2457 flags=flags, is_add=1)
2458 self.vapi.nat44_interface_add_del_feature(
2459 sw_if_index=self.pg1.sw_if_index,
2462 # add static mapping for servers
2463 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2464 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2469 IP(src=host.ip4, dst=server1_nat_ip) /
2470 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2473 IP(src=host.ip4, dst=server1_nat_ip) /
2474 UDP(sport=self.udp_port_in, dport=server_udp_port))
2476 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2477 IP(src=host.ip4, dst=server1_nat_ip) /
2478 ICMP(id=self.icmp_id_in, type='echo-request'))
2480 self.pg0.add_stream(pkts)
2481 self.pg_enable_capture(self.pg_interfaces)
2483 capture = self.pg0.get_capture(len(pkts))
2484 for packet in capture:
2486 self.assertEqual(packet[IP].src, self.nat_addr)
2487 self.assertEqual(packet[IP].dst, server1.ip4)
2488 if packet.haslayer(TCP):
2489 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2490 self.assertEqual(packet[TCP].dport, server_tcp_port)
2491 self.tcp_port_out = packet[TCP].sport
2492 self.assert_packet_checksums_valid(packet)
2493 elif packet.haslayer(UDP):
2494 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2495 self.assertEqual(packet[UDP].dport, server_udp_port)
2496 self.udp_port_out = packet[UDP].sport
2498 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2499 self.icmp_id_out = packet[ICMP].id
2501 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2507 IP(src=server1.ip4, dst=self.nat_addr) /
2508 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2510 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2511 IP(src=server1.ip4, dst=self.nat_addr) /
2512 UDP(sport=server_udp_port, dport=self.udp_port_out))
2514 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2515 IP(src=server1.ip4, dst=self.nat_addr) /
2516 ICMP(id=self.icmp_id_out, type='echo-reply'))
2518 self.pg0.add_stream(pkts)
2519 self.pg_enable_capture(self.pg_interfaces)
2521 capture = self.pg0.get_capture(len(pkts))
2522 for packet in capture:
2524 self.assertEqual(packet[IP].src, server1_nat_ip)
2525 self.assertEqual(packet[IP].dst, host.ip4)
2526 if packet.haslayer(TCP):
2527 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2528 self.assertEqual(packet[TCP].sport, server_tcp_port)
2529 self.assert_packet_checksums_valid(packet)
2530 elif packet.haslayer(UDP):
2531 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2532 self.assertEqual(packet[UDP].sport, server_udp_port)
2534 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2536 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2539 # server2 to server1
2541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2542 IP(src=server2.ip4, dst=server1_nat_ip) /
2543 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2545 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2546 IP(src=server2.ip4, dst=server1_nat_ip) /
2547 UDP(sport=self.udp_port_in, dport=server_udp_port))
2549 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2550 IP(src=server2.ip4, dst=server1_nat_ip) /
2551 ICMP(id=self.icmp_id_in, type='echo-request'))
2553 self.pg0.add_stream(pkts)
2554 self.pg_enable_capture(self.pg_interfaces)
2556 capture = self.pg0.get_capture(len(pkts))
2557 for packet in capture:
2559 self.assertEqual(packet[IP].src, server2_nat_ip)
2560 self.assertEqual(packet[IP].dst, server1.ip4)
2561 if packet.haslayer(TCP):
2562 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2563 self.assertEqual(packet[TCP].dport, server_tcp_port)
2564 self.tcp_port_out = packet[TCP].sport
2565 self.assert_packet_checksums_valid(packet)
2566 elif packet.haslayer(UDP):
2567 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2568 self.assertEqual(packet[UDP].dport, server_udp_port)
2569 self.udp_port_out = packet[UDP].sport
2571 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2572 self.icmp_id_out = packet[ICMP].id
2574 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2577 # server1 to server2
2579 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2580 IP(src=server1.ip4, dst=server2_nat_ip) /
2581 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2583 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2584 IP(src=server1.ip4, dst=server2_nat_ip) /
2585 UDP(sport=server_udp_port, dport=self.udp_port_out))
2587 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2588 IP(src=server1.ip4, dst=server2_nat_ip) /
2589 ICMP(id=self.icmp_id_out, type='echo-reply'))
2591 self.pg0.add_stream(pkts)
2592 self.pg_enable_capture(self.pg_interfaces)
2594 capture = self.pg0.get_capture(len(pkts))
2595 for packet in capture:
2597 self.assertEqual(packet[IP].src, server1_nat_ip)
2598 self.assertEqual(packet[IP].dst, server2.ip4)
2599 if packet.haslayer(TCP):
2600 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2601 self.assertEqual(packet[TCP].sport, server_tcp_port)
2602 self.assert_packet_checksums_valid(packet)
2603 elif packet.haslayer(UDP):
2604 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2605 self.assertEqual(packet[UDP].sport, server_udp_port)
2607 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2612 def test_max_translations_per_user(self):
2613 """ MAX translations per user - recycle the least recently used """
2615 self.nat44_add_address(self.nat_addr)
2616 flags = self.config_flags.NAT_IS_INSIDE
2617 self.vapi.nat44_interface_add_del_feature(
2618 sw_if_index=self.pg0.sw_if_index,
2619 flags=flags, is_add=1)
2620 self.vapi.nat44_interface_add_del_feature(
2621 sw_if_index=self.pg1.sw_if_index,
2624 # get maximum number of translations per user
2625 nat44_config = self.vapi.nat_show_config()
2627 # send more than maximum number of translations per user packets
2628 pkts_num = nat44_config.max_translations_per_user + 5
2630 for port in range(0, pkts_num):
2631 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2632 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2633 TCP(sport=1025 + port))
2635 self.pg0.add_stream(pkts)
2636 self.pg_enable_capture(self.pg_interfaces)
2639 # verify number of translated packet
2640 self.pg1.get_capture(pkts_num)
2642 users = self.vapi.nat44_user_dump()
2644 if user.ip_address == self.pg0.remote_ip4n:
2645 self.assertEqual(user.nsessions,
2646 nat44_config.max_translations_per_user)
2647 self.assertEqual(user.nstaticsessions, 0)
2650 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2652 proto=IP_PROTOS.tcp)
2653 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2654 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2655 TCP(sport=tcp_port))
2656 self.pg0.add_stream(p)
2657 self.pg_enable_capture(self.pg_interfaces)
2659 self.pg1.get_capture(1)
2660 users = self.vapi.nat44_user_dump()
2662 if user.ip_address == self.pg0.remote_ip4n:
2663 self.assertEqual(user.nsessions,
2664 nat44_config.max_translations_per_user - 1)
2665 self.assertEqual(user.nstaticsessions, 1)
2667 def test_interface_addr(self):
2668 """ Acquire NAT44 addresses from interface """
2669 self.vapi.nat44_add_del_interface_addr(
2671 sw_if_index=self.pg7.sw_if_index)
2673 # no address in NAT pool
2674 addresses = self.vapi.nat44_address_dump()
2675 self.assertEqual(0, len(addresses))
2677 # configure interface address and check NAT address pool
2678 self.pg7.config_ip4()
2679 addresses = self.vapi.nat44_address_dump()
2680 self.assertEqual(1, len(addresses))
2681 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2683 # remove interface address and check NAT address pool
2684 self.pg7.unconfig_ip4()
2685 addresses = self.vapi.nat44_address_dump()
2686 self.assertEqual(0, len(addresses))
2688 def test_interface_addr_static_mapping(self):
2689 """ Static mapping with addresses from interface """
2692 self.vapi.nat44_add_del_interface_addr(
2694 sw_if_index=self.pg7.sw_if_index)
2695 self.nat44_add_static_mapping(
2697 external_sw_if_index=self.pg7.sw_if_index,
2700 # static mappings with external interface
2701 static_mappings = self.vapi.nat44_static_mapping_dump()
2702 self.assertEqual(1, len(static_mappings))
2703 self.assertEqual(self.pg7.sw_if_index,
2704 static_mappings[0].external_sw_if_index)
2705 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2707 # configure interface address and check static mappings
2708 self.pg7.config_ip4()
2709 static_mappings = self.vapi.nat44_static_mapping_dump()
2710 self.assertEqual(2, len(static_mappings))
2712 for sm in static_mappings:
2713 if sm.external_sw_if_index == 0xFFFFFFFF:
2714 self.assertEqual(str(sm.external_ip_address),
2716 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2718 self.assertTrue(resolved)
2720 # remove interface address and check static mappings
2721 self.pg7.unconfig_ip4()
2722 static_mappings = self.vapi.nat44_static_mapping_dump()
2723 self.assertEqual(1, len(static_mappings))
2724 self.assertEqual(self.pg7.sw_if_index,
2725 static_mappings[0].external_sw_if_index)
2726 self.assertEqual((static_mappings[0].tag).split(b'\0', 1)[0], tag)
2728 # configure interface address again and check static mappings
2729 self.pg7.config_ip4()
2730 static_mappings = self.vapi.nat44_static_mapping_dump()
2731 self.assertEqual(2, len(static_mappings))
2733 for sm in static_mappings:
2734 if sm.external_sw_if_index == 0xFFFFFFFF:
2735 self.assertEqual(str(sm.external_ip_address),
2737 self.assertEqual((sm.tag).split(b'\0', 1)[0], tag)
2739 self.assertTrue(resolved)
2741 # remove static mapping
2742 self.nat44_add_static_mapping(
2744 external_sw_if_index=self.pg7.sw_if_index,
2747 static_mappings = self.vapi.nat44_static_mapping_dump()
2748 self.assertEqual(0, len(static_mappings))
2750 def test_interface_addr_identity_nat(self):
2751 """ Identity NAT with addresses from interface """
2754 self.vapi.nat44_add_del_interface_addr(
2756 sw_if_index=self.pg7.sw_if_index)
2757 self.vapi.nat44_add_del_identity_mapping(
2759 sw_if_index=self.pg7.sw_if_index,
2761 protocol=IP_PROTOS.tcp,
2764 # identity mappings with external interface
2765 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2766 self.assertEqual(1, len(identity_mappings))
2767 self.assertEqual(self.pg7.sw_if_index,
2768 identity_mappings[0].sw_if_index)
2770 # configure interface address and check identity mappings
2771 self.pg7.config_ip4()
2772 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2774 self.assertEqual(2, len(identity_mappings))
2775 for sm in identity_mappings:
2776 if sm.sw_if_index == 0xFFFFFFFF:
2777 self.assertEqual(str(identity_mappings[0].ip_address),
2779 self.assertEqual(port, identity_mappings[0].port)
2780 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2782 self.assertTrue(resolved)
2784 # remove interface address and check identity mappings
2785 self.pg7.unconfig_ip4()
2786 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2787 self.assertEqual(1, len(identity_mappings))
2788 self.assertEqual(self.pg7.sw_if_index,
2789 identity_mappings[0].sw_if_index)
2791 def test_ipfix_nat44_sess(self):
2792 """ IPFIX logging NAT44 session created/deleted """
2793 self.ipfix_domain_id = 10
2794 self.ipfix_src_port = 20202
2795 collector_port = 30303
2796 bind_layers(UDP, IPFIX, dport=30303)
2797 self.nat44_add_address(self.nat_addr)
2798 flags = self.config_flags.NAT_IS_INSIDE
2799 self.vapi.nat44_interface_add_del_feature(
2800 sw_if_index=self.pg0.sw_if_index,
2801 flags=flags, is_add=1)
2802 self.vapi.nat44_interface_add_del_feature(
2803 sw_if_index=self.pg1.sw_if_index,
2805 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2806 src_address=self.pg3.local_ip4n,
2808 template_interval=10,
2809 collector_port=collector_port)
2810 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2811 src_port=self.ipfix_src_port,
2814 pkts = self.create_stream_in(self.pg0, self.pg1)
2815 self.pg0.add_stream(pkts)
2816 self.pg_enable_capture(self.pg_interfaces)
2818 capture = self.pg1.get_capture(len(pkts))
2819 self.verify_capture_out(capture)
2820 self.nat44_add_address(self.nat_addr, is_add=0)
2821 self.vapi.ipfix_flush()
2822 capture = self.pg3.get_capture(9)
2823 ipfix = IPFIXDecoder()
2824 # first load template
2826 self.assertTrue(p.haslayer(IPFIX))
2827 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2828 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2829 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2830 self.assertEqual(p[UDP].dport, collector_port)
2831 self.assertEqual(p[IPFIX].observationDomainID,
2832 self.ipfix_domain_id)
2833 if p.haslayer(Template):
2834 ipfix.add_template(p.getlayer(Template))
2835 # verify events in data set
2837 if p.haslayer(Data):
2838 data = ipfix.decode_data_set(p.getlayer(Set))
2839 self.verify_ipfix_nat44_ses(data)
2841 def test_ipfix_addr_exhausted(self):
2842 """ IPFIX logging NAT addresses exhausted """
2843 flags = self.config_flags.NAT_IS_INSIDE
2844 self.vapi.nat44_interface_add_del_feature(
2845 sw_if_index=self.pg0.sw_if_index,
2846 flags=flags, is_add=1)
2847 self.vapi.nat44_interface_add_del_feature(
2848 sw_if_index=self.pg1.sw_if_index,
2850 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2851 src_address=self.pg3.local_ip4n,
2853 template_interval=10)
2854 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2855 src_port=self.ipfix_src_port,
2858 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2859 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2861 self.pg0.add_stream(p)
2862 self.pg_enable_capture(self.pg_interfaces)
2864 self.pg1.assert_nothing_captured()
2866 self.vapi.ipfix_flush()
2867 capture = self.pg3.get_capture(9)
2868 ipfix = IPFIXDecoder()
2869 # first load template
2871 self.assertTrue(p.haslayer(IPFIX))
2872 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2873 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2874 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2875 self.assertEqual(p[UDP].dport, 4739)
2876 self.assertEqual(p[IPFIX].observationDomainID,
2877 self.ipfix_domain_id)
2878 if p.haslayer(Template):
2879 ipfix.add_template(p.getlayer(Template))
2880 # verify events in data set
2882 if p.haslayer(Data):
2883 data = ipfix.decode_data_set(p.getlayer(Set))
2884 self.verify_ipfix_addr_exhausted(data)
2886 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2887 def test_ipfix_max_sessions(self):
2888 """ IPFIX logging maximum session entries exceeded """
2889 self.nat44_add_address(self.nat_addr)
2890 flags = self.config_flags.NAT_IS_INSIDE
2891 self.vapi.nat44_interface_add_del_feature(
2892 sw_if_index=self.pg0.sw_if_index,
2893 flags=flags, is_add=1)
2894 self.vapi.nat44_interface_add_del_feature(
2895 sw_if_index=self.pg1.sw_if_index,
2898 nat44_config = self.vapi.nat_show_config()
2899 max_sessions = 10 * nat44_config.translation_buckets
2902 for i in range(0, max_sessions):
2903 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2904 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2905 IP(src=src, dst=self.pg1.remote_ip4) /
2908 self.pg0.add_stream(pkts)
2909 self.pg_enable_capture(self.pg_interfaces)
2912 self.pg1.get_capture(max_sessions)
2913 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2914 src_address=self.pg3.local_ip4n,
2916 template_interval=10)
2917 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2918 src_port=self.ipfix_src_port,
2921 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2922 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2924 self.pg0.add_stream(p)
2925 self.pg_enable_capture(self.pg_interfaces)
2927 self.pg1.assert_nothing_captured()
2929 self.vapi.ipfix_flush()
2930 capture = self.pg3.get_capture(7)
2931 ipfix = IPFIXDecoder()
2932 # first load template
2934 self.assertTrue(p.haslayer(IPFIX))
2935 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2936 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2937 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2938 self.assertEqual(p[UDP].dport, 4739)
2939 self.assertEqual(p[IPFIX].observationDomainID,
2940 self.ipfix_domain_id)
2941 if p.haslayer(Template):
2942 ipfix.add_template(p.getlayer(Template))
2943 # verify events in data set
2945 if p.haslayer(Data):
2946 data = ipfix.decode_data_set(p.getlayer(Set))
2947 self.verify_ipfix_max_sessions(data, max_sessions)
2949 def test_syslog_apmap(self):
2950 """ Test syslog address and port mapping creation and deletion """
2951 self.vapi.syslog_set_filter(
2952 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2953 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
2954 self.nat44_add_address(self.nat_addr)
2955 flags = self.config_flags.NAT_IS_INSIDE
2956 self.vapi.nat44_interface_add_del_feature(
2957 sw_if_index=self.pg0.sw_if_index,
2958 flags=flags, is_add=1)
2959 self.vapi.nat44_interface_add_del_feature(
2960 sw_if_index=self.pg1.sw_if_index,
2963 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2964 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2965 TCP(sport=self.tcp_port_in, dport=20))
2966 self.pg0.add_stream(p)
2967 self.pg_enable_capture(self.pg_interfaces)
2969 capture = self.pg1.get_capture(1)
2970 self.tcp_port_out = capture[0][TCP].sport
2971 capture = self.pg3.get_capture(1)
2972 self.verify_syslog_apmap(capture[0][Raw].load)
2974 self.pg_enable_capture(self.pg_interfaces)
2976 self.nat44_add_address(self.nat_addr, is_add=0)
2977 capture = self.pg3.get_capture(1)
2978 self.verify_syslog_apmap(capture[0][Raw].load, False)
2980 def test_pool_addr_fib(self):
2981 """ NAT44 add pool addresses to FIB """
2982 static_addr = '10.0.0.10'
2983 self.nat44_add_address(self.nat_addr)
2984 flags = self.config_flags.NAT_IS_INSIDE
2985 self.vapi.nat44_interface_add_del_feature(
2986 sw_if_index=self.pg0.sw_if_index,
2987 flags=flags, is_add=1)
2988 self.vapi.nat44_interface_add_del_feature(
2989 sw_if_index=self.pg1.sw_if_index,
2991 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2994 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2995 ARP(op=ARP.who_has, pdst=self.nat_addr,
2996 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2997 self.pg1.add_stream(p)
2998 self.pg_enable_capture(self.pg_interfaces)
3000 capture = self.pg1.get_capture(1)
3001 self.assertTrue(capture[0].haslayer(ARP))
3002 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3005 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3006 ARP(op=ARP.who_has, pdst=static_addr,
3007 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3008 self.pg1.add_stream(p)
3009 self.pg_enable_capture(self.pg_interfaces)
3011 capture = self.pg1.get_capture(1)
3012 self.assertTrue(capture[0].haslayer(ARP))
3013 self.assertTrue(capture[0][ARP].op, ARP.is_at)
3015 # send ARP to non-NAT44 interface
3016 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3017 ARP(op=ARP.who_has, pdst=self.nat_addr,
3018 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
3019 self.pg2.add_stream(p)
3020 self.pg_enable_capture(self.pg_interfaces)
3022 self.pg1.assert_nothing_captured()
3024 # remove addresses and verify
3025 self.nat44_add_address(self.nat_addr, is_add=0)
3026 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
3029 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3030 ARP(op=ARP.who_has, pdst=self.nat_addr,
3031 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3032 self.pg1.add_stream(p)
3033 self.pg_enable_capture(self.pg_interfaces)
3035 self.pg1.assert_nothing_captured()
3037 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
3038 ARP(op=ARP.who_has, pdst=static_addr,
3039 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
3040 self.pg1.add_stream(p)
3041 self.pg_enable_capture(self.pg_interfaces)
3043 self.pg1.assert_nothing_captured()
3045 def test_vrf_mode(self):
3046 """ NAT44 tenant VRF aware address pool mode """
3050 nat_ip1 = "10.0.0.10"
3051 nat_ip2 = "10.0.0.11"
3053 self.pg0.unconfig_ip4()
3054 self.pg1.unconfig_ip4()
3055 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3056 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3057 self.pg0.set_table_ip4(vrf_id1)
3058 self.pg1.set_table_ip4(vrf_id2)
3059 self.pg0.config_ip4()
3060 self.pg1.config_ip4()
3061 self.pg0.resolve_arp()
3062 self.pg1.resolve_arp()
3064 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3065 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3066 flags = self.config_flags.NAT_IS_INSIDE
3067 self.vapi.nat44_interface_add_del_feature(
3068 sw_if_index=self.pg0.sw_if_index,
3069 flags=flags, is_add=1)
3070 self.vapi.nat44_interface_add_del_feature(
3071 sw_if_index=self.pg1.sw_if_index,
3072 flags=flags, is_add=1)
3073 self.vapi.nat44_interface_add_del_feature(
3074 sw_if_index=self.pg2.sw_if_index,
3079 pkts = self.create_stream_in(self.pg0, self.pg2)
3080 self.pg0.add_stream(pkts)
3081 self.pg_enable_capture(self.pg_interfaces)
3083 capture = self.pg2.get_capture(len(pkts))
3084 self.verify_capture_out(capture, nat_ip1)
3087 pkts = self.create_stream_in(self.pg1, self.pg2)
3088 self.pg1.add_stream(pkts)
3089 self.pg_enable_capture(self.pg_interfaces)
3091 capture = self.pg2.get_capture(len(pkts))
3092 self.verify_capture_out(capture, nat_ip2)
3095 self.pg0.unconfig_ip4()
3096 self.pg1.unconfig_ip4()
3097 self.pg0.set_table_ip4(0)
3098 self.pg1.set_table_ip4(0)
3099 self.pg0.config_ip4()
3100 self.pg1.config_ip4()
3101 self.pg0.resolve_arp()
3102 self.pg1.resolve_arp()
3103 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
3104 self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
3106 def test_vrf_feature_independent(self):
3107 """ NAT44 tenant VRF independent address pool mode """
3109 nat_ip1 = "10.0.0.10"
3110 nat_ip2 = "10.0.0.11"
3112 self.nat44_add_address(nat_ip1)
3113 self.nat44_add_address(nat_ip2, vrf_id=99)
3114 flags = self.config_flags.NAT_IS_INSIDE
3115 self.vapi.nat44_interface_add_del_feature(
3116 sw_if_index=self.pg0.sw_if_index,
3117 flags=flags, is_add=1)
3118 self.vapi.nat44_interface_add_del_feature(
3119 sw_if_index=self.pg1.sw_if_index,
3120 flags=flags, is_add=1)
3121 self.vapi.nat44_interface_add_del_feature(
3122 sw_if_index=self.pg2.sw_if_index,
3126 pkts = self.create_stream_in(self.pg0, self.pg2)
3127 self.pg0.add_stream(pkts)
3128 self.pg_enable_capture(self.pg_interfaces)
3130 capture = self.pg2.get_capture(len(pkts))
3131 self.verify_capture_out(capture, nat_ip1)
3134 pkts = self.create_stream_in(self.pg1, self.pg2)
3135 self.pg1.add_stream(pkts)
3136 self.pg_enable_capture(self.pg_interfaces)
3138 capture = self.pg2.get_capture(len(pkts))
3139 self.verify_capture_out(capture, nat_ip1)
3141 def create_routes_and_neigbors(self):
3142 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3143 [VppRoutePath(self.pg7.remote_ip4,
3144 self.pg7.sw_if_index)])
3145 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3146 [VppRoutePath(self.pg8.remote_ip4,
3147 self.pg8.sw_if_index)])
3151 n1 = VppNeighbor(self,
3152 self.pg7.sw_if_index,
3153 self.pg7.remote_mac,
3154 self.pg7.remote_ip4,
3156 n2 = VppNeighbor(self,
3157 self.pg8.sw_if_index,
3158 self.pg8.remote_mac,
3159 self.pg8.remote_ip4,
3164 def test_dynamic_ipless_interfaces(self):
3165 """ NAT44 interfaces without configured IP address """
3166 self.create_routes_and_neigbors()
3167 self.nat44_add_address(self.nat_addr)
3168 flags = self.config_flags.NAT_IS_INSIDE
3169 self.vapi.nat44_interface_add_del_feature(
3170 sw_if_index=self.pg7.sw_if_index,
3171 flags=flags, is_add=1)
3172 self.vapi.nat44_interface_add_del_feature(
3173 sw_if_index=self.pg8.sw_if_index,
3177 pkts = self.create_stream_in(self.pg7, self.pg8)
3178 self.pg7.add_stream(pkts)
3179 self.pg_enable_capture(self.pg_interfaces)
3181 capture = self.pg8.get_capture(len(pkts))
3182 self.verify_capture_out(capture)
3185 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3186 self.pg8.add_stream(pkts)
3187 self.pg_enable_capture(self.pg_interfaces)
3189 capture = self.pg7.get_capture(len(pkts))
3190 self.verify_capture_in(capture, self.pg7)
3192 def test_static_ipless_interfaces(self):
3193 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3195 self.create_routes_and_neigbors()
3196 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3197 flags = self.config_flags.NAT_IS_INSIDE
3198 self.vapi.nat44_interface_add_del_feature(
3199 sw_if_index=self.pg7.sw_if_index,
3200 flags=flags, is_add=1)
3201 self.vapi.nat44_interface_add_del_feature(
3202 sw_if_index=self.pg8.sw_if_index,
3206 pkts = self.create_stream_out(self.pg8)
3207 self.pg8.add_stream(pkts)
3208 self.pg_enable_capture(self.pg_interfaces)
3210 capture = self.pg7.get_capture(len(pkts))
3211 self.verify_capture_in(capture, self.pg7)
3214 pkts = self.create_stream_in(self.pg7, self.pg8)
3215 self.pg7.add_stream(pkts)
3216 self.pg_enable_capture(self.pg_interfaces)
3218 capture = self.pg8.get_capture(len(pkts))
3219 self.verify_capture_out(capture, self.nat_addr, True)
3221 def test_static_with_port_ipless_interfaces(self):
3222 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3224 self.tcp_port_out = 30606
3225 self.udp_port_out = 30607
3226 self.icmp_id_out = 30608
3228 self.create_routes_and_neigbors()
3229 self.nat44_add_address(self.nat_addr)
3230 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3231 self.tcp_port_in, self.tcp_port_out,
3232 proto=IP_PROTOS.tcp)
3233 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3234 self.udp_port_in, self.udp_port_out,
3235 proto=IP_PROTOS.udp)
3236 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3237 self.icmp_id_in, self.icmp_id_out,
3238 proto=IP_PROTOS.icmp)
3239 flags = self.config_flags.NAT_IS_INSIDE
3240 self.vapi.nat44_interface_add_del_feature(
3241 sw_if_index=self.pg7.sw_if_index,
3242 flags=flags, is_add=1)
3243 self.vapi.nat44_interface_add_del_feature(
3244 sw_if_index=self.pg8.sw_if_index,
3248 pkts = self.create_stream_out(self.pg8)
3249 self.pg8.add_stream(pkts)
3250 self.pg_enable_capture(self.pg_interfaces)
3252 capture = self.pg7.get_capture(len(pkts))
3253 self.verify_capture_in(capture, self.pg7)
3256 pkts = self.create_stream_in(self.pg7, self.pg8)
3257 self.pg7.add_stream(pkts)
3258 self.pg_enable_capture(self.pg_interfaces)
3260 capture = self.pg8.get_capture(len(pkts))
3261 self.verify_capture_out(capture)
3263 def test_static_unknown_proto(self):
3264 """ 1:1 NAT translate packet with unknown protocol """
3265 nat_ip = "10.0.0.10"
3266 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3267 flags = self.config_flags.NAT_IS_INSIDE
3268 self.vapi.nat44_interface_add_del_feature(
3269 sw_if_index=self.pg0.sw_if_index,
3270 flags=flags, is_add=1)
3271 self.vapi.nat44_interface_add_del_feature(
3272 sw_if_index=self.pg1.sw_if_index,
3276 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3277 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3279 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3280 TCP(sport=1234, dport=1234))
3281 self.pg0.add_stream(p)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 p = self.pg1.get_capture(1)
3287 self.assertEqual(packet[IP].src, nat_ip)
3288 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3289 self.assertEqual(packet.haslayer(GRE), 1)
3290 self.assert_packet_checksums_valid(packet)
3292 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3296 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3297 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3299 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3300 TCP(sport=1234, dport=1234))
3301 self.pg1.add_stream(p)
3302 self.pg_enable_capture(self.pg_interfaces)
3304 p = self.pg0.get_capture(1)
3307 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3308 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3309 self.assertEqual(packet.haslayer(GRE), 1)
3310 self.assert_packet_checksums_valid(packet)
3312 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3315 def test_hairpinning_static_unknown_proto(self):
3316 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3318 host = self.pg0.remote_hosts[0]
3319 server = self.pg0.remote_hosts[1]
3321 host_nat_ip = "10.0.0.10"
3322 server_nat_ip = "10.0.0.11"
3324 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3325 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3326 flags = self.config_flags.NAT_IS_INSIDE
3327 self.vapi.nat44_interface_add_del_feature(
3328 sw_if_index=self.pg0.sw_if_index,
3329 flags=flags, is_add=1)
3330 self.vapi.nat44_interface_add_del_feature(
3331 sw_if_index=self.pg1.sw_if_index,
3335 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3336 IP(src=host.ip4, dst=server_nat_ip) /
3338 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3339 TCP(sport=1234, dport=1234))
3340 self.pg0.add_stream(p)
3341 self.pg_enable_capture(self.pg_interfaces)
3343 p = self.pg0.get_capture(1)
3346 self.assertEqual(packet[IP].src, host_nat_ip)
3347 self.assertEqual(packet[IP].dst, server.ip4)
3348 self.assertEqual(packet.haslayer(GRE), 1)
3349 self.assert_packet_checksums_valid(packet)
3351 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3355 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3356 IP(src=server.ip4, dst=host_nat_ip) /
3358 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3359 TCP(sport=1234, dport=1234))
3360 self.pg0.add_stream(p)
3361 self.pg_enable_capture(self.pg_interfaces)
3363 p = self.pg0.get_capture(1)
3366 self.assertEqual(packet[IP].src, server_nat_ip)
3367 self.assertEqual(packet[IP].dst, host.ip4)
3368 self.assertEqual(packet.haslayer(GRE), 1)
3369 self.assert_packet_checksums_valid(packet)
3371 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3374 def test_output_feature(self):
3375 """ NAT44 interface output feature (in2out postrouting) """
3376 self.nat44_add_address(self.nat_addr)
3377 flags = self.config_flags.NAT_IS_INSIDE
3378 self.vapi.nat44_interface_add_del_output_feature(
3379 is_add=1, flags=flags,
3380 sw_if_index=self.pg0.sw_if_index)
3381 self.vapi.nat44_interface_add_del_output_feature(
3382 is_add=1, flags=flags,
3383 sw_if_index=self.pg1.sw_if_index)
3384 self.vapi.nat44_interface_add_del_output_feature(
3386 sw_if_index=self.pg3.sw_if_index)
3389 pkts = self.create_stream_in(self.pg0, self.pg3)
3390 self.pg0.add_stream(pkts)
3391 self.pg_enable_capture(self.pg_interfaces)
3393 capture = self.pg3.get_capture(len(pkts))
3394 self.verify_capture_out(capture)
3397 pkts = self.create_stream_out(self.pg3)
3398 self.pg3.add_stream(pkts)
3399 self.pg_enable_capture(self.pg_interfaces)
3401 capture = self.pg0.get_capture(len(pkts))
3402 self.verify_capture_in(capture, self.pg0)
3404 # from non-NAT interface to NAT inside interface
3405 pkts = self.create_stream_in(self.pg2, self.pg0)
3406 self.pg2.add_stream(pkts)
3407 self.pg_enable_capture(self.pg_interfaces)
3409 capture = self.pg0.get_capture(len(pkts))
3410 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3412 def test_output_feature_vrf_aware(self):
3413 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3414 nat_ip_vrf10 = "10.0.0.10"
3415 nat_ip_vrf20 = "10.0.0.20"
3417 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3418 [VppRoutePath(self.pg3.remote_ip4,
3419 self.pg3.sw_if_index)],
3421 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3422 [VppRoutePath(self.pg3.remote_ip4,
3423 self.pg3.sw_if_index)],
3428 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3429 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3430 flags = self.config_flags.NAT_IS_INSIDE
3431 self.vapi.nat44_interface_add_del_output_feature(
3432 is_add=1, flags=flags,
3433 sw_if_index=self.pg4.sw_if_index)
3434 self.vapi.nat44_interface_add_del_output_feature(
3435 is_add=1, flags=flags,
3436 sw_if_index=self.pg6.sw_if_index)
3437 self.vapi.nat44_interface_add_del_output_feature(
3439 sw_if_index=self.pg3.sw_if_index)
3442 pkts = self.create_stream_in(self.pg4, self.pg3)
3443 self.pg4.add_stream(pkts)
3444 self.pg_enable_capture(self.pg_interfaces)
3446 capture = self.pg3.get_capture(len(pkts))
3447 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3450 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3451 self.pg3.add_stream(pkts)
3452 self.pg_enable_capture(self.pg_interfaces)
3454 capture = self.pg4.get_capture(len(pkts))
3455 self.verify_capture_in(capture, self.pg4)
3458 pkts = self.create_stream_in(self.pg6, self.pg3)
3459 self.pg6.add_stream(pkts)
3460 self.pg_enable_capture(self.pg_interfaces)
3462 capture = self.pg3.get_capture(len(pkts))
3463 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3466 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3467 self.pg3.add_stream(pkts)
3468 self.pg_enable_capture(self.pg_interfaces)
3470 capture = self.pg6.get_capture(len(pkts))
3471 self.verify_capture_in(capture, self.pg6)
3473 def test_output_feature_hairpinning(self):
3474 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3475 host = self.pg0.remote_hosts[0]
3476 server = self.pg0.remote_hosts[1]
3479 server_in_port = 5678
3480 server_out_port = 8765
3482 self.nat44_add_address(self.nat_addr)
3483 flags = self.config_flags.NAT_IS_INSIDE
3484 self.vapi.nat44_interface_add_del_output_feature(
3485 is_add=1, flags=flags,
3486 sw_if_index=self.pg0.sw_if_index)
3487 self.vapi.nat44_interface_add_del_output_feature(
3489 sw_if_index=self.pg1.sw_if_index)
3491 # add static mapping for server
3492 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3493 server_in_port, server_out_port,
3494 proto=IP_PROTOS.tcp)
3496 # send packet from host to server
3497 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3498 IP(src=host.ip4, dst=self.nat_addr) /
3499 TCP(sport=host_in_port, dport=server_out_port))
3500 self.pg0.add_stream(p)
3501 self.pg_enable_capture(self.pg_interfaces)
3503 capture = self.pg0.get_capture(1)
3508 self.assertEqual(ip.src, self.nat_addr)
3509 self.assertEqual(ip.dst, server.ip4)
3510 self.assertNotEqual(tcp.sport, host_in_port)
3511 self.assertEqual(tcp.dport, server_in_port)
3512 self.assert_packet_checksums_valid(p)
3513 host_out_port = tcp.sport
3515 self.logger.error(ppp("Unexpected or invalid packet:", p))
3518 # send reply from server to host
3519 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3520 IP(src=server.ip4, dst=self.nat_addr) /
3521 TCP(sport=server_in_port, dport=host_out_port))
3522 self.pg0.add_stream(p)
3523 self.pg_enable_capture(self.pg_interfaces)
3525 capture = self.pg0.get_capture(1)
3530 self.assertEqual(ip.src, self.nat_addr)
3531 self.assertEqual(ip.dst, host.ip4)
3532 self.assertEqual(tcp.sport, server_out_port)
3533 self.assertEqual(tcp.dport, host_in_port)
3534 self.assert_packet_checksums_valid(p)
3536 self.logger.error(ppp("Unexpected or invalid packet:", p))
3539 def test_one_armed_nat44(self):
3540 """ One armed NAT44 """
3541 remote_host = self.pg9.remote_hosts[0]
3542 local_host = self.pg9.remote_hosts[1]
3545 self.nat44_add_address(self.nat_addr)
3546 flags = self.config_flags.NAT_IS_INSIDE
3547 self.vapi.nat44_interface_add_del_feature(
3548 sw_if_index=self.pg9.sw_if_index,
3550 self.vapi.nat44_interface_add_del_feature(
3551 sw_if_index=self.pg9.sw_if_index,
3552 flags=flags, is_add=1)
3555 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3556 IP(src=local_host.ip4, dst=remote_host.ip4) /
3557 TCP(sport=12345, dport=80))
3558 self.pg9.add_stream(p)
3559 self.pg_enable_capture(self.pg_interfaces)
3561 capture = self.pg9.get_capture(1)
3566 self.assertEqual(ip.src, self.nat_addr)
3567 self.assertEqual(ip.dst, remote_host.ip4)
3568 self.assertNotEqual(tcp.sport, 12345)
3569 external_port = tcp.sport
3570 self.assertEqual(tcp.dport, 80)
3571 self.assert_packet_checksums_valid(p)
3573 self.logger.error(ppp("Unexpected or invalid packet:", p))
3577 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3578 IP(src=remote_host.ip4, dst=self.nat_addr) /
3579 TCP(sport=80, dport=external_port))
3580 self.pg9.add_stream(p)
3581 self.pg_enable_capture(self.pg_interfaces)
3583 capture = self.pg9.get_capture(1)
3588 self.assertEqual(ip.src, remote_host.ip4)
3589 self.assertEqual(ip.dst, local_host.ip4)
3590 self.assertEqual(tcp.sport, 80)
3591 self.assertEqual(tcp.dport, 12345)
3592 self.assert_packet_checksums_valid(p)
3594 self.logger.error(ppp("Unexpected or invalid packet:", p))
3597 err = self.statistics.get_err_counter(
3598 '/err/nat44-classify/next in2out')
3599 self.assertEqual(err, 1)
3600 err = self.statistics.get_err_counter(
3601 '/err/nat44-classify/next out2in')
3602 self.assertEqual(err, 1)
3604 def test_del_session(self):
3605 """ Delete NAT44 session """
3606 self.nat44_add_address(self.nat_addr)
3607 flags = self.config_flags.NAT_IS_INSIDE
3608 self.vapi.nat44_interface_add_del_feature(
3609 sw_if_index=self.pg0.sw_if_index,
3610 flags=flags, is_add=1)
3611 self.vapi.nat44_interface_add_del_feature(
3612 sw_if_index=self.pg1.sw_if_index,
3615 pkts = self.create_stream_in(self.pg0, self.pg1)
3616 self.pg0.add_stream(pkts)
3617 self.pg_enable_capture(self.pg_interfaces)
3619 self.pg1.get_capture(len(pkts))
3621 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3622 nsessions = len(sessions)
3624 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3625 port=sessions[0].inside_port,
3626 protocol=sessions[0].protocol,
3627 flags=self.config_flags.NAT_IS_INSIDE)
3628 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3629 port=sessions[1].outside_port,
3630 protocol=sessions[1].protocol)
3632 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3633 self.assertEqual(nsessions - len(sessions), 2)
3635 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3636 port=sessions[0].inside_port,
3637 protocol=sessions[0].protocol,
3638 flags=self.config_flags.NAT_IS_INSIDE)
3640 self.verify_no_nat44_user()
3642 def test_set_get_reass(self):
3643 """ NAT44 set/get virtual fragmentation reassembly """
3644 reas_cfg1 = self.vapi.nat_get_reass()
3646 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3647 max_reass=reas_cfg1.ip4_max_reass * 2,
3648 max_frag=reas_cfg1.ip4_max_frag * 2,
3651 reas_cfg2 = self.vapi.nat_get_reass()
3653 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3654 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3655 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3657 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=5,
3659 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3661 def test_frag_in_order(self):
3662 """ NAT44 translate fragments arriving in order """
3664 self.nat44_add_address(self.nat_addr)
3665 flags = self.config_flags.NAT_IS_INSIDE
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg0.sw_if_index,
3668 flags=flags, is_add=1)
3669 self.vapi.nat44_interface_add_del_feature(
3670 sw_if_index=self.pg1.sw_if_index,
3673 reas_cfg1 = self.vapi.nat_get_reass()
3674 # this test was intermittently failing in some cases
3675 # until we temporarily bump the reassembly timeouts
3676 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
3679 self.frag_in_order(proto=IP_PROTOS.tcp)
3680 self.frag_in_order(proto=IP_PROTOS.udp)
3681 self.frag_in_order(proto=IP_PROTOS.icmp)
3683 # restore the reassembly timeouts
3684 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
3685 max_reass=reas_cfg1.ip4_max_reass,
3686 max_frag=reas_cfg1.ip4_max_frag,
3687 drop_frag=reas_cfg1.ip4_drop_frag)
3689 def test_frag_forwarding(self):
3690 """ NAT44 forwarding fragment test """
3691 self.vapi.nat44_add_del_interface_addr(
3693 sw_if_index=self.pg1.sw_if_index)
3694 flags = self.config_flags.NAT_IS_INSIDE
3695 self.vapi.nat44_interface_add_del_feature(
3696 sw_if_index=self.pg0.sw_if_index,
3697 flags=flags, is_add=1)
3698 self.vapi.nat44_interface_add_del_feature(
3699 sw_if_index=self.pg1.sw_if_index,
3701 self.vapi.nat44_forwarding_enable_disable(enable=1)
3703 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3704 pkts = self.create_stream_frag(self.pg1,
3705 self.pg0.remote_ip4,
3709 proto=IP_PROTOS.udp)
3710 self.pg1.add_stream(pkts)
3711 self.pg_enable_capture(self.pg_interfaces)
3713 frags = self.pg0.get_capture(len(pkts))
3714 p = self.reass_frags_and_verify(frags,
3715 self.pg1.remote_ip4,
3716 self.pg0.remote_ip4)
3717 self.assertEqual(p[UDP].sport, 4789)
3718 self.assertEqual(p[UDP].dport, 4789)
3719 self.assertEqual(data, p[Raw].load)
3721 def test_reass_hairpinning(self):
3722 """ NAT44 fragments hairpinning """
3724 self.server = self.pg0.remote_hosts[1]
3725 self.host_in_port = random.randint(1025, 65535)
3726 self.server_in_port = random.randint(1025, 65535)
3727 self.server_out_port = random.randint(1025, 65535)
3729 self.nat44_add_address(self.nat_addr)
3730 flags = self.config_flags.NAT_IS_INSIDE
3731 self.vapi.nat44_interface_add_del_feature(
3732 sw_if_index=self.pg0.sw_if_index,
3733 flags=flags, is_add=1)
3734 self.vapi.nat44_interface_add_del_feature(
3735 sw_if_index=self.pg1.sw_if_index,
3737 # add static mapping for server
3738 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3739 self.server_in_port,
3740 self.server_out_port,
3741 proto=IP_PROTOS.tcp)
3742 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3743 self.server_in_port,
3744 self.server_out_port,
3745 proto=IP_PROTOS.udp)
3746 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3748 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3749 self.reass_hairpinning(proto=IP_PROTOS.udp)
3750 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3752 def test_frag_out_of_order(self):
3753 """ NAT44 translate fragments arriving out of order """
3755 self.nat44_add_address(self.nat_addr)
3756 flags = self.config_flags.NAT_IS_INSIDE
3757 self.vapi.nat44_interface_add_del_feature(
3758 sw_if_index=self.pg0.sw_if_index,
3759 flags=flags, is_add=1)
3760 self.vapi.nat44_interface_add_del_feature(
3761 sw_if_index=self.pg1.sw_if_index,
3764 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3765 self.frag_out_of_order(proto=IP_PROTOS.udp)
3766 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3768 def test_port_restricted(self):
3769 """ Port restricted NAT44 (MAP-E CE) """
3770 self.nat44_add_address(self.nat_addr)
3771 flags = self.config_flags.NAT_IS_INSIDE
3772 self.vapi.nat44_interface_add_del_feature(
3773 sw_if_index=self.pg0.sw_if_index,
3774 flags=flags, is_add=1)
3775 self.vapi.nat44_interface_add_del_feature(
3776 sw_if_index=self.pg1.sw_if_index,
3778 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3783 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3784 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3785 TCP(sport=4567, dport=22))
3786 self.pg0.add_stream(p)
3787 self.pg_enable_capture(self.pg_interfaces)
3789 capture = self.pg1.get_capture(1)
3794 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3795 self.assertEqual(ip.src, self.nat_addr)
3796 self.assertEqual(tcp.dport, 22)
3797 self.assertNotEqual(tcp.sport, 4567)
3798 self.assertEqual((tcp.sport >> 6) & 63, 10)
3799 self.assert_packet_checksums_valid(p)
3801 self.logger.error(ppp("Unexpected or invalid packet:", p))
3804 def test_port_range(self):
3805 """ External address port range """
3806 self.nat44_add_address(self.nat_addr)
3807 flags = self.config_flags.NAT_IS_INSIDE
3808 self.vapi.nat44_interface_add_del_feature(
3809 sw_if_index=self.pg0.sw_if_index,
3810 flags=flags, is_add=1)
3811 self.vapi.nat44_interface_add_del_feature(
3812 sw_if_index=self.pg1.sw_if_index,
3814 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3819 for port in range(0, 5):
3820 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3821 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3822 TCP(sport=1125 + port))
3824 self.pg0.add_stream(pkts)
3825 self.pg_enable_capture(self.pg_interfaces)
3827 capture = self.pg1.get_capture(3)
3830 self.assertGreaterEqual(tcp.sport, 1025)
3831 self.assertLessEqual(tcp.sport, 1027)
3833 def test_ipfix_max_frags(self):
3834 """ IPFIX logging maximum fragments pending reassembly exceeded """
3835 self.nat44_add_address(self.nat_addr)
3836 flags = self.config_flags.NAT_IS_INSIDE
3837 self.vapi.nat44_interface_add_del_feature(
3838 sw_if_index=self.pg0.sw_if_index,
3839 flags=flags, is_add=1)
3840 self.vapi.nat44_interface_add_del_feature(
3841 sw_if_index=self.pg1.sw_if_index,
3843 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
3845 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3846 src_address=self.pg3.local_ip4n,
3848 template_interval=10)
3849 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
3850 src_port=self.ipfix_src_port,
3853 data = b"A" * 4 + b"B" * 16 + b"C" * 3
3854 self.tcp_port_in = random.randint(1025, 65535)
3855 pkts = self.create_stream_frag(self.pg0,
3856 self.pg1.remote_ip4,
3861 self.pg0.add_stream(pkts)
3862 self.pg_enable_capture(self.pg_interfaces)
3864 self.pg1.assert_nothing_captured()
3866 self.vapi.ipfix_flush()
3867 capture = self.pg3.get_capture(9)
3868 ipfix = IPFIXDecoder()
3869 # first load template
3871 self.assertTrue(p.haslayer(IPFIX))
3872 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3873 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3874 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3875 self.assertEqual(p[UDP].dport, 4739)
3876 self.assertEqual(p[IPFIX].observationDomainID,
3877 self.ipfix_domain_id)
3878 if p.haslayer(Template):
3879 ipfix.add_template(p.getlayer(Template))
3880 # verify events in data set
3882 if p.haslayer(Data):
3883 data = ipfix.decode_data_set(p.getlayer(Set))
3884 self.verify_ipfix_max_fragments_ip4(data, 1,
3885 self.pg0.remote_ip4n)
3887 def test_multiple_outside_vrf(self):
3888 """ Multiple outside VRF """
3892 self.pg1.unconfig_ip4()
3893 self.pg2.unconfig_ip4()
3894 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
3895 self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
3896 self.pg1.set_table_ip4(vrf_id1)
3897 self.pg2.set_table_ip4(vrf_id2)
3898 self.pg1.config_ip4()
3899 self.pg2.config_ip4()
3900 self.pg1.resolve_arp()
3901 self.pg2.resolve_arp()
3903 self.nat44_add_address(self.nat_addr)
3904 flags = self.config_flags.NAT_IS_INSIDE
3905 self.vapi.nat44_interface_add_del_feature(
3906 sw_if_index=self.pg0.sw_if_index,
3907 flags=flags, is_add=1)
3908 self.vapi.nat44_interface_add_del_feature(
3909 sw_if_index=self.pg1.sw_if_index,
3911 self.vapi.nat44_interface_add_del_feature(
3912 sw_if_index=self.pg2.sw_if_index,
3917 pkts = self.create_stream_in(self.pg0, self.pg1)
3918 self.pg0.add_stream(pkts)
3919 self.pg_enable_capture(self.pg_interfaces)
3921 capture = self.pg1.get_capture(len(pkts))
3922 self.verify_capture_out(capture, self.nat_addr)
3924 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3925 self.pg1.add_stream(pkts)
3926 self.pg_enable_capture(self.pg_interfaces)
3928 capture = self.pg0.get_capture(len(pkts))
3929 self.verify_capture_in(capture, self.pg0)
3931 self.tcp_port_in = 60303
3932 self.udp_port_in = 60304
3933 self.icmp_id_in = 60305
3936 pkts = self.create_stream_in(self.pg0, self.pg2)
3937 self.pg0.add_stream(pkts)
3938 self.pg_enable_capture(self.pg_interfaces)
3940 capture = self.pg2.get_capture(len(pkts))
3941 self.verify_capture_out(capture, self.nat_addr)
3943 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3944 self.pg2.add_stream(pkts)
3945 self.pg_enable_capture(self.pg_interfaces)
3947 capture = self.pg0.get_capture(len(pkts))
3948 self.verify_capture_in(capture, self.pg0)
3951 self.nat44_add_address(self.nat_addr, is_add=0)
3952 self.pg1.unconfig_ip4()
3953 self.pg2.unconfig_ip4()
3954 self.pg1.set_table_ip4(0)
3955 self.pg2.set_table_ip4(0)
3956 self.pg1.config_ip4()
3957 self.pg2.config_ip4()
3958 self.pg1.resolve_arp()
3959 self.pg2.resolve_arp()
3961 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3962 def test_session_timeout(self):
3963 """ NAT44 session timeouts """
3964 self.nat44_add_address(self.nat_addr)
3965 flags = self.config_flags.NAT_IS_INSIDE
3966 self.vapi.nat44_interface_add_del_feature(
3967 sw_if_index=self.pg0.sw_if_index,
3968 flags=flags, is_add=1)
3969 self.vapi.nat44_interface_add_del_feature(
3970 sw_if_index=self.pg1.sw_if_index,
3972 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3973 tcp_transitory=240, icmp=60)
3977 for i in range(0, max_sessions):
3978 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3979 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3980 IP(src=src, dst=self.pg1.remote_ip4) /
3981 UDP(sport=1025, dport=53))
3983 self.pg0.add_stream(pkts)
3984 self.pg_enable_capture(self.pg_interfaces)
3986 self.pg1.get_capture(max_sessions)
3991 for i in range(0, max_sessions):
3992 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3993 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3994 IP(src=src, dst=self.pg1.remote_ip4) /
3995 UDP(sport=1026, dport=53))
3997 self.pg0.add_stream(pkts)
3998 self.pg_enable_capture(self.pg_interfaces)
4000 self.pg1.get_capture(max_sessions)
4003 users = self.vapi.nat44_user_dump()
4005 nsessions = nsessions + user.nsessions
4006 self.assertLess(nsessions, 2 * max_sessions)
4008 def test_mss_clamping(self):
4009 """ TCP MSS clamping """
4010 self.nat44_add_address(self.nat_addr)
4011 flags = self.config_flags.NAT_IS_INSIDE
4012 self.vapi.nat44_interface_add_del_feature(
4013 sw_if_index=self.pg0.sw_if_index,
4014 flags=flags, is_add=1)
4015 self.vapi.nat44_interface_add_del_feature(
4016 sw_if_index=self.pg1.sw_if_index,
4019 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4020 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4021 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4022 flags="S", options=[('MSS', 1400)]))
4024 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
4025 self.pg0.add_stream(p)
4026 self.pg_enable_capture(self.pg_interfaces)
4028 capture = self.pg1.get_capture(1)
4029 # Negotiated MSS value greater than configured - changed
4030 self.verify_mss_value(capture[0], 1000)
4032 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
4033 self.pg0.add_stream(p)
4034 self.pg_enable_capture(self.pg_interfaces)
4036 capture = self.pg1.get_capture(1)
4037 # MSS clamping disabled - negotiated MSS unchanged
4038 self.verify_mss_value(capture[0], 1400)
4040 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
4041 self.pg0.add_stream(p)
4042 self.pg_enable_capture(self.pg_interfaces)
4044 capture = self.pg1.get_capture(1)
4045 # Negotiated MSS value smaller than configured - unchanged
4046 self.verify_mss_value(capture[0], 1400)
4048 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4049 def test_ha_send(self):
4050 """ Send HA session synchronization events (active) """
4051 self.nat44_add_address(self.nat_addr)
4052 flags = self.config_flags.NAT_IS_INSIDE
4053 self.vapi.nat44_interface_add_del_feature(
4054 sw_if_index=self.pg0.sw_if_index,
4055 flags=flags, is_add=1)
4056 self.vapi.nat44_interface_add_del_feature(
4057 sw_if_index=self.pg1.sw_if_index,
4059 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4062 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
4063 port=12346, session_refresh_interval=10)
4064 bind_layers(UDP, HANATStateSync, sport=12345)
4067 pkts = self.create_stream_in(self.pg0, self.pg1)
4068 self.pg0.add_stream(pkts)
4069 self.pg_enable_capture(self.pg_interfaces)
4071 capture = self.pg1.get_capture(len(pkts))
4072 self.verify_capture_out(capture)
4073 # active send HA events
4074 self.vapi.nat_ha_flush()
4075 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
4076 self.assertEqual(stats[0][0], 3)
4077 capture = self.pg3.get_capture(1)
4079 self.assert_packet_checksums_valid(p)
4083 hanat = p[HANATStateSync]
4085 self.logger.error(ppp("Invalid packet:", p))
4088 self.assertEqual(ip.src, self.pg3.local_ip4)
4089 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4090 self.assertEqual(udp.sport, 12345)
4091 self.assertEqual(udp.dport, 12346)
4092 self.assertEqual(hanat.version, 1)
4093 self.assertEqual(hanat.thread_index, 0)
4094 self.assertEqual(hanat.count, 3)
4095 seq = hanat.sequence_number
4096 for event in hanat.events:
4097 self.assertEqual(event.event_type, 1)
4098 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
4099 self.assertEqual(event.out_addr, self.nat_addr)
4100 self.assertEqual(event.fib_index, 0)
4102 # ACK received events
4103 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4104 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4105 UDP(sport=12346, dport=12345) /
4106 HANATStateSync(sequence_number=seq, flags='ACK'))
4107 self.pg3.add_stream(ack)
4109 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4110 self.assertEqual(stats[0][0], 1)
4112 # delete one session
4113 self.pg_enable_capture(self.pg_interfaces)
4114 self.vapi.nat44_del_session(address=self.pg0.remote_ip4n,
4115 port=self.tcp_port_in,
4116 protocol=IP_PROTOS.tcp,
4117 flags=self.config_flags.NAT_IS_INSIDE)
4118 self.vapi.nat_ha_flush()
4119 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
4120 self.assertEqual(stats[0][0], 1)
4121 capture = self.pg3.get_capture(1)
4124 hanat = p[HANATStateSync]
4126 self.logger.error(ppp("Invalid packet:", p))
4129 self.assertGreater(hanat.sequence_number, seq)
4131 # do not send ACK, active retry send HA event again
4132 self.pg_enable_capture(self.pg_interfaces)
4134 stats = self.statistics.get_counter('/nat44/ha/retry-count')
4135 self.assertEqual(stats[0][0], 3)
4136 stats = self.statistics.get_counter('/nat44/ha/missed-count')
4137 self.assertEqual(stats[0][0], 1)
4138 capture = self.pg3.get_capture(3)
4139 for packet in capture:
4140 self.assertEqual(packet, p)
4142 # session counters refresh
4143 pkts = self.create_stream_out(self.pg1)
4144 self.pg1.add_stream(pkts)
4145 self.pg_enable_capture(self.pg_interfaces)
4147 self.pg0.get_capture(2)
4148 self.vapi.nat_ha_flush()
4149 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4150 self.assertEqual(stats[0][0], 2)
4151 capture = self.pg3.get_capture(1)
4153 self.assert_packet_checksums_valid(p)
4157 hanat = p[HANATStateSync]
4159 self.logger.error(ppp("Invalid packet:", p))
4162 self.assertEqual(ip.src, self.pg3.local_ip4)
4163 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4164 self.assertEqual(udp.sport, 12345)
4165 self.assertEqual(udp.dport, 12346)
4166 self.assertEqual(hanat.version, 1)
4167 self.assertEqual(hanat.count, 2)
4168 seq = hanat.sequence_number
4169 for event in hanat.events:
4170 self.assertEqual(event.event_type, 3)
4171 self.assertEqual(event.out_addr, self.nat_addr)
4172 self.assertEqual(event.fib_index, 0)
4173 self.assertEqual(event.total_pkts, 2)
4174 self.assertGreater(event.total_bytes, 0)
4176 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4177 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4178 UDP(sport=12346, dport=12345) /
4179 HANATStateSync(sequence_number=seq, flags='ACK'))
4180 self.pg3.add_stream(ack)
4182 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4183 self.assertEqual(stats[0][0], 2)
4185 def test_ha_recv(self):
4186 """ Receive HA session synchronization events (passive) """
4187 self.nat44_add_address(self.nat_addr)
4188 flags = self.config_flags.NAT_IS_INSIDE
4189 self.vapi.nat44_interface_add_del_feature(
4190 sw_if_index=self.pg0.sw_if_index,
4191 flags=flags, is_add=1)
4192 self.vapi.nat44_interface_add_del_feature(
4193 sw_if_index=self.pg1.sw_if_index,
4195 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4198 bind_layers(UDP, HANATStateSync, sport=12345)
4200 self.tcp_port_out = random.randint(1025, 65535)
4201 self.udp_port_out = random.randint(1025, 65535)
4203 # send HA session add events to failover/passive
4204 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4205 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4206 UDP(sport=12346, dport=12345) /
4207 HANATStateSync(sequence_number=1, events=[
4208 Event(event_type='add', protocol='tcp',
4209 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4210 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4211 eh_addr=self.pg1.remote_ip4,
4212 ehn_addr=self.pg1.remote_ip4,
4213 eh_port=self.tcp_external_port,
4214 ehn_port=self.tcp_external_port, fib_index=0),
4215 Event(event_type='add', protocol='udp',
4216 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4217 in_port=self.udp_port_in, out_port=self.udp_port_out,
4218 eh_addr=self.pg1.remote_ip4,
4219 ehn_addr=self.pg1.remote_ip4,
4220 eh_port=self.udp_external_port,
4221 ehn_port=self.udp_external_port, fib_index=0)]))
4223 self.pg3.add_stream(p)
4224 self.pg_enable_capture(self.pg_interfaces)
4227 capture = self.pg3.get_capture(1)
4230 hanat = p[HANATStateSync]
4232 self.logger.error(ppp("Invalid packet:", p))
4235 self.assertEqual(hanat.sequence_number, 1)
4236 self.assertEqual(hanat.flags, 'ACK')
4237 self.assertEqual(hanat.version, 1)
4238 self.assertEqual(hanat.thread_index, 0)
4239 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4240 self.assertEqual(stats[0][0], 1)
4241 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4242 self.assertEqual(stats[0][0], 2)
4243 users = self.statistics.get_counter('/nat44/total-users')
4244 self.assertEqual(users[0][0], 1)
4245 sessions = self.statistics.get_counter('/nat44/total-sessions')
4246 self.assertEqual(sessions[0][0], 2)
4247 users = self.vapi.nat44_user_dump()
4248 self.assertEqual(len(users), 1)
4249 self.assertEqual(str(users[0].ip_address),
4250 self.pg0.remote_ip4)
4251 # there should be 2 sessions created by HA
4252 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4254 self.assertEqual(len(sessions), 2)
4255 for session in sessions:
4256 self.assertEqual(str(session.inside_ip_address),
4257 self.pg0.remote_ip4)
4258 self.assertEqual(str(session.outside_ip_address),
4260 self.assertIn(session.inside_port,
4261 [self.tcp_port_in, self.udp_port_in])
4262 self.assertIn(session.outside_port,
4263 [self.tcp_port_out, self.udp_port_out])
4264 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4266 # send HA session delete event to failover/passive
4267 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4268 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4269 UDP(sport=12346, dport=12345) /
4270 HANATStateSync(sequence_number=2, events=[
4271 Event(event_type='del', protocol='udp',
4272 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4273 in_port=self.udp_port_in, out_port=self.udp_port_out,
4274 eh_addr=self.pg1.remote_ip4,
4275 ehn_addr=self.pg1.remote_ip4,
4276 eh_port=self.udp_external_port,
4277 ehn_port=self.udp_external_port, fib_index=0)]))
4279 self.pg3.add_stream(p)
4280 self.pg_enable_capture(self.pg_interfaces)
4283 capture = self.pg3.get_capture(1)
4286 hanat = p[HANATStateSync]
4288 self.logger.error(ppp("Invalid packet:", p))
4291 self.assertEqual(hanat.sequence_number, 2)
4292 self.assertEqual(hanat.flags, 'ACK')
4293 self.assertEqual(hanat.version, 1)
4294 users = self.vapi.nat44_user_dump()
4295 self.assertEqual(len(users), 1)
4296 self.assertEqual(str(users[0].ip_address),
4297 self.pg0.remote_ip4)
4298 # now we should have only 1 session, 1 deleted by HA
4299 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4301 self.assertEqual(len(sessions), 1)
4302 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4303 self.assertEqual(stats[0][0], 1)
4305 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4306 self.assertEqual(stats, 2)
4308 # send HA session refresh event to failover/passive
4309 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4310 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4311 UDP(sport=12346, dport=12345) /
4312 HANATStateSync(sequence_number=3, events=[
4313 Event(event_type='refresh', protocol='tcp',
4314 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4315 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4316 eh_addr=self.pg1.remote_ip4,
4317 ehn_addr=self.pg1.remote_ip4,
4318 eh_port=self.tcp_external_port,
4319 ehn_port=self.tcp_external_port, fib_index=0,
4320 total_bytes=1024, total_pkts=2)]))
4321 self.pg3.add_stream(p)
4322 self.pg_enable_capture(self.pg_interfaces)
4325 capture = self.pg3.get_capture(1)
4328 hanat = p[HANATStateSync]
4330 self.logger.error(ppp("Invalid packet:", p))
4333 self.assertEqual(hanat.sequence_number, 3)
4334 self.assertEqual(hanat.flags, 'ACK')
4335 self.assertEqual(hanat.version, 1)
4336 users = self.vapi.nat44_user_dump()
4337 self.assertEqual(len(users), 1)
4338 self.assertEqual(str(users[0].ip_address),
4339 self.pg0.remote_ip4)
4340 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4342 self.assertEqual(len(sessions), 1)
4343 session = sessions[0]
4344 self.assertEqual(session.total_bytes, 1024)
4345 self.assertEqual(session.total_pkts, 2)
4346 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4347 self.assertEqual(stats[0][0], 1)
4349 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4350 self.assertEqual(stats, 3)
4352 # send packet to test session created by HA
4353 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4354 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4355 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4356 self.pg1.add_stream(p)
4357 self.pg_enable_capture(self.pg_interfaces)
4359 capture = self.pg0.get_capture(1)
4365 self.logger.error(ppp("Invalid packet:", p))
4368 self.assertEqual(ip.src, self.pg1.remote_ip4)
4369 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4370 self.assertEqual(tcp.sport, self.tcp_external_port)
4371 self.assertEqual(tcp.dport, self.tcp_port_in)
4374 super(TestNAT44, self).tearDown()
4376 self.vapi.cli("clear logging")
4378 def show_commands_at_teardown(self):
4379 self.logger.info(self.vapi.cli("show nat44 addresses"))
4380 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4381 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4382 self.logger.info(self.vapi.cli("show nat44 interface address"))
4383 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4384 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
4385 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4386 self.logger.info(self.vapi.cli("show nat timeouts"))
4388 self.vapi.cli("show nat addr-port-assignment-alg"))
4389 self.logger.info(self.vapi.cli("show nat ha"))
4392 class TestNAT44EndpointDependent(MethodHolder):
4393 """ Endpoint-Dependent mapping and filtering test cases """
4396 def setUpConstants(cls):
4397 super(TestNAT44EndpointDependent, cls).setUpConstants()
4398 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4401 def setUpClass(cls):
4402 super(TestNAT44EndpointDependent, cls).setUpClass()
4403 cls.vapi.cli("set log class nat level debug")
4405 cls.tcp_port_in = 6303
4406 cls.tcp_port_out = 6303
4407 cls.udp_port_in = 6304
4408 cls.udp_port_out = 6304
4409 cls.icmp_id_in = 6305
4410 cls.icmp_id_out = 6305
4411 cls.nat_addr = '10.0.0.3'
4412 cls.ipfix_src_port = 4739
4413 cls.ipfix_domain_id = 1
4414 cls.tcp_external_port = 80
4416 cls.create_pg_interfaces(range(9))
4417 cls.interfaces = list(cls.pg_interfaces[0:3])
4419 for i in cls.interfaces:
4424 cls.pg0.generate_remote_hosts(3)
4425 cls.pg0.configure_ipv4_neighbors()
4429 cls.pg4.generate_remote_hosts(2)
4430 cls.pg4.config_ip4()
4431 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
4432 cls.vapi.sw_interface_add_del_address(
4433 sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
4436 cls.pg4.resolve_arp()
4437 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4438 cls.pg4.resolve_arp()
4440 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4441 cls.vapi.ip_table_add_del(is_add=1, table_id=1)
4443 cls.pg5._local_ip4 = "10.1.1.1"
4444 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
4446 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4447 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
4448 socket.AF_INET, cls.pg5.remote_ip4)
4449 cls.pg5.set_table_ip4(1)
4450 cls.pg5.config_ip4()
4452 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4453 [VppRoutePath("0.0.0.0",
4454 cls.pg5.sw_if_index)],
4459 cls.pg6._local_ip4 = "10.1.2.1"
4460 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
4462 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4463 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
4464 socket.AF_INET, cls.pg6.remote_ip4)
4465 cls.pg6.set_table_ip4(1)
4466 cls.pg6.config_ip4()
4469 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4470 [VppRoutePath("0.0.0.0",
4471 cls.pg6.sw_if_index)],
4474 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4475 [VppRoutePath("0.0.0.0",
4480 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4481 [VppRoutePath("0.0.0.0", 0xffffffff,
4485 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4486 [VppRoutePath(cls.pg1.local_ip4,
4487 cls.pg1.sw_if_index)],
4494 cls.pg5.resolve_arp()
4495 cls.pg6.resolve_arp()
4498 cls.pg7.config_ip4()
4499 cls.pg7.resolve_arp()
4500 cls.pg7.generate_remote_hosts(3)
4501 cls.pg7.configure_ipv4_neighbors()
4504 cls.pg8.config_ip4()
4505 cls.pg8.resolve_arp()
4508 super(TestNAT44EndpointDependent, cls).tearDownClass()
4512 def tearDownClass(cls):
4513 super(TestNAT44EndpointDependent, cls).tearDownClass()
4515 def test_frag_in_order(self):
4516 """ NAT44 translate fragments arriving in order """
4517 self.nat44_add_address(self.nat_addr)
4518 flags = self.config_flags.NAT_IS_INSIDE
4519 self.vapi.nat44_interface_add_del_feature(
4520 sw_if_index=self.pg0.sw_if_index,
4521 flags=flags, is_add=1)
4522 self.vapi.nat44_interface_add_del_feature(
4523 sw_if_index=self.pg1.sw_if_index,
4525 self.frag_in_order(proto=IP_PROTOS.tcp)
4526 self.frag_in_order(proto=IP_PROTOS.udp)
4527 self.frag_in_order(proto=IP_PROTOS.icmp)
4529 def test_frag_in_order_dont_translate(self):
4530 """ NAT44 don't translate fragments arriving in order """
4531 flags = self.config_flags.NAT_IS_INSIDE
4532 self.vapi.nat44_interface_add_del_feature(
4533 sw_if_index=self.pg0.sw_if_index,
4534 flags=flags, is_add=1)
4535 self.vapi.nat44_interface_add_del_feature(
4536 sw_if_index=self.pg1.sw_if_index,
4538 self.vapi.nat44_forwarding_enable_disable(enable=True)
4539 reas_cfg1 = self.vapi.nat_get_reass()
4540 # this test was intermittently failing in some cases
4541 # until we temporarily bump the reassembly timeouts
4542 self.vapi.nat_set_reass(timeout=20, max_reass=1024, max_frag=5,
4544 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4545 # restore the reassembly timeouts
4546 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout,
4547 max_reass=reas_cfg1.ip4_max_reass,
4548 max_frag=reas_cfg1.ip4_max_frag,
4549 drop_frag=reas_cfg1.ip4_drop_frag)
4551 def test_frag_out_of_order(self):
4552 """ NAT44 translate fragments arriving out of order """
4553 self.nat44_add_address(self.nat_addr)
4554 flags = self.config_flags.NAT_IS_INSIDE
4555 self.vapi.nat44_interface_add_del_feature(
4556 sw_if_index=self.pg0.sw_if_index,
4557 flags=flags, is_add=1)
4558 self.vapi.nat44_interface_add_del_feature(
4559 sw_if_index=self.pg1.sw_if_index,
4561 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4562 self.frag_out_of_order(proto=IP_PROTOS.udp)
4563 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4565 def test_frag_out_of_order_dont_translate(self):
4566 """ NAT44 don't translate fragments arriving out of order """
4567 flags = self.config_flags.NAT_IS_INSIDE
4568 self.vapi.nat44_interface_add_del_feature(
4569 sw_if_index=self.pg0.sw_if_index,
4570 flags=flags, is_add=1)
4571 self.vapi.nat44_interface_add_del_feature(
4572 sw_if_index=self.pg1.sw_if_index,
4574 self.vapi.nat44_forwarding_enable_disable(enable=True)
4575 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4577 def test_frag_in_order_in_plus_out(self):
4578 """ in+out interface fragments in order """
4579 flags = self.config_flags.NAT_IS_INSIDE
4580 self.vapi.nat44_interface_add_del_feature(
4581 sw_if_index=self.pg0.sw_if_index,
4583 self.vapi.nat44_interface_add_del_feature(
4584 sw_if_index=self.pg0.sw_if_index,
4585 flags=flags, is_add=1)
4586 self.vapi.nat44_interface_add_del_feature(
4587 sw_if_index=self.pg1.sw_if_index,
4589 self.vapi.nat44_interface_add_del_feature(
4590 sw_if_index=self.pg1.sw_if_index,
4591 flags=flags, is_add=1)
4593 self.server = self.pg1.remote_hosts[0]
4595 self.server_in_addr = self.server.ip4
4596 self.server_out_addr = '11.11.11.11'
4597 self.server_in_port = random.randint(1025, 65535)
4598 self.server_out_port = random.randint(1025, 65535)
4600 self.nat44_add_address(self.server_out_addr)
4602 # add static mappings for server
4603 self.nat44_add_static_mapping(self.server_in_addr,
4604 self.server_out_addr,
4605 self.server_in_port,
4606 self.server_out_port,
4607 proto=IP_PROTOS.tcp)
4608 self.nat44_add_static_mapping(self.server_in_addr,
4609 self.server_out_addr,
4610 self.server_in_port,
4611 self.server_out_port,
4612 proto=IP_PROTOS.udp)
4613 self.nat44_add_static_mapping(self.server_in_addr,
4614 self.server_out_addr,
4615 proto=IP_PROTOS.icmp)
4617 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4620 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4621 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4622 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4624 def test_frag_out_of_order_in_plus_out(self):
4625 """ in+out interface fragments out of order """
4626 flags = self.config_flags.NAT_IS_INSIDE
4627 self.vapi.nat44_interface_add_del_feature(
4628 sw_if_index=self.pg0.sw_if_index,
4630 self.vapi.nat44_interface_add_del_feature(
4631 sw_if_index=self.pg0.sw_if_index,
4632 flags=flags, is_add=1)
4633 self.vapi.nat44_interface_add_del_feature(
4634 sw_if_index=self.pg1.sw_if_index,
4636 self.vapi.nat44_interface_add_del_feature(
4637 sw_if_index=self.pg1.sw_if_index,
4638 flags=flags, is_add=1)
4640 self.server = self.pg1.remote_hosts[0]
4642 self.server_in_addr = self.server.ip4
4643 self.server_out_addr = '11.11.11.11'
4644 self.server_in_port = random.randint(1025, 65535)
4645 self.server_out_port = random.randint(1025, 65535)
4647 self.nat44_add_address(self.server_out_addr)
4649 # add static mappings for server
4650 self.nat44_add_static_mapping(self.server_in_addr,
4651 self.server_out_addr,
4652 self.server_in_port,
4653 self.server_out_port,
4654 proto=IP_PROTOS.tcp)
4655 self.nat44_add_static_mapping(self.server_in_addr,
4656 self.server_out_addr,
4657 self.server_in_port,
4658 self.server_out_port,
4659 proto=IP_PROTOS.udp)
4660 self.nat44_add_static_mapping(self.server_in_addr,
4661 self.server_out_addr,
4662 proto=IP_PROTOS.icmp)
4664 self.vapi.nat_set_reass(timeout=10, max_reass=1024, max_frag=5,
4667 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4668 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4669 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4671 def test_reass_hairpinning(self):
4672 """ NAT44 fragments hairpinning """
4673 self.server = self.pg0.remote_hosts[1]
4674 self.host_in_port = random.randint(1025, 65535)
4675 self.server_in_port = random.randint(1025, 65535)
4676 self.server_out_port = random.randint(1025, 65535)
4678 self.nat44_add_address(self.nat_addr)
4679 flags = self.config_flags.NAT_IS_INSIDE
4680 self.vapi.nat44_interface_add_del_feature(
4681 sw_if_index=self.pg0.sw_if_index,
4682 flags=flags, is_add=1)
4683 self.vapi.nat44_interface_add_del_feature(
4684 sw_if_index=self.pg1.sw_if_index,
4686 # add static mapping for server
4687 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4688 self.server_in_port,
4689 self.server_out_port,
4690 proto=IP_PROTOS.tcp)
4691 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4692 self.server_in_port,
4693 self.server_out_port,
4694 proto=IP_PROTOS.udp)
4695 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4697 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4698 self.reass_hairpinning(proto=IP_PROTOS.udp)
4699 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4701 def test_dynamic(self):
4702 """ NAT44 dynamic translation test """
4704 self.nat44_add_address(self.nat_addr)
4705 flags = self.config_flags.NAT_IS_INSIDE
4706 self.vapi.nat44_interface_add_del_feature(
4707 sw_if_index=self.pg0.sw_if_index,
4708 flags=flags, is_add=1)
4709 self.vapi.nat44_interface_add_del_feature(
4710 sw_if_index=self.pg1.sw_if_index,
4713 nat_config = self.vapi.nat_show_config()
4714 self.assertEqual(1, nat_config.endpoint_dependent)
4717 tcpn = self.statistics.get_err_counter(
4718 '/err/nat44-ed-in2out-slowpath/TCP packets')
4719 udpn = self.statistics.get_err_counter(
4720 '/err/nat44-ed-in2out-slowpath/UDP packets')
4721 icmpn = self.statistics.get_err_counter(
4722 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4723 totaln = self.statistics.get_err_counter(
4724 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4726 pkts = self.create_stream_in(self.pg0, self.pg1)
4727 self.pg0.add_stream(pkts)
4728 self.pg_enable_capture(self.pg_interfaces)
4730 capture = self.pg1.get_capture(len(pkts))
4731 self.verify_capture_out(capture)
4733 err = self.statistics.get_err_counter(
4734 '/err/nat44-ed-in2out-slowpath/TCP packets')
4735 self.assertEqual(err - tcpn, 2)
4736 err = self.statistics.get_err_counter(
4737 '/err/nat44-ed-in2out-slowpath/UDP packets')
4738 self.assertEqual(err - udpn, 1)
4739 err = self.statistics.get_err_counter(
4740 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4741 self.assertEqual(err - icmpn, 1)
4742 err = self.statistics.get_err_counter(
4743 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4744 self.assertEqual(err - totaln, 4)
4747 tcpn = self.statistics.get_err_counter(
4748 '/err/nat44-ed-out2in/TCP packets')
4749 udpn = self.statistics.get_err_counter(
4750 '/err/nat44-ed-out2in/UDP packets')
4751 icmpn = self.statistics.get_err_counter(
4752 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4753 totaln = self.statistics.get_err_counter(
4754 '/err/nat44-ed-out2in/good out2in packets processed')
4756 pkts = self.create_stream_out(self.pg1)
4757 self.pg1.add_stream(pkts)
4758 self.pg_enable_capture(self.pg_interfaces)
4760 capture = self.pg0.get_capture(len(pkts))
4761 self.verify_capture_in(capture, self.pg0)
4763 err = self.statistics.get_err_counter(
4764 '/err/nat44-ed-out2in/TCP packets')
4765 self.assertEqual(err - tcpn, 2)
4766 err = self.statistics.get_err_counter(
4767 '/err/nat44-ed-out2in/UDP packets')
4768 self.assertEqual(err - udpn, 1)
4769 err = self.statistics.get_err_counter(
4770 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4771 self.assertEqual(err - icmpn, 1)
4772 err = self.statistics.get_err_counter(
4773 '/err/nat44-ed-out2in/good out2in packets processed')
4774 self.assertEqual(err - totaln, 3)
4776 users = self.statistics.get_counter('/nat44/total-users')
4777 self.assertEqual(users[0][0], 1)
4778 sessions = self.statistics.get_counter('/nat44/total-sessions')
4779 self.assertEqual(sessions[0][0], 3)
4781 def test_dynamic_output_feature_vrf(self):
4782 """ NAT44 dynamic translation test: output-feature, VRF"""
4784 # other then default (0)
4787 self.nat44_add_address(self.nat_addr)
4788 flags = self.config_flags.NAT_IS_INSIDE
4789 self.vapi.nat44_interface_add_del_output_feature(
4790 sw_if_index=self.pg7.sw_if_index,
4791 flags=flags, is_add=1)
4792 self.vapi.nat44_interface_add_del_output_feature(
4793 sw_if_index=self.pg8.sw_if_index,
4797 self.vapi.ip_table_add_del(is_add=1, table_id=new_vrf_id)
4799 self.pg7.unconfig_ip4()
4800 self.pg7.set_table_ip4(new_vrf_id)
4801 self.pg7.config_ip4()
4802 self.pg7.resolve_arp()
4804 self.pg8.unconfig_ip4()
4805 self.pg8.set_table_ip4(new_vrf_id)
4806 self.pg8.config_ip4()
4807 self.pg8.resolve_arp()
4809 nat_config = self.vapi.nat_show_config()
4810 self.assertEqual(1, nat_config.endpoint_dependent)
4813 tcpn = self.statistics.get_err_counter(
4814 '/err/nat44-ed-in2out-slowpath/TCP packets')
4815 udpn = self.statistics.get_err_counter(
4816 '/err/nat44-ed-in2out-slowpath/UDP packets')
4817 icmpn = self.statistics.get_err_counter(
4818 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4819 totaln = self.statistics.get_err_counter(
4820 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4822 pkts = self.create_stream_in(self.pg7, self.pg8)
4823 self.pg7.add_stream(pkts)
4824 self.pg_enable_capture(self.pg_interfaces)
4826 capture = self.pg8.get_capture(len(pkts))
4827 self.verify_capture_out(capture)
4829 err = self.statistics.get_err_counter(
4830 '/err/nat44-ed-in2out-slowpath/TCP packets')
4831 self.assertEqual(err - tcpn, 2)
4832 err = self.statistics.get_err_counter(
4833 '/err/nat44-ed-in2out-slowpath/UDP packets')
4834 self.assertEqual(err - udpn, 1)
4835 err = self.statistics.get_err_counter(
4836 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4837 self.assertEqual(err - icmpn, 1)
4838 err = self.statistics.get_err_counter(
4839 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4840 self.assertEqual(err - totaln, 4)
4843 tcpn = self.statistics.get_err_counter(
4844 '/err/nat44-ed-out2in/TCP packets')
4845 udpn = self.statistics.get_err_counter(
4846 '/err/nat44-ed-out2in/UDP packets')
4847 icmpn = self.statistics.get_err_counter(
4848 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4849 totaln = self.statistics.get_err_counter(
4850 '/err/nat44-ed-out2in/good out2in packets processed')
4852 pkts = self.create_stream_out(self.pg8)
4853 self.pg8.add_stream(pkts)
4854 self.pg_enable_capture(self.pg_interfaces)
4856 capture = self.pg7.get_capture(len(pkts))
4857 self.verify_capture_in(capture, self.pg7)
4859 err = self.statistics.get_err_counter(
4860 '/err/nat44-ed-out2in/TCP packets')
4861 self.assertEqual(err - tcpn, 2)
4862 err = self.statistics.get_err_counter(
4863 '/err/nat44-ed-out2in/UDP packets')
4864 self.assertEqual(err - udpn, 1)
4865 err = self.statistics.get_err_counter(
4866 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4867 self.assertEqual(err - icmpn, 1)
4868 err = self.statistics.get_err_counter(
4869 '/err/nat44-ed-out2in/good out2in packets processed')
4870 self.assertEqual(err - totaln, 3)
4872 users = self.statistics.get_counter('/nat44/total-users')
4873 self.assertEqual(users[0][0], 1)
4874 sessions = self.statistics.get_counter('/nat44/total-sessions')
4875 self.assertEqual(sessions[0][0], 3)
4878 self.pg7.unconfig_ip4()
4879 self.pg7.set_table_ip4(1)
4880 self.pg7.config_ip4()
4881 self.pg7.resolve_arp()
4883 self.pg8.unconfig_ip4()
4884 self.pg8.set_table_ip4(1)
4885 self.pg8.config_ip4()
4886 self.pg8.resolve_arp()
4888 self.vapi.ip_table_add_del(is_add=0, table_id=new_vrf_id)
4890 def test_forwarding(self):
4891 """ NAT44 forwarding test """
4893 flags = self.config_flags.NAT_IS_INSIDE
4894 self.vapi.nat44_interface_add_del_feature(
4895 sw_if_index=self.pg0.sw_if_index,
4896 flags=flags, is_add=1)
4897 self.vapi.nat44_interface_add_del_feature(
4898 sw_if_index=self.pg1.sw_if_index,
4900 self.vapi.nat44_forwarding_enable_disable(enable=1)
4902 real_ip = self.pg0.remote_ip4
4903 alias_ip = self.nat_addr
4904 flags = self.config_flags.NAT_IS_ADDR_ONLY
4905 self.vapi.nat44_add_del_static_mapping(is_add=1,
4906 local_ip_address=real_ip,
4907 external_ip_address=alias_ip,
4908 external_sw_if_index=0xFFFFFFFF,
4912 # in2out - static mapping match
4914 pkts = self.create_stream_out(self.pg1)
4915 self.pg1.add_stream(pkts)
4916 self.pg_enable_capture(self.pg_interfaces)
4918 capture = self.pg0.get_capture(len(pkts))
4919 self.verify_capture_in(capture, self.pg0)
4921 pkts = self.create_stream_in(self.pg0, self.pg1)
4922 self.pg0.add_stream(pkts)
4923 self.pg_enable_capture(self.pg_interfaces)
4925 capture = self.pg1.get_capture(len(pkts))
4926 self.verify_capture_out(capture, same_port=True)
4928 # in2out - no static mapping match
4930 host0 = self.pg0.remote_hosts[0]
4931 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4933 pkts = self.create_stream_out(self.pg1,
4934 dst_ip=self.pg0.remote_ip4,
4935 use_inside_ports=True)
4936 self.pg1.add_stream(pkts)
4937 self.pg_enable_capture(self.pg_interfaces)
4939 capture = self.pg0.get_capture(len(pkts))
4940 self.verify_capture_in(capture, self.pg0)
4942 pkts = self.create_stream_in(self.pg0, self.pg1)
4943 self.pg0.add_stream(pkts)
4944 self.pg_enable_capture(self.pg_interfaces)
4946 capture = self.pg1.get_capture(len(pkts))
4947 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4950 self.pg0.remote_hosts[0] = host0
4952 user = self.pg0.remote_hosts[1]
4953 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4954 self.assertEqual(len(sessions), 3)
4955 self.assertTrue(sessions[0].flags &
4956 self.config_flags.NAT_IS_EXT_HOST_VALID)
4957 self.vapi.nat44_del_session(
4958 address=sessions[0].inside_ip_address,
4959 port=sessions[0].inside_port,
4960 protocol=sessions[0].protocol,
4961 flags=(self.config_flags.NAT_IS_INSIDE |
4962 self.config_flags.NAT_IS_EXT_HOST_VALID),
4963 ext_host_address=sessions[0].ext_host_address,
4964 ext_host_port=sessions[0].ext_host_port)
4965 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4966 self.assertEqual(len(sessions), 2)
4969 self.vapi.nat44_forwarding_enable_disable(enable=0)
4970 flags = self.config_flags.NAT_IS_ADDR_ONLY
4971 self.vapi.nat44_add_del_static_mapping(
4973 local_ip_address=real_ip,
4974 external_ip_address=alias_ip,
4975 external_sw_if_index=0xFFFFFFFF,
4978 def test_static_lb(self):
4979 """ NAT44 local service load balancing """
4980 external_addr_n = self.nat_addr
4983 server1 = self.pg0.remote_hosts[0]
4984 server2 = self.pg0.remote_hosts[1]
4986 locals = [{'addr': server1.ip4n,
4990 {'addr': server2.ip4n,
4995 self.nat44_add_address(self.nat_addr)
4996 self.vapi.nat44_add_del_lb_static_mapping(
4998 external_addr=external_addr_n,
4999 external_port=external_port,
5000 protocol=IP_PROTOS.tcp,
5001 local_num=len(locals),
5003 flags = self.config_flags.NAT_IS_INSIDE
5004 self.vapi.nat44_interface_add_del_feature(
5005 sw_if_index=self.pg0.sw_if_index,
5006 flags=flags, is_add=1)
5007 self.vapi.nat44_interface_add_del_feature(
5008 sw_if_index=self.pg1.sw_if_index,
5011 # from client to service
5012 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5013 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5014 TCP(sport=12345, dport=external_port))
5015 self.pg1.add_stream(p)
5016 self.pg_enable_capture(self.pg_interfaces)
5018 capture = self.pg0.get_capture(1)
5024 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5025 if ip.dst == server1.ip4:
5029 self.assertEqual(tcp.dport, local_port)
5030 self.assert_packet_checksums_valid(p)
5032 self.logger.error(ppp("Unexpected or invalid packet:", p))
5035 # from service back to client
5036 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5037 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5038 TCP(sport=local_port, dport=12345))
5039 self.pg0.add_stream(p)
5040 self.pg_enable_capture(self.pg_interfaces)
5042 capture = self.pg1.get_capture(1)
5047 self.assertEqual(ip.src, self.nat_addr)
5048 self.assertEqual(tcp.sport, external_port)
5049 self.assert_packet_checksums_valid(p)
5051 self.logger.error(ppp("Unexpected or invalid packet:", p))
5054 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5055 self.assertEqual(len(sessions), 1)
5056 self.assertTrue(sessions[0].flags &
5057 self.config_flags.NAT_IS_EXT_HOST_VALID)
5058 self.vapi.nat44_del_session(
5059 address=sessions[0].inside_ip_address,
5060 port=sessions[0].inside_port,
5061 protocol=sessions[0].protocol,
5062 flags=(self.config_flags.NAT_IS_INSIDE |
5063 self.config_flags.NAT_IS_EXT_HOST_VALID),
5064 ext_host_address=sessions[0].ext_host_address,
5065 ext_host_port=sessions[0].ext_host_port)
5066 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5067 self.assertEqual(len(sessions), 0)
5069 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5070 def test_static_lb_multi_clients(self):
5071 """ NAT44 local service load balancing - multiple clients"""
5073 external_addr = self.nat_addr
5076 server1 = self.pg0.remote_hosts[0]
5077 server2 = self.pg0.remote_hosts[1]
5078 server3 = self.pg0.remote_hosts[2]
5080 locals = [{'addr': server1.ip4n,
5084 {'addr': server2.ip4n,
5089 self.nat44_add_address(self.nat_addr)
5090 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5091 external_addr=external_addr,
5092 external_port=external_port,
5093 protocol=IP_PROTOS.tcp,
5094 local_num=len(locals),
5096 flags = self.config_flags.NAT_IS_INSIDE
5097 self.vapi.nat44_interface_add_del_feature(
5098 sw_if_index=self.pg0.sw_if_index,
5099 flags=flags, is_add=1)
5100 self.vapi.nat44_interface_add_del_feature(
5101 sw_if_index=self.pg1.sw_if_index,
5106 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5108 for client in clients:
5109 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5110 IP(src=client, dst=self.nat_addr) /
5111 TCP(sport=12345, dport=external_port))
5113 self.pg1.add_stream(pkts)
5114 self.pg_enable_capture(self.pg_interfaces)
5116 capture = self.pg0.get_capture(len(pkts))
5118 if p[IP].dst == server1.ip4:
5122 self.assertGreater(server1_n, server2_n)
5125 'addr': server3.ip4n,
5132 self.vapi.nat44_lb_static_mapping_add_del_local(
5134 external_addr=external_addr,
5135 external_port=external_port,
5137 protocol=IP_PROTOS.tcp)
5141 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5143 for client in clients:
5144 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5145 IP(src=client, dst=self.nat_addr) /
5146 TCP(sport=12346, dport=external_port))
5148 self.assertGreater(len(pkts), 0)
5149 self.pg1.add_stream(pkts)
5150 self.pg_enable_capture(self.pg_interfaces)
5152 capture = self.pg0.get_capture(len(pkts))
5154 if p[IP].dst == server1.ip4:
5156 elif p[IP].dst == server2.ip4:
5160 self.assertGreater(server1_n, 0)
5161 self.assertGreater(server2_n, 0)
5162 self.assertGreater(server3_n, 0)
5165 'addr': server2.ip4n,
5171 # remove one back-end
5172 self.vapi.nat44_lb_static_mapping_add_del_local(
5174 external_addr=external_addr,
5175 external_port=external_port,
5177 protocol=IP_PROTOS.tcp)
5181 self.pg1.add_stream(pkts)
5182 self.pg_enable_capture(self.pg_interfaces)
5184 capture = self.pg0.get_capture(len(pkts))
5186 if p[IP].dst == server1.ip4:
5188 elif p[IP].dst == server2.ip4:
5192 self.assertGreater(server1_n, 0)
5193 self.assertEqual(server2_n, 0)
5194 self.assertGreater(server3_n, 0)
5196 def test_static_lb_2(self):
5197 """ NAT44 local service load balancing (asymmetrical rule) """
5198 external_addr = self.nat_addr
5201 server1 = self.pg0.remote_hosts[0]
5202 server2 = self.pg0.remote_hosts[1]
5204 locals = [{'addr': server1.ip4n,
5208 {'addr': server2.ip4n,
5213 self.vapi.nat44_forwarding_enable_disable(enable=1)
5214 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5215 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5216 external_addr=external_addr,
5217 external_port=external_port,
5218 protocol=IP_PROTOS.tcp,
5219 local_num=len(locals),
5221 flags = self.config_flags.NAT_IS_INSIDE
5222 self.vapi.nat44_interface_add_del_feature(
5223 sw_if_index=self.pg0.sw_if_index,
5224 flags=flags, is_add=1)
5225 self.vapi.nat44_interface_add_del_feature(
5226 sw_if_index=self.pg1.sw_if_index,
5229 # from client to service
5230 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5231 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5232 TCP(sport=12345, dport=external_port))
5233 self.pg1.add_stream(p)
5234 self.pg_enable_capture(self.pg_interfaces)
5236 capture = self.pg0.get_capture(1)
5242 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5243 if ip.dst == server1.ip4:
5247 self.assertEqual(tcp.dport, local_port)
5248 self.assert_packet_checksums_valid(p)
5250 self.logger.error(ppp("Unexpected or invalid packet:", p))
5253 # from service back to client
5254 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5255 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5256 TCP(sport=local_port, dport=12345))
5257 self.pg0.add_stream(p)
5258 self.pg_enable_capture(self.pg_interfaces)
5260 capture = self.pg1.get_capture(1)
5265 self.assertEqual(ip.src, self.nat_addr)
5266 self.assertEqual(tcp.sport, external_port)
5267 self.assert_packet_checksums_valid(p)
5269 self.logger.error(ppp("Unexpected or invalid packet:", p))
5272 # from client to server (no translation)
5273 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5274 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5275 TCP(sport=12346, dport=local_port))
5276 self.pg1.add_stream(p)
5277 self.pg_enable_capture(self.pg_interfaces)
5279 capture = self.pg0.get_capture(1)
5285 self.assertEqual(ip.dst, server1.ip4)
5286 self.assertEqual(tcp.dport, local_port)
5287 self.assert_packet_checksums_valid(p)
5289 self.logger.error(ppp("Unexpected or invalid packet:", p))
5292 # from service back to client (no translation)
5293 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5294 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5295 TCP(sport=local_port, dport=12346))
5296 self.pg0.add_stream(p)
5297 self.pg_enable_capture(self.pg_interfaces)
5299 capture = self.pg1.get_capture(1)
5304 self.assertEqual(ip.src, server1.ip4)
5305 self.assertEqual(tcp.sport, local_port)
5306 self.assert_packet_checksums_valid(p)
5308 self.logger.error(ppp("Unexpected or invalid packet:", p))
5311 def test_lb_affinity(self):
5312 """ NAT44 local service load balancing affinity """
5313 external_addr = self.nat_addr
5316 server1 = self.pg0.remote_hosts[0]
5317 server2 = self.pg0.remote_hosts[1]
5319 locals = [{'addr': server1.ip4n,
5323 {'addr': server2.ip4n,
5328 self.nat44_add_address(self.nat_addr)
5329 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5330 external_addr=external_addr,
5331 external_port=external_port,
5332 protocol=IP_PROTOS.tcp,
5334 local_num=len(locals),
5336 flags = self.config_flags.NAT_IS_INSIDE
5337 self.vapi.nat44_interface_add_del_feature(
5338 sw_if_index=self.pg0.sw_if_index,
5339 flags=flags, is_add=1)
5340 self.vapi.nat44_interface_add_del_feature(
5341 sw_if_index=self.pg1.sw_if_index,
5344 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5345 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5346 TCP(sport=1025, dport=external_port))
5347 self.pg1.add_stream(p)
5348 self.pg_enable_capture(self.pg_interfaces)
5350 capture = self.pg0.get_capture(1)
5351 backend = capture[0][IP].dst
5353 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5354 self.assertEqual(len(sessions), 1)
5355 self.assertTrue(sessions[0].flags &
5356 self.config_flags.NAT_IS_EXT_HOST_VALID)
5357 self.vapi.nat44_del_session(
5358 address=sessions[0].inside_ip_address,
5359 port=sessions[0].inside_port,
5360 protocol=sessions[0].protocol,
5361 flags=(self.config_flags.NAT_IS_INSIDE |
5362 self.config_flags.NAT_IS_EXT_HOST_VALID),
5363 ext_host_address=sessions[0].ext_host_address,
5364 ext_host_port=sessions[0].ext_host_port)
5367 for port in range(1030, 1100):
5368 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5369 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5370 TCP(sport=port, dport=external_port))
5372 self.pg1.add_stream(pkts)
5373 self.pg_enable_capture(self.pg_interfaces)
5375 capture = self.pg0.get_capture(len(pkts))
5377 self.assertEqual(p[IP].dst, backend)
5379 def test_unknown_proto(self):
5380 """ NAT44 translate packet with unknown protocol """
5381 self.nat44_add_address(self.nat_addr)
5382 flags = self.config_flags.NAT_IS_INSIDE
5383 self.vapi.nat44_interface_add_del_feature(
5384 sw_if_index=self.pg0.sw_if_index,
5385 flags=flags, is_add=1)
5386 self.vapi.nat44_interface_add_del_feature(
5387 sw_if_index=self.pg1.sw_if_index,
5391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5392 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5393 TCP(sport=self.tcp_port_in, dport=20))
5394 self.pg0.add_stream(p)
5395 self.pg_enable_capture(self.pg_interfaces)
5397 p = self.pg1.get_capture(1)
5399 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5400 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5402 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5403 TCP(sport=1234, dport=1234))
5404 self.pg0.add_stream(p)
5405 self.pg_enable_capture(self.pg_interfaces)
5407 p = self.pg1.get_capture(1)
5410 self.assertEqual(packet[IP].src, self.nat_addr)
5411 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5412 self.assertEqual(packet.haslayer(GRE), 1)
5413 self.assert_packet_checksums_valid(packet)
5415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5419 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5420 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5422 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5423 TCP(sport=1234, dport=1234))
5424 self.pg1.add_stream(p)
5425 self.pg_enable_capture(self.pg_interfaces)
5427 p = self.pg0.get_capture(1)
5430 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5431 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5432 self.assertEqual(packet.haslayer(GRE), 1)
5433 self.assert_packet_checksums_valid(packet)
5435 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5438 def test_hairpinning_unknown_proto(self):
5439 """ NAT44 translate packet with unknown protocol - hairpinning """
5440 host = self.pg0.remote_hosts[0]
5441 server = self.pg0.remote_hosts[1]
5443 server_out_port = 8765
5444 server_nat_ip = "10.0.0.11"
5446 self.nat44_add_address(self.nat_addr)
5447 flags = self.config_flags.NAT_IS_INSIDE
5448 self.vapi.nat44_interface_add_del_feature(
5449 sw_if_index=self.pg0.sw_if_index,
5450 flags=flags, is_add=1)
5451 self.vapi.nat44_interface_add_del_feature(
5452 sw_if_index=self.pg1.sw_if_index,
5455 # add static mapping for server
5456 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5459 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5460 IP(src=host.ip4, dst=server_nat_ip) /
5461 TCP(sport=host_in_port, dport=server_out_port))
5462 self.pg0.add_stream(p)
5463 self.pg_enable_capture(self.pg_interfaces)
5465 self.pg0.get_capture(1)
5467 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5468 IP(src=host.ip4, dst=server_nat_ip) /
5470 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5471 TCP(sport=1234, dport=1234))
5472 self.pg0.add_stream(p)
5473 self.pg_enable_capture(self.pg_interfaces)
5475 p = self.pg0.get_capture(1)
5478 self.assertEqual(packet[IP].src, self.nat_addr)
5479 self.assertEqual(packet[IP].dst, server.ip4)
5480 self.assertEqual(packet.haslayer(GRE), 1)
5481 self.assert_packet_checksums_valid(packet)
5483 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5487 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5488 IP(src=server.ip4, dst=self.nat_addr) /
5490 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5491 TCP(sport=1234, dport=1234))
5492 self.pg0.add_stream(p)
5493 self.pg_enable_capture(self.pg_interfaces)
5495 p = self.pg0.get_capture(1)
5498 self.assertEqual(packet[IP].src, server_nat_ip)
5499 self.assertEqual(packet[IP].dst, host.ip4)
5500 self.assertEqual(packet.haslayer(GRE), 1)
5501 self.assert_packet_checksums_valid(packet)
5503 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5506 def test_output_feature_and_service(self):
5507 """ NAT44 interface output feature and services """
5508 external_addr = '1.2.3.4'
5512 self.vapi.nat44_forwarding_enable_disable(enable=1)
5513 self.nat44_add_address(self.nat_addr)
5514 flags = self.config_flags.NAT_IS_ADDR_ONLY
5515 self.vapi.nat44_add_del_identity_mapping(
5516 ip_address=self.pg1.remote_ip4n, sw_if_index=0xFFFFFFFF,
5517 flags=flags, is_add=1)
5518 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5519 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5520 local_port, external_port,
5521 proto=IP_PROTOS.tcp, flags=flags)
5522 flags = self.config_flags.NAT_IS_INSIDE
5523 self.vapi.nat44_interface_add_del_feature(
5524 sw_if_index=self.pg0.sw_if_index,
5526 self.vapi.nat44_interface_add_del_feature(
5527 sw_if_index=self.pg0.sw_if_index,
5528 flags=flags, is_add=1)
5529 self.vapi.nat44_interface_add_del_output_feature(
5531 sw_if_index=self.pg1.sw_if_index)
5533 # from client to service
5534 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5535 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5536 TCP(sport=12345, dport=external_port))
5537 self.pg1.add_stream(p)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg0.get_capture(1)
5545 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5546 self.assertEqual(tcp.dport, local_port)
5547 self.assert_packet_checksums_valid(p)
5549 self.logger.error(ppp("Unexpected or invalid packet:", p))
5552 # from service back to client
5553 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5554 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5555 TCP(sport=local_port, dport=12345))
5556 self.pg0.add_stream(p)
5557 self.pg_enable_capture(self.pg_interfaces)
5559 capture = self.pg1.get_capture(1)
5564 self.assertEqual(ip.src, external_addr)
5565 self.assertEqual(tcp.sport, external_port)
5566 self.assert_packet_checksums_valid(p)
5568 self.logger.error(ppp("Unexpected or invalid packet:", p))
5571 # from local network host to external network
5572 pkts = self.create_stream_in(self.pg0, self.pg1)
5573 self.pg0.add_stream(pkts)
5574 self.pg_enable_capture(self.pg_interfaces)
5576 capture = self.pg1.get_capture(len(pkts))
5577 self.verify_capture_out(capture)
5578 pkts = self.create_stream_in(self.pg0, self.pg1)
5579 self.pg0.add_stream(pkts)
5580 self.pg_enable_capture(self.pg_interfaces)
5582 capture = self.pg1.get_capture(len(pkts))
5583 self.verify_capture_out(capture)
5585 # from external network back to local network host
5586 pkts = self.create_stream_out(self.pg1)
5587 self.pg1.add_stream(pkts)
5588 self.pg_enable_capture(self.pg_interfaces)
5590 capture = self.pg0.get_capture(len(pkts))
5591 self.verify_capture_in(capture, self.pg0)
5593 def test_output_feature_and_service2(self):
5594 """ NAT44 interface output feature and service host direct access """
5595 self.vapi.nat44_forwarding_enable_disable(enable=1)
5596 self.nat44_add_address(self.nat_addr)
5597 self.vapi.nat44_interface_add_del_output_feature(
5599 sw_if_index=self.pg1.sw_if_index)
5601 # session initiated from service host - translate
5602 pkts = self.create_stream_in(self.pg0, self.pg1)
5603 self.pg0.add_stream(pkts)
5604 self.pg_enable_capture(self.pg_interfaces)
5606 capture = self.pg1.get_capture(len(pkts))
5607 self.verify_capture_out(capture)
5609 pkts = self.create_stream_out(self.pg1)
5610 self.pg1.add_stream(pkts)
5611 self.pg_enable_capture(self.pg_interfaces)
5613 capture = self.pg0.get_capture(len(pkts))
5614 self.verify_capture_in(capture, self.pg0)
5616 # session initiated from remote host - do not translate
5617 self.tcp_port_in = 60303
5618 self.udp_port_in = 60304
5619 self.icmp_id_in = 60305
5620 pkts = self.create_stream_out(self.pg1,
5621 self.pg0.remote_ip4,
5622 use_inside_ports=True)
5623 self.pg1.add_stream(pkts)
5624 self.pg_enable_capture(self.pg_interfaces)
5626 capture = self.pg0.get_capture(len(pkts))
5627 self.verify_capture_in(capture, self.pg0)
5629 pkts = self.create_stream_in(self.pg0, self.pg1)
5630 self.pg0.add_stream(pkts)
5631 self.pg_enable_capture(self.pg_interfaces)
5633 capture = self.pg1.get_capture(len(pkts))
5634 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5637 def test_output_feature_and_service3(self):
5638 """ NAT44 interface output feature and DST NAT """
5639 external_addr = '1.2.3.4'
5643 self.vapi.nat44_forwarding_enable_disable(enable=1)
5644 self.nat44_add_address(self.nat_addr)
5645 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5646 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5647 local_port, external_port,
5648 proto=IP_PROTOS.tcp, flags=flags)
5649 flags = self.config_flags.NAT_IS_INSIDE
5650 self.vapi.nat44_interface_add_del_feature(
5651 sw_if_index=self.pg0.sw_if_index,
5653 self.vapi.nat44_interface_add_del_feature(
5654 sw_if_index=self.pg0.sw_if_index,
5655 flags=flags, is_add=1)
5656 self.vapi.nat44_interface_add_del_output_feature(
5658 sw_if_index=self.pg1.sw_if_index)
5660 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5661 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5662 TCP(sport=12345, dport=external_port))
5663 self.pg0.add_stream(p)
5664 self.pg_enable_capture(self.pg_interfaces)
5666 capture = self.pg1.get_capture(1)
5671 self.assertEqual(ip.src, self.pg0.remote_ip4)
5672 self.assertEqual(tcp.sport, 12345)
5673 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5674 self.assertEqual(tcp.dport, local_port)
5675 self.assert_packet_checksums_valid(p)
5677 self.logger.error(ppp("Unexpected or invalid packet:", p))
5680 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5681 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5682 TCP(sport=local_port, dport=12345))
5683 self.pg1.add_stream(p)
5684 self.pg_enable_capture(self.pg_interfaces)
5686 capture = self.pg0.get_capture(1)
5691 self.assertEqual(ip.src, external_addr)
5692 self.assertEqual(tcp.sport, external_port)
5693 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5694 self.assertEqual(tcp.dport, 12345)
5695 self.assert_packet_checksums_valid(p)
5697 self.logger.error(ppp("Unexpected or invalid packet:", p))
5700 def test_next_src_nat(self):
5701 """ On way back forward packet to nat44-in2out node. """
5702 twice_nat_addr = '10.0.1.3'
5705 post_twice_nat_port = 0
5707 self.vapi.nat44_forwarding_enable_disable(enable=1)
5708 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5709 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5710 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5711 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5712 local_port, external_port,
5713 proto=IP_PROTOS.tcp, vrf_id=1,
5715 self.vapi.nat44_interface_add_del_feature(
5716 sw_if_index=self.pg6.sw_if_index,
5719 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5720 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5721 TCP(sport=12345, dport=external_port))
5722 self.pg6.add_stream(p)
5723 self.pg_enable_capture(self.pg_interfaces)
5725 capture = self.pg6.get_capture(1)
5730 self.assertEqual(ip.src, twice_nat_addr)
5731 self.assertNotEqual(tcp.sport, 12345)
5732 post_twice_nat_port = tcp.sport
5733 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5734 self.assertEqual(tcp.dport, local_port)
5735 self.assert_packet_checksums_valid(p)
5737 self.logger.error(ppp("Unexpected or invalid packet:", p))
5740 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5741 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5742 TCP(sport=local_port, dport=post_twice_nat_port))
5743 self.pg6.add_stream(p)
5744 self.pg_enable_capture(self.pg_interfaces)
5746 capture = self.pg6.get_capture(1)
5751 self.assertEqual(ip.src, self.pg1.remote_ip4)
5752 self.assertEqual(tcp.sport, external_port)
5753 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5754 self.assertEqual(tcp.dport, 12345)
5755 self.assert_packet_checksums_valid(p)
5757 self.logger.error(ppp("Unexpected or invalid packet:", p))
5760 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5762 twice_nat_addr = '10.0.1.3'
5770 port_in1 = port_in + 1
5771 port_in2 = port_in + 2
5776 server1 = self.pg0.remote_hosts[0]
5777 server2 = self.pg0.remote_hosts[1]
5789 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5792 self.nat44_add_address(self.nat_addr)
5793 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5797 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5799 flags |= self.config_flags.NAT_IS_TWICE_NAT
5802 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5804 proto=IP_PROTOS.tcp,
5807 locals = [{'addr': server1.ip4n,
5811 {'addr': server2.ip4n,
5815 out_addr = self.nat_addr
5817 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5818 external_addr=out_addr,
5819 external_port=port_out,
5820 protocol=IP_PROTOS.tcp,
5821 local_num=len(locals),
5823 flags = self.config_flags.NAT_IS_INSIDE
5824 self.vapi.nat44_interface_add_del_feature(
5825 sw_if_index=pg0.sw_if_index,
5826 flags=flags, is_add=1)
5827 self.vapi.nat44_interface_add_del_feature(
5828 sw_if_index=pg1.sw_if_index,
5835 assert client_id is not None
5837 client = self.pg0.remote_hosts[0]
5838 elif client_id == 2:
5839 client = self.pg0.remote_hosts[1]
5841 client = pg1.remote_hosts[0]
5842 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5843 IP(src=client.ip4, dst=self.nat_addr) /
5844 TCP(sport=eh_port_out, dport=port_out))
5846 self.pg_enable_capture(self.pg_interfaces)
5848 capture = pg0.get_capture(1)
5854 if ip.dst == server1.ip4:
5860 self.assertEqual(ip.dst, server.ip4)
5862 self.assertIn(tcp.dport, [port_in1, port_in2])
5864 self.assertEqual(tcp.dport, port_in)
5866 self.assertEqual(ip.src, twice_nat_addr)
5867 self.assertNotEqual(tcp.sport, eh_port_out)
5869 self.assertEqual(ip.src, client.ip4)
5870 self.assertEqual(tcp.sport, eh_port_out)
5872 eh_port_in = tcp.sport
5873 saved_port_in = tcp.dport
5874 self.assert_packet_checksums_valid(p)
5876 self.logger.error(ppp("Unexpected or invalid packet:", p))
5879 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5880 IP(src=server.ip4, dst=eh_addr_in) /
5881 TCP(sport=saved_port_in, dport=eh_port_in))
5883 self.pg_enable_capture(self.pg_interfaces)
5885 capture = pg1.get_capture(1)
5890 self.assertEqual(ip.dst, client.ip4)
5891 self.assertEqual(ip.src, self.nat_addr)
5892 self.assertEqual(tcp.dport, eh_port_out)
5893 self.assertEqual(tcp.sport, port_out)
5894 self.assert_packet_checksums_valid(p)
5896 self.logger.error(ppp("Unexpected or invalid packet:", p))
5900 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5901 self.assertEqual(len(sessions), 1)
5902 self.assertTrue(sessions[0].flags &
5903 self.config_flags.NAT_IS_EXT_HOST_VALID)
5904 self.assertTrue(sessions[0].flags &
5905 self.config_flags.NAT_IS_TWICE_NAT)
5906 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5907 self.vapi.nat44_del_session(
5908 address=sessions[0].inside_ip_address,
5909 port=sessions[0].inside_port,
5910 protocol=sessions[0].protocol,
5911 flags=(self.config_flags.NAT_IS_INSIDE |
5912 self.config_flags.NAT_IS_EXT_HOST_VALID),
5913 ext_host_address=sessions[0].ext_host_nat_address,
5914 ext_host_port=sessions[0].ext_host_nat_port)
5915 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5916 self.assertEqual(len(sessions), 0)
5918 def test_twice_nat(self):
5920 self.twice_nat_common()
5922 def test_self_twice_nat_positive(self):
5923 """ Self Twice NAT44 (positive test) """
5924 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5926 def test_self_twice_nat_negative(self):
5927 """ Self Twice NAT44 (negative test) """
5928 self.twice_nat_common(self_twice_nat=True)
5930 def test_twice_nat_lb(self):
5931 """ Twice NAT44 local service load balancing """
5932 self.twice_nat_common(lb=True)
5934 def test_self_twice_nat_lb_positive(self):
5935 """ Self Twice NAT44 local service load balancing (positive test) """
5936 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5939 def test_self_twice_nat_lb_negative(self):
5940 """ Self Twice NAT44 local service load balancing (negative test) """
5941 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5944 def test_twice_nat_interface_addr(self):
5945 """ Acquire twice NAT44 addresses from interface """
5946 flags = self.config_flags.NAT_IS_TWICE_NAT
5947 self.vapi.nat44_add_del_interface_addr(
5949 sw_if_index=self.pg3.sw_if_index,
5952 # no address in NAT pool
5953 adresses = self.vapi.nat44_address_dump()
5954 self.assertEqual(0, len(adresses))
5956 # configure interface address and check NAT address pool
5957 self.pg3.config_ip4()
5958 adresses = self.vapi.nat44_address_dump()
5959 self.assertEqual(1, len(adresses))
5960 self.assertEqual(str(adresses[0].ip_address),
5962 self.assertEqual(adresses[0].flags, flags)
5964 # remove interface address and check NAT address pool
5965 self.pg3.unconfig_ip4()
5966 adresses = self.vapi.nat44_address_dump()
5967 self.assertEqual(0, len(adresses))
5969 def test_tcp_close(self):
5970 """ Close TCP session from inside network - output feature """
5971 self.vapi.nat44_forwarding_enable_disable(enable=1)
5972 self.nat44_add_address(self.pg1.local_ip4)
5973 twice_nat_addr = '10.0.1.3'
5974 service_ip = '192.168.16.150'
5975 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5976 flags = self.config_flags.NAT_IS_INSIDE
5977 self.vapi.nat44_interface_add_del_feature(
5978 sw_if_index=self.pg0.sw_if_index,
5980 self.vapi.nat44_interface_add_del_feature(
5981 sw_if_index=self.pg0.sw_if_index,
5982 flags=flags, is_add=1)
5983 self.vapi.nat44_interface_add_del_output_feature(
5985 sw_if_index=self.pg1.sw_if_index)
5986 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5987 self.config_flags.NAT_IS_TWICE_NAT)
5988 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5992 proto=IP_PROTOS.tcp,
5994 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5995 start_sessnum = len(sessions)
5997 # SYN packet out->in
5998 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5999 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6000 TCP(sport=33898, dport=80, flags="S"))
6001 self.pg1.add_stream(p)
6002 self.pg_enable_capture(self.pg_interfaces)
6004 capture = self.pg0.get_capture(1)
6006 tcp_port = p[TCP].sport
6008 # SYN + ACK packet in->out
6009 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6010 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6011 TCP(sport=80, dport=tcp_port, flags="SA"))
6012 self.pg0.add_stream(p)
6013 self.pg_enable_capture(self.pg_interfaces)
6015 self.pg1.get_capture(1)
6017 # ACK packet out->in
6018 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6019 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6020 TCP(sport=33898, dport=80, flags="A"))
6021 self.pg1.add_stream(p)
6022 self.pg_enable_capture(self.pg_interfaces)
6024 self.pg0.get_capture(1)
6026 # FIN packet in -> out
6027 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6028 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6029 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6030 self.pg0.add_stream(p)
6031 self.pg_enable_capture(self.pg_interfaces)
6033 self.pg1.get_capture(1)
6035 # FIN+ACK packet out -> in
6036 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6037 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6038 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6039 self.pg1.add_stream(p)
6040 self.pg_enable_capture(self.pg_interfaces)
6042 self.pg0.get_capture(1)
6044 # ACK packet in -> out
6045 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6046 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6047 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6048 self.pg0.add_stream(p)
6049 self.pg_enable_capture(self.pg_interfaces)
6051 self.pg1.get_capture(1)
6053 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6055 self.assertEqual(len(sessions) - start_sessnum, 0)
6057 def test_tcp_session_close_in(self):
6058 """ Close TCP session from inside network """
6059 self.tcp_port_out = 10505
6060 self.nat44_add_address(self.nat_addr)
6061 flags = self.config_flags.NAT_IS_TWICE_NAT
6062 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6066 proto=IP_PROTOS.tcp,
6068 flags = self.config_flags.NAT_IS_INSIDE
6069 self.vapi.nat44_interface_add_del_feature(
6070 sw_if_index=self.pg0.sw_if_index,
6071 flags=flags, is_add=1)
6072 self.vapi.nat44_interface_add_del_feature(
6073 sw_if_index=self.pg1.sw_if_index,
6076 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6077 start_sessnum = len(sessions)
6079 self.initiate_tcp_session(self.pg0, self.pg1)
6081 # FIN packet in -> out
6082 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6083 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6084 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6085 flags="FA", seq=100, ack=300))
6086 self.pg0.add_stream(p)
6087 self.pg_enable_capture(self.pg_interfaces)
6089 self.pg1.get_capture(1)
6093 # ACK packet out -> in
6094 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6095 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6096 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6097 flags="A", seq=300, ack=101))
6100 # FIN packet out -> in
6101 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6102 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6103 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6104 flags="FA", seq=300, ack=101))
6107 self.pg1.add_stream(pkts)
6108 self.pg_enable_capture(self.pg_interfaces)
6110 self.pg0.get_capture(2)
6112 # ACK packet in -> out
6113 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6114 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6115 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6116 flags="A", seq=101, ack=301))
6117 self.pg0.add_stream(p)
6118 self.pg_enable_capture(self.pg_interfaces)
6120 self.pg1.get_capture(1)
6122 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6124 self.assertEqual(len(sessions) - start_sessnum, 0)
6126 def test_tcp_session_close_out(self):
6127 """ Close TCP session from outside network """
6128 self.tcp_port_out = 10505
6129 self.nat44_add_address(self.nat_addr)
6130 flags = self.config_flags.NAT_IS_TWICE_NAT
6131 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6135 proto=IP_PROTOS.tcp,
6137 flags = self.config_flags.NAT_IS_INSIDE
6138 self.vapi.nat44_interface_add_del_feature(
6139 sw_if_index=self.pg0.sw_if_index,
6140 flags=flags, is_add=1)
6141 self.vapi.nat44_interface_add_del_feature(
6142 sw_if_index=self.pg1.sw_if_index,
6145 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6146 start_sessnum = len(sessions)
6148 self.initiate_tcp_session(self.pg0, self.pg1)
6150 # FIN packet out -> in
6151 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6152 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6153 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6154 flags="FA", seq=100, ack=300))
6155 self.pg1.add_stream(p)
6156 self.pg_enable_capture(self.pg_interfaces)
6158 self.pg0.get_capture(1)
6160 # FIN+ACK packet in -> out
6161 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6162 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6163 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6164 flags="FA", seq=300, ack=101))
6166 self.pg0.add_stream(p)
6167 self.pg_enable_capture(self.pg_interfaces)
6169 self.pg1.get_capture(1)
6171 # ACK packet out -> in
6172 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6173 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6174 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6175 flags="A", seq=101, ack=301))
6176 self.pg1.add_stream(p)
6177 self.pg_enable_capture(self.pg_interfaces)
6179 self.pg0.get_capture(1)
6181 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6183 self.assertEqual(len(sessions) - start_sessnum, 0)
6185 def test_tcp_session_close_simultaneous(self):
6186 """ Close TCP session from inside network """
6187 self.tcp_port_out = 10505
6188 self.nat44_add_address(self.nat_addr)
6189 flags = self.config_flags.NAT_IS_TWICE_NAT
6190 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6194 proto=IP_PROTOS.tcp,
6196 flags = self.config_flags.NAT_IS_INSIDE
6197 self.vapi.nat44_interface_add_del_feature(
6198 sw_if_index=self.pg0.sw_if_index,
6199 flags=flags, is_add=1)
6200 self.vapi.nat44_interface_add_del_feature(
6201 sw_if_index=self.pg1.sw_if_index,
6204 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
6205 start_sessnum = len(sessions)
6207 self.initiate_tcp_session(self.pg0, self.pg1)
6209 # FIN packet in -> out
6210 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6211 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6212 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6213 flags="FA", seq=100, ack=300))
6214 self.pg0.add_stream(p)
6215 self.pg_enable_capture(self.pg_interfaces)
6217 self.pg1.get_capture(1)
6219 # FIN packet out -> in
6220 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6221 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6222 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6223 flags="FA", seq=300, ack=100))
6224 self.pg1.add_stream(p)
6225 self.pg_enable_capture(self.pg_interfaces)
6227 self.pg0.get_capture(1)
6229 # ACK packet in -> out
6230 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6231 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6232 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6233 flags="A", seq=101, ack=301))
6234 self.pg0.add_stream(p)
6235 self.pg_enable_capture(self.pg_interfaces)
6237 self.pg1.get_capture(1)
6239 # ACK packet out -> in
6240 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6241 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6242 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6243 flags="A", seq=301, ack=101))
6244 self.pg1.add_stream(p)
6245 self.pg_enable_capture(self.pg_interfaces)
6247 self.pg0.get_capture(1)
6249 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
6251 self.assertEqual(len(sessions) - start_sessnum, 0)
6253 def test_one_armed_nat44_static(self):
6254 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6255 remote_host = self.pg4.remote_hosts[0]
6256 local_host = self.pg4.remote_hosts[1]
6261 self.vapi.nat44_forwarding_enable_disable(enable=1)
6262 self.nat44_add_address(self.nat_addr, twice_nat=1)
6263 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6264 self.config_flags.NAT_IS_TWICE_NAT)
6265 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6266 local_port, external_port,
6267 proto=IP_PROTOS.tcp, flags=flags)
6268 flags = self.config_flags.NAT_IS_INSIDE
6269 self.vapi.nat44_interface_add_del_feature(
6270 sw_if_index=self.pg4.sw_if_index,
6272 self.vapi.nat44_interface_add_del_feature(
6273 sw_if_index=self.pg4.sw_if_index,
6274 flags=flags, is_add=1)
6276 # from client to service
6277 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6278 IP(src=remote_host.ip4, dst=self.nat_addr) /
6279 TCP(sport=12345, dport=external_port))
6280 self.pg4.add_stream(p)
6281 self.pg_enable_capture(self.pg_interfaces)
6283 capture = self.pg4.get_capture(1)
6288 self.assertEqual(ip.dst, local_host.ip4)
6289 self.assertEqual(ip.src, self.nat_addr)
6290 self.assertEqual(tcp.dport, local_port)
6291 self.assertNotEqual(tcp.sport, 12345)
6292 eh_port_in = tcp.sport
6293 self.assert_packet_checksums_valid(p)
6295 self.logger.error(ppp("Unexpected or invalid packet:", p))
6298 # from service back to client
6299 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6300 IP(src=local_host.ip4, dst=self.nat_addr) /
6301 TCP(sport=local_port, dport=eh_port_in))
6302 self.pg4.add_stream(p)
6303 self.pg_enable_capture(self.pg_interfaces)
6305 capture = self.pg4.get_capture(1)
6310 self.assertEqual(ip.src, self.nat_addr)
6311 self.assertEqual(ip.dst, remote_host.ip4)
6312 self.assertEqual(tcp.sport, external_port)
6313 self.assertEqual(tcp.dport, 12345)
6314 self.assert_packet_checksums_valid(p)
6316 self.logger.error(ppp("Unexpected or invalid packet:", p))
6319 def test_static_with_port_out2(self):
6320 """ 1:1 NAPT asymmetrical rule """
6325 self.vapi.nat44_forwarding_enable_disable(enable=1)
6326 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6327 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6328 local_port, external_port,
6329 proto=IP_PROTOS.tcp, flags=flags)
6330 flags = self.config_flags.NAT_IS_INSIDE
6331 self.vapi.nat44_interface_add_del_feature(
6332 sw_if_index=self.pg0.sw_if_index,
6333 flags=flags, is_add=1)
6334 self.vapi.nat44_interface_add_del_feature(
6335 sw_if_index=self.pg1.sw_if_index,
6338 # from client to service
6339 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6340 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6341 TCP(sport=12345, dport=external_port))
6342 self.pg1.add_stream(p)
6343 self.pg_enable_capture(self.pg_interfaces)
6345 capture = self.pg0.get_capture(1)
6350 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6351 self.assertEqual(tcp.dport, local_port)
6352 self.assert_packet_checksums_valid(p)
6354 self.logger.error(ppp("Unexpected or invalid packet:", p))
6358 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6359 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6360 ICMP(type=11) / capture[0][IP])
6361 self.pg0.add_stream(p)
6362 self.pg_enable_capture(self.pg_interfaces)
6364 capture = self.pg1.get_capture(1)
6367 self.assertEqual(p[IP].src, self.nat_addr)
6369 self.assertEqual(inner.dst, self.nat_addr)
6370 self.assertEqual(inner[TCPerror].dport, external_port)
6372 self.logger.error(ppp("Unexpected or invalid packet:", p))
6375 # from service back to client
6376 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6377 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6378 TCP(sport=local_port, dport=12345))
6379 self.pg0.add_stream(p)
6380 self.pg_enable_capture(self.pg_interfaces)
6382 capture = self.pg1.get_capture(1)
6387 self.assertEqual(ip.src, self.nat_addr)
6388 self.assertEqual(tcp.sport, external_port)
6389 self.assert_packet_checksums_valid(p)
6391 self.logger.error(ppp("Unexpected or invalid packet:", p))
6395 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6396 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6397 ICMP(type=11) / capture[0][IP])
6398 self.pg1.add_stream(p)
6399 self.pg_enable_capture(self.pg_interfaces)
6401 capture = self.pg0.get_capture(1)
6404 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6406 self.assertEqual(inner.src, self.pg0.remote_ip4)
6407 self.assertEqual(inner[TCPerror].sport, local_port)
6409 self.logger.error(ppp("Unexpected or invalid packet:", p))
6412 # from client to server (no translation)
6413 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6414 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6415 TCP(sport=12346, dport=local_port))
6416 self.pg1.add_stream(p)
6417 self.pg_enable_capture(self.pg_interfaces)
6419 capture = self.pg0.get_capture(1)
6424 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6425 self.assertEqual(tcp.dport, local_port)
6426 self.assert_packet_checksums_valid(p)
6428 self.logger.error(ppp("Unexpected or invalid packet:", p))
6431 # from service back to client (no translation)
6432 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6433 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6434 TCP(sport=local_port, dport=12346))
6435 self.pg0.add_stream(p)
6436 self.pg_enable_capture(self.pg_interfaces)
6438 capture = self.pg1.get_capture(1)
6443 self.assertEqual(ip.src, self.pg0.remote_ip4)
6444 self.assertEqual(tcp.sport, local_port)
6445 self.assert_packet_checksums_valid(p)
6447 self.logger.error(ppp("Unexpected or invalid packet:", p))
6450 def test_output_feature(self):
6451 """ NAT44 interface output feature (in2out postrouting) """
6452 self.vapi.nat44_forwarding_enable_disable(enable=1)
6453 self.nat44_add_address(self.nat_addr)
6454 self.vapi.nat44_interface_add_del_feature(
6455 sw_if_index=self.pg0.sw_if_index,
6457 self.vapi.nat44_interface_add_del_output_feature(
6459 sw_if_index=self.pg1.sw_if_index)
6462 pkts = self.create_stream_in(self.pg0, self.pg1)
6463 self.pg0.add_stream(pkts)
6464 self.pg_enable_capture(self.pg_interfaces)
6466 capture = self.pg1.get_capture(len(pkts))
6467 self.verify_capture_out(capture)
6470 pkts = self.create_stream_out(self.pg1)
6471 self.pg1.add_stream(pkts)
6472 self.pg_enable_capture(self.pg_interfaces)
6474 capture = self.pg0.get_capture(len(pkts))
6475 self.verify_capture_in(capture, self.pg0)
6477 def test_multiple_vrf(self):
6478 """ Multiple VRF setup """
6479 external_addr = '1.2.3.4'
6484 self.vapi.nat44_forwarding_enable_disable(enable=1)
6485 self.nat44_add_address(self.nat_addr)
6486 flags = self.config_flags.NAT_IS_INSIDE
6487 self.vapi.nat44_interface_add_del_feature(
6488 sw_if_index=self.pg0.sw_if_index,
6490 self.vapi.nat44_interface_add_del_feature(
6491 sw_if_index=self.pg0.sw_if_index,
6492 flags=flags, is_add=1)
6493 self.vapi.nat44_interface_add_del_output_feature(
6495 sw_if_index=self.pg1.sw_if_index)
6496 self.vapi.nat44_interface_add_del_feature(
6497 sw_if_index=self.pg5.sw_if_index,
6499 self.vapi.nat44_interface_add_del_feature(
6500 sw_if_index=self.pg5.sw_if_index,
6501 flags=flags, is_add=1)
6502 self.vapi.nat44_interface_add_del_feature(
6503 sw_if_index=self.pg6.sw_if_index,
6505 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6506 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6507 local_port, external_port, vrf_id=1,
6508 proto=IP_PROTOS.tcp, flags=flags)
6509 self.nat44_add_static_mapping(
6510 self.pg0.remote_ip4,
6511 external_sw_if_index=self.pg0.sw_if_index,
6512 local_port=local_port,
6514 external_port=external_port,
6515 proto=IP_PROTOS.tcp,
6519 # from client to service (both VRF1)
6520 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6521 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6522 TCP(sport=12345, dport=external_port))
6523 self.pg6.add_stream(p)
6524 self.pg_enable_capture(self.pg_interfaces)
6526 capture = self.pg5.get_capture(1)
6531 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6532 self.assertEqual(tcp.dport, local_port)
6533 self.assert_packet_checksums_valid(p)
6535 self.logger.error(ppp("Unexpected or invalid packet:", p))
6538 # from service back to client (both VRF1)
6539 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6540 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6541 TCP(sport=local_port, dport=12345))
6542 self.pg5.add_stream(p)
6543 self.pg_enable_capture(self.pg_interfaces)
6545 capture = self.pg6.get_capture(1)
6550 self.assertEqual(ip.src, external_addr)
6551 self.assertEqual(tcp.sport, external_port)
6552 self.assert_packet_checksums_valid(p)
6554 self.logger.error(ppp("Unexpected or invalid packet:", p))
6557 # dynamic NAT from VRF1 to VRF0 (output-feature)
6558 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6559 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6560 TCP(sport=2345, dport=22))
6561 self.pg5.add_stream(p)
6562 self.pg_enable_capture(self.pg_interfaces)
6564 capture = self.pg1.get_capture(1)
6569 self.assertEqual(ip.src, self.nat_addr)
6570 self.assertNotEqual(tcp.sport, 2345)
6571 self.assert_packet_checksums_valid(p)
6574 self.logger.error(ppp("Unexpected or invalid packet:", p))
6577 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6578 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6579 TCP(sport=22, dport=port))
6580 self.pg1.add_stream(p)
6581 self.pg_enable_capture(self.pg_interfaces)
6583 capture = self.pg5.get_capture(1)
6588 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6589 self.assertEqual(tcp.dport, 2345)
6590 self.assert_packet_checksums_valid(p)
6592 self.logger.error(ppp("Unexpected or invalid packet:", p))
6595 # from client VRF1 to service VRF0
6596 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6597 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6598 TCP(sport=12346, dport=external_port))
6599 self.pg6.add_stream(p)
6600 self.pg_enable_capture(self.pg_interfaces)
6602 capture = self.pg0.get_capture(1)
6607 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6608 self.assertEqual(tcp.dport, local_port)
6609 self.assert_packet_checksums_valid(p)
6611 self.logger.error(ppp("Unexpected or invalid packet:", p))
6614 # from service VRF0 back to client VRF1
6615 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6616 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6617 TCP(sport=local_port, dport=12346))
6618 self.pg0.add_stream(p)
6619 self.pg_enable_capture(self.pg_interfaces)
6621 capture = self.pg6.get_capture(1)
6626 self.assertEqual(ip.src, self.pg0.local_ip4)
6627 self.assertEqual(tcp.sport, external_port)
6628 self.assert_packet_checksums_valid(p)
6630 self.logger.error(ppp("Unexpected or invalid packet:", p))
6633 # from client VRF0 to service VRF1
6634 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6635 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6636 TCP(sport=12347, dport=external_port))
6637 self.pg0.add_stream(p)
6638 self.pg_enable_capture(self.pg_interfaces)
6640 capture = self.pg5.get_capture(1)
6645 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6646 self.assertEqual(tcp.dport, local_port)
6647 self.assert_packet_checksums_valid(p)
6649 self.logger.error(ppp("Unexpected or invalid packet:", p))
6652 # from service VRF1 back to client VRF0
6653 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6654 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6655 TCP(sport=local_port, dport=12347))
6656 self.pg5.add_stream(p)
6657 self.pg_enable_capture(self.pg_interfaces)
6659 capture = self.pg0.get_capture(1)
6664 self.assertEqual(ip.src, external_addr)
6665 self.assertEqual(tcp.sport, external_port)
6666 self.assert_packet_checksums_valid(p)
6668 self.logger.error(ppp("Unexpected or invalid packet:", p))
6671 # from client to server (both VRF1, no translation)
6672 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6673 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6674 TCP(sport=12348, dport=local_port))
6675 self.pg6.add_stream(p)
6676 self.pg_enable_capture(self.pg_interfaces)
6678 capture = self.pg5.get_capture(1)
6683 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6684 self.assertEqual(tcp.dport, local_port)
6685 self.assert_packet_checksums_valid(p)
6687 self.logger.error(ppp("Unexpected or invalid packet:", p))
6690 # from server back to client (both VRF1, no translation)
6691 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6692 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6693 TCP(sport=local_port, dport=12348))
6694 self.pg5.add_stream(p)
6695 self.pg_enable_capture(self.pg_interfaces)
6697 capture = self.pg6.get_capture(1)
6702 self.assertEqual(ip.src, self.pg5.remote_ip4)
6703 self.assertEqual(tcp.sport, local_port)
6704 self.assert_packet_checksums_valid(p)
6706 self.logger.error(ppp("Unexpected or invalid packet:", p))
6709 # from client VRF1 to server VRF0 (no translation)
6710 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6711 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6712 TCP(sport=local_port, dport=12349))
6713 self.pg0.add_stream(p)
6714 self.pg_enable_capture(self.pg_interfaces)
6716 capture = self.pg6.get_capture(1)
6721 self.assertEqual(ip.src, self.pg0.remote_ip4)
6722 self.assertEqual(tcp.sport, local_port)
6723 self.assert_packet_checksums_valid(p)
6725 self.logger.error(ppp("Unexpected or invalid packet:", p))
6728 # from server VRF0 back to client VRF1 (no translation)
6729 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6730 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6731 TCP(sport=local_port, dport=12349))
6732 self.pg0.add_stream(p)
6733 self.pg_enable_capture(self.pg_interfaces)
6735 capture = self.pg6.get_capture(1)
6740 self.assertEqual(ip.src, self.pg0.remote_ip4)
6741 self.assertEqual(tcp.sport, local_port)
6742 self.assert_packet_checksums_valid(p)
6744 self.logger.error(ppp("Unexpected or invalid packet:", p))
6747 # from client VRF0 to server VRF1 (no translation)
6748 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6749 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6750 TCP(sport=12344, dport=local_port))
6751 self.pg0.add_stream(p)
6752 self.pg_enable_capture(self.pg_interfaces)
6754 capture = self.pg5.get_capture(1)
6759 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6760 self.assertEqual(tcp.dport, local_port)
6761 self.assert_packet_checksums_valid(p)
6763 self.logger.error(ppp("Unexpected or invalid packet:", p))
6766 # from server VRF1 back to client VRF0 (no translation)
6767 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6768 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6769 TCP(sport=local_port, dport=12344))
6770 self.pg5.add_stream(p)
6771 self.pg_enable_capture(self.pg_interfaces)
6773 capture = self.pg0.get_capture(1)
6778 self.assertEqual(ip.src, self.pg5.remote_ip4)
6779 self.assertEqual(tcp.sport, local_port)
6780 self.assert_packet_checksums_valid(p)
6782 self.logger.error(ppp("Unexpected or invalid packet:", p))
6785 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6786 def test_session_timeout(self):
6787 """ NAT44 session timeouts """
6788 self.nat44_add_address(self.nat_addr)
6789 flags = self.config_flags.NAT_IS_INSIDE
6790 self.vapi.nat44_interface_add_del_feature(
6791 sw_if_index=self.pg0.sw_if_index,
6792 flags=flags, is_add=1)
6793 self.vapi.nat44_interface_add_del_feature(
6794 sw_if_index=self.pg1.sw_if_index,
6796 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6797 tcp_transitory=240, icmp=5)
6801 for i in range(0, max_sessions):
6802 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6803 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6804 IP(src=src, dst=self.pg1.remote_ip4) /
6805 ICMP(id=1025, type='echo-request'))
6807 self.pg0.add_stream(pkts)
6808 self.pg_enable_capture(self.pg_interfaces)
6810 self.pg1.get_capture(max_sessions)
6815 for i in range(0, max_sessions):
6816 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6817 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6818 IP(src=src, dst=self.pg1.remote_ip4) /
6819 ICMP(id=1026, type='echo-request'))
6821 self.pg0.add_stream(pkts)
6822 self.pg_enable_capture(self.pg_interfaces)
6824 self.pg1.get_capture(max_sessions)
6827 users = self.vapi.nat44_user_dump()
6829 nsessions = nsessions + user.nsessions
6830 self.assertLess(nsessions, 2 * max_sessions)
6832 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6833 def test_session_rst_timeout(self):
6834 """ NAT44 session RST timeouts """
6835 self.nat44_add_address(self.nat_addr)
6836 flags = self.config_flags.NAT_IS_INSIDE
6837 self.vapi.nat44_interface_add_del_feature(
6838 sw_if_index=self.pg0.sw_if_index,
6839 flags=flags, is_add=1)
6840 self.vapi.nat44_interface_add_del_feature(
6841 sw_if_index=self.pg1.sw_if_index,
6843 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6844 tcp_transitory=5, icmp=60)
6846 self.initiate_tcp_session(self.pg0, self.pg1)
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, dport=self.tcp_external_port,
6851 self.pg0.add_stream(p)
6852 self.pg_enable_capture(self.pg_interfaces)
6854 self.pg1.get_capture(1)
6858 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6859 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6860 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6862 self.pg0.add_stream(p)
6863 self.pg_enable_capture(self.pg_interfaces)
6865 self.pg1.get_capture(1)
6868 users = self.vapi.nat44_user_dump()
6869 self.assertEqual(len(users), 1)
6870 self.assertEqual(str(users[0].ip_address),
6871 self.pg0.remote_ip4)
6872 self.assertEqual(users[0].nsessions, 1)
6874 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6875 def test_session_limit_per_user(self):
6876 """ Maximum sessions per user limit """
6877 self.nat44_add_address(self.nat_addr)
6878 flags = self.config_flags.NAT_IS_INSIDE
6879 self.vapi.nat44_interface_add_del_feature(
6880 sw_if_index=self.pg0.sw_if_index,
6881 flags=flags, is_add=1)
6882 self.vapi.nat44_interface_add_del_feature(
6883 sw_if_index=self.pg1.sw_if_index,
6885 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6886 src_address=self.pg2.local_ip4n,
6888 template_interval=10)
6889 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6890 tcp_transitory=240, icmp=60)
6892 # get maximum number of translations per user
6893 nat44_config = self.vapi.nat_show_config()
6896 for port in range(0, nat44_config.max_translations_per_user):
6897 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6898 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6899 UDP(sport=1025 + port, dport=1025 + port))
6902 self.pg0.add_stream(pkts)
6903 self.pg_enable_capture(self.pg_interfaces)
6905 capture = self.pg1.get_capture(len(pkts))
6907 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6908 src_port=self.ipfix_src_port,
6911 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6912 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6913 UDP(sport=3001, dport=3002))
6914 self.pg0.add_stream(p)
6915 self.pg_enable_capture(self.pg_interfaces)
6917 capture = self.pg1.assert_nothing_captured()
6919 # verify IPFIX logging
6920 self.vapi.ipfix_flush()
6922 capture = self.pg2.get_capture(10)
6923 ipfix = IPFIXDecoder()
6924 # first load template
6926 self.assertTrue(p.haslayer(IPFIX))
6927 if p.haslayer(Template):
6928 ipfix.add_template(p.getlayer(Template))
6929 # verify events in data set
6931 if p.haslayer(Data):
6932 data = ipfix.decode_data_set(p.getlayer(Set))
6933 self.verify_ipfix_max_entries_per_user(
6935 nat44_config.max_translations_per_user,
6936 self.pg0.remote_ip4n)
6939 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6940 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6941 UDP(sport=3001, dport=3002))
6942 self.pg0.add_stream(p)
6943 self.pg_enable_capture(self.pg_interfaces)
6945 self.pg1.get_capture(1)
6947 def test_syslog_sess(self):
6948 """ Test syslog session creation and deletion """
6949 self.vapi.syslog_set_filter(
6950 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6951 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
6952 self.nat44_add_address(self.nat_addr)
6953 flags = self.config_flags.NAT_IS_INSIDE
6954 self.vapi.nat44_interface_add_del_feature(
6955 sw_if_index=self.pg0.sw_if_index,
6956 flags=flags, is_add=1)
6957 self.vapi.nat44_interface_add_del_feature(
6958 sw_if_index=self.pg1.sw_if_index,
6961 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6962 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6963 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6964 self.pg0.add_stream(p)
6965 self.pg_enable_capture(self.pg_interfaces)
6967 capture = self.pg1.get_capture(1)
6968 self.tcp_port_out = capture[0][TCP].sport
6969 capture = self.pg2.get_capture(1)
6970 self.verify_syslog_sess(capture[0][Raw].load)
6972 self.pg_enable_capture(self.pg_interfaces)
6974 self.nat44_add_address(self.nat_addr, is_add=0)
6975 capture = self.pg2.get_capture(1)
6976 self.verify_syslog_sess(capture[0][Raw].load, False)
6979 super(TestNAT44EndpointDependent, self).tearDown()
6980 if not self.vpp_dead:
6982 self.vapi.cli("clear logging")
6984 def show_commands_at_teardown(self):
6985 self.logger.info(self.vapi.cli("show nat44 addresses"))
6986 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6987 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6988 self.logger.info(self.vapi.cli("show nat44 interface address"))
6989 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6990 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6991 self.logger.info(self.vapi.cli("show nat timeouts"))
6994 class TestNAT44Out2InDPO(MethodHolder):
6995 """ NAT44 Test Cases using out2in DPO """
6998 def setUpConstants(cls):
6999 super(TestNAT44Out2InDPO, cls).setUpConstants()
7000 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7003 def setUpClass(cls):
7004 super(TestNAT44Out2InDPO, cls).setUpClass()
7005 cls.vapi.cli("set log class nat level debug")
7008 cls.tcp_port_in = 6303
7009 cls.tcp_port_out = 6303
7010 cls.udp_port_in = 6304
7011 cls.udp_port_out = 6304
7012 cls.icmp_id_in = 6305
7013 cls.icmp_id_out = 6305
7014 cls.nat_addr = '10.0.0.3'
7015 cls.dst_ip4 = '192.168.70.1'
7017 cls.create_pg_interfaces(range(2))
7020 cls.pg0.config_ip4()
7021 cls.pg0.resolve_arp()
7024 cls.pg1.config_ip6()
7025 cls.pg1.resolve_ndp()
7027 r1 = VppIpRoute(cls, "::", 0,
7028 [VppRoutePath(cls.pg1.remote_ip6,
7029 cls.pg1.sw_if_index)],
7034 super(TestNAT44Out2InDPO, cls).tearDownClass()
7038 def tearDownClass(cls):
7039 super(TestNAT44Out2InDPO, cls).tearDownClass()
7041 def configure_xlat(self):
7042 self.dst_ip6_pfx = '1:2:3::'
7043 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7045 self.dst_ip6_pfx_len = 96
7046 self.src_ip6_pfx = '4:5:6::'
7047 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7049 self.src_ip6_pfx_len = 96
7050 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7051 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7052 '\x00\x00\x00\x00', 0)
7054 @unittest.skip('Temporary disabled')
7055 def test_464xlat_ce(self):
7056 """ Test 464XLAT CE with NAT44 """
7058 nat_config = self.vapi.nat_show_config()
7059 self.assertEqual(1, nat_config.out2in_dpo)
7061 self.configure_xlat()
7063 flags = self.config_flags.NAT_IS_INSIDE
7064 self.vapi.nat44_interface_add_del_feature(
7065 sw_if_index=self.pg0.sw_if_index,
7066 flags=flags, is_add=1)
7067 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7068 last_ip_address=self.nat_addr_n,
7069 vrf_id=0xFFFFFFFF, is_add=1)
7071 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7072 self.dst_ip6_pfx_len)
7073 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7074 self.src_ip6_pfx_len)
7077 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7078 self.pg0.add_stream(pkts)
7079 self.pg_enable_capture(self.pg_interfaces)
7081 capture = self.pg1.get_capture(len(pkts))
7082 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7085 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7087 self.pg1.add_stream(pkts)
7088 self.pg_enable_capture(self.pg_interfaces)
7090 capture = self.pg0.get_capture(len(pkts))
7091 self.verify_capture_in(capture, self.pg0)
7093 self.vapi.nat44_interface_add_del_feature(
7094 sw_if_index=self.pg0.sw_if_index,
7096 self.vapi.nat44_add_del_address_range(
7097 first_ip_address=self.nat_addr_n,
7098 last_ip_address=self.nat_addr_n,
7101 @unittest.skip('Temporary disabled')
7102 def test_464xlat_ce_no_nat(self):
7103 """ Test 464XLAT CE without NAT44 """
7105 self.configure_xlat()
7107 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7108 self.dst_ip6_pfx_len)
7109 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7110 self.src_ip6_pfx_len)
7112 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7113 self.pg0.add_stream(pkts)
7114 self.pg_enable_capture(self.pg_interfaces)
7116 capture = self.pg1.get_capture(len(pkts))
7117 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7118 nat_ip=out_dst_ip6, same_port=True)
7120 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7121 self.pg1.add_stream(pkts)
7122 self.pg_enable_capture(self.pg_interfaces)
7124 capture = self.pg0.get_capture(len(pkts))
7125 self.verify_capture_in(capture, self.pg0)
7128 class TestDeterministicNAT(MethodHolder):
7129 """ Deterministic NAT Test Cases """
7132 def setUpConstants(cls):
7133 super(TestDeterministicNAT, cls).setUpConstants()
7134 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7137 def setUpClass(cls):
7138 super(TestDeterministicNAT, cls).setUpClass()
7139 cls.vapi.cli("set log class nat level debug")
7142 cls.tcp_port_in = 6303
7143 cls.tcp_external_port = 6303
7144 cls.udp_port_in = 6304
7145 cls.udp_external_port = 6304
7146 cls.icmp_id_in = 6305
7147 cls.nat_addr = '10.0.0.3'
7149 cls.create_pg_interfaces(range(3))
7150 cls.interfaces = list(cls.pg_interfaces)
7152 for i in cls.interfaces:
7157 cls.pg0.generate_remote_hosts(2)
7158 cls.pg0.configure_ipv4_neighbors()
7161 super(TestDeterministicNAT, cls).tearDownClass()
7165 def tearDownClass(cls):
7166 super(TestDeterministicNAT, cls).tearDownClass()
7168 def create_stream_in(self, in_if, out_if, ttl=64):
7170 Create packet stream for inside network
7172 :param in_if: Inside interface
7173 :param out_if: Outside interface
7174 :param ttl: TTL of generated packets
7178 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7179 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7180 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7184 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7185 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7186 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7190 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7191 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7192 ICMP(id=self.icmp_id_in, type='echo-request'))
7197 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7199 Create packet stream for outside network
7201 :param out_if: Outside interface
7202 :param dst_ip: Destination IP address (Default use global NAT address)
7203 :param ttl: TTL of generated packets
7206 dst_ip = self.nat_addr
7209 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7210 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7211 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7215 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7216 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7217 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7221 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7222 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7223 ICMP(id=self.icmp_external_id, type='echo-reply'))
7228 def verify_capture_out(self, capture, nat_ip=None):
7230 Verify captured packets on outside network
7232 :param capture: Captured packets
7233 :param nat_ip: Translated IP address (Default use global NAT address)
7234 :param same_port: Source port number is not translated (Default False)
7237 nat_ip = self.nat_addr
7238 for packet in capture:
7240 self.assertEqual(packet[IP].src, nat_ip)
7241 if packet.haslayer(TCP):
7242 self.tcp_port_out = packet[TCP].sport
7243 elif packet.haslayer(UDP):
7244 self.udp_port_out = packet[UDP].sport
7246 self.icmp_external_id = packet[ICMP].id
7248 self.logger.error(ppp("Unexpected or invalid packet "
7249 "(outside network):", packet))
7252 def test_deterministic_mode(self):
7253 """ NAT plugin run deterministic mode """
7254 in_addr = '172.16.255.0'
7255 out_addr = '172.17.255.50'
7256 in_addr_t = '172.16.255.20'
7260 nat_config = self.vapi.nat_show_config()
7261 self.assertEqual(1, nat_config.deterministic)
7263 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7264 in_plen=in_plen, out_addr=out_addr,
7267 rep1 = self.vapi.nat_det_forward(in_addr_t)
7268 self.assertEqual(str(rep1.out_addr), out_addr)
7269 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7271 self.assertEqual(str(rep2.in_addr), in_addr_t)
7273 deterministic_mappings = self.vapi.nat_det_map_dump()
7274 self.assertEqual(len(deterministic_mappings), 1)
7275 dsm = deterministic_mappings[0]
7276 self.assertEqual(in_addr, str(dsm.in_addr))
7277 self.assertEqual(in_plen, dsm.in_plen)
7278 self.assertEqual(out_addr, str(dsm.out_addr))
7279 self.assertEqual(out_plen, dsm.out_plen)
7281 self.clear_nat_det()
7282 deterministic_mappings = self.vapi.nat_det_map_dump()
7283 self.assertEqual(len(deterministic_mappings), 0)
7285 def test_set_timeouts(self):
7286 """ Set deterministic NAT timeouts """
7287 timeouts_before = self.vapi.nat_get_timeouts()
7289 self.vapi.nat_set_timeouts(
7290 udp=timeouts_before.udp + 10,
7291 tcp_established=timeouts_before.tcp_established + 10,
7292 tcp_transitory=timeouts_before.tcp_transitory + 10,
7293 icmp=timeouts_before.icmp + 10)
7295 timeouts_after = self.vapi.nat_get_timeouts()
7297 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7298 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7299 self.assertNotEqual(timeouts_before.tcp_established,
7300 timeouts_after.tcp_established)
7301 self.assertNotEqual(timeouts_before.tcp_transitory,
7302 timeouts_after.tcp_transitory)
7304 def test_det_in(self):
7305 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7307 nat_ip = "10.0.0.10"
7309 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7311 out_addr=socket.inet_aton(nat_ip),
7314 flags = self.config_flags.NAT_IS_INSIDE
7315 self.vapi.nat44_interface_add_del_feature(
7316 sw_if_index=self.pg0.sw_if_index,
7317 flags=flags, is_add=1)
7318 self.vapi.nat44_interface_add_del_feature(
7319 sw_if_index=self.pg1.sw_if_index,
7323 pkts = self.create_stream_in(self.pg0, self.pg1)
7324 self.pg0.add_stream(pkts)
7325 self.pg_enable_capture(self.pg_interfaces)
7327 capture = self.pg1.get_capture(len(pkts))
7328 self.verify_capture_out(capture, nat_ip)
7331 pkts = self.create_stream_out(self.pg1, nat_ip)
7332 self.pg1.add_stream(pkts)
7333 self.pg_enable_capture(self.pg_interfaces)
7335 capture = self.pg0.get_capture(len(pkts))
7336 self.verify_capture_in(capture, self.pg0)
7339 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
7340 self.assertEqual(len(sessions), 3)
7344 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7345 self.assertEqual(s.in_port, self.tcp_port_in)
7346 self.assertEqual(s.out_port, self.tcp_port_out)
7347 self.assertEqual(s.ext_port, self.tcp_external_port)
7351 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7352 self.assertEqual(s.in_port, self.udp_port_in)
7353 self.assertEqual(s.out_port, self.udp_port_out)
7354 self.assertEqual(s.ext_port, self.udp_external_port)
7358 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7359 self.assertEqual(s.in_port, self.icmp_id_in)
7360 self.assertEqual(s.out_port, self.icmp_external_id)
7362 def test_multiple_users(self):
7363 """ Deterministic NAT multiple users """
7365 nat_ip = "10.0.0.10"
7367 external_port = 6303
7369 host0 = self.pg0.remote_hosts[0]
7370 host1 = self.pg0.remote_hosts[1]
7372 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4n, in_plen=24,
7373 out_addr=socket.inet_aton(nat_ip),
7375 flags = self.config_flags.NAT_IS_INSIDE
7376 self.vapi.nat44_interface_add_del_feature(
7377 sw_if_index=self.pg0.sw_if_index,
7378 flags=flags, is_add=1)
7379 self.vapi.nat44_interface_add_del_feature(
7380 sw_if_index=self.pg1.sw_if_index,
7384 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7385 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7386 TCP(sport=port_in, dport=external_port))
7387 self.pg0.add_stream(p)
7388 self.pg_enable_capture(self.pg_interfaces)
7390 capture = self.pg1.get_capture(1)
7395 self.assertEqual(ip.src, nat_ip)
7396 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7397 self.assertEqual(tcp.dport, external_port)
7398 port_out0 = tcp.sport
7400 self.logger.error(ppp("Unexpected or invalid packet:", p))
7404 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7405 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7406 TCP(sport=port_in, dport=external_port))
7407 self.pg0.add_stream(p)
7408 self.pg_enable_capture(self.pg_interfaces)
7410 capture = self.pg1.get_capture(1)
7415 self.assertEqual(ip.src, nat_ip)
7416 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7417 self.assertEqual(tcp.dport, external_port)
7418 port_out1 = tcp.sport
7420 self.logger.error(ppp("Unexpected or invalid packet:", p))
7423 dms = self.vapi.nat_det_map_dump()
7424 self.assertEqual(1, len(dms))
7425 self.assertEqual(2, dms[0].ses_num)
7428 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7429 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7430 TCP(sport=external_port, dport=port_out0))
7431 self.pg1.add_stream(p)
7432 self.pg_enable_capture(self.pg_interfaces)
7434 capture = self.pg0.get_capture(1)
7439 self.assertEqual(ip.src, self.pg1.remote_ip4)
7440 self.assertEqual(ip.dst, host0.ip4)
7441 self.assertEqual(tcp.dport, port_in)
7442 self.assertEqual(tcp.sport, external_port)
7444 self.logger.error(ppp("Unexpected or invalid packet:", p))
7448 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7449 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7450 TCP(sport=external_port, dport=port_out1))
7451 self.pg1.add_stream(p)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 capture = self.pg0.get_capture(1)
7459 self.assertEqual(ip.src, self.pg1.remote_ip4)
7460 self.assertEqual(ip.dst, host1.ip4)
7461 self.assertEqual(tcp.dport, port_in)
7462 self.assertEqual(tcp.sport, external_port)
7464 self.logger.error(ppp("Unexpected or invalid packet", p))
7467 # session close api test
7468 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7470 self.pg1.remote_ip4n,
7472 dms = self.vapi.nat_det_map_dump()
7473 self.assertEqual(dms[0].ses_num, 1)
7475 self.vapi.nat_det_close_session_in(host0.ip4n,
7477 self.pg1.remote_ip4n,
7479 dms = self.vapi.nat_det_map_dump()
7480 self.assertEqual(dms[0].ses_num, 0)
7482 def test_tcp_session_close_detection_in(self):
7483 """ Deterministic NAT TCP session close from inside network """
7484 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7486 out_addr=socket.inet_aton(self.nat_addr),
7488 flags = self.config_flags.NAT_IS_INSIDE
7489 self.vapi.nat44_interface_add_del_feature(
7490 sw_if_index=self.pg0.sw_if_index,
7491 flags=flags, is_add=1)
7492 self.vapi.nat44_interface_add_del_feature(
7493 sw_if_index=self.pg1.sw_if_index,
7496 self.initiate_tcp_session(self.pg0, self.pg1)
7498 # close the session from inside
7500 # FIN packet in -> out
7501 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7502 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7503 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7505 self.pg0.add_stream(p)
7506 self.pg_enable_capture(self.pg_interfaces)
7508 self.pg1.get_capture(1)
7512 # ACK packet out -> in
7513 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7514 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7515 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7519 # FIN packet out -> in
7520 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7521 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7522 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7526 self.pg1.add_stream(pkts)
7527 self.pg_enable_capture(self.pg_interfaces)
7529 self.pg0.get_capture(2)
7531 # ACK packet in -> out
7532 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7533 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7534 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7536 self.pg0.add_stream(p)
7537 self.pg_enable_capture(self.pg_interfaces)
7539 self.pg1.get_capture(1)
7541 # Check if deterministic NAT44 closed the session
7542 dms = self.vapi.nat_det_map_dump()
7543 self.assertEqual(0, dms[0].ses_num)
7545 self.logger.error("TCP session termination failed")
7548 def test_tcp_session_close_detection_out(self):
7549 """ Deterministic NAT TCP session close from outside network """
7550 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7552 out_addr=socket.inet_aton(self.nat_addr),
7554 flags = self.config_flags.NAT_IS_INSIDE
7555 self.vapi.nat44_interface_add_del_feature(
7556 sw_if_index=self.pg0.sw_if_index,
7557 flags=flags, is_add=1)
7558 self.vapi.nat44_interface_add_del_feature(
7559 sw_if_index=self.pg1.sw_if_index,
7562 self.initiate_tcp_session(self.pg0, self.pg1)
7564 # close the session from outside
7566 # FIN packet out -> in
7567 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7568 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7569 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7571 self.pg1.add_stream(p)
7572 self.pg_enable_capture(self.pg_interfaces)
7574 self.pg0.get_capture(1)
7578 # ACK packet in -> out
7579 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7580 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7581 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7585 # ACK packet in -> out
7586 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7587 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7588 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7592 self.pg0.add_stream(pkts)
7593 self.pg_enable_capture(self.pg_interfaces)
7595 self.pg1.get_capture(2)
7597 # ACK packet out -> in
7598 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7599 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7600 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7602 self.pg1.add_stream(p)
7603 self.pg_enable_capture(self.pg_interfaces)
7605 self.pg0.get_capture(1)
7607 # Check if deterministic NAT44 closed the session
7608 dms = self.vapi.nat_det_map_dump()
7609 self.assertEqual(0, dms[0].ses_num)
7611 self.logger.error("TCP session termination failed")
7614 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7615 def test_session_timeout(self):
7616 """ Deterministic NAT session timeouts """
7617 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7619 out_addr=socket.inet_aton(self.nat_addr),
7621 flags = self.config_flags.NAT_IS_INSIDE
7622 self.vapi.nat44_interface_add_del_feature(
7623 sw_if_index=self.pg0.sw_if_index,
7624 flags=flags, is_add=1)
7625 self.vapi.nat44_interface_add_del_feature(
7626 sw_if_index=self.pg1.sw_if_index,
7629 self.initiate_tcp_session(self.pg0, self.pg1)
7630 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7632 pkts = self.create_stream_in(self.pg0, self.pg1)
7633 self.pg0.add_stream(pkts)
7634 self.pg_enable_capture(self.pg_interfaces)
7636 capture = self.pg1.get_capture(len(pkts))
7639 dms = self.vapi.nat_det_map_dump()
7640 self.assertEqual(0, dms[0].ses_num)
7642 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7643 def test_session_limit_per_user(self):
7644 """ Deterministic NAT maximum sessions per user limit """
7645 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4n,
7647 out_addr=socket.inet_aton(self.nat_addr),
7649 flags = self.config_flags.NAT_IS_INSIDE
7650 self.vapi.nat44_interface_add_del_feature(
7651 sw_if_index=self.pg0.sw_if_index,
7652 flags=flags, is_add=1)
7653 self.vapi.nat44_interface_add_del_feature(
7654 sw_if_index=self.pg1.sw_if_index,
7656 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
7657 src_address=self.pg2.local_ip4n,
7659 template_interval=10)
7660 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7664 for port in range(1025, 2025):
7665 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7666 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7667 UDP(sport=port, dport=port))
7670 self.pg0.add_stream(pkts)
7671 self.pg_enable_capture(self.pg_interfaces)
7673 capture = self.pg1.get_capture(len(pkts))
7675 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7676 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7677 UDP(sport=3001, dport=3002))
7678 self.pg0.add_stream(p)
7679 self.pg_enable_capture(self.pg_interfaces)
7681 capture = self.pg1.assert_nothing_captured()
7683 # verify ICMP error packet
7684 capture = self.pg0.get_capture(1)
7686 self.assertTrue(p.haslayer(ICMP))
7688 self.assertEqual(icmp.type, 3)
7689 self.assertEqual(icmp.code, 1)
7690 self.assertTrue(icmp.haslayer(IPerror))
7691 inner_ip = icmp[IPerror]
7692 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7693 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7695 dms = self.vapi.nat_det_map_dump()
7697 self.assertEqual(1000, dms[0].ses_num)
7699 # verify IPFIX logging
7700 self.vapi.ipfix_flush()
7702 capture = self.pg2.get_capture(2)
7703 ipfix = IPFIXDecoder()
7704 # first load template
7706 self.assertTrue(p.haslayer(IPFIX))
7707 if p.haslayer(Template):
7708 ipfix.add_template(p.getlayer(Template))
7709 # verify events in data set
7711 if p.haslayer(Data):
7712 data = ipfix.decode_data_set(p.getlayer(Set))
7713 self.verify_ipfix_max_entries_per_user(data,
7715 self.pg0.remote_ip4n)
7717 def clear_nat_det(self):
7719 Clear deterministic NAT configuration.
7721 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7723 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7724 tcp_transitory=240, icmp=60)
7725 deterministic_mappings = self.vapi.nat_det_map_dump()
7726 for dsm in deterministic_mappings:
7727 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7728 in_plen=dsm.in_plen,
7729 out_addr=dsm.out_addr,
7730 out_plen=dsm.out_plen)
7732 interfaces = self.vapi.nat44_interface_dump()
7733 for intf in interfaces:
7734 self.vapi.nat44_interface_add_del_feature(
7735 sw_if_index=intf.sw_if_index,
7739 super(TestDeterministicNAT, self).tearDown()
7740 if not self.vpp_dead:
7741 self.clear_nat_det()
7743 def show_commands_at_teardown(self):
7744 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7745 self.logger.info(self.vapi.cli("show nat timeouts"))
7747 self.vapi.cli("show nat44 deterministic mappings"))
7749 self.vapi.cli("show nat44 deterministic sessions"))
7752 class TestNAT64(MethodHolder):
7753 """ NAT64 Test Cases """
7756 def setUpConstants(cls):
7757 super(TestNAT64, cls).setUpConstants()
7758 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7759 "nat64 st hash buckets 256", "}"])
7762 def setUpClass(cls):
7763 super(TestNAT64, cls).setUpClass()
7766 cls.tcp_port_in = 6303
7767 cls.tcp_port_out = 6303
7768 cls.udp_port_in = 6304
7769 cls.udp_port_out = 6304
7770 cls.icmp_id_in = 6305
7771 cls.icmp_id_out = 6305
7772 cls.tcp_external_port = 80
7773 cls.nat_addr = '10.0.0.3'
7774 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7776 cls.vrf1_nat_addr = '10.0.10.3'
7777 cls.ipfix_src_port = 4739
7778 cls.ipfix_domain_id = 1
7780 cls.create_pg_interfaces(range(6))
7781 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7782 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7783 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7785 cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
7786 table_id=cls.vrf1_id)
7788 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7790 cls.pg0.generate_remote_hosts(2)
7792 for i in cls.ip6_interfaces:
7795 i.configure_ipv6_neighbors()
7797 for i in cls.ip4_interfaces:
7803 cls.pg3.config_ip4()
7804 cls.pg3.resolve_arp()
7805 cls.pg3.config_ip6()
7806 cls.pg3.configure_ipv6_neighbors()
7809 cls.pg5.config_ip6()
7812 super(TestNAT64, cls).tearDownClass()
7816 def tearDownClass(cls):
7817 super(TestNAT64, cls).tearDownClass()
7819 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7820 """ NAT64 inside interface handles Neighbor Advertisement """
7822 flags = self.config_flags.NAT_IS_INSIDE
7823 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7824 sw_if_index=self.pg5.sw_if_index)
7827 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7828 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7829 ICMPv6EchoRequest())
7831 self.pg5.add_stream(pkts)
7832 self.pg_enable_capture(self.pg_interfaces)
7835 # Wait for Neighbor Solicitation
7836 capture = self.pg5.get_capture(len(pkts))
7839 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7840 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7841 tgt = packet[ICMPv6ND_NS].tgt
7843 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7846 # Send Neighbor Advertisement
7847 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7848 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7849 ICMPv6ND_NA(tgt=tgt) /
7850 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7852 self.pg5.add_stream(pkts)
7853 self.pg_enable_capture(self.pg_interfaces)
7856 # Try to send ping again
7858 self.pg5.add_stream(pkts)
7859 self.pg_enable_capture(self.pg_interfaces)
7862 # Wait for ping reply
7863 capture = self.pg5.get_capture(len(pkts))
7866 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7867 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7868 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7870 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7873 def test_pool(self):
7874 """ Add/delete address to NAT64 pool """
7875 nat_addr = '1.2.3.4'
7877 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7879 vrf_id=0xFFFFFFFF, is_add=1)
7881 addresses = self.vapi.nat64_pool_addr_dump()
7882 self.assertEqual(len(addresses), 1)
7883 self.assertEqual(str(addresses[0].address), nat_addr)
7885 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7887 vrf_id=0xFFFFFFFF, is_add=0)
7889 addresses = self.vapi.nat64_pool_addr_dump()
7890 self.assertEqual(len(addresses), 0)
7892 def test_interface(self):
7893 """ Enable/disable NAT64 feature on the interface """
7894 flags = self.config_flags.NAT_IS_INSIDE
7895 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7896 sw_if_index=self.pg0.sw_if_index)
7897 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7898 sw_if_index=self.pg1.sw_if_index)
7900 interfaces = self.vapi.nat64_interface_dump()
7901 self.assertEqual(len(interfaces), 2)
7904 for intf in interfaces:
7905 if intf.sw_if_index == self.pg0.sw_if_index:
7906 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7908 elif intf.sw_if_index == self.pg1.sw_if_index:
7909 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7911 self.assertTrue(pg0_found)
7912 self.assertTrue(pg1_found)
7914 features = self.vapi.cli("show interface features pg0")
7915 self.assertIn('nat64-in2out', features)
7916 features = self.vapi.cli("show interface features pg1")
7917 self.assertIn('nat64-out2in', features)
7919 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7920 sw_if_index=self.pg0.sw_if_index)
7921 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7922 sw_if_index=self.pg1.sw_if_index)
7924 interfaces = self.vapi.nat64_interface_dump()
7925 self.assertEqual(len(interfaces), 0)
7927 def test_static_bib(self):
7928 """ Add/delete static BIB entry """
7929 in_addr = '2001:db8:85a3::8a2e:370:7334'
7930 out_addr = '10.1.1.3'
7933 proto = IP_PROTOS.tcp
7935 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7936 i_port=in_port, o_port=out_port,
7937 proto=proto, vrf_id=0, is_add=1)
7938 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7941 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7943 self.assertEqual(str(bibe.i_addr), in_addr)
7944 self.assertEqual(str(bibe.o_addr), out_addr)
7945 self.assertEqual(bibe.i_port, in_port)
7946 self.assertEqual(bibe.o_port, out_port)
7947 self.assertEqual(static_bib_num, 1)
7948 bibs = self.statistics.get_counter('/nat64/total-bibs')
7949 self.assertEqual(bibs[0][0], 1)
7951 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7952 i_port=in_port, o_port=out_port,
7953 proto=proto, vrf_id=0, is_add=0)
7954 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7957 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7959 self.assertEqual(static_bib_num, 0)
7960 bibs = self.statistics.get_counter('/nat64/total-bibs')
7961 self.assertEqual(bibs[0][0], 0)
7963 def test_set_timeouts(self):
7964 """ Set NAT64 timeouts """
7965 # verify default values
7966 timeouts = self.vapi.nat_get_timeouts()
7967 self.assertEqual(timeouts.udp, 300)
7968 self.assertEqual(timeouts.icmp, 60)
7969 self.assertEqual(timeouts.tcp_transitory, 240)
7970 self.assertEqual(timeouts.tcp_established, 7440)
7972 # set and verify custom values
7973 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7974 tcp_transitory=250, icmp=30)
7975 timeouts = self.vapi.nat_get_timeouts()
7976 self.assertEqual(timeouts.udp, 200)
7977 self.assertEqual(timeouts.icmp, 30)
7978 self.assertEqual(timeouts.tcp_transitory, 250)
7979 self.assertEqual(timeouts.tcp_established, 7450)
7981 def test_dynamic(self):
7982 """ NAT64 dynamic translation test """
7983 self.tcp_port_in = 6303
7984 self.udp_port_in = 6304
7985 self.icmp_id_in = 6305
7987 ses_num_start = self.nat64_get_ses_num()
7989 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7990 end_addr=self.nat_addr,
7993 flags = self.config_flags.NAT_IS_INSIDE
7994 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7995 sw_if_index=self.pg0.sw_if_index)
7996 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7997 sw_if_index=self.pg1.sw_if_index)
8000 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8001 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8002 icmpn = self.statistics.get_err_counter(
8003 '/err/nat64-in2out/ICMP packets')
8004 totaln = self.statistics.get_err_counter(
8005 '/err/nat64-in2out/good in2out packets processed')
8007 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8008 self.pg0.add_stream(pkts)
8009 self.pg_enable_capture(self.pg_interfaces)
8011 capture = self.pg1.get_capture(len(pkts))
8012 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8013 dst_ip=self.pg1.remote_ip4)
8015 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8016 self.assertEqual(err - tcpn, 1)
8017 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8018 self.assertEqual(err - udpn, 1)
8019 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8020 self.assertEqual(err - icmpn, 1)
8021 err = self.statistics.get_err_counter(
8022 '/err/nat64-in2out/good in2out packets processed')
8023 self.assertEqual(err - totaln, 3)
8026 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8027 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8028 icmpn = self.statistics.get_err_counter(
8029 '/err/nat64-out2in/ICMP packets')
8030 totaln = self.statistics.get_err_counter(
8031 '/err/nat64-out2in/good out2in packets processed')
8033 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8034 self.pg1.add_stream(pkts)
8035 self.pg_enable_capture(self.pg_interfaces)
8037 capture = self.pg0.get_capture(len(pkts))
8038 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8039 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8041 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8042 self.assertEqual(err - tcpn, 2)
8043 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8044 self.assertEqual(err - udpn, 1)
8045 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8046 self.assertEqual(err - icmpn, 1)
8047 err = self.statistics.get_err_counter(
8048 '/err/nat64-out2in/good out2in packets processed')
8049 self.assertEqual(err - totaln, 4)
8051 bibs = self.statistics.get_counter('/nat64/total-bibs')
8052 self.assertEqual(bibs[0][0], 3)
8053 sessions = self.statistics.get_counter('/nat64/total-sessions')
8054 self.assertEqual(sessions[0][0], 3)
8057 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8058 self.pg0.add_stream(pkts)
8059 self.pg_enable_capture(self.pg_interfaces)
8061 capture = self.pg1.get_capture(len(pkts))
8062 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8063 dst_ip=self.pg1.remote_ip4)
8066 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8067 self.pg1.add_stream(pkts)
8068 self.pg_enable_capture(self.pg_interfaces)
8070 capture = self.pg0.get_capture(len(pkts))
8071 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8073 ses_num_end = self.nat64_get_ses_num()
8075 self.assertEqual(ses_num_end - ses_num_start, 3)
8077 # tenant with specific VRF
8078 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8079 end_addr=self.vrf1_nat_addr,
8080 vrf_id=self.vrf1_id, is_add=1)
8081 flags = self.config_flags.NAT_IS_INSIDE
8082 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8083 sw_if_index=self.pg2.sw_if_index)
8085 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8086 self.pg2.add_stream(pkts)
8087 self.pg_enable_capture(self.pg_interfaces)
8089 capture = self.pg1.get_capture(len(pkts))
8090 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8091 dst_ip=self.pg1.remote_ip4)
8093 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8094 self.pg1.add_stream(pkts)
8095 self.pg_enable_capture(self.pg_interfaces)
8097 capture = self.pg2.get_capture(len(pkts))
8098 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8100 def test_static(self):
8101 """ NAT64 static translation test """
8102 self.tcp_port_in = 60303
8103 self.udp_port_in = 60304
8104 self.icmp_id_in = 60305
8105 self.tcp_port_out = 60303
8106 self.udp_port_out = 60304
8107 self.icmp_id_out = 60305
8109 ses_num_start = self.nat64_get_ses_num()
8111 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8112 end_addr=self.nat_addr,
8115 flags = self.config_flags.NAT_IS_INSIDE
8116 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8117 sw_if_index=self.pg0.sw_if_index)
8118 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8119 sw_if_index=self.pg1.sw_if_index)
8121 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8122 o_addr=self.nat_addr,
8123 i_port=self.tcp_port_in,
8124 o_port=self.tcp_port_out,
8125 proto=IP_PROTOS.tcp, vrf_id=0,
8127 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8128 o_addr=self.nat_addr,
8129 i_port=self.udp_port_in,
8130 o_port=self.udp_port_out,
8131 proto=IP_PROTOS.udp, vrf_id=0,
8133 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8134 o_addr=self.nat_addr,
8135 i_port=self.icmp_id_in,
8136 o_port=self.icmp_id_out,
8137 proto=IP_PROTOS.icmp, vrf_id=0,
8141 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8142 self.pg0.add_stream(pkts)
8143 self.pg_enable_capture(self.pg_interfaces)
8145 capture = self.pg1.get_capture(len(pkts))
8146 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8147 dst_ip=self.pg1.remote_ip4, same_port=True)
8150 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8151 self.pg1.add_stream(pkts)
8152 self.pg_enable_capture(self.pg_interfaces)
8154 capture = self.pg0.get_capture(len(pkts))
8155 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8156 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8158 ses_num_end = self.nat64_get_ses_num()
8160 self.assertEqual(ses_num_end - ses_num_start, 3)
8162 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8163 def test_session_timeout(self):
8164 """ NAT64 session timeout """
8165 self.icmp_id_in = 1234
8166 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8167 end_addr=self.nat_addr,
8170 flags = self.config_flags.NAT_IS_INSIDE
8171 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8172 sw_if_index=self.pg0.sw_if_index)
8173 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8174 sw_if_index=self.pg1.sw_if_index)
8175 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8179 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8180 self.pg0.add_stream(pkts)
8181 self.pg_enable_capture(self.pg_interfaces)
8183 capture = self.pg1.get_capture(len(pkts))
8185 ses_num_before_timeout = self.nat64_get_ses_num()
8189 # ICMP and TCP session after timeout
8190 ses_num_after_timeout = self.nat64_get_ses_num()
8191 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8193 def test_icmp_error(self):
8194 """ NAT64 ICMP Error message translation """
8195 self.tcp_port_in = 6303
8196 self.udp_port_in = 6304
8197 self.icmp_id_in = 6305
8199 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8200 end_addr=self.nat_addr,
8203 flags = self.config_flags.NAT_IS_INSIDE
8204 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8205 sw_if_index=self.pg0.sw_if_index)
8206 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8207 sw_if_index=self.pg1.sw_if_index)
8209 # send some packets to create sessions
8210 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8211 self.pg0.add_stream(pkts)
8212 self.pg_enable_capture(self.pg_interfaces)
8214 capture_ip4 = self.pg1.get_capture(len(pkts))
8215 self.verify_capture_out(capture_ip4,
8216 nat_ip=self.nat_addr,
8217 dst_ip=self.pg1.remote_ip4)
8219 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8220 self.pg1.add_stream(pkts)
8221 self.pg_enable_capture(self.pg_interfaces)
8223 capture_ip6 = self.pg0.get_capture(len(pkts))
8224 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8225 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8226 self.pg0.remote_ip6)
8229 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8230 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8231 ICMPv6DestUnreach(code=1) /
8232 packet[IPv6] for packet in capture_ip6]
8233 self.pg0.add_stream(pkts)
8234 self.pg_enable_capture(self.pg_interfaces)
8236 capture = self.pg1.get_capture(len(pkts))
8237 for packet in capture:
8239 self.assertEqual(packet[IP].src, self.nat_addr)
8240 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8241 self.assertEqual(packet[ICMP].type, 3)
8242 self.assertEqual(packet[ICMP].code, 13)
8243 inner = packet[IPerror]
8244 self.assertEqual(inner.src, self.pg1.remote_ip4)
8245 self.assertEqual(inner.dst, self.nat_addr)
8246 self.assert_packet_checksums_valid(packet)
8247 if inner.haslayer(TCPerror):
8248 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8249 elif inner.haslayer(UDPerror):
8250 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8252 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8254 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8258 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8259 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8260 ICMP(type=3, code=13) /
8261 packet[IP] for packet in capture_ip4]
8262 self.pg1.add_stream(pkts)
8263 self.pg_enable_capture(self.pg_interfaces)
8265 capture = self.pg0.get_capture(len(pkts))
8266 for packet in capture:
8268 self.assertEqual(packet[IPv6].src, ip.src)
8269 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8270 icmp = packet[ICMPv6DestUnreach]
8271 self.assertEqual(icmp.code, 1)
8272 inner = icmp[IPerror6]
8273 self.assertEqual(inner.src, self.pg0.remote_ip6)
8274 self.assertEqual(inner.dst, ip.src)
8275 self.assert_icmpv6_checksum_valid(packet)
8276 if inner.haslayer(TCPerror):
8277 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8278 elif inner.haslayer(UDPerror):
8279 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8281 self.assertEqual(inner[ICMPv6EchoRequest].id,
8284 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8287 def test_hairpinning(self):
8288 """ NAT64 hairpinning """
8290 client = self.pg0.remote_hosts[0]
8291 server = self.pg0.remote_hosts[1]
8292 server_tcp_in_port = 22
8293 server_tcp_out_port = 4022
8294 server_udp_in_port = 23
8295 server_udp_out_port = 4023
8296 client_tcp_in_port = 1234
8297 client_udp_in_port = 1235
8298 client_tcp_out_port = 0
8299 client_udp_out_port = 0
8300 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8301 nat_addr_ip6 = ip.src
8303 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8304 end_addr=self.nat_addr,
8307 flags = self.config_flags.NAT_IS_INSIDE
8308 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8309 sw_if_index=self.pg0.sw_if_index)
8310 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8311 sw_if_index=self.pg1.sw_if_index)
8313 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8314 o_addr=self.nat_addr,
8315 i_port=server_tcp_in_port,
8316 o_port=server_tcp_out_port,
8317 proto=IP_PROTOS.tcp, vrf_id=0,
8319 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8320 o_addr=self.nat_addr,
8321 i_port=server_udp_in_port,
8322 o_port=server_udp_out_port,
8323 proto=IP_PROTOS.udp, vrf_id=0,
8328 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8329 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8330 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8332 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8333 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8334 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8336 self.pg0.add_stream(pkts)
8337 self.pg_enable_capture(self.pg_interfaces)
8339 capture = self.pg0.get_capture(len(pkts))
8340 for packet in capture:
8342 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8343 self.assertEqual(packet[IPv6].dst, server.ip6)
8344 self.assert_packet_checksums_valid(packet)
8345 if packet.haslayer(TCP):
8346 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8347 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8348 client_tcp_out_port = packet[TCP].sport
8350 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8351 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8352 client_udp_out_port = packet[UDP].sport
8354 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8359 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8360 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8361 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8363 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8364 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8365 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8367 self.pg0.add_stream(pkts)
8368 self.pg_enable_capture(self.pg_interfaces)
8370 capture = self.pg0.get_capture(len(pkts))
8371 for packet in capture:
8373 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8374 self.assertEqual(packet[IPv6].dst, client.ip6)
8375 self.assert_packet_checksums_valid(packet)
8376 if packet.haslayer(TCP):
8377 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8378 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8380 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8381 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8383 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8388 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8389 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8390 ICMPv6DestUnreach(code=1) /
8391 packet[IPv6] for packet in capture]
8392 self.pg0.add_stream(pkts)
8393 self.pg_enable_capture(self.pg_interfaces)
8395 capture = self.pg0.get_capture(len(pkts))
8396 for packet in capture:
8398 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8399 self.assertEqual(packet[IPv6].dst, server.ip6)
8400 icmp = packet[ICMPv6DestUnreach]
8401 self.assertEqual(icmp.code, 1)
8402 inner = icmp[IPerror6]
8403 self.assertEqual(inner.src, server.ip6)
8404 self.assertEqual(inner.dst, nat_addr_ip6)
8405 self.assert_packet_checksums_valid(packet)
8406 if inner.haslayer(TCPerror):
8407 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8408 self.assertEqual(inner[TCPerror].dport,
8409 client_tcp_out_port)
8411 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8412 self.assertEqual(inner[UDPerror].dport,
8413 client_udp_out_port)
8415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8418 def test_prefix(self):
8419 """ NAT64 Network-Specific Prefix """
8421 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8422 end_addr=self.nat_addr,
8425 flags = self.config_flags.NAT_IS_INSIDE
8426 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8427 sw_if_index=self.pg0.sw_if_index)
8428 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8429 sw_if_index=self.pg1.sw_if_index)
8430 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8431 end_addr=self.vrf1_nat_addr,
8432 vrf_id=self.vrf1_id, is_add=1)
8433 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8434 sw_if_index=self.pg2.sw_if_index)
8437 global_pref64 = "2001:db8::"
8438 global_pref64_len = 32
8439 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8440 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8443 prefix = self.vapi.nat64_prefix_dump()
8444 self.assertEqual(len(prefix), 1)
8445 self.assertEqual(prefix[0].prefix,
8446 IPv6Network(unicode(global_pref64_str)))
8447 self.assertEqual(prefix[0].vrf_id, 0)
8449 # Add tenant specific prefix
8450 vrf1_pref64 = "2001:db8:122:300::"
8451 vrf1_pref64_len = 56
8452 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8453 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8454 vrf_id=self.vrf1_id, is_add=1)
8456 prefix = self.vapi.nat64_prefix_dump()
8457 self.assertEqual(len(prefix), 2)
8460 pkts = self.create_stream_in_ip6(self.pg0,
8463 plen=global_pref64_len)
8464 self.pg0.add_stream(pkts)
8465 self.pg_enable_capture(self.pg_interfaces)
8467 capture = self.pg1.get_capture(len(pkts))
8468 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8469 dst_ip=self.pg1.remote_ip4)
8471 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8472 self.pg1.add_stream(pkts)
8473 self.pg_enable_capture(self.pg_interfaces)
8475 capture = self.pg0.get_capture(len(pkts))
8476 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8479 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8481 # Tenant specific prefix
8482 pkts = self.create_stream_in_ip6(self.pg2,
8485 plen=vrf1_pref64_len)
8486 self.pg2.add_stream(pkts)
8487 self.pg_enable_capture(self.pg_interfaces)
8489 capture = self.pg1.get_capture(len(pkts))
8490 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8491 dst_ip=self.pg1.remote_ip4)
8493 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8494 self.pg1.add_stream(pkts)
8495 self.pg_enable_capture(self.pg_interfaces)
8497 capture = self.pg2.get_capture(len(pkts))
8498 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8501 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8503 def test_unknown_proto(self):
8504 """ NAT64 translate packet with unknown protocol """
8506 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8507 end_addr=self.nat_addr,
8510 flags = self.config_flags.NAT_IS_INSIDE
8511 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8512 sw_if_index=self.pg0.sw_if_index)
8513 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8514 sw_if_index=self.pg1.sw_if_index)
8515 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8518 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8519 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8520 TCP(sport=self.tcp_port_in, dport=20))
8521 self.pg0.add_stream(p)
8522 self.pg_enable_capture(self.pg_interfaces)
8524 p = self.pg1.get_capture(1)
8526 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8527 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8529 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8530 TCP(sport=1234, dport=1234))
8531 self.pg0.add_stream(p)
8532 self.pg_enable_capture(self.pg_interfaces)
8534 p = self.pg1.get_capture(1)
8537 self.assertEqual(packet[IP].src, self.nat_addr)
8538 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8539 self.assertEqual(packet.haslayer(GRE), 1)
8540 self.assert_packet_checksums_valid(packet)
8542 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8546 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8547 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8549 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8550 TCP(sport=1234, dport=1234))
8551 self.pg1.add_stream(p)
8552 self.pg_enable_capture(self.pg_interfaces)
8554 p = self.pg0.get_capture(1)
8557 self.assertEqual(packet[IPv6].src, remote_ip6)
8558 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8559 self.assertEqual(packet[IPv6].nh, 47)
8561 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8564 def test_hairpinning_unknown_proto(self):
8565 """ NAT64 translate packet with unknown protocol - hairpinning """
8567 client = self.pg0.remote_hosts[0]
8568 server = self.pg0.remote_hosts[1]
8569 server_tcp_in_port = 22
8570 server_tcp_out_port = 4022
8571 client_tcp_in_port = 1234
8572 client_tcp_out_port = 1235
8573 server_nat_ip = "10.0.0.100"
8574 client_nat_ip = "10.0.0.110"
8575 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8576 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8578 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8579 end_addr=client_nat_ip,
8582 flags = self.config_flags.NAT_IS_INSIDE
8583 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8584 sw_if_index=self.pg0.sw_if_index)
8585 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8586 sw_if_index=self.pg1.sw_if_index)
8588 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8589 o_addr=server_nat_ip,
8590 i_port=server_tcp_in_port,
8591 o_port=server_tcp_out_port,
8592 proto=IP_PROTOS.tcp, vrf_id=0,
8595 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8596 o_addr=server_nat_ip, i_port=0,
8598 proto=IP_PROTOS.gre, vrf_id=0,
8601 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8602 o_addr=client_nat_ip,
8603 i_port=client_tcp_in_port,
8604 o_port=client_tcp_out_port,
8605 proto=IP_PROTOS.tcp, vrf_id=0,
8609 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8610 IPv6(src=client.ip6, dst=server_nat_ip6) /
8611 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8612 self.pg0.add_stream(p)
8613 self.pg_enable_capture(self.pg_interfaces)
8615 p = self.pg0.get_capture(1)
8617 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8618 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8620 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8621 TCP(sport=1234, dport=1234))
8622 self.pg0.add_stream(p)
8623 self.pg_enable_capture(self.pg_interfaces)
8625 p = self.pg0.get_capture(1)
8628 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8629 self.assertEqual(packet[IPv6].dst, server.ip6)
8630 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8632 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8636 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8637 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8639 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8640 TCP(sport=1234, dport=1234))
8641 self.pg0.add_stream(p)
8642 self.pg_enable_capture(self.pg_interfaces)
8644 p = self.pg0.get_capture(1)
8647 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8648 self.assertEqual(packet[IPv6].dst, client.ip6)
8649 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8651 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8654 def test_one_armed_nat64(self):
8655 """ One armed NAT64 """
8657 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8661 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8662 end_addr=self.nat_addr,
8665 flags = self.config_flags.NAT_IS_INSIDE
8666 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8667 sw_if_index=self.pg3.sw_if_index)
8668 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8669 sw_if_index=self.pg3.sw_if_index)
8672 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8673 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8674 TCP(sport=12345, dport=80))
8675 self.pg3.add_stream(p)
8676 self.pg_enable_capture(self.pg_interfaces)
8678 capture = self.pg3.get_capture(1)
8683 self.assertEqual(ip.src, self.nat_addr)
8684 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8685 self.assertNotEqual(tcp.sport, 12345)
8686 external_port = tcp.sport
8687 self.assertEqual(tcp.dport, 80)
8688 self.assert_packet_checksums_valid(p)
8690 self.logger.error(ppp("Unexpected or invalid packet:", p))
8694 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8695 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8696 TCP(sport=80, dport=external_port))
8697 self.pg3.add_stream(p)
8698 self.pg_enable_capture(self.pg_interfaces)
8700 capture = self.pg3.get_capture(1)
8705 self.assertEqual(ip.src, remote_host_ip6)
8706 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8707 self.assertEqual(tcp.sport, 80)
8708 self.assertEqual(tcp.dport, 12345)
8709 self.assert_packet_checksums_valid(p)
8711 self.logger.error(ppp("Unexpected or invalid packet:", p))
8714 def test_frag_in_order(self):
8715 """ NAT64 translate fragments arriving in order """
8716 self.tcp_port_in = random.randint(1025, 65535)
8718 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8719 end_addr=self.nat_addr,
8722 flags = self.config_flags.NAT_IS_INSIDE
8723 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8724 sw_if_index=self.pg0.sw_if_index)
8725 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8726 sw_if_index=self.pg1.sw_if_index)
8728 reass = self.vapi.nat_reass_dump()
8729 reass_n_start = len(reass)
8733 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8734 self.tcp_port_in, 20, data)
8735 self.pg0.add_stream(pkts)
8736 self.pg_enable_capture(self.pg_interfaces)
8738 frags = self.pg1.get_capture(len(pkts))
8739 p = self.reass_frags_and_verify(frags,
8741 self.pg1.remote_ip4)
8742 self.assertEqual(p[TCP].dport, 20)
8743 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8744 self.tcp_port_out = p[TCP].sport
8745 self.assertEqual(data, p[Raw].load)
8748 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8749 pkts = self.create_stream_frag(self.pg1,
8754 self.pg1.add_stream(pkts)
8755 self.pg_enable_capture(self.pg_interfaces)
8757 frags = self.pg0.get_capture(len(pkts))
8758 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8759 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8760 self.assertEqual(p[TCP].sport, 20)
8761 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8762 self.assertEqual(data, p[Raw].load)
8764 reass = self.vapi.nat_reass_dump()
8765 reass_n_end = len(reass)
8767 self.assertEqual(reass_n_end - reass_n_start, 2)
8769 def test_reass_hairpinning(self):
8770 """ NAT64 fragments hairpinning """
8772 server = self.pg0.remote_hosts[1]
8773 server_in_port = random.randint(1025, 65535)
8774 server_out_port = random.randint(1025, 65535)
8775 client_in_port = random.randint(1025, 65535)
8776 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8777 nat_addr_ip6 = ip.src
8779 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8780 end_addr=self.nat_addr,
8783 flags = self.config_flags.NAT_IS_INSIDE
8784 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8785 sw_if_index=self.pg0.sw_if_index)
8786 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8787 sw_if_index=self.pg1.sw_if_index)
8789 # add static BIB entry for server
8790 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8791 o_addr=self.nat_addr,
8792 i_port=server_in_port,
8793 o_port=server_out_port,
8794 proto=IP_PROTOS.tcp, vrf_id=0,
8797 # send packet from host to server
8798 pkts = self.create_stream_frag_ip6(self.pg0,
8803 self.pg0.add_stream(pkts)
8804 self.pg_enable_capture(self.pg_interfaces)
8806 frags = self.pg0.get_capture(len(pkts))
8807 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8808 self.assertNotEqual(p[TCP].sport, client_in_port)
8809 self.assertEqual(p[TCP].dport, server_in_port)
8810 self.assertEqual(data, p[Raw].load)
8812 def test_frag_out_of_order(self):
8813 """ NAT64 translate fragments arriving out of order """
8814 self.tcp_port_in = random.randint(1025, 65535)
8816 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8817 end_addr=self.nat_addr,
8820 flags = self.config_flags.NAT_IS_INSIDE
8821 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8822 sw_if_index=self.pg0.sw_if_index)
8823 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8824 sw_if_index=self.pg1.sw_if_index)
8828 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8829 self.tcp_port_in, 20, data)
8831 self.pg0.add_stream(pkts)
8832 self.pg_enable_capture(self.pg_interfaces)
8834 frags = self.pg1.get_capture(len(pkts))
8835 p = self.reass_frags_and_verify(frags,
8837 self.pg1.remote_ip4)
8838 self.assertEqual(p[TCP].dport, 20)
8839 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8840 self.tcp_port_out = p[TCP].sport
8841 self.assertEqual(data, p[Raw].load)
8844 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8845 pkts = self.create_stream_frag(self.pg1,
8851 self.pg1.add_stream(pkts)
8852 self.pg_enable_capture(self.pg_interfaces)
8854 frags = self.pg0.get_capture(len(pkts))
8855 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8856 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8857 self.assertEqual(p[TCP].sport, 20)
8858 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8859 self.assertEqual(data, p[Raw].load)
8861 def test_interface_addr(self):
8862 """ Acquire NAT64 pool addresses from interface """
8863 self.vapi.nat64_add_del_interface_addr(
8865 sw_if_index=self.pg4.sw_if_index)
8867 # no address in NAT64 pool
8868 addresses = self.vapi.nat44_address_dump()
8869 self.assertEqual(0, len(addresses))
8871 # configure interface address and check NAT64 address pool
8872 self.pg4.config_ip4()
8873 addresses = self.vapi.nat64_pool_addr_dump()
8874 self.assertEqual(len(addresses), 1)
8876 self.assertEqual(str(addresses[0].address),
8879 # remove interface address and check NAT64 address pool
8880 self.pg4.unconfig_ip4()
8881 addresses = self.vapi.nat64_pool_addr_dump()
8882 self.assertEqual(0, len(addresses))
8884 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8885 def test_ipfix_max_bibs_sessions(self):
8886 """ IPFIX logging maximum session and BIB entries exceeded """
8889 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8893 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8894 end_addr=self.nat_addr,
8897 flags = self.config_flags.NAT_IS_INSIDE
8898 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8899 sw_if_index=self.pg0.sw_if_index)
8900 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8901 sw_if_index=self.pg1.sw_if_index)
8905 for i in range(0, max_bibs):
8906 src = "fd01:aa::%x" % (i)
8907 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8908 IPv6(src=src, dst=remote_host_ip6) /
8909 TCP(sport=12345, dport=80))
8911 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8912 IPv6(src=src, dst=remote_host_ip6) /
8913 TCP(sport=12345, dport=22))
8915 self.pg0.add_stream(pkts)
8916 self.pg_enable_capture(self.pg_interfaces)
8918 self.pg1.get_capture(max_sessions)
8920 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8921 src_address=self.pg3.local_ip4n,
8923 template_interval=10)
8924 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8925 src_port=self.ipfix_src_port,
8928 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8929 IPv6(src=src, dst=remote_host_ip6) /
8930 TCP(sport=12345, dport=25))
8931 self.pg0.add_stream(p)
8932 self.pg_enable_capture(self.pg_interfaces)
8934 self.pg1.assert_nothing_captured()
8936 self.vapi.ipfix_flush()
8937 capture = self.pg3.get_capture(7)
8938 ipfix = IPFIXDecoder()
8939 # first load template
8941 self.assertTrue(p.haslayer(IPFIX))
8942 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8943 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8944 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8945 self.assertEqual(p[UDP].dport, 4739)
8946 self.assertEqual(p[IPFIX].observationDomainID,
8947 self.ipfix_domain_id)
8948 if p.haslayer(Template):
8949 ipfix.add_template(p.getlayer(Template))
8950 # verify events in data set
8952 if p.haslayer(Data):
8953 data = ipfix.decode_data_set(p.getlayer(Set))
8954 self.verify_ipfix_max_sessions(data, max_sessions)
8956 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8957 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8958 TCP(sport=12345, dport=80))
8959 self.pg0.add_stream(p)
8960 self.pg_enable_capture(self.pg_interfaces)
8962 self.pg1.assert_nothing_captured()
8964 self.vapi.ipfix_flush()
8965 capture = self.pg3.get_capture(1)
8966 # verify events in data set
8968 self.assertTrue(p.haslayer(IPFIX))
8969 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8970 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8971 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8972 self.assertEqual(p[UDP].dport, 4739)
8973 self.assertEqual(p[IPFIX].observationDomainID,
8974 self.ipfix_domain_id)
8975 if p.haslayer(Data):
8976 data = ipfix.decode_data_set(p.getlayer(Set))
8977 self.verify_ipfix_max_bibs(data, max_bibs)
8979 def test_ipfix_max_frags(self):
8980 """ IPFIX logging maximum fragments pending reassembly exceeded """
8981 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8982 end_addr=self.nat_addr,
8985 flags = self.config_flags.NAT_IS_INSIDE
8986 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8987 sw_if_index=self.pg0.sw_if_index)
8988 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8989 sw_if_index=self.pg1.sw_if_index)
8990 self.vapi.nat_set_reass(timeout=2, max_reass=1024, max_frag=1,
8991 drop_frag=0, is_ip6=1)
8992 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
8993 src_address=self.pg3.local_ip4n,
8995 template_interval=10)
8996 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8997 src_port=self.ipfix_src_port,
9001 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9002 self.tcp_port_in, 20, data)
9004 self.pg0.add_stream(pkts)
9005 self.pg_enable_capture(self.pg_interfaces)
9007 self.pg1.assert_nothing_captured()
9009 self.vapi.ipfix_flush()
9010 capture = self.pg3.get_capture(9)
9011 ipfix = IPFIXDecoder()
9012 # first load template
9014 self.assertTrue(p.haslayer(IPFIX))
9015 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9016 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9017 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9018 self.assertEqual(p[UDP].dport, 4739)
9019 self.assertEqual(p[IPFIX].observationDomainID,
9020 self.ipfix_domain_id)
9021 if p.haslayer(Template):
9022 ipfix.add_template(p.getlayer(Template))
9023 # verify events in data set
9025 if p.haslayer(Data):
9026 data = ipfix.decode_data_set(p.getlayer(Set))
9027 self.verify_ipfix_max_fragments_ip6(data, 1,
9028 self.pg0.remote_ip6n)
9030 def test_ipfix_bib_ses(self):
9031 """ IPFIX logging NAT64 BIB/session create and delete events """
9032 self.tcp_port_in = random.randint(1025, 65535)
9033 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9037 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9038 end_addr=self.nat_addr,
9041 flags = self.config_flags.NAT_IS_INSIDE
9042 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9043 sw_if_index=self.pg0.sw_if_index)
9044 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9045 sw_if_index=self.pg1.sw_if_index)
9046 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
9047 src_address=self.pg3.local_ip4n,
9049 template_interval=10)
9050 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9051 src_port=self.ipfix_src_port,
9055 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9056 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9057 TCP(sport=self.tcp_port_in, dport=25))
9058 self.pg0.add_stream(p)
9059 self.pg_enable_capture(self.pg_interfaces)
9061 p = self.pg1.get_capture(1)
9062 self.tcp_port_out = p[0][TCP].sport
9063 self.vapi.ipfix_flush()
9064 capture = self.pg3.get_capture(10)
9065 ipfix = IPFIXDecoder()
9066 # first load template
9068 self.assertTrue(p.haslayer(IPFIX))
9069 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9070 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9071 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9072 self.assertEqual(p[UDP].dport, 4739)
9073 self.assertEqual(p[IPFIX].observationDomainID,
9074 self.ipfix_domain_id)
9075 if p.haslayer(Template):
9076 ipfix.add_template(p.getlayer(Template))
9077 # verify events in data set
9079 if p.haslayer(Data):
9080 data = ipfix.decode_data_set(p.getlayer(Set))
9081 if scapy.compat.orb(data[0][230]) == 10:
9082 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
9083 elif scapy.compat.orb(data[0][230]) == 6:
9084 self.verify_ipfix_nat64_ses(data,
9086 self.pg0.remote_ip6n,
9087 self.pg1.remote_ip4,
9090 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9093 self.pg_enable_capture(self.pg_interfaces)
9094 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9095 end_addr=self.nat_addr,
9098 self.vapi.ipfix_flush()
9099 capture = self.pg3.get_capture(2)
9100 # verify events in data set
9102 self.assertTrue(p.haslayer(IPFIX))
9103 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9104 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9105 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9106 self.assertEqual(p[UDP].dport, 4739)
9107 self.assertEqual(p[IPFIX].observationDomainID,
9108 self.ipfix_domain_id)
9109 if p.haslayer(Data):
9110 data = ipfix.decode_data_set(p.getlayer(Set))
9111 if scapy.compat.orb(data[0][230]) == 11:
9112 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9113 elif scapy.compat.orb(data[0][230]) == 7:
9114 self.verify_ipfix_nat64_ses(data,
9116 self.pg0.remote_ip6n,
9117 self.pg1.remote_ip4,
9120 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9122 def test_syslog_sess(self):
9123 """ Test syslog session creation and deletion """
9124 self.tcp_port_in = random.randint(1025, 65535)
9125 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9129 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9130 end_addr=self.nat_addr,
9133 flags = self.config_flags.NAT_IS_INSIDE
9134 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9135 sw_if_index=self.pg0.sw_if_index)
9136 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9137 sw_if_index=self.pg1.sw_if_index)
9138 self.vapi.syslog_set_filter(
9139 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9140 self.vapi.syslog_set_sender(self.pg3.local_ip4n, self.pg3.remote_ip4n)
9142 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9143 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9144 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9145 self.pg0.add_stream(p)
9146 self.pg_enable_capture(self.pg_interfaces)
9148 p = self.pg1.get_capture(1)
9149 self.tcp_port_out = p[0][TCP].sport
9150 capture = self.pg3.get_capture(1)
9151 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9153 self.pg_enable_capture(self.pg_interfaces)
9155 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9156 end_addr=self.nat_addr,
9159 capture = self.pg3.get_capture(1)
9160 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9162 def nat64_get_ses_num(self):
9164 Return number of active NAT64 sessions.
9166 st = self.vapi.nat64_st_dump(proto=255)
9169 def clear_nat64(self):
9171 Clear NAT64 configuration.
9173 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9174 src_port=self.ipfix_src_port,
9176 self.ipfix_src_port = 4739
9177 self.ipfix_domain_id = 1
9179 self.vapi.syslog_set_filter(
9180 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9182 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9183 tcp_transitory=240, icmp=60)
9185 interfaces = self.vapi.nat64_interface_dump()
9186 for intf in interfaces:
9187 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9188 sw_if_index=intf.sw_if_index)
9190 bib = self.vapi.nat64_bib_dump(proto=255)
9192 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9193 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9201 adresses = self.vapi.nat64_pool_addr_dump()
9202 for addr in adresses:
9203 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9204 end_addr=addr.address,
9208 prefixes = self.vapi.nat64_prefix_dump()
9209 for prefix in prefixes:
9210 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9211 vrf_id=prefix.vrf_id, is_add=0)
9213 bibs = self.statistics.get_counter('/nat64/total-bibs')
9214 self.assertEqual(bibs[0][0], 0)
9215 sessions = self.statistics.get_counter('/nat64/total-sessions')
9216 self.assertEqual(sessions[0][0], 0)
9219 super(TestNAT64, self).tearDown()
9220 if not self.vpp_dead:
9223 def show_commands_at_teardown(self):
9224 self.logger.info(self.vapi.cli("show nat64 pool"))
9225 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9226 self.logger.info(self.vapi.cli("show nat64 prefix"))
9227 self.logger.info(self.vapi.cli("show nat64 bib all"))
9228 self.logger.info(self.vapi.cli("show nat64 session table all"))
9229 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
9232 class TestDSlite(MethodHolder):
9233 """ DS-Lite Test Cases """
9236 def setUpClass(cls):
9237 super(TestDSlite, cls).setUpClass()
9240 cls.nat_addr = '10.0.0.3'
9242 cls.create_pg_interfaces(range(3))
9244 cls.pg0.config_ip4()
9245 cls.pg0.resolve_arp()
9247 cls.pg1.config_ip6()
9248 cls.pg1.generate_remote_hosts(2)
9249 cls.pg1.configure_ipv6_neighbors()
9251 cls.pg2.config_ip4()
9252 cls.pg2.resolve_arp()
9255 super(TestDSlite, cls).tearDownClass()
9259 def tearDownClass(cls):
9260 super(TestDSlite, cls).tearDownClass()
9262 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9264 message = data.decode('utf-8')
9266 message = SyslogMessage.parse(message)
9267 except ParseError as e:
9268 self.logger.error(e)
9270 self.assertEqual(message.severity, SyslogSeverity.info)
9271 self.assertEqual(message.appname, 'NAT')
9272 self.assertEqual(message.msgid, 'APMADD')
9273 sd_params = message.sd.get('napmap')
9274 self.assertTrue(sd_params is not None)
9275 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9276 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9277 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9278 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9279 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9280 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9281 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9282 self.assertTrue(sd_params.get('SSUBIX') is not None)
9283 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9285 def test_dslite(self):
9286 """ Test DS-Lite """
9287 nat_config = self.vapi.nat_show_config()
9288 self.assertEqual(0, nat_config.dslite_ce)
9290 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9291 end_addr=self.nat_addr,
9293 aftr_ip4 = '192.0.0.1'
9294 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9295 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9296 self.vapi.syslog_set_sender(self.pg2.local_ip4n, self.pg2.remote_ip4n)
9299 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9300 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9301 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9302 UDP(sport=20000, dport=10000))
9303 self.pg1.add_stream(p)
9304 self.pg_enable_capture(self.pg_interfaces)
9306 capture = self.pg0.get_capture(1)
9307 capture = capture[0]
9308 self.assertFalse(capture.haslayer(IPv6))
9309 self.assertEqual(capture[IP].src, self.nat_addr)
9310 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9311 self.assertNotEqual(capture[UDP].sport, 20000)
9312 self.assertEqual(capture[UDP].dport, 10000)
9313 self.assert_packet_checksums_valid(capture)
9314 out_port = capture[UDP].sport
9315 capture = self.pg2.get_capture(1)
9316 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9317 20000, self.nat_addr, out_port,
9318 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9320 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9321 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9322 UDP(sport=10000, dport=out_port))
9323 self.pg0.add_stream(p)
9324 self.pg_enable_capture(self.pg_interfaces)
9326 capture = self.pg1.get_capture(1)
9327 capture = capture[0]
9328 self.assertEqual(capture[IPv6].src, aftr_ip6)
9329 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9330 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9331 self.assertEqual(capture[IP].dst, '192.168.1.1')
9332 self.assertEqual(capture[UDP].sport, 10000)
9333 self.assertEqual(capture[UDP].dport, 20000)
9334 self.assert_packet_checksums_valid(capture)
9337 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9338 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9339 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9340 TCP(sport=20001, dport=10001))
9341 self.pg1.add_stream(p)
9342 self.pg_enable_capture(self.pg_interfaces)
9344 capture = self.pg0.get_capture(1)
9345 capture = capture[0]
9346 self.assertFalse(capture.haslayer(IPv6))
9347 self.assertEqual(capture[IP].src, self.nat_addr)
9348 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9349 self.assertNotEqual(capture[TCP].sport, 20001)
9350 self.assertEqual(capture[TCP].dport, 10001)
9351 self.assert_packet_checksums_valid(capture)
9352 out_port = capture[TCP].sport
9354 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9355 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9356 TCP(sport=10001, dport=out_port))
9357 self.pg0.add_stream(p)
9358 self.pg_enable_capture(self.pg_interfaces)
9360 capture = self.pg1.get_capture(1)
9361 capture = capture[0]
9362 self.assertEqual(capture[IPv6].src, aftr_ip6)
9363 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9364 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9365 self.assertEqual(capture[IP].dst, '192.168.1.1')
9366 self.assertEqual(capture[TCP].sport, 10001)
9367 self.assertEqual(capture[TCP].dport, 20001)
9368 self.assert_packet_checksums_valid(capture)
9371 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9372 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9373 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9374 ICMP(id=4000, type='echo-request'))
9375 self.pg1.add_stream(p)
9376 self.pg_enable_capture(self.pg_interfaces)
9378 capture = self.pg0.get_capture(1)
9379 capture = capture[0]
9380 self.assertFalse(capture.haslayer(IPv6))
9381 self.assertEqual(capture[IP].src, self.nat_addr)
9382 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9383 self.assertNotEqual(capture[ICMP].id, 4000)
9384 self.assert_packet_checksums_valid(capture)
9385 out_id = capture[ICMP].id
9387 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9388 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9389 ICMP(id=out_id, type='echo-reply'))
9390 self.pg0.add_stream(p)
9391 self.pg_enable_capture(self.pg_interfaces)
9393 capture = self.pg1.get_capture(1)
9394 capture = capture[0]
9395 self.assertEqual(capture[IPv6].src, aftr_ip6)
9396 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9397 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9398 self.assertEqual(capture[IP].dst, '192.168.1.1')
9399 self.assertEqual(capture[ICMP].id, 4000)
9400 self.assert_packet_checksums_valid(capture)
9402 # ping DS-Lite AFTR tunnel endpoint address
9403 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9404 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9405 ICMPv6EchoRequest())
9406 self.pg1.add_stream(p)
9407 self.pg_enable_capture(self.pg_interfaces)
9409 capture = self.pg1.get_capture(1)
9410 capture = capture[0]
9411 self.assertEqual(capture[IPv6].src, aftr_ip6)
9412 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9413 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9415 b4s = self.statistics.get_counter('/dslite/total-b4s')
9416 self.assertEqual(b4s[0][0], 2)
9417 sessions = self.statistics.get_counter('/dslite/total-sessions')
9418 self.assertEqual(sessions[0][0], 3)
9421 super(TestDSlite, self).tearDown()
9423 def show_commands_at_teardown(self):
9424 self.logger.info(self.vapi.cli("show dslite pool"))
9426 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9427 self.logger.info(self.vapi.cli("show dslite sessions"))
9430 class TestDSliteCE(MethodHolder):
9431 """ DS-Lite CE Test Cases """
9434 def setUpConstants(cls):
9435 super(TestDSliteCE, cls).setUpConstants()
9436 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9439 def setUpClass(cls):
9440 super(TestDSliteCE, cls).setUpClass()
9443 cls.create_pg_interfaces(range(2))
9445 cls.pg0.config_ip4()
9446 cls.pg0.resolve_arp()
9448 cls.pg1.config_ip6()
9449 cls.pg1.generate_remote_hosts(1)
9450 cls.pg1.configure_ipv6_neighbors()
9453 super(TestDSliteCE, cls).tearDownClass()
9457 def tearDownClass(cls):
9458 super(TestDSliteCE, cls).tearDownClass()
9460 def test_dslite_ce(self):
9461 """ Test DS-Lite CE """
9463 nat_config = self.vapi.nat_show_config()
9464 self.assertEqual(1, nat_config.dslite_ce)
9466 b4_ip4 = '192.0.0.2'
9467 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9468 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9470 aftr_ip4 = '192.0.0.1'
9471 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9472 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9473 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9475 r1 = VppIpRoute(self, aftr_ip6, 128,
9476 [VppRoutePath(self.pg1.remote_ip6,
9477 self.pg1.sw_if_index)])
9481 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9482 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9483 UDP(sport=10000, dport=20000))
9484 self.pg0.add_stream(p)
9485 self.pg_enable_capture(self.pg_interfaces)
9487 capture = self.pg1.get_capture(1)
9488 capture = capture[0]
9489 self.assertEqual(capture[IPv6].src, b4_ip6)
9490 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9491 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9492 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9493 self.assertEqual(capture[UDP].sport, 10000)
9494 self.assertEqual(capture[UDP].dport, 20000)
9495 self.assert_packet_checksums_valid(capture)
9498 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9499 IPv6(dst=b4_ip6, src=aftr_ip6) /
9500 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9501 UDP(sport=20000, dport=10000))
9502 self.pg1.add_stream(p)
9503 self.pg_enable_capture(self.pg_interfaces)
9505 capture = self.pg0.get_capture(1)
9506 capture = capture[0]
9507 self.assertFalse(capture.haslayer(IPv6))
9508 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9509 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9510 self.assertEqual(capture[UDP].sport, 20000)
9511 self.assertEqual(capture[UDP].dport, 10000)
9512 self.assert_packet_checksums_valid(capture)
9514 # ping DS-Lite B4 tunnel endpoint address
9515 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9516 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9517 ICMPv6EchoRequest())
9518 self.pg1.add_stream(p)
9519 self.pg_enable_capture(self.pg_interfaces)
9521 capture = self.pg1.get_capture(1)
9522 capture = capture[0]
9523 self.assertEqual(capture[IPv6].src, b4_ip6)
9524 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9525 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9528 super(TestDSliteCE, self).tearDown()
9530 def show_commands_at_teardown(self):
9532 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9534 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9537 class TestNAT66(MethodHolder):
9538 """ NAT66 Test Cases """
9541 def setUpClass(cls):
9542 super(TestNAT66, cls).setUpClass()
9545 cls.nat_addr = 'fd01:ff::2'
9547 cls.create_pg_interfaces(range(2))
9548 cls.interfaces = list(cls.pg_interfaces)
9550 for i in cls.interfaces:
9553 i.configure_ipv6_neighbors()
9556 super(TestNAT66, cls).tearDownClass()
9560 def tearDownClass(cls):
9561 super(TestNAT66, cls).tearDownClass()
9563 def test_static(self):
9564 """ 1:1 NAT66 test """
9565 flags = self.config_flags.NAT_IS_INSIDE
9566 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9567 sw_if_index=self.pg0.sw_if_index)
9568 self.vapi.nat66_add_del_interface(is_add=1,
9569 sw_if_index=self.pg1.sw_if_index)
9570 self.vapi.nat66_add_del_static_mapping(
9571 local_ip_address=self.pg0.remote_ip6n,
9572 external_ip_address=self.nat_addr,
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) /
9581 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9582 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9585 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9586 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9587 ICMPv6EchoRequest())
9589 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9590 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9591 GRE() / IP() / TCP())
9593 self.pg0.add_stream(pkts)
9594 self.pg_enable_capture(self.pg_interfaces)
9596 capture = self.pg1.get_capture(len(pkts))
9597 for packet in capture:
9599 self.assertEqual(packet[IPv6].src, self.nat_addr)
9600 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9601 self.assert_packet_checksums_valid(packet)
9603 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9608 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9609 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9612 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9613 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9616 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9617 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9620 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9621 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9622 GRE() / IP() / TCP())
9624 self.pg1.add_stream(pkts)
9625 self.pg_enable_capture(self.pg_interfaces)
9627 capture = self.pg0.get_capture(len(pkts))
9628 for packet in capture:
9630 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9631 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9632 self.assert_packet_checksums_valid(packet)
9634 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9637 sm = self.vapi.nat66_static_mapping_dump()
9638 self.assertEqual(len(sm), 1)
9639 self.assertEqual(sm[0].total_pkts, 8)
9641 def test_check_no_translate(self):
9642 """ NAT66 translate only when egress interface is outside interface """
9643 flags = self.config_flags.NAT_IS_INSIDE
9644 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9645 sw_if_index=self.pg0.sw_if_index)
9646 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9647 sw_if_index=self.pg1.sw_if_index)
9648 self.vapi.nat66_add_del_static_mapping(
9649 local_ip_address=self.pg0.remote_ip6n,
9650 external_ip_address=self.nat_addr,
9654 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9655 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9657 self.pg0.add_stream([p])
9658 self.pg_enable_capture(self.pg_interfaces)
9660 capture = self.pg1.get_capture(1)
9663 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9664 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9666 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9669 def clear_nat66(self):
9671 Clear NAT66 configuration.
9673 interfaces = self.vapi.nat66_interface_dump()
9674 for intf in interfaces:
9675 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9676 sw_if_index=intf.sw_if_index)
9678 static_mappings = self.vapi.nat66_static_mapping_dump()
9679 for sm in static_mappings:
9680 self.vapi.nat66_add_del_static_mapping(
9681 local_ip_address=sm.local_ip_address,
9682 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9686 super(TestNAT66, self).tearDown()
9689 def show_commands_at_teardown(self):
9690 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9691 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9694 if __name__ == '__main__':
9695 unittest.main(testRunner=VppTestRunner)