9 from framework import VppTestCase, VppTestRunner, running_extended_tests
12 from scapy.layers.inet import IP, TCP, UDP, ICMP
13 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
14 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
15 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
16 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
17 from scapy.layers.l2 import Ether, ARP, GRE
18 from scapy.data import IP_PROTOS
19 from scapy.packet import bind_layers, Raw
21 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
22 from time import sleep
23 from util import ip4_range
24 from vpp_papi import mac_pton
25 from syslog_rfc5424_parser import SyslogMessage, ParseError
26 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
27 from io import BytesIO
28 from vpp_papi import VppEnum
29 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
30 from vpp_neighbor import VppNeighbor
31 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
32 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
34 from ipaddress import IPv6Network
35 from util import ppc, ppp
36 from socket import inet_pton, AF_INET
37 from vpp_acl import AclRule, VppAcl, VppAclInterface
40 # NAT HA protocol event data
43 fields_desc = [ByteEnumField("event_type", None,
44 {1: "add", 2: "del", 3: "refresh"}),
45 ByteEnumField("protocol", None,
46 {0: "udp", 1: "tcp", 2: "icmp"}),
47 ShortField("flags", 0),
48 IPField("in_addr", None),
49 IPField("out_addr", None),
50 ShortField("in_port", None),
51 ShortField("out_port", None),
52 IPField("eh_addr", None),
53 IPField("ehn_addr", None),
54 ShortField("eh_port", None),
55 ShortField("ehn_port", None),
56 IntField("fib_index", None),
57 IntField("total_pkts", 0),
58 LongField("total_bytes", 0)]
60 def extract_padding(self, s):
64 # NAT HA protocol header
65 class HANATStateSync(Packet):
66 name = "HA NAT state sync"
67 fields_desc = [XByteField("version", 1),
68 FlagsField("flags", 0, 8, ['ACK']),
69 FieldLenField("count", None, count_of="events"),
70 IntField("sequence_number", 1),
71 IntField("thread_index", 0),
72 PacketListField("events", [], Event,
73 count_from=lambda pkt: pkt.count)]
76 class MethodHolder(VppTestCase):
77 """ NAT create capture and verify method holder """
80 def config_flags(self):
81 return VppEnum.vl_api_nat_config_flags_t
84 def SYSLOG_SEVERITY(self):
85 return VppEnum.vl_api_syslog_severity_t
87 def clear_nat44(self):
89 Clear NAT44 configuration.
91 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
92 if self.pg7.has_ip4_config:
93 self.pg7.unconfig_ip4()
95 self.vapi.nat44_forwarding_enable_disable(enable=0)
97 interfaces = self.vapi.nat44_interface_addr_dump()
98 for intf in interfaces:
99 self.vapi.nat44_add_del_interface_addr(
101 sw_if_index=intf.sw_if_index,
104 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
105 src_port=self.ipfix_src_port,
107 self.ipfix_src_port = 4739
108 self.ipfix_domain_id = 1
110 self.vapi.syslog_set_filter(
111 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
113 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
115 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
116 session_refresh_interval=10)
118 interfaces = self.vapi.nat44_interface_dump()
119 for intf in interfaces:
120 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
121 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
122 self.vapi.nat44_interface_add_del_feature(
123 sw_if_index=intf.sw_if_index)
124 self.vapi.nat44_interface_add_del_feature(
125 sw_if_index=intf.sw_if_index,
128 interfaces = self.vapi.nat44_interface_output_feature_dump()
129 for intf in interfaces:
130 self.vapi.nat44_interface_add_del_output_feature(
133 sw_if_index=intf.sw_if_index)
134 static_mappings = self.vapi.nat44_static_mapping_dump()
135 for sm in static_mappings:
136 self.vapi.nat44_add_del_static_mapping(
138 local_ip_address=sm.local_ip_address,
139 external_ip_address=sm.external_ip_address,
140 external_sw_if_index=sm.external_sw_if_index,
141 local_port=sm.local_port,
142 external_port=sm.external_port,
144 protocol=sm.protocol,
145 flags=sm.flags, tag=sm.tag)
147 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
148 for lb_sm in lb_static_mappings:
149 self.vapi.nat44_add_del_lb_static_mapping(
152 external_addr=lb_sm.external_addr,
153 external_port=lb_sm.external_port,
154 protocol=lb_sm.protocol,
155 local_num=0, locals=[],
158 identity_mappings = self.vapi.nat44_identity_mapping_dump()
159 for id_m in identity_mappings:
160 self.vapi.nat44_add_del_identity_mapping(
161 ip_address=id_m.ip_address,
162 sw_if_index=id_m.sw_if_index,
166 protocol=id_m.protocol)
168 addresses = self.vapi.nat44_address_dump()
169 for addr in addresses:
170 self.vapi.nat44_add_del_address_range(
171 first_ip_address=addr.ip_address,
172 last_ip_address=addr.ip_address,
173 vrf_id=0xFFFFFFFF, flags=addr.flags)
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.logger.debug(ppp("Reassembled:", p))
766 self.assert_tcp_checksum_valid(p)
767 elif ip.proto == IP_PROTOS.udp:
768 p = (ip / UDP(buffer.getvalue()[:8]) /
769 Raw(buffer.getvalue()[8:]))
770 elif ip.proto == IP_PROTOS.icmp:
771 p = (ip / ICMP(buffer.getvalue()))
774 def reass_frags_and_verify_ip6(self, frags, src, dst):
776 Reassemble and verify fragmented packet
778 :param frags: Captured fragments
779 :param src: Source IPv6 address to verify
780 :param dst: Destination IPv6 address to verify
782 :returns: Reassembled IPv6 packet
786 self.assertEqual(p[IPv6].src, src)
787 self.assertEqual(p[IPv6].dst, dst)
788 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
789 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
790 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
791 nh=frags[0][IPv6ExtHdrFragment].nh)
792 if ip.nh == IP_PROTOS.tcp:
793 p = (ip / TCP(buffer.getvalue()))
794 elif ip.nh == IP_PROTOS.udp:
795 p = (ip / UDP(buffer.getvalue()))
796 self.logger.debug(ppp("Reassembled:", p))
797 self.assert_packet_checksums_valid(p)
800 def initiate_tcp_session(self, in_if, out_if):
802 Initiates TCP session
804 :param in_if: Inside interface
805 :param out_if: Outside interface
809 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
810 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
811 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
814 self.pg_enable_capture(self.pg_interfaces)
816 capture = out_if.get_capture(1)
818 self.tcp_port_out = p[TCP].sport
820 # SYN + ACK packet out->in
821 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
822 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
823 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
826 self.pg_enable_capture(self.pg_interfaces)
831 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
832 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
833 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
836 self.pg_enable_capture(self.pg_interfaces)
838 out_if.get_capture(1)
841 self.logger.error("TCP 3 way handshake failed")
844 def verify_ipfix_nat44_ses(self, data):
846 Verify IPFIX NAT44 session create/delete event
848 :param data: Decoded IPFIX data records
850 nat44_ses_create_num = 0
851 nat44_ses_delete_num = 0
852 self.assertEqual(6, len(data))
855 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
856 if scapy.compat.orb(record[230]) == 4:
857 nat44_ses_create_num += 1
859 nat44_ses_delete_num += 1
861 self.assertEqual(self.pg0.remote_ip4,
862 str(ipaddress.IPv4Address(record[8])))
863 # postNATSourceIPv4Address
864 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
867 self.assertEqual(struct.pack("!I", 0), record[234])
868 # protocolIdentifier/sourceTransportPort
869 # /postNAPTSourceTransportPort
870 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
871 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
872 self.assertEqual(struct.pack("!H", self.icmp_id_out),
874 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
875 self.assertEqual(struct.pack("!H", self.tcp_port_in),
877 self.assertEqual(struct.pack("!H", self.tcp_port_out),
879 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
880 self.assertEqual(struct.pack("!H", self.udp_port_in),
882 self.assertEqual(struct.pack("!H", self.udp_port_out),
885 self.fail("Invalid protocol")
886 self.assertEqual(3, nat44_ses_create_num)
887 self.assertEqual(3, nat44_ses_delete_num)
889 def verify_ipfix_addr_exhausted(self, data):
891 Verify IPFIX NAT addresses event
893 :param data: Decoded IPFIX data records
895 self.assertEqual(1, len(data))
898 self.assertEqual(scapy.compat.orb(record[230]), 3)
900 self.assertEqual(struct.pack("!I", 0), record[283])
902 def verify_ipfix_max_sessions(self, data, limit):
904 Verify IPFIX maximum session entries exceeded event
906 :param data: Decoded IPFIX data records
907 :param limit: Number of maximum session entries that can be created.
909 self.assertEqual(1, len(data))
912 self.assertEqual(scapy.compat.orb(record[230]), 13)
913 # natQuotaExceededEvent
914 self.assertEqual(struct.pack("I", 1), record[466])
916 self.assertEqual(struct.pack("I", limit), record[471])
918 def verify_ipfix_max_bibs(self, data, limit):
920 Verify IPFIX maximum BIB entries exceeded event
922 :param data: Decoded IPFIX data records
923 :param limit: Number of maximum BIB entries that can be created.
925 self.assertEqual(1, len(data))
928 self.assertEqual(scapy.compat.orb(record[230]), 13)
929 # natQuotaExceededEvent
930 self.assertEqual(struct.pack("I", 2), record[466])
932 self.assertEqual(struct.pack("I", limit), record[472])
934 def verify_ipfix_bib(self, data, is_create, src_addr):
936 Verify IPFIX NAT64 BIB create and delete events
938 :param data: Decoded IPFIX data records
939 :param is_create: Create event if nonzero value otherwise delete event
940 :param src_addr: IPv6 source address
942 self.assertEqual(1, len(data))
946 self.assertEqual(scapy.compat.orb(record[230]), 10)
948 self.assertEqual(scapy.compat.orb(record[230]), 11)
950 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
951 # postNATSourceIPv4Address
952 self.assertEqual(self.nat_addr_n, record[225])
954 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
956 self.assertEqual(struct.pack("!I", 0), record[234])
957 # sourceTransportPort
958 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
959 # postNAPTSourceTransportPort
960 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
962 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
965 Verify IPFIX NAT64 session create and delete events
967 :param data: Decoded IPFIX data records
968 :param is_create: Create event if nonzero value otherwise delete event
969 :param src_addr: IPv6 source address
970 :param dst_addr: IPv4 destination address
971 :param dst_port: destination TCP port
973 self.assertEqual(1, len(data))
977 self.assertEqual(scapy.compat.orb(record[230]), 6)
979 self.assertEqual(scapy.compat.orb(record[230]), 7)
981 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
982 # destinationIPv6Address
983 self.assertEqual(socket.inet_pton(socket.AF_INET6,
984 self.compose_ip6(dst_addr,
988 # postNATSourceIPv4Address
989 self.assertEqual(self.nat_addr_n, record[225])
990 # postNATDestinationIPv4Address
991 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
994 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
996 self.assertEqual(struct.pack("!I", 0), record[234])
997 # sourceTransportPort
998 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
999 # postNAPTSourceTransportPort
1000 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1001 # destinationTransportPort
1002 self.assertEqual(struct.pack("!H", dst_port), record[11])
1003 # postNAPTDestinationTransportPort
1004 self.assertEqual(struct.pack("!H", dst_port), record[228])
1006 def verify_no_nat44_user(self):
1007 """ Verify that there is no NAT44 user """
1008 users = self.vapi.nat44_user_dump()
1009 self.assertEqual(len(users), 0)
1010 users = self.statistics.get_counter('/nat44/total-users')
1011 self.assertEqual(users[0][0], 0)
1012 sessions = self.statistics.get_counter('/nat44/total-sessions')
1013 self.assertEqual(sessions[0][0], 0)
1015 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1017 Verify IPFIX maximum entries per user exceeded event
1019 :param data: Decoded IPFIX data records
1020 :param limit: Number of maximum entries per user
1021 :param src_addr: IPv4 source address
1023 self.assertEqual(1, len(data))
1026 self.assertEqual(scapy.compat.orb(record[230]), 13)
1027 # natQuotaExceededEvent
1028 self.assertEqual(struct.pack("I", 3), record[466])
1030 self.assertEqual(struct.pack("I", limit), record[473])
1032 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1034 def verify_syslog_apmap(self, data, is_add=True):
1035 message = data.decode('utf-8')
1037 message = SyslogMessage.parse(message)
1038 except ParseError as e:
1039 self.logger.error(e)
1042 self.assertEqual(message.severity, SyslogSeverity.info)
1043 self.assertEqual(message.appname, 'NAT')
1044 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1045 sd_params = message.sd.get('napmap')
1046 self.assertTrue(sd_params is not None)
1047 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1048 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1049 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1050 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1051 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1052 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1053 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1054 self.assertTrue(sd_params.get('SSUBIX') is not None)
1055 self.assertEqual(sd_params.get('SVLAN'), '0')
1057 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1058 message = data.decode('utf-8')
1060 message = SyslogMessage.parse(message)
1061 except ParseError as e:
1062 self.logger.error(e)
1065 self.assertEqual(message.severity, SyslogSeverity.info)
1066 self.assertEqual(message.appname, 'NAT')
1067 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1068 sd_params = message.sd.get('nsess')
1069 self.assertTrue(sd_params is not None)
1071 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1072 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1074 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1075 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1076 self.assertTrue(sd_params.get('SSUBIX') is not None)
1077 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1078 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1079 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1080 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1081 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1082 self.assertEqual(sd_params.get('SVLAN'), '0')
1083 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1084 self.assertEqual(sd_params.get('XDPORT'),
1085 "%d" % self.tcp_external_port)
1087 def verify_mss_value(self, pkt, mss):
1089 Verify TCP MSS value
1094 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1095 raise TypeError("Not a TCP/IP packet")
1097 for option in pkt[TCP].options:
1098 if option[0] == 'MSS':
1099 self.assertEqual(option[1], mss)
1100 self.assert_tcp_checksum_valid(pkt)
1103 def proto2layer(proto):
1104 if proto == IP_PROTOS.tcp:
1106 elif proto == IP_PROTOS.udp:
1108 elif proto == IP_PROTOS.icmp:
1111 raise Exception("Unsupported protocol")
1113 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1114 layer = self.proto2layer(proto)
1116 if proto == IP_PROTOS.tcp:
1117 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1119 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1120 self.port_in = random.randint(1025, 65535)
1123 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1124 self.port_in, 20, data, proto)
1125 self.pg0.add_stream(pkts)
1126 self.pg_enable_capture(self.pg_interfaces)
1128 frags = self.pg1.get_capture(len(pkts))
1129 if not dont_translate:
1130 p = self.reass_frags_and_verify(frags,
1132 self.pg1.remote_ip4)
1134 p = self.reass_frags_and_verify(frags,
1135 self.pg0.remote_ip4,
1136 self.pg1.remote_ip4)
1137 if proto != IP_PROTOS.icmp:
1138 if not dont_translate:
1139 self.assertEqual(p[layer].dport, 20)
1140 self.assertNotEqual(p[layer].sport, self.port_in)
1142 self.assertEqual(p[layer].sport, self.port_in)
1144 if not dont_translate:
1145 self.assertNotEqual(p[layer].id, self.port_in)
1147 self.assertEqual(p[layer].id, self.port_in)
1148 self.assertEqual(data, p[Raw].load)
1151 if not dont_translate:
1152 dst_addr = self.nat_addr
1154 dst_addr = self.pg0.remote_ip4
1155 if proto != IP_PROTOS.icmp:
1157 dport = p[layer].sport
1161 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
1162 proto, echo_reply=True)
1163 self.pg1.add_stream(pkts)
1164 self.pg_enable_capture(self.pg_interfaces)
1166 frags = self.pg0.get_capture(len(pkts))
1167 p = self.reass_frags_and_verify(frags,
1168 self.pg1.remote_ip4,
1169 self.pg0.remote_ip4)
1170 if proto != IP_PROTOS.icmp:
1171 self.assertEqual(p[layer].sport, 20)
1172 self.assertEqual(p[layer].dport, self.port_in)
1174 self.assertEqual(p[layer].id, self.port_in)
1175 self.assertEqual(data, p[Raw].load)
1177 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1178 layer = self.proto2layer(proto)
1180 if proto == IP_PROTOS.tcp:
1181 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1183 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1184 self.port_in = random.randint(1025, 65535)
1188 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1189 self.port_in, self.server_out_port,
1191 self.pg0.add_stream(pkts)
1192 self.pg_enable_capture(self.pg_interfaces)
1194 frags = self.pg1.get_capture(len(pkts))
1195 p = self.reass_frags_and_verify(frags,
1196 self.pg0.remote_ip4,
1197 self.server_in_addr)
1198 if proto != IP_PROTOS.icmp:
1199 self.assertEqual(p[layer].sport, self.port_in)
1200 self.assertEqual(p[layer].dport, self.server_in_port)
1202 self.assertEqual(p[layer].id, self.port_in)
1203 self.assertEqual(data, p[Raw].load)
1206 if proto != IP_PROTOS.icmp:
1207 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1208 self.server_in_port,
1209 p[layer].sport, data, proto)
1211 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1212 p[layer].id, 0, data, proto,
1214 self.pg1.add_stream(pkts)
1215 self.pg_enable_capture(self.pg_interfaces)
1217 frags = self.pg0.get_capture(len(pkts))
1218 p = self.reass_frags_and_verify(frags,
1219 self.server_out_addr,
1220 self.pg0.remote_ip4)
1221 if proto != IP_PROTOS.icmp:
1222 self.assertEqual(p[layer].sport, self.server_out_port)
1223 self.assertEqual(p[layer].dport, self.port_in)
1225 self.assertEqual(p[layer].id, self.port_in)
1226 self.assertEqual(data, p[Raw].load)
1228 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1229 layer = self.proto2layer(proto)
1231 if proto == IP_PROTOS.tcp:
1232 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1234 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1236 # send packet from host to server
1237 pkts = self.create_stream_frag(self.pg0,
1240 self.server_out_port,
1243 self.pg0.add_stream(pkts)
1244 self.pg_enable_capture(self.pg_interfaces)
1246 frags = self.pg0.get_capture(len(pkts))
1247 p = self.reass_frags_and_verify(frags,
1250 if proto != IP_PROTOS.icmp:
1251 self.assertNotEqual(p[layer].sport, self.host_in_port)
1252 self.assertEqual(p[layer].dport, self.server_in_port)
1254 self.assertNotEqual(p[layer].id, self.host_in_port)
1255 self.assertEqual(data, p[Raw].load)
1257 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1258 layer = self.proto2layer(proto)
1260 if proto == IP_PROTOS.tcp:
1261 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1263 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1264 self.port_in = random.randint(1025, 65535)
1268 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1269 self.port_in, 20, data, proto)
1271 self.pg0.add_stream(pkts)
1272 self.pg_enable_capture(self.pg_interfaces)
1274 frags = self.pg1.get_capture(len(pkts))
1275 if not dont_translate:
1276 p = self.reass_frags_and_verify(frags,
1278 self.pg1.remote_ip4)
1280 p = self.reass_frags_and_verify(frags,
1281 self.pg0.remote_ip4,
1282 self.pg1.remote_ip4)
1283 if proto != IP_PROTOS.icmp:
1284 if not dont_translate:
1285 self.assertEqual(p[layer].dport, 20)
1286 self.assertNotEqual(p[layer].sport, self.port_in)
1288 self.assertEqual(p[layer].sport, self.port_in)
1290 if not dont_translate:
1291 self.assertNotEqual(p[layer].id, self.port_in)
1293 self.assertEqual(p[layer].id, self.port_in)
1294 self.assertEqual(data, p[Raw].load)
1297 if not dont_translate:
1298 dst_addr = self.nat_addr
1300 dst_addr = self.pg0.remote_ip4
1301 if proto != IP_PROTOS.icmp:
1303 dport = p[layer].sport
1307 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1308 data, proto, echo_reply=True)
1310 self.pg1.add_stream(pkts)
1311 self.pg_enable_capture(self.pg_interfaces)
1313 frags = self.pg0.get_capture(len(pkts))
1314 p = self.reass_frags_and_verify(frags,
1315 self.pg1.remote_ip4,
1316 self.pg0.remote_ip4)
1317 if proto != IP_PROTOS.icmp:
1318 self.assertEqual(p[layer].sport, 20)
1319 self.assertEqual(p[layer].dport, self.port_in)
1321 self.assertEqual(p[layer].id, self.port_in)
1322 self.assertEqual(data, p[Raw].load)
1324 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1325 layer = self.proto2layer(proto)
1327 if proto == IP_PROTOS.tcp:
1328 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1330 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1331 self.port_in = random.randint(1025, 65535)
1335 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1336 self.port_in, self.server_out_port,
1339 self.pg0.add_stream(pkts)
1340 self.pg_enable_capture(self.pg_interfaces)
1342 frags = self.pg1.get_capture(len(pkts))
1343 p = self.reass_frags_and_verify(frags,
1344 self.pg0.remote_ip4,
1345 self.server_in_addr)
1346 if proto != IP_PROTOS.icmp:
1347 self.assertEqual(p[layer].dport, self.server_in_port)
1348 self.assertEqual(p[layer].sport, self.port_in)
1349 self.assertEqual(p[layer].dport, self.server_in_port)
1351 self.assertEqual(p[layer].id, self.port_in)
1352 self.assertEqual(data, p[Raw].load)
1355 if proto != IP_PROTOS.icmp:
1356 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1357 self.server_in_port,
1358 p[layer].sport, data, proto)
1360 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1361 p[layer].id, 0, data, proto,
1364 self.pg1.add_stream(pkts)
1365 self.pg_enable_capture(self.pg_interfaces)
1367 frags = self.pg0.get_capture(len(pkts))
1368 p = self.reass_frags_and_verify(frags,
1369 self.server_out_addr,
1370 self.pg0.remote_ip4)
1371 if proto != IP_PROTOS.icmp:
1372 self.assertEqual(p[layer].sport, self.server_out_port)
1373 self.assertEqual(p[layer].dport, self.port_in)
1375 self.assertEqual(p[layer].id, self.port_in)
1376 self.assertEqual(data, p[Raw].load)
1379 class TestNAT44(MethodHolder):
1380 """ NAT44 Test Cases """
1383 def setUpClass(cls):
1384 super(TestNAT44, cls).setUpClass()
1385 cls.vapi.cli("set log class nat level debug")
1387 cls.tcp_port_in = 6303
1388 cls.tcp_port_out = 6303
1389 cls.udp_port_in = 6304
1390 cls.udp_port_out = 6304
1391 cls.icmp_id_in = 6305
1392 cls.icmp_id_out = 6305
1393 cls.nat_addr = '10.0.0.3'
1394 cls.ipfix_src_port = 4739
1395 cls.ipfix_domain_id = 1
1396 cls.tcp_external_port = 80
1397 cls.udp_external_port = 69
1399 cls.create_pg_interfaces(range(10))
1400 cls.interfaces = list(cls.pg_interfaces[0:4])
1402 for i in cls.interfaces:
1407 cls.pg0.generate_remote_hosts(3)
1408 cls.pg0.configure_ipv4_neighbors()
1410 cls.pg1.generate_remote_hosts(1)
1411 cls.pg1.configure_ipv4_neighbors()
1413 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1414 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1415 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1417 cls.pg4._local_ip4 = "172.16.255.1"
1418 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1419 cls.pg4.set_table_ip4(10)
1420 cls.pg5._local_ip4 = "172.17.255.3"
1421 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1422 cls.pg5.set_table_ip4(10)
1423 cls.pg6._local_ip4 = "172.16.255.1"
1424 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1425 cls.pg6.set_table_ip4(20)
1426 for i in cls.overlapping_interfaces:
1434 cls.pg9.generate_remote_hosts(2)
1435 cls.pg9.config_ip4()
1436 cls.vapi.sw_interface_add_del_address(
1437 sw_if_index=cls.pg9.sw_if_index,
1438 prefix="10.0.0.1/24")
1441 cls.pg9.resolve_arp()
1442 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1443 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1444 cls.pg9.resolve_arp()
1447 def tearDownClass(cls):
1448 super(TestNAT44, cls).tearDownClass()
1450 def test_dynamic(self):
1451 """ NAT44 dynamic translation test """
1452 self.nat44_add_address(self.nat_addr)
1453 flags = self.config_flags.NAT_IS_INSIDE
1454 self.vapi.nat44_interface_add_del_feature(
1455 sw_if_index=self.pg0.sw_if_index,
1456 flags=flags, is_add=1)
1457 self.vapi.nat44_interface_add_del_feature(
1458 sw_if_index=self.pg1.sw_if_index,
1462 tcpn = self.statistics.get_err_counter(
1463 '/err/nat44-in2out-slowpath/TCP packets')
1464 udpn = self.statistics.get_err_counter(
1465 '/err/nat44-in2out-slowpath/UDP packets')
1466 icmpn = self.statistics.get_err_counter(
1467 '/err/nat44-in2out-slowpath/ICMP packets')
1468 totaln = self.statistics.get_err_counter(
1469 '/err/nat44-in2out-slowpath/good in2out packets processed')
1471 pkts = self.create_stream_in(self.pg0, self.pg1)
1472 self.pg0.add_stream(pkts)
1473 self.pg_enable_capture(self.pg_interfaces)
1475 capture = self.pg1.get_capture(len(pkts))
1476 self.verify_capture_out(capture)
1478 err = self.statistics.get_err_counter(
1479 '/err/nat44-in2out-slowpath/TCP packets')
1480 self.assertEqual(err - tcpn, 2)
1481 err = self.statistics.get_err_counter(
1482 '/err/nat44-in2out-slowpath/UDP packets')
1483 self.assertEqual(err - udpn, 1)
1484 err = self.statistics.get_err_counter(
1485 '/err/nat44-in2out-slowpath/ICMP packets')
1486 self.assertEqual(err - icmpn, 1)
1487 err = self.statistics.get_err_counter(
1488 '/err/nat44-in2out-slowpath/good in2out packets processed')
1489 self.assertEqual(err - totaln, 4)
1492 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1493 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1494 icmpn = self.statistics.get_err_counter(
1495 '/err/nat44-out2in/ICMP packets')
1496 totaln = self.statistics.get_err_counter(
1497 '/err/nat44-out2in/good out2in packets processed')
1499 pkts = self.create_stream_out(self.pg1)
1500 self.pg1.add_stream(pkts)
1501 self.pg_enable_capture(self.pg_interfaces)
1503 capture = self.pg0.get_capture(len(pkts))
1504 self.verify_capture_in(capture, self.pg0)
1506 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1507 self.assertEqual(err - tcpn, 2)
1508 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1509 self.assertEqual(err - udpn, 1)
1510 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1511 self.assertEqual(err - icmpn, 1)
1512 err = self.statistics.get_err_counter(
1513 '/err/nat44-out2in/good out2in packets processed')
1514 self.assertEqual(err - totaln, 4)
1516 users = self.statistics.get_counter('/nat44/total-users')
1517 self.assertEqual(users[0][0], 1)
1518 sessions = self.statistics.get_counter('/nat44/total-sessions')
1519 self.assertEqual(sessions[0][0], 3)
1521 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1522 """ NAT44 handling of client packets with TTL=1 """
1524 self.nat44_add_address(self.nat_addr)
1525 flags = self.config_flags.NAT_IS_INSIDE
1526 self.vapi.nat44_interface_add_del_feature(
1527 sw_if_index=self.pg0.sw_if_index,
1528 flags=flags, is_add=1)
1529 self.vapi.nat44_interface_add_del_feature(
1530 sw_if_index=self.pg1.sw_if_index,
1533 # Client side - generate traffic
1534 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1535 self.pg0.add_stream(pkts)
1536 self.pg_enable_capture(self.pg_interfaces)
1539 # Client side - verify ICMP type 11 packets
1540 capture = self.pg0.get_capture(len(pkts))
1541 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1543 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1544 """ NAT44 handling of server packets with TTL=1 """
1546 self.nat44_add_address(self.nat_addr)
1547 flags = self.config_flags.NAT_IS_INSIDE
1548 self.vapi.nat44_interface_add_del_feature(
1549 sw_if_index=self.pg0.sw_if_index,
1550 flags=flags, is_add=1)
1551 self.vapi.nat44_interface_add_del_feature(
1552 sw_if_index=self.pg1.sw_if_index,
1555 # Client side - create sessions
1556 pkts = self.create_stream_in(self.pg0, self.pg1)
1557 self.pg0.add_stream(pkts)
1558 self.pg_enable_capture(self.pg_interfaces)
1561 # Server side - generate traffic
1562 capture = self.pg1.get_capture(len(pkts))
1563 self.verify_capture_out(capture)
1564 pkts = self.create_stream_out(self.pg1, ttl=1)
1565 self.pg1.add_stream(pkts)
1566 self.pg_enable_capture(self.pg_interfaces)
1569 # Server side - verify ICMP type 11 packets
1570 capture = self.pg1.get_capture(len(pkts))
1571 self.verify_capture_out_with_icmp_errors(capture,
1572 src_ip=self.pg1.local_ip4)
1574 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1575 """ NAT44 handling of error responses to client packets with TTL=2 """
1577 self.nat44_add_address(self.nat_addr)
1578 flags = self.config_flags.NAT_IS_INSIDE
1579 self.vapi.nat44_interface_add_del_feature(
1580 sw_if_index=self.pg0.sw_if_index,
1581 flags=flags, is_add=1)
1582 self.vapi.nat44_interface_add_del_feature(
1583 sw_if_index=self.pg1.sw_if_index,
1586 # Client side - generate traffic
1587 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1588 self.pg0.add_stream(pkts)
1589 self.pg_enable_capture(self.pg_interfaces)
1592 # Server side - simulate ICMP type 11 response
1593 capture = self.pg1.get_capture(len(pkts))
1594 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1595 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1596 ICMP(type=11) / packet[IP] for packet in capture]
1597 self.pg1.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1601 # Client side - verify ICMP type 11 packets
1602 capture = self.pg0.get_capture(len(pkts))
1603 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1605 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1606 """ NAT44 handling of error responses to server packets with TTL=2 """
1608 self.nat44_add_address(self.nat_addr)
1609 flags = self.config_flags.NAT_IS_INSIDE
1610 self.vapi.nat44_interface_add_del_feature(
1611 sw_if_index=self.pg0.sw_if_index,
1612 flags=flags, is_add=1)
1613 self.vapi.nat44_interface_add_del_feature(
1614 sw_if_index=self.pg1.sw_if_index,
1617 # Client side - create sessions
1618 pkts = self.create_stream_in(self.pg0, self.pg1)
1619 self.pg0.add_stream(pkts)
1620 self.pg_enable_capture(self.pg_interfaces)
1623 # Server side - generate traffic
1624 capture = self.pg1.get_capture(len(pkts))
1625 self.verify_capture_out(capture)
1626 pkts = self.create_stream_out(self.pg1, ttl=2)
1627 self.pg1.add_stream(pkts)
1628 self.pg_enable_capture(self.pg_interfaces)
1631 # Client side - simulate ICMP type 11 response
1632 capture = self.pg0.get_capture(len(pkts))
1633 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1634 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1635 ICMP(type=11) / packet[IP] for packet in capture]
1636 self.pg0.add_stream(pkts)
1637 self.pg_enable_capture(self.pg_interfaces)
1640 # Server side - verify ICMP type 11 packets
1641 capture = self.pg1.get_capture(len(pkts))
1642 self.verify_capture_out_with_icmp_errors(capture)
1644 def test_ping_out_interface_from_outside(self):
1645 """ Ping NAT44 out interface from outside network """
1647 self.nat44_add_address(self.nat_addr)
1648 flags = self.config_flags.NAT_IS_INSIDE
1649 self.vapi.nat44_interface_add_del_feature(
1650 sw_if_index=self.pg0.sw_if_index,
1651 flags=flags, is_add=1)
1652 self.vapi.nat44_interface_add_del_feature(
1653 sw_if_index=self.pg1.sw_if_index,
1656 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1657 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1658 ICMP(id=self.icmp_id_out, type='echo-request'))
1660 self.pg1.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1663 capture = self.pg1.get_capture(len(pkts))
1666 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1667 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1668 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1669 self.assertEqual(packet[ICMP].type, 0) # echo reply
1671 self.logger.error(ppp("Unexpected or invalid packet "
1672 "(outside network):", packet))
1675 def test_ping_internal_host_from_outside(self):
1676 """ Ping internal host from outside network """
1678 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1679 flags = self.config_flags.NAT_IS_INSIDE
1680 self.vapi.nat44_interface_add_del_feature(
1681 sw_if_index=self.pg0.sw_if_index,
1682 flags=flags, is_add=1)
1683 self.vapi.nat44_interface_add_del_feature(
1684 sw_if_index=self.pg1.sw_if_index,
1688 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1689 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1690 ICMP(id=self.icmp_id_out, type='echo-request'))
1691 self.pg1.add_stream(pkt)
1692 self.pg_enable_capture(self.pg_interfaces)
1694 capture = self.pg0.get_capture(1)
1695 self.verify_capture_in(capture, self.pg0)
1696 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1699 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1700 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1701 ICMP(id=self.icmp_id_in, type='echo-reply'))
1702 self.pg0.add_stream(pkt)
1703 self.pg_enable_capture(self.pg_interfaces)
1705 capture = self.pg1.get_capture(1)
1706 self.verify_capture_out(capture, same_port=True)
1707 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1709 def test_forwarding(self):
1710 """ NAT44 forwarding test """
1712 flags = self.config_flags.NAT_IS_INSIDE
1713 self.vapi.nat44_interface_add_del_feature(
1714 sw_if_index=self.pg0.sw_if_index,
1715 flags=flags, is_add=1)
1716 self.vapi.nat44_interface_add_del_feature(
1717 sw_if_index=self.pg1.sw_if_index,
1719 self.vapi.nat44_forwarding_enable_disable(enable=1)
1721 real_ip = self.pg0.remote_ip4
1722 alias_ip = self.nat_addr
1723 flags = self.config_flags.NAT_IS_ADDR_ONLY
1724 self.vapi.nat44_add_del_static_mapping(is_add=1,
1725 local_ip_address=real_ip,
1726 external_ip_address=alias_ip,
1727 external_sw_if_index=0xFFFFFFFF,
1731 # static mapping match
1733 pkts = self.create_stream_out(self.pg1)
1734 self.pg1.add_stream(pkts)
1735 self.pg_enable_capture(self.pg_interfaces)
1737 capture = self.pg0.get_capture(len(pkts))
1738 self.verify_capture_in(capture, self.pg0)
1740 pkts = self.create_stream_in(self.pg0, self.pg1)
1741 self.pg0.add_stream(pkts)
1742 self.pg_enable_capture(self.pg_interfaces)
1744 capture = self.pg1.get_capture(len(pkts))
1745 self.verify_capture_out(capture, same_port=True)
1747 # no static mapping match
1749 host0 = self.pg0.remote_hosts[0]
1750 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1752 pkts = self.create_stream_out(self.pg1,
1753 dst_ip=self.pg0.remote_ip4,
1754 use_inside_ports=True)
1755 self.pg1.add_stream(pkts)
1756 self.pg_enable_capture(self.pg_interfaces)
1758 capture = self.pg0.get_capture(len(pkts))
1759 self.verify_capture_in(capture, self.pg0)
1761 pkts = self.create_stream_in(self.pg0, self.pg1)
1762 self.pg0.add_stream(pkts)
1763 self.pg_enable_capture(self.pg_interfaces)
1765 capture = self.pg1.get_capture(len(pkts))
1766 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1769 self.pg0.remote_hosts[0] = host0
1772 self.vapi.nat44_forwarding_enable_disable(enable=0)
1773 flags = self.config_flags.NAT_IS_ADDR_ONLY
1774 self.vapi.nat44_add_del_static_mapping(
1776 local_ip_address=real_ip,
1777 external_ip_address=alias_ip,
1778 external_sw_if_index=0xFFFFFFFF,
1781 def test_static_in(self):
1782 """ 1:1 NAT initialized from inside network """
1784 nat_ip = "10.0.0.10"
1785 self.tcp_port_out = 6303
1786 self.udp_port_out = 6304
1787 self.icmp_id_out = 6305
1789 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1790 flags = self.config_flags.NAT_IS_INSIDE
1791 self.vapi.nat44_interface_add_del_feature(
1792 sw_if_index=self.pg0.sw_if_index,
1793 flags=flags, is_add=1)
1794 self.vapi.nat44_interface_add_del_feature(
1795 sw_if_index=self.pg1.sw_if_index,
1797 sm = self.vapi.nat44_static_mapping_dump()
1798 self.assertEqual(len(sm), 1)
1799 self.assertEqual(sm[0].tag, '')
1800 self.assertEqual(sm[0].protocol, 0)
1801 self.assertEqual(sm[0].local_port, 0)
1802 self.assertEqual(sm[0].external_port, 0)
1805 pkts = self.create_stream_in(self.pg0, self.pg1)
1806 self.pg0.add_stream(pkts)
1807 self.pg_enable_capture(self.pg_interfaces)
1809 capture = self.pg1.get_capture(len(pkts))
1810 self.verify_capture_out(capture, nat_ip, True)
1813 pkts = self.create_stream_out(self.pg1, nat_ip)
1814 self.pg1.add_stream(pkts)
1815 self.pg_enable_capture(self.pg_interfaces)
1817 capture = self.pg0.get_capture(len(pkts))
1818 self.verify_capture_in(capture, self.pg0)
1820 def test_static_out(self):
1821 """ 1:1 NAT initialized from outside network """
1823 nat_ip = "10.0.0.20"
1824 self.tcp_port_out = 6303
1825 self.udp_port_out = 6304
1826 self.icmp_id_out = 6305
1829 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1830 flags = self.config_flags.NAT_IS_INSIDE
1831 self.vapi.nat44_interface_add_del_feature(
1832 sw_if_index=self.pg0.sw_if_index,
1833 flags=flags, is_add=1)
1834 self.vapi.nat44_interface_add_del_feature(
1835 sw_if_index=self.pg1.sw_if_index,
1837 sm = self.vapi.nat44_static_mapping_dump()
1838 self.assertEqual(len(sm), 1)
1839 self.assertEqual(sm[0].tag, tag)
1842 pkts = self.create_stream_out(self.pg1, nat_ip)
1843 self.pg1.add_stream(pkts)
1844 self.pg_enable_capture(self.pg_interfaces)
1846 capture = self.pg0.get_capture(len(pkts))
1847 self.verify_capture_in(capture, self.pg0)
1850 pkts = self.create_stream_in(self.pg0, self.pg1)
1851 self.pg0.add_stream(pkts)
1852 self.pg_enable_capture(self.pg_interfaces)
1854 capture = self.pg1.get_capture(len(pkts))
1855 self.verify_capture_out(capture, nat_ip, True)
1857 def test_static_with_port_in(self):
1858 """ 1:1 NAPT initialized from inside network """
1860 self.tcp_port_out = 3606
1861 self.udp_port_out = 3607
1862 self.icmp_id_out = 3608
1864 self.nat44_add_address(self.nat_addr)
1865 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1866 self.tcp_port_in, self.tcp_port_out,
1867 proto=IP_PROTOS.tcp)
1868 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1869 self.udp_port_in, self.udp_port_out,
1870 proto=IP_PROTOS.udp)
1871 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1872 self.icmp_id_in, self.icmp_id_out,
1873 proto=IP_PROTOS.icmp)
1874 flags = self.config_flags.NAT_IS_INSIDE
1875 self.vapi.nat44_interface_add_del_feature(
1876 sw_if_index=self.pg0.sw_if_index,
1877 flags=flags, is_add=1)
1878 self.vapi.nat44_interface_add_del_feature(
1879 sw_if_index=self.pg1.sw_if_index,
1883 pkts = self.create_stream_in(self.pg0, self.pg1)
1884 self.pg0.add_stream(pkts)
1885 self.pg_enable_capture(self.pg_interfaces)
1887 capture = self.pg1.get_capture(len(pkts))
1888 self.verify_capture_out(capture)
1891 pkts = self.create_stream_out(self.pg1)
1892 self.pg1.add_stream(pkts)
1893 self.pg_enable_capture(self.pg_interfaces)
1895 capture = self.pg0.get_capture(len(pkts))
1896 self.verify_capture_in(capture, self.pg0)
1898 def test_static_with_port_out(self):
1899 """ 1:1 NAPT initialized from outside network """
1901 self.tcp_port_out = 30606
1902 self.udp_port_out = 30607
1903 self.icmp_id_out = 30608
1905 self.nat44_add_address(self.nat_addr)
1906 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1907 self.tcp_port_in, self.tcp_port_out,
1908 proto=IP_PROTOS.tcp)
1909 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1910 self.udp_port_in, self.udp_port_out,
1911 proto=IP_PROTOS.udp)
1912 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1913 self.icmp_id_in, self.icmp_id_out,
1914 proto=IP_PROTOS.icmp)
1915 flags = self.config_flags.NAT_IS_INSIDE
1916 self.vapi.nat44_interface_add_del_feature(
1917 sw_if_index=self.pg0.sw_if_index,
1918 flags=flags, is_add=1)
1919 self.vapi.nat44_interface_add_del_feature(
1920 sw_if_index=self.pg1.sw_if_index,
1924 pkts = self.create_stream_out(self.pg1)
1925 self.pg1.add_stream(pkts)
1926 self.pg_enable_capture(self.pg_interfaces)
1928 capture = self.pg0.get_capture(len(pkts))
1929 self.verify_capture_in(capture, self.pg0)
1932 pkts = self.create_stream_in(self.pg0, self.pg1)
1933 self.pg0.add_stream(pkts)
1934 self.pg_enable_capture(self.pg_interfaces)
1936 capture = self.pg1.get_capture(len(pkts))
1937 self.verify_capture_out(capture)
1939 def test_static_vrf_aware(self):
1940 """ 1:1 NAT VRF awareness """
1942 nat_ip1 = "10.0.0.30"
1943 nat_ip2 = "10.0.0.40"
1944 self.tcp_port_out = 6303
1945 self.udp_port_out = 6304
1946 self.icmp_id_out = 6305
1948 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1950 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1952 flags = self.config_flags.NAT_IS_INSIDE
1953 self.vapi.nat44_interface_add_del_feature(
1954 sw_if_index=self.pg3.sw_if_index,
1956 self.vapi.nat44_interface_add_del_feature(
1957 sw_if_index=self.pg0.sw_if_index,
1958 flags=flags, is_add=1)
1959 self.vapi.nat44_interface_add_del_feature(
1960 sw_if_index=self.pg4.sw_if_index,
1961 flags=flags, is_add=1)
1963 # inside interface VRF match NAT44 static mapping VRF
1964 pkts = self.create_stream_in(self.pg4, self.pg3)
1965 self.pg4.add_stream(pkts)
1966 self.pg_enable_capture(self.pg_interfaces)
1968 capture = self.pg3.get_capture(len(pkts))
1969 self.verify_capture_out(capture, nat_ip1, True)
1971 # inside interface VRF don't match NAT44 static mapping VRF (packets
1973 pkts = self.create_stream_in(self.pg0, self.pg3)
1974 self.pg0.add_stream(pkts)
1975 self.pg_enable_capture(self.pg_interfaces)
1977 self.pg3.assert_nothing_captured()
1979 def test_dynamic_to_static(self):
1980 """ Switch from dynamic translation to 1:1NAT """
1981 nat_ip = "10.0.0.10"
1982 self.tcp_port_out = 6303
1983 self.udp_port_out = 6304
1984 self.icmp_id_out = 6305
1986 self.nat44_add_address(self.nat_addr)
1987 flags = self.config_flags.NAT_IS_INSIDE
1988 self.vapi.nat44_interface_add_del_feature(
1989 sw_if_index=self.pg0.sw_if_index,
1990 flags=flags, is_add=1)
1991 self.vapi.nat44_interface_add_del_feature(
1992 sw_if_index=self.pg1.sw_if_index,
1996 pkts = self.create_stream_in(self.pg0, self.pg1)
1997 self.pg0.add_stream(pkts)
1998 self.pg_enable_capture(self.pg_interfaces)
2000 capture = self.pg1.get_capture(len(pkts))
2001 self.verify_capture_out(capture)
2004 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2005 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2006 self.assertEqual(len(sessions), 0)
2007 pkts = self.create_stream_in(self.pg0, self.pg1)
2008 self.pg0.add_stream(pkts)
2009 self.pg_enable_capture(self.pg_interfaces)
2011 capture = self.pg1.get_capture(len(pkts))
2012 self.verify_capture_out(capture, nat_ip, True)
2014 def test_identity_nat(self):
2015 """ Identity NAT """
2016 flags = self.config_flags.NAT_IS_ADDR_ONLY
2017 self.vapi.nat44_add_del_identity_mapping(
2018 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2019 flags=flags, is_add=1)
2020 flags = self.config_flags.NAT_IS_INSIDE
2021 self.vapi.nat44_interface_add_del_feature(
2022 sw_if_index=self.pg0.sw_if_index,
2023 flags=flags, is_add=1)
2024 self.vapi.nat44_interface_add_del_feature(
2025 sw_if_index=self.pg1.sw_if_index,
2028 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2029 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2030 TCP(sport=12345, dport=56789))
2031 self.pg1.add_stream(p)
2032 self.pg_enable_capture(self.pg_interfaces)
2034 capture = self.pg0.get_capture(1)
2039 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2040 self.assertEqual(ip.src, self.pg1.remote_ip4)
2041 self.assertEqual(tcp.dport, 56789)
2042 self.assertEqual(tcp.sport, 12345)
2043 self.assert_packet_checksums_valid(p)
2045 self.logger.error(ppp("Unexpected or invalid packet:", p))
2048 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2049 self.assertEqual(len(sessions), 0)
2050 flags = self.config_flags.NAT_IS_ADDR_ONLY
2051 self.vapi.nat44_add_del_identity_mapping(
2052 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2053 flags=flags, vrf_id=1, is_add=1)
2054 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2055 self.assertEqual(len(identity_mappings), 2)
2057 def test_multiple_inside_interfaces(self):
2058 """ NAT44 multiple non-overlapping address space inside interfaces """
2060 self.nat44_add_address(self.nat_addr)
2061 flags = self.config_flags.NAT_IS_INSIDE
2062 self.vapi.nat44_interface_add_del_feature(
2063 sw_if_index=self.pg0.sw_if_index,
2064 flags=flags, is_add=1)
2065 self.vapi.nat44_interface_add_del_feature(
2066 sw_if_index=self.pg1.sw_if_index,
2067 flags=flags, is_add=1)
2068 self.vapi.nat44_interface_add_del_feature(
2069 sw_if_index=self.pg3.sw_if_index,
2072 # between two NAT44 inside interfaces (no translation)
2073 pkts = self.create_stream_in(self.pg0, self.pg1)
2074 self.pg0.add_stream(pkts)
2075 self.pg_enable_capture(self.pg_interfaces)
2077 capture = self.pg1.get_capture(len(pkts))
2078 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2080 # from NAT44 inside to interface without NAT44 feature (no translation)
2081 pkts = self.create_stream_in(self.pg0, self.pg2)
2082 self.pg0.add_stream(pkts)
2083 self.pg_enable_capture(self.pg_interfaces)
2085 capture = self.pg2.get_capture(len(pkts))
2086 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2088 # in2out 1st interface
2089 pkts = self.create_stream_in(self.pg0, self.pg3)
2090 self.pg0.add_stream(pkts)
2091 self.pg_enable_capture(self.pg_interfaces)
2093 capture = self.pg3.get_capture(len(pkts))
2094 self.verify_capture_out(capture)
2096 # out2in 1st interface
2097 pkts = self.create_stream_out(self.pg3)
2098 self.pg3.add_stream(pkts)
2099 self.pg_enable_capture(self.pg_interfaces)
2101 capture = self.pg0.get_capture(len(pkts))
2102 self.verify_capture_in(capture, self.pg0)
2104 # in2out 2nd interface
2105 pkts = self.create_stream_in(self.pg1, self.pg3)
2106 self.pg1.add_stream(pkts)
2107 self.pg_enable_capture(self.pg_interfaces)
2109 capture = self.pg3.get_capture(len(pkts))
2110 self.verify_capture_out(capture)
2112 # out2in 2nd interface
2113 pkts = self.create_stream_out(self.pg3)
2114 self.pg3.add_stream(pkts)
2115 self.pg_enable_capture(self.pg_interfaces)
2117 capture = self.pg1.get_capture(len(pkts))
2118 self.verify_capture_in(capture, self.pg1)
2120 def test_inside_overlapping_interfaces(self):
2121 """ NAT44 multiple inside interfaces with overlapping address space """
2123 static_nat_ip = "10.0.0.10"
2124 self.nat44_add_address(self.nat_addr)
2125 flags = self.config_flags.NAT_IS_INSIDE
2126 self.vapi.nat44_interface_add_del_feature(
2127 sw_if_index=self.pg3.sw_if_index,
2129 self.vapi.nat44_interface_add_del_feature(
2130 sw_if_index=self.pg4.sw_if_index,
2131 flags=flags, is_add=1)
2132 self.vapi.nat44_interface_add_del_feature(
2133 sw_if_index=self.pg5.sw_if_index,
2134 flags=flags, is_add=1)
2135 self.vapi.nat44_interface_add_del_feature(
2136 sw_if_index=self.pg6.sw_if_index,
2137 flags=flags, is_add=1)
2138 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2141 # between NAT44 inside interfaces with same VRF (no translation)
2142 pkts = self.create_stream_in(self.pg4, self.pg5)
2143 self.pg4.add_stream(pkts)
2144 self.pg_enable_capture(self.pg_interfaces)
2146 capture = self.pg5.get_capture(len(pkts))
2147 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2149 # between NAT44 inside interfaces with different VRF (hairpinning)
2150 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2151 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2152 TCP(sport=1234, dport=5678))
2153 self.pg4.add_stream(p)
2154 self.pg_enable_capture(self.pg_interfaces)
2156 capture = self.pg6.get_capture(1)
2161 self.assertEqual(ip.src, self.nat_addr)
2162 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2163 self.assertNotEqual(tcp.sport, 1234)
2164 self.assertEqual(tcp.dport, 5678)
2166 self.logger.error(ppp("Unexpected or invalid packet:", p))
2169 # in2out 1st interface
2170 pkts = self.create_stream_in(self.pg4, self.pg3)
2171 self.pg4.add_stream(pkts)
2172 self.pg_enable_capture(self.pg_interfaces)
2174 capture = self.pg3.get_capture(len(pkts))
2175 self.verify_capture_out(capture)
2177 # out2in 1st interface
2178 pkts = self.create_stream_out(self.pg3)
2179 self.pg3.add_stream(pkts)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg4.get_capture(len(pkts))
2183 self.verify_capture_in(capture, self.pg4)
2185 # in2out 2nd interface
2186 pkts = self.create_stream_in(self.pg5, self.pg3)
2187 self.pg5.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 2nd 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.pg5.get_capture(len(pkts))
2199 self.verify_capture_in(capture, self.pg5)
2202 addresses = self.vapi.nat44_address_dump()
2203 self.assertEqual(len(addresses), 1)
2204 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2205 self.assertEqual(len(sessions), 3)
2206 for session in sessions:
2207 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2208 self.assertEqual(str(session.inside_ip_address),
2209 self.pg5.remote_ip4)
2210 self.assertEqual(session.outside_ip_address,
2211 addresses[0].ip_address)
2212 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2213 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2214 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2215 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2216 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2217 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2218 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2219 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2220 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2222 # in2out 3rd interface
2223 pkts = self.create_stream_in(self.pg6, self.pg3)
2224 self.pg6.add_stream(pkts)
2225 self.pg_enable_capture(self.pg_interfaces)
2227 capture = self.pg3.get_capture(len(pkts))
2228 self.verify_capture_out(capture, static_nat_ip, True)
2230 # out2in 3rd interface
2231 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2232 self.pg3.add_stream(pkts)
2233 self.pg_enable_capture(self.pg_interfaces)
2235 capture = self.pg6.get_capture(len(pkts))
2236 self.verify_capture_in(capture, self.pg6)
2238 # general user and session dump verifications
2239 users = self.vapi.nat44_user_dump()
2240 self.assertGreaterEqual(len(users), 3)
2241 addresses = self.vapi.nat44_address_dump()
2242 self.assertEqual(len(addresses), 1)
2244 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2246 for session in sessions:
2247 self.assertEqual(user.ip_address, session.inside_ip_address)
2248 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2249 self.assertTrue(session.protocol in
2250 [IP_PROTOS.tcp, IP_PROTOS.udp,
2252 self.assertFalse(session.flags &
2253 self.config_flags.NAT_IS_EXT_HOST_VALID)
2256 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2257 self.assertGreaterEqual(len(sessions), 4)
2258 for session in sessions:
2259 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2260 self.assertEqual(str(session.inside_ip_address),
2261 self.pg4.remote_ip4)
2262 self.assertEqual(session.outside_ip_address,
2263 addresses[0].ip_address)
2266 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2267 self.assertGreaterEqual(len(sessions), 3)
2268 for session in sessions:
2269 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2270 self.assertEqual(str(session.inside_ip_address),
2271 self.pg6.remote_ip4)
2272 self.assertEqual(str(session.outside_ip_address),
2274 self.assertTrue(session.inside_port in
2275 [self.tcp_port_in, self.udp_port_in,
2278 def test_hairpinning(self):
2279 """ NAT44 hairpinning - 1:1 NAPT """
2281 host = self.pg0.remote_hosts[0]
2282 server = self.pg0.remote_hosts[1]
2285 server_in_port = 5678
2286 server_out_port = 8765
2288 self.nat44_add_address(self.nat_addr)
2289 flags = self.config_flags.NAT_IS_INSIDE
2290 self.vapi.nat44_interface_add_del_feature(
2291 sw_if_index=self.pg0.sw_if_index,
2292 flags=flags, is_add=1)
2293 self.vapi.nat44_interface_add_del_feature(
2294 sw_if_index=self.pg1.sw_if_index,
2297 # add static mapping for server
2298 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2299 server_in_port, server_out_port,
2300 proto=IP_PROTOS.tcp)
2302 # send packet from host to server
2303 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2304 IP(src=host.ip4, dst=self.nat_addr) /
2305 TCP(sport=host_in_port, dport=server_out_port))
2306 self.pg0.add_stream(p)
2307 self.pg_enable_capture(self.pg_interfaces)
2309 capture = self.pg0.get_capture(1)
2314 self.assertEqual(ip.src, self.nat_addr)
2315 self.assertEqual(ip.dst, server.ip4)
2316 self.assertNotEqual(tcp.sport, host_in_port)
2317 self.assertEqual(tcp.dport, server_in_port)
2318 self.assert_packet_checksums_valid(p)
2319 host_out_port = tcp.sport
2321 self.logger.error(ppp("Unexpected or invalid packet:", p))
2324 # send reply from server to host
2325 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2326 IP(src=server.ip4, dst=self.nat_addr) /
2327 TCP(sport=server_in_port, dport=host_out_port))
2328 self.pg0.add_stream(p)
2329 self.pg_enable_capture(self.pg_interfaces)
2331 capture = self.pg0.get_capture(1)
2336 self.assertEqual(ip.src, self.nat_addr)
2337 self.assertEqual(ip.dst, host.ip4)
2338 self.assertEqual(tcp.sport, server_out_port)
2339 self.assertEqual(tcp.dport, host_in_port)
2340 self.assert_packet_checksums_valid(p)
2342 self.logger.error(ppp("Unexpected or invalid packet:", p))
2345 def test_hairpinning2(self):
2346 """ NAT44 hairpinning - 1:1 NAT"""
2348 server1_nat_ip = "10.0.0.10"
2349 server2_nat_ip = "10.0.0.11"
2350 host = self.pg0.remote_hosts[0]
2351 server1 = self.pg0.remote_hosts[1]
2352 server2 = self.pg0.remote_hosts[2]
2353 server_tcp_port = 22
2354 server_udp_port = 20
2356 self.nat44_add_address(self.nat_addr)
2357 flags = self.config_flags.NAT_IS_INSIDE
2358 self.vapi.nat44_interface_add_del_feature(
2359 sw_if_index=self.pg0.sw_if_index,
2360 flags=flags, is_add=1)
2361 self.vapi.nat44_interface_add_del_feature(
2362 sw_if_index=self.pg1.sw_if_index,
2365 # add static mapping for servers
2366 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2367 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2371 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2372 IP(src=host.ip4, dst=server1_nat_ip) /
2373 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2376 IP(src=host.ip4, dst=server1_nat_ip) /
2377 UDP(sport=self.udp_port_in, dport=server_udp_port))
2379 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2380 IP(src=host.ip4, dst=server1_nat_ip) /
2381 ICMP(id=self.icmp_id_in, type='echo-request'))
2383 self.pg0.add_stream(pkts)
2384 self.pg_enable_capture(self.pg_interfaces)
2386 capture = self.pg0.get_capture(len(pkts))
2387 for packet in capture:
2389 self.assertEqual(packet[IP].src, self.nat_addr)
2390 self.assertEqual(packet[IP].dst, server1.ip4)
2391 if packet.haslayer(TCP):
2392 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2393 self.assertEqual(packet[TCP].dport, server_tcp_port)
2394 self.tcp_port_out = packet[TCP].sport
2395 self.assert_packet_checksums_valid(packet)
2396 elif packet.haslayer(UDP):
2397 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2398 self.assertEqual(packet[UDP].dport, server_udp_port)
2399 self.udp_port_out = packet[UDP].sport
2401 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2402 self.icmp_id_out = packet[ICMP].id
2404 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2409 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2410 IP(src=server1.ip4, dst=self.nat_addr) /
2411 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2413 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2414 IP(src=server1.ip4, dst=self.nat_addr) /
2415 UDP(sport=server_udp_port, dport=self.udp_port_out))
2417 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2418 IP(src=server1.ip4, dst=self.nat_addr) /
2419 ICMP(id=self.icmp_id_out, type='echo-reply'))
2421 self.pg0.add_stream(pkts)
2422 self.pg_enable_capture(self.pg_interfaces)
2424 capture = self.pg0.get_capture(len(pkts))
2425 for packet in capture:
2427 self.assertEqual(packet[IP].src, server1_nat_ip)
2428 self.assertEqual(packet[IP].dst, host.ip4)
2429 if packet.haslayer(TCP):
2430 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2431 self.assertEqual(packet[TCP].sport, server_tcp_port)
2432 self.assert_packet_checksums_valid(packet)
2433 elif packet.haslayer(UDP):
2434 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2435 self.assertEqual(packet[UDP].sport, server_udp_port)
2437 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2439 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2442 # server2 to server1
2444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2445 IP(src=server2.ip4, dst=server1_nat_ip) /
2446 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2449 IP(src=server2.ip4, dst=server1_nat_ip) /
2450 UDP(sport=self.udp_port_in, dport=server_udp_port))
2452 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2453 IP(src=server2.ip4, dst=server1_nat_ip) /
2454 ICMP(id=self.icmp_id_in, type='echo-request'))
2456 self.pg0.add_stream(pkts)
2457 self.pg_enable_capture(self.pg_interfaces)
2459 capture = self.pg0.get_capture(len(pkts))
2460 for packet in capture:
2462 self.assertEqual(packet[IP].src, server2_nat_ip)
2463 self.assertEqual(packet[IP].dst, server1.ip4)
2464 if packet.haslayer(TCP):
2465 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2466 self.assertEqual(packet[TCP].dport, server_tcp_port)
2467 self.tcp_port_out = packet[TCP].sport
2468 self.assert_packet_checksums_valid(packet)
2469 elif packet.haslayer(UDP):
2470 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2471 self.assertEqual(packet[UDP].dport, server_udp_port)
2472 self.udp_port_out = packet[UDP].sport
2474 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2475 self.icmp_id_out = packet[ICMP].id
2477 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2480 # server1 to server2
2482 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2483 IP(src=server1.ip4, dst=server2_nat_ip) /
2484 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2486 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2487 IP(src=server1.ip4, dst=server2_nat_ip) /
2488 UDP(sport=server_udp_port, dport=self.udp_port_out))
2490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2491 IP(src=server1.ip4, dst=server2_nat_ip) /
2492 ICMP(id=self.icmp_id_out, type='echo-reply'))
2494 self.pg0.add_stream(pkts)
2495 self.pg_enable_capture(self.pg_interfaces)
2497 capture = self.pg0.get_capture(len(pkts))
2498 for packet in capture:
2500 self.assertEqual(packet[IP].src, server1_nat_ip)
2501 self.assertEqual(packet[IP].dst, server2.ip4)
2502 if packet.haslayer(TCP):
2503 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2504 self.assertEqual(packet[TCP].sport, server_tcp_port)
2505 self.assert_packet_checksums_valid(packet)
2506 elif packet.haslayer(UDP):
2507 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2508 self.assertEqual(packet[UDP].sport, server_udp_port)
2510 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2512 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2515 def test_interface_addr(self):
2516 """ Acquire NAT44 addresses from interface """
2517 self.vapi.nat44_add_del_interface_addr(
2519 sw_if_index=self.pg7.sw_if_index)
2521 # no address in NAT pool
2522 addresses = self.vapi.nat44_address_dump()
2523 self.assertEqual(0, len(addresses))
2525 # configure interface address and check NAT address pool
2526 self.pg7.config_ip4()
2527 addresses = self.vapi.nat44_address_dump()
2528 self.assertEqual(1, len(addresses))
2529 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2531 # remove interface address and check NAT address pool
2532 self.pg7.unconfig_ip4()
2533 addresses = self.vapi.nat44_address_dump()
2534 self.assertEqual(0, len(addresses))
2536 def test_interface_addr_static_mapping(self):
2537 """ Static mapping with addresses from interface """
2540 self.vapi.nat44_add_del_interface_addr(
2542 sw_if_index=self.pg7.sw_if_index)
2543 self.nat44_add_static_mapping(
2545 external_sw_if_index=self.pg7.sw_if_index,
2548 # static mappings with external interface
2549 static_mappings = self.vapi.nat44_static_mapping_dump()
2550 self.assertEqual(1, len(static_mappings))
2551 self.assertEqual(self.pg7.sw_if_index,
2552 static_mappings[0].external_sw_if_index)
2553 self.assertEqual(static_mappings[0].tag, tag)
2555 # configure interface address and check static mappings
2556 self.pg7.config_ip4()
2557 static_mappings = self.vapi.nat44_static_mapping_dump()
2558 self.assertEqual(2, len(static_mappings))
2560 for sm in static_mappings:
2561 if sm.external_sw_if_index == 0xFFFFFFFF:
2562 self.assertEqual(str(sm.external_ip_address),
2564 self.assertEqual(sm.tag, tag)
2566 self.assertTrue(resolved)
2568 # remove interface address and check static mappings
2569 self.pg7.unconfig_ip4()
2570 static_mappings = self.vapi.nat44_static_mapping_dump()
2571 self.assertEqual(1, len(static_mappings))
2572 self.assertEqual(self.pg7.sw_if_index,
2573 static_mappings[0].external_sw_if_index)
2574 self.assertEqual(static_mappings[0].tag, tag)
2576 # configure interface address again and check static mappings
2577 self.pg7.config_ip4()
2578 static_mappings = self.vapi.nat44_static_mapping_dump()
2579 self.assertEqual(2, len(static_mappings))
2581 for sm in static_mappings:
2582 if sm.external_sw_if_index == 0xFFFFFFFF:
2583 self.assertEqual(str(sm.external_ip_address),
2585 self.assertEqual(sm.tag, tag)
2587 self.assertTrue(resolved)
2589 # remove static mapping
2590 self.nat44_add_static_mapping(
2592 external_sw_if_index=self.pg7.sw_if_index,
2595 static_mappings = self.vapi.nat44_static_mapping_dump()
2596 self.assertEqual(0, len(static_mappings))
2598 def test_interface_addr_identity_nat(self):
2599 """ Identity NAT with addresses from interface """
2602 self.vapi.nat44_add_del_interface_addr(
2604 sw_if_index=self.pg7.sw_if_index)
2605 self.vapi.nat44_add_del_identity_mapping(
2607 sw_if_index=self.pg7.sw_if_index,
2609 protocol=IP_PROTOS.tcp,
2612 # identity mappings with external interface
2613 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2614 self.assertEqual(1, len(identity_mappings))
2615 self.assertEqual(self.pg7.sw_if_index,
2616 identity_mappings[0].sw_if_index)
2618 # configure interface address and check identity mappings
2619 self.pg7.config_ip4()
2620 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2622 self.assertEqual(2, len(identity_mappings))
2623 for sm in identity_mappings:
2624 if sm.sw_if_index == 0xFFFFFFFF:
2625 self.assertEqual(str(identity_mappings[0].ip_address),
2627 self.assertEqual(port, identity_mappings[0].port)
2628 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2630 self.assertTrue(resolved)
2632 # remove interface address and check identity mappings
2633 self.pg7.unconfig_ip4()
2634 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2635 self.assertEqual(1, len(identity_mappings))
2636 self.assertEqual(self.pg7.sw_if_index,
2637 identity_mappings[0].sw_if_index)
2639 def test_ipfix_nat44_sess(self):
2640 """ IPFIX logging NAT44 session created/deleted """
2641 self.ipfix_domain_id = 10
2642 self.ipfix_src_port = 20202
2643 collector_port = 30303
2644 bind_layers(UDP, IPFIX, dport=30303)
2645 self.nat44_add_address(self.nat_addr)
2646 flags = self.config_flags.NAT_IS_INSIDE
2647 self.vapi.nat44_interface_add_del_feature(
2648 sw_if_index=self.pg0.sw_if_index,
2649 flags=flags, is_add=1)
2650 self.vapi.nat44_interface_add_del_feature(
2651 sw_if_index=self.pg1.sw_if_index,
2653 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2654 src_address=self.pg3.local_ip4,
2656 template_interval=10,
2657 collector_port=collector_port)
2658 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2659 src_port=self.ipfix_src_port,
2662 pkts = self.create_stream_in(self.pg0, self.pg1)
2663 self.pg0.add_stream(pkts)
2664 self.pg_enable_capture(self.pg_interfaces)
2666 capture = self.pg1.get_capture(len(pkts))
2667 self.verify_capture_out(capture)
2668 self.nat44_add_address(self.nat_addr, is_add=0)
2669 self.vapi.ipfix_flush()
2670 capture = self.pg3.get_capture(7)
2671 ipfix = IPFIXDecoder()
2672 # first load template
2674 self.assertTrue(p.haslayer(IPFIX))
2675 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2676 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2677 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2678 self.assertEqual(p[UDP].dport, collector_port)
2679 self.assertEqual(p[IPFIX].observationDomainID,
2680 self.ipfix_domain_id)
2681 if p.haslayer(Template):
2682 ipfix.add_template(p.getlayer(Template))
2683 # verify events in data set
2685 if p.haslayer(Data):
2686 data = ipfix.decode_data_set(p.getlayer(Set))
2687 self.verify_ipfix_nat44_ses(data)
2689 def test_ipfix_addr_exhausted(self):
2690 """ IPFIX logging NAT addresses exhausted """
2691 flags = self.config_flags.NAT_IS_INSIDE
2692 self.vapi.nat44_interface_add_del_feature(
2693 sw_if_index=self.pg0.sw_if_index,
2694 flags=flags, is_add=1)
2695 self.vapi.nat44_interface_add_del_feature(
2696 sw_if_index=self.pg1.sw_if_index,
2698 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2699 src_address=self.pg3.local_ip4,
2701 template_interval=10)
2702 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2703 src_port=self.ipfix_src_port,
2706 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2707 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2709 self.pg0.add_stream(p)
2710 self.pg_enable_capture(self.pg_interfaces)
2712 self.pg1.assert_nothing_captured()
2714 self.vapi.ipfix_flush()
2715 capture = self.pg3.get_capture(7)
2716 ipfix = IPFIXDecoder()
2717 # first load template
2719 self.assertTrue(p.haslayer(IPFIX))
2720 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2721 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2722 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2723 self.assertEqual(p[UDP].dport, 4739)
2724 self.assertEqual(p[IPFIX].observationDomainID,
2725 self.ipfix_domain_id)
2726 if p.haslayer(Template):
2727 ipfix.add_template(p.getlayer(Template))
2728 # verify events in data set
2730 if p.haslayer(Data):
2731 data = ipfix.decode_data_set(p.getlayer(Set))
2732 self.verify_ipfix_addr_exhausted(data)
2734 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2735 def test_ipfix_max_sessions(self):
2736 """ IPFIX logging maximum session entries exceeded """
2737 self.nat44_add_address(self.nat_addr)
2738 flags = self.config_flags.NAT_IS_INSIDE
2739 self.vapi.nat44_interface_add_del_feature(
2740 sw_if_index=self.pg0.sw_if_index,
2741 flags=flags, is_add=1)
2742 self.vapi.nat44_interface_add_del_feature(
2743 sw_if_index=self.pg1.sw_if_index,
2746 nat44_config = self.vapi.nat_show_config()
2747 max_sessions = 10 * nat44_config.translation_buckets
2750 for i in range(0, max_sessions):
2751 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2752 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2753 IP(src=src, dst=self.pg1.remote_ip4) /
2756 self.pg0.add_stream(pkts)
2757 self.pg_enable_capture(self.pg_interfaces)
2760 self.pg1.get_capture(max_sessions)
2761 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2762 src_address=self.pg3.local_ip4,
2764 template_interval=10)
2765 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2766 src_port=self.ipfix_src_port,
2769 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2770 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2772 self.pg0.add_stream(p)
2773 self.pg_enable_capture(self.pg_interfaces)
2775 self.pg1.assert_nothing_captured()
2777 self.vapi.ipfix_flush()
2778 capture = self.pg3.get_capture(7)
2779 ipfix = IPFIXDecoder()
2780 # first load template
2782 self.assertTrue(p.haslayer(IPFIX))
2783 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2784 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2785 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2786 self.assertEqual(p[UDP].dport, 4739)
2787 self.assertEqual(p[IPFIX].observationDomainID,
2788 self.ipfix_domain_id)
2789 if p.haslayer(Template):
2790 ipfix.add_template(p.getlayer(Template))
2791 # verify events in data set
2793 if p.haslayer(Data):
2794 data = ipfix.decode_data_set(p.getlayer(Set))
2795 self.verify_ipfix_max_sessions(data, max_sessions)
2797 def test_syslog_apmap(self):
2798 """ Test syslog address and port mapping creation and deletion """
2799 self.vapi.syslog_set_filter(
2800 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2801 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2802 self.nat44_add_address(self.nat_addr)
2803 flags = self.config_flags.NAT_IS_INSIDE
2804 self.vapi.nat44_interface_add_del_feature(
2805 sw_if_index=self.pg0.sw_if_index,
2806 flags=flags, is_add=1)
2807 self.vapi.nat44_interface_add_del_feature(
2808 sw_if_index=self.pg1.sw_if_index,
2811 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2812 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2813 TCP(sport=self.tcp_port_in, dport=20))
2814 self.pg0.add_stream(p)
2815 self.pg_enable_capture(self.pg_interfaces)
2817 capture = self.pg1.get_capture(1)
2818 self.tcp_port_out = capture[0][TCP].sport
2819 capture = self.pg3.get_capture(1)
2820 self.verify_syslog_apmap(capture[0][Raw].load)
2822 self.pg_enable_capture(self.pg_interfaces)
2824 self.nat44_add_address(self.nat_addr, is_add=0)
2825 capture = self.pg3.get_capture(1)
2826 self.verify_syslog_apmap(capture[0][Raw].load, False)
2828 def test_pool_addr_fib(self):
2829 """ NAT44 add pool addresses to FIB """
2830 static_addr = '10.0.0.10'
2831 self.nat44_add_address(self.nat_addr)
2832 flags = self.config_flags.NAT_IS_INSIDE
2833 self.vapi.nat44_interface_add_del_feature(
2834 sw_if_index=self.pg0.sw_if_index,
2835 flags=flags, is_add=1)
2836 self.vapi.nat44_interface_add_del_feature(
2837 sw_if_index=self.pg1.sw_if_index,
2839 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2842 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2843 ARP(op=ARP.who_has, pdst=self.nat_addr,
2844 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2845 self.pg1.add_stream(p)
2846 self.pg_enable_capture(self.pg_interfaces)
2848 capture = self.pg1.get_capture(1)
2849 self.assertTrue(capture[0].haslayer(ARP))
2850 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2853 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2854 ARP(op=ARP.who_has, pdst=static_addr,
2855 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2856 self.pg1.add_stream(p)
2857 self.pg_enable_capture(self.pg_interfaces)
2859 capture = self.pg1.get_capture(1)
2860 self.assertTrue(capture[0].haslayer(ARP))
2861 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2863 # send ARP to non-NAT44 interface
2864 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2865 ARP(op=ARP.who_has, pdst=self.nat_addr,
2866 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2867 self.pg2.add_stream(p)
2868 self.pg_enable_capture(self.pg_interfaces)
2870 self.pg1.assert_nothing_captured()
2872 # remove addresses and verify
2873 self.nat44_add_address(self.nat_addr, is_add=0)
2874 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2877 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2878 ARP(op=ARP.who_has, pdst=self.nat_addr,
2879 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2880 self.pg1.add_stream(p)
2881 self.pg_enable_capture(self.pg_interfaces)
2883 self.pg1.assert_nothing_captured()
2885 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2886 ARP(op=ARP.who_has, pdst=static_addr,
2887 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2888 self.pg1.add_stream(p)
2889 self.pg_enable_capture(self.pg_interfaces)
2891 self.pg1.assert_nothing_captured()
2893 def test_vrf_mode(self):
2894 """ NAT44 tenant VRF aware address pool mode """
2898 nat_ip1 = "10.0.0.10"
2899 nat_ip2 = "10.0.0.11"
2901 self.pg0.unconfig_ip4()
2902 self.pg1.unconfig_ip4()
2903 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2904 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2905 self.pg0.set_table_ip4(vrf_id1)
2906 self.pg1.set_table_ip4(vrf_id2)
2907 self.pg0.config_ip4()
2908 self.pg1.config_ip4()
2909 self.pg0.resolve_arp()
2910 self.pg1.resolve_arp()
2912 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2913 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2914 flags = self.config_flags.NAT_IS_INSIDE
2915 self.vapi.nat44_interface_add_del_feature(
2916 sw_if_index=self.pg0.sw_if_index,
2917 flags=flags, is_add=1)
2918 self.vapi.nat44_interface_add_del_feature(
2919 sw_if_index=self.pg1.sw_if_index,
2920 flags=flags, is_add=1)
2921 self.vapi.nat44_interface_add_del_feature(
2922 sw_if_index=self.pg2.sw_if_index,
2927 pkts = self.create_stream_in(self.pg0, self.pg2)
2928 self.pg0.add_stream(pkts)
2929 self.pg_enable_capture(self.pg_interfaces)
2931 capture = self.pg2.get_capture(len(pkts))
2932 self.verify_capture_out(capture, nat_ip1)
2935 pkts = self.create_stream_in(self.pg1, self.pg2)
2936 self.pg1.add_stream(pkts)
2937 self.pg_enable_capture(self.pg_interfaces)
2939 capture = self.pg2.get_capture(len(pkts))
2940 self.verify_capture_out(capture, nat_ip2)
2943 self.pg0.unconfig_ip4()
2944 self.pg1.unconfig_ip4()
2945 self.pg0.set_table_ip4(0)
2946 self.pg1.set_table_ip4(0)
2947 self.pg0.config_ip4()
2948 self.pg1.config_ip4()
2949 self.pg0.resolve_arp()
2950 self.pg1.resolve_arp()
2951 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2952 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2954 def test_vrf_feature_independent(self):
2955 """ NAT44 tenant VRF independent address pool mode """
2957 nat_ip1 = "10.0.0.10"
2958 nat_ip2 = "10.0.0.11"
2960 self.nat44_add_address(nat_ip1)
2961 self.nat44_add_address(nat_ip2, vrf_id=99)
2962 flags = self.config_flags.NAT_IS_INSIDE
2963 self.vapi.nat44_interface_add_del_feature(
2964 sw_if_index=self.pg0.sw_if_index,
2965 flags=flags, is_add=1)
2966 self.vapi.nat44_interface_add_del_feature(
2967 sw_if_index=self.pg1.sw_if_index,
2968 flags=flags, is_add=1)
2969 self.vapi.nat44_interface_add_del_feature(
2970 sw_if_index=self.pg2.sw_if_index,
2974 pkts = self.create_stream_in(self.pg0, self.pg2)
2975 self.pg0.add_stream(pkts)
2976 self.pg_enable_capture(self.pg_interfaces)
2978 capture = self.pg2.get_capture(len(pkts))
2979 self.verify_capture_out(capture, nat_ip1)
2982 pkts = self.create_stream_in(self.pg1, self.pg2)
2983 self.pg1.add_stream(pkts)
2984 self.pg_enable_capture(self.pg_interfaces)
2986 capture = self.pg2.get_capture(len(pkts))
2987 self.verify_capture_out(capture, nat_ip1)
2989 def create_routes_and_neigbors(self):
2990 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
2991 [VppRoutePath(self.pg7.remote_ip4,
2992 self.pg7.sw_if_index)])
2993 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
2994 [VppRoutePath(self.pg8.remote_ip4,
2995 self.pg8.sw_if_index)])
2999 n1 = VppNeighbor(self,
3000 self.pg7.sw_if_index,
3001 self.pg7.remote_mac,
3002 self.pg7.remote_ip4,
3004 n2 = VppNeighbor(self,
3005 self.pg8.sw_if_index,
3006 self.pg8.remote_mac,
3007 self.pg8.remote_ip4,
3012 def test_dynamic_ipless_interfaces(self):
3013 """ NAT44 interfaces without configured IP address """
3014 self.create_routes_and_neigbors()
3015 self.nat44_add_address(self.nat_addr)
3016 flags = self.config_flags.NAT_IS_INSIDE
3017 self.vapi.nat44_interface_add_del_feature(
3018 sw_if_index=self.pg7.sw_if_index,
3019 flags=flags, is_add=1)
3020 self.vapi.nat44_interface_add_del_feature(
3021 sw_if_index=self.pg8.sw_if_index,
3025 pkts = self.create_stream_in(self.pg7, self.pg8)
3026 self.pg7.add_stream(pkts)
3027 self.pg_enable_capture(self.pg_interfaces)
3029 capture = self.pg8.get_capture(len(pkts))
3030 self.verify_capture_out(capture)
3033 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3034 self.pg8.add_stream(pkts)
3035 self.pg_enable_capture(self.pg_interfaces)
3037 capture = self.pg7.get_capture(len(pkts))
3038 self.verify_capture_in(capture, self.pg7)
3040 def test_static_ipless_interfaces(self):
3041 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3043 self.create_routes_and_neigbors()
3044 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3045 flags = self.config_flags.NAT_IS_INSIDE
3046 self.vapi.nat44_interface_add_del_feature(
3047 sw_if_index=self.pg7.sw_if_index,
3048 flags=flags, is_add=1)
3049 self.vapi.nat44_interface_add_del_feature(
3050 sw_if_index=self.pg8.sw_if_index,
3054 pkts = self.create_stream_out(self.pg8)
3055 self.pg8.add_stream(pkts)
3056 self.pg_enable_capture(self.pg_interfaces)
3058 capture = self.pg7.get_capture(len(pkts))
3059 self.verify_capture_in(capture, self.pg7)
3062 pkts = self.create_stream_in(self.pg7, self.pg8)
3063 self.pg7.add_stream(pkts)
3064 self.pg_enable_capture(self.pg_interfaces)
3066 capture = self.pg8.get_capture(len(pkts))
3067 self.verify_capture_out(capture, self.nat_addr, True)
3069 def test_static_with_port_ipless_interfaces(self):
3070 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3072 self.tcp_port_out = 30606
3073 self.udp_port_out = 30607
3074 self.icmp_id_out = 30608
3076 self.create_routes_and_neigbors()
3077 self.nat44_add_address(self.nat_addr)
3078 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3079 self.tcp_port_in, self.tcp_port_out,
3080 proto=IP_PROTOS.tcp)
3081 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3082 self.udp_port_in, self.udp_port_out,
3083 proto=IP_PROTOS.udp)
3084 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3085 self.icmp_id_in, self.icmp_id_out,
3086 proto=IP_PROTOS.icmp)
3087 flags = self.config_flags.NAT_IS_INSIDE
3088 self.vapi.nat44_interface_add_del_feature(
3089 sw_if_index=self.pg7.sw_if_index,
3090 flags=flags, is_add=1)
3091 self.vapi.nat44_interface_add_del_feature(
3092 sw_if_index=self.pg8.sw_if_index,
3096 pkts = self.create_stream_out(self.pg8)
3097 self.pg8.add_stream(pkts)
3098 self.pg_enable_capture(self.pg_interfaces)
3100 capture = self.pg7.get_capture(len(pkts))
3101 self.verify_capture_in(capture, self.pg7)
3104 pkts = self.create_stream_in(self.pg7, self.pg8)
3105 self.pg7.add_stream(pkts)
3106 self.pg_enable_capture(self.pg_interfaces)
3108 capture = self.pg8.get_capture(len(pkts))
3109 self.verify_capture_out(capture)
3111 def test_static_unknown_proto(self):
3112 """ 1:1 NAT translate packet with unknown protocol """
3113 nat_ip = "10.0.0.10"
3114 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3115 flags = self.config_flags.NAT_IS_INSIDE
3116 self.vapi.nat44_interface_add_del_feature(
3117 sw_if_index=self.pg0.sw_if_index,
3118 flags=flags, is_add=1)
3119 self.vapi.nat44_interface_add_del_feature(
3120 sw_if_index=self.pg1.sw_if_index,
3124 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3125 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3127 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3128 TCP(sport=1234, dport=1234))
3129 self.pg0.add_stream(p)
3130 self.pg_enable_capture(self.pg_interfaces)
3132 p = self.pg1.get_capture(1)
3135 self.assertEqual(packet[IP].src, nat_ip)
3136 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3137 self.assertEqual(packet.haslayer(GRE), 1)
3138 self.assert_packet_checksums_valid(packet)
3140 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3144 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3145 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3147 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3148 TCP(sport=1234, dport=1234))
3149 self.pg1.add_stream(p)
3150 self.pg_enable_capture(self.pg_interfaces)
3152 p = self.pg0.get_capture(1)
3155 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3156 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3157 self.assertEqual(packet.haslayer(GRE), 1)
3158 self.assert_packet_checksums_valid(packet)
3160 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3163 def test_hairpinning_static_unknown_proto(self):
3164 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3166 host = self.pg0.remote_hosts[0]
3167 server = self.pg0.remote_hosts[1]
3169 host_nat_ip = "10.0.0.10"
3170 server_nat_ip = "10.0.0.11"
3172 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3173 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3174 flags = self.config_flags.NAT_IS_INSIDE
3175 self.vapi.nat44_interface_add_del_feature(
3176 sw_if_index=self.pg0.sw_if_index,
3177 flags=flags, is_add=1)
3178 self.vapi.nat44_interface_add_del_feature(
3179 sw_if_index=self.pg1.sw_if_index,
3183 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3184 IP(src=host.ip4, dst=server_nat_ip) /
3186 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3187 TCP(sport=1234, dport=1234))
3188 self.pg0.add_stream(p)
3189 self.pg_enable_capture(self.pg_interfaces)
3191 p = self.pg0.get_capture(1)
3194 self.assertEqual(packet[IP].src, host_nat_ip)
3195 self.assertEqual(packet[IP].dst, server.ip4)
3196 self.assertEqual(packet.haslayer(GRE), 1)
3197 self.assert_packet_checksums_valid(packet)
3199 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3203 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3204 IP(src=server.ip4, dst=host_nat_ip) /
3206 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3207 TCP(sport=1234, dport=1234))
3208 self.pg0.add_stream(p)
3209 self.pg_enable_capture(self.pg_interfaces)
3211 p = self.pg0.get_capture(1)
3214 self.assertEqual(packet[IP].src, server_nat_ip)
3215 self.assertEqual(packet[IP].dst, host.ip4)
3216 self.assertEqual(packet.haslayer(GRE), 1)
3217 self.assert_packet_checksums_valid(packet)
3219 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3222 def test_output_feature(self):
3223 """ NAT44 interface output feature (in2out postrouting) """
3224 self.nat44_add_address(self.nat_addr)
3225 flags = self.config_flags.NAT_IS_INSIDE
3226 self.vapi.nat44_interface_add_del_output_feature(
3227 is_add=1, flags=flags,
3228 sw_if_index=self.pg0.sw_if_index)
3229 self.vapi.nat44_interface_add_del_output_feature(
3230 is_add=1, flags=flags,
3231 sw_if_index=self.pg1.sw_if_index)
3232 self.vapi.nat44_interface_add_del_output_feature(
3234 sw_if_index=self.pg3.sw_if_index)
3237 pkts = self.create_stream_in(self.pg0, self.pg3)
3238 self.pg0.add_stream(pkts)
3239 self.pg_enable_capture(self.pg_interfaces)
3241 capture = self.pg3.get_capture(len(pkts))
3242 self.verify_capture_out(capture)
3245 pkts = self.create_stream_out(self.pg3)
3246 self.pg3.add_stream(pkts)
3247 self.pg_enable_capture(self.pg_interfaces)
3249 capture = self.pg0.get_capture(len(pkts))
3250 self.verify_capture_in(capture, self.pg0)
3252 # from non-NAT interface to NAT inside interface
3253 pkts = self.create_stream_in(self.pg2, self.pg0)
3254 self.pg2.add_stream(pkts)
3255 self.pg_enable_capture(self.pg_interfaces)
3257 capture = self.pg0.get_capture(len(pkts))
3258 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3260 def test_output_feature_vrf_aware(self):
3261 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3262 nat_ip_vrf10 = "10.0.0.10"
3263 nat_ip_vrf20 = "10.0.0.20"
3265 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3266 [VppRoutePath(self.pg3.remote_ip4,
3267 self.pg3.sw_if_index)],
3269 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3270 [VppRoutePath(self.pg3.remote_ip4,
3271 self.pg3.sw_if_index)],
3276 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3277 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3278 flags = self.config_flags.NAT_IS_INSIDE
3279 self.vapi.nat44_interface_add_del_output_feature(
3280 is_add=1, flags=flags,
3281 sw_if_index=self.pg4.sw_if_index)
3282 self.vapi.nat44_interface_add_del_output_feature(
3283 is_add=1, flags=flags,
3284 sw_if_index=self.pg6.sw_if_index)
3285 self.vapi.nat44_interface_add_del_output_feature(
3287 sw_if_index=self.pg3.sw_if_index)
3290 pkts = self.create_stream_in(self.pg4, self.pg3)
3291 self.pg4.add_stream(pkts)
3292 self.pg_enable_capture(self.pg_interfaces)
3294 capture = self.pg3.get_capture(len(pkts))
3295 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3298 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3299 self.pg3.add_stream(pkts)
3300 self.pg_enable_capture(self.pg_interfaces)
3302 capture = self.pg4.get_capture(len(pkts))
3303 self.verify_capture_in(capture, self.pg4)
3306 pkts = self.create_stream_in(self.pg6, self.pg3)
3307 self.pg6.add_stream(pkts)
3308 self.pg_enable_capture(self.pg_interfaces)
3310 capture = self.pg3.get_capture(len(pkts))
3311 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3314 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3315 self.pg3.add_stream(pkts)
3316 self.pg_enable_capture(self.pg_interfaces)
3318 capture = self.pg6.get_capture(len(pkts))
3319 self.verify_capture_in(capture, self.pg6)
3321 def test_output_feature_hairpinning(self):
3322 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3323 host = self.pg0.remote_hosts[0]
3324 server = self.pg0.remote_hosts[1]
3327 server_in_port = 5678
3328 server_out_port = 8765
3330 self.nat44_add_address(self.nat_addr)
3331 flags = self.config_flags.NAT_IS_INSIDE
3332 self.vapi.nat44_interface_add_del_output_feature(
3333 is_add=1, flags=flags,
3334 sw_if_index=self.pg0.sw_if_index)
3335 self.vapi.nat44_interface_add_del_output_feature(
3337 sw_if_index=self.pg1.sw_if_index)
3339 # add static mapping for server
3340 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3341 server_in_port, server_out_port,
3342 proto=IP_PROTOS.tcp)
3344 # send packet from host to server
3345 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3346 IP(src=host.ip4, dst=self.nat_addr) /
3347 TCP(sport=host_in_port, dport=server_out_port))
3348 self.pg0.add_stream(p)
3349 self.pg_enable_capture(self.pg_interfaces)
3351 capture = self.pg0.get_capture(1)
3356 self.assertEqual(ip.src, self.nat_addr)
3357 self.assertEqual(ip.dst, server.ip4)
3358 self.assertNotEqual(tcp.sport, host_in_port)
3359 self.assertEqual(tcp.dport, server_in_port)
3360 self.assert_packet_checksums_valid(p)
3361 host_out_port = tcp.sport
3363 self.logger.error(ppp("Unexpected or invalid packet:", p))
3366 # send reply from server to host
3367 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3368 IP(src=server.ip4, dst=self.nat_addr) /
3369 TCP(sport=server_in_port, dport=host_out_port))
3370 self.pg0.add_stream(p)
3371 self.pg_enable_capture(self.pg_interfaces)
3373 capture = self.pg0.get_capture(1)
3378 self.assertEqual(ip.src, self.nat_addr)
3379 self.assertEqual(ip.dst, host.ip4)
3380 self.assertEqual(tcp.sport, server_out_port)
3381 self.assertEqual(tcp.dport, host_in_port)
3382 self.assert_packet_checksums_valid(p)
3384 self.logger.error(ppp("Unexpected or invalid packet:", p))
3387 def test_one_armed_nat44(self):
3388 """ One armed NAT44 """
3389 remote_host = self.pg9.remote_hosts[0]
3390 local_host = self.pg9.remote_hosts[1]
3393 self.nat44_add_address(self.nat_addr)
3394 flags = self.config_flags.NAT_IS_INSIDE
3395 self.vapi.nat44_interface_add_del_feature(
3396 sw_if_index=self.pg9.sw_if_index,
3398 self.vapi.nat44_interface_add_del_feature(
3399 sw_if_index=self.pg9.sw_if_index,
3400 flags=flags, is_add=1)
3403 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3404 IP(src=local_host.ip4, dst=remote_host.ip4) /
3405 TCP(sport=12345, dport=80))
3406 self.pg9.add_stream(p)
3407 self.pg_enable_capture(self.pg_interfaces)
3409 capture = self.pg9.get_capture(1)
3414 self.assertEqual(ip.src, self.nat_addr)
3415 self.assertEqual(ip.dst, remote_host.ip4)
3416 self.assertNotEqual(tcp.sport, 12345)
3417 external_port = tcp.sport
3418 self.assertEqual(tcp.dport, 80)
3419 self.assert_packet_checksums_valid(p)
3421 self.logger.error(ppp("Unexpected or invalid packet:", p))
3425 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3426 IP(src=remote_host.ip4, dst=self.nat_addr) /
3427 TCP(sport=80, dport=external_port))
3428 self.pg9.add_stream(p)
3429 self.pg_enable_capture(self.pg_interfaces)
3431 capture = self.pg9.get_capture(1)
3436 self.assertEqual(ip.src, remote_host.ip4)
3437 self.assertEqual(ip.dst, local_host.ip4)
3438 self.assertEqual(tcp.sport, 80)
3439 self.assertEqual(tcp.dport, 12345)
3440 self.assert_packet_checksums_valid(p)
3442 self.logger.error(ppp("Unexpected or invalid packet:", p))
3445 err = self.statistics.get_err_counter(
3446 '/err/nat44-classify/next in2out')
3447 self.assertEqual(err, 1)
3448 err = self.statistics.get_err_counter(
3449 '/err/nat44-classify/next out2in')
3450 self.assertEqual(err, 1)
3452 def test_del_session(self):
3453 """ Delete NAT44 session """
3454 self.nat44_add_address(self.nat_addr)
3455 flags = self.config_flags.NAT_IS_INSIDE
3456 self.vapi.nat44_interface_add_del_feature(
3457 sw_if_index=self.pg0.sw_if_index,
3458 flags=flags, is_add=1)
3459 self.vapi.nat44_interface_add_del_feature(
3460 sw_if_index=self.pg1.sw_if_index,
3463 pkts = self.create_stream_in(self.pg0, self.pg1)
3464 self.pg0.add_stream(pkts)
3465 self.pg_enable_capture(self.pg_interfaces)
3467 self.pg1.get_capture(len(pkts))
3469 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3470 nsessions = len(sessions)
3472 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3473 port=sessions[0].inside_port,
3474 protocol=sessions[0].protocol,
3475 flags=self.config_flags.NAT_IS_INSIDE)
3476 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3477 port=sessions[1].outside_port,
3478 protocol=sessions[1].protocol)
3480 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3481 self.assertEqual(nsessions - len(sessions), 2)
3483 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3484 port=sessions[0].inside_port,
3485 protocol=sessions[0].protocol,
3486 flags=self.config_flags.NAT_IS_INSIDE)
3488 self.verify_no_nat44_user()
3490 def test_frag_in_order(self):
3491 """ NAT44 translate fragments arriving in order """
3493 self.nat44_add_address(self.nat_addr)
3494 flags = self.config_flags.NAT_IS_INSIDE
3495 self.vapi.nat44_interface_add_del_feature(
3496 sw_if_index=self.pg0.sw_if_index,
3497 flags=flags, is_add=1)
3498 self.vapi.nat44_interface_add_del_feature(
3499 sw_if_index=self.pg1.sw_if_index,
3502 self.frag_in_order(proto=IP_PROTOS.tcp)
3503 self.frag_in_order(proto=IP_PROTOS.udp)
3504 self.frag_in_order(proto=IP_PROTOS.icmp)
3506 def test_frag_forwarding(self):
3507 """ NAT44 forwarding fragment test """
3508 self.vapi.nat44_add_del_interface_addr(
3510 sw_if_index=self.pg1.sw_if_index)
3511 flags = self.config_flags.NAT_IS_INSIDE
3512 self.vapi.nat44_interface_add_del_feature(
3513 sw_if_index=self.pg0.sw_if_index,
3514 flags=flags, is_add=1)
3515 self.vapi.nat44_interface_add_del_feature(
3516 sw_if_index=self.pg1.sw_if_index,
3518 self.vapi.nat44_forwarding_enable_disable(enable=1)
3520 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3521 pkts = self.create_stream_frag(self.pg1,
3522 self.pg0.remote_ip4,
3526 proto=IP_PROTOS.udp)
3527 self.pg1.add_stream(pkts)
3528 self.pg_enable_capture(self.pg_interfaces)
3530 frags = self.pg0.get_capture(len(pkts))
3531 p = self.reass_frags_and_verify(frags,
3532 self.pg1.remote_ip4,
3533 self.pg0.remote_ip4)
3534 self.assertEqual(p[UDP].sport, 4789)
3535 self.assertEqual(p[UDP].dport, 4789)
3536 self.assertEqual(data, p[Raw].load)
3538 def test_reass_hairpinning(self):
3539 """ NAT44 fragments hairpinning """
3541 self.server = self.pg0.remote_hosts[1]
3542 self.host_in_port = random.randint(1025, 65535)
3543 self.server_in_port = random.randint(1025, 65535)
3544 self.server_out_port = random.randint(1025, 65535)
3546 self.nat44_add_address(self.nat_addr)
3547 flags = self.config_flags.NAT_IS_INSIDE
3548 self.vapi.nat44_interface_add_del_feature(
3549 sw_if_index=self.pg0.sw_if_index,
3550 flags=flags, is_add=1)
3551 self.vapi.nat44_interface_add_del_feature(
3552 sw_if_index=self.pg1.sw_if_index,
3554 # add static mapping for server
3555 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3556 self.server_in_port,
3557 self.server_out_port,
3558 proto=IP_PROTOS.tcp)
3559 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3560 self.server_in_port,
3561 self.server_out_port,
3562 proto=IP_PROTOS.udp)
3563 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3565 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3566 self.reass_hairpinning(proto=IP_PROTOS.udp)
3567 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3569 def test_frag_out_of_order(self):
3570 """ NAT44 translate fragments arriving out of order """
3572 self.nat44_add_address(self.nat_addr)
3573 flags = self.config_flags.NAT_IS_INSIDE
3574 self.vapi.nat44_interface_add_del_feature(
3575 sw_if_index=self.pg0.sw_if_index,
3576 flags=flags, is_add=1)
3577 self.vapi.nat44_interface_add_del_feature(
3578 sw_if_index=self.pg1.sw_if_index,
3581 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3582 self.frag_out_of_order(proto=IP_PROTOS.udp)
3583 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3585 def test_port_restricted(self):
3586 """ Port restricted NAT44 (MAP-E CE) """
3587 self.nat44_add_address(self.nat_addr)
3588 flags = self.config_flags.NAT_IS_INSIDE
3589 self.vapi.nat44_interface_add_del_feature(
3590 sw_if_index=self.pg0.sw_if_index,
3591 flags=flags, is_add=1)
3592 self.vapi.nat44_interface_add_del_feature(
3593 sw_if_index=self.pg1.sw_if_index,
3595 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3600 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3601 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3602 TCP(sport=4567, dport=22))
3603 self.pg0.add_stream(p)
3604 self.pg_enable_capture(self.pg_interfaces)
3606 capture = self.pg1.get_capture(1)
3611 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3612 self.assertEqual(ip.src, self.nat_addr)
3613 self.assertEqual(tcp.dport, 22)
3614 self.assertNotEqual(tcp.sport, 4567)
3615 self.assertEqual((tcp.sport >> 6) & 63, 10)
3616 self.assert_packet_checksums_valid(p)
3618 self.logger.error(ppp("Unexpected or invalid packet:", p))
3621 def test_port_range(self):
3622 """ External address port range """
3623 self.nat44_add_address(self.nat_addr)
3624 flags = self.config_flags.NAT_IS_INSIDE
3625 self.vapi.nat44_interface_add_del_feature(
3626 sw_if_index=self.pg0.sw_if_index,
3627 flags=flags, is_add=1)
3628 self.vapi.nat44_interface_add_del_feature(
3629 sw_if_index=self.pg1.sw_if_index,
3631 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3636 for port in range(0, 5):
3637 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3638 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3639 TCP(sport=1125 + port))
3641 self.pg0.add_stream(pkts)
3642 self.pg_enable_capture(self.pg_interfaces)
3644 capture = self.pg1.get_capture(3)
3647 self.assertGreaterEqual(tcp.sport, 1025)
3648 self.assertLessEqual(tcp.sport, 1027)
3650 def test_multiple_outside_vrf(self):
3651 """ Multiple outside VRF """
3655 self.pg1.unconfig_ip4()
3656 self.pg2.unconfig_ip4()
3657 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3658 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3659 self.pg1.set_table_ip4(vrf_id1)
3660 self.pg2.set_table_ip4(vrf_id2)
3661 self.pg1.config_ip4()
3662 self.pg2.config_ip4()
3663 self.pg1.resolve_arp()
3664 self.pg2.resolve_arp()
3666 self.nat44_add_address(self.nat_addr)
3667 flags = self.config_flags.NAT_IS_INSIDE
3668 self.vapi.nat44_interface_add_del_feature(
3669 sw_if_index=self.pg0.sw_if_index,
3670 flags=flags, is_add=1)
3671 self.vapi.nat44_interface_add_del_feature(
3672 sw_if_index=self.pg1.sw_if_index,
3674 self.vapi.nat44_interface_add_del_feature(
3675 sw_if_index=self.pg2.sw_if_index,
3680 pkts = self.create_stream_in(self.pg0, self.pg1)
3681 self.pg0.add_stream(pkts)
3682 self.pg_enable_capture(self.pg_interfaces)
3684 capture = self.pg1.get_capture(len(pkts))
3685 self.verify_capture_out(capture, self.nat_addr)
3687 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3688 self.pg1.add_stream(pkts)
3689 self.pg_enable_capture(self.pg_interfaces)
3691 capture = self.pg0.get_capture(len(pkts))
3692 self.verify_capture_in(capture, self.pg0)
3694 self.tcp_port_in = 60303
3695 self.udp_port_in = 60304
3696 self.icmp_id_in = 60305
3699 pkts = self.create_stream_in(self.pg0, self.pg2)
3700 self.pg0.add_stream(pkts)
3701 self.pg_enable_capture(self.pg_interfaces)
3703 capture = self.pg2.get_capture(len(pkts))
3704 self.verify_capture_out(capture, self.nat_addr)
3706 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3707 self.pg2.add_stream(pkts)
3708 self.pg_enable_capture(self.pg_interfaces)
3710 capture = self.pg0.get_capture(len(pkts))
3711 self.verify_capture_in(capture, self.pg0)
3714 self.nat44_add_address(self.nat_addr, is_add=0)
3715 self.pg1.unconfig_ip4()
3716 self.pg2.unconfig_ip4()
3717 self.pg1.set_table_ip4(0)
3718 self.pg2.set_table_ip4(0)
3719 self.pg1.config_ip4()
3720 self.pg2.config_ip4()
3721 self.pg1.resolve_arp()
3722 self.pg2.resolve_arp()
3724 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3725 def test_session_timeout(self):
3726 """ NAT44 session timeouts """
3727 self.nat44_add_address(self.nat_addr)
3728 flags = self.config_flags.NAT_IS_INSIDE
3729 self.vapi.nat44_interface_add_del_feature(
3730 sw_if_index=self.pg0.sw_if_index,
3731 flags=flags, is_add=1)
3732 self.vapi.nat44_interface_add_del_feature(
3733 sw_if_index=self.pg1.sw_if_index,
3735 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3736 tcp_transitory=240, icmp=60)
3740 for i in range(0, max_sessions):
3741 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3742 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3743 IP(src=src, dst=self.pg1.remote_ip4) /
3744 UDP(sport=1025, dport=53))
3746 self.pg0.add_stream(pkts)
3747 self.pg_enable_capture(self.pg_interfaces)
3749 self.pg1.get_capture(max_sessions)
3754 for i in range(0, max_sessions):
3755 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3756 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3757 IP(src=src, dst=self.pg1.remote_ip4) /
3758 UDP(sport=1026, dport=53))
3760 self.pg0.add_stream(pkts)
3761 self.pg_enable_capture(self.pg_interfaces)
3763 self.pg1.get_capture(max_sessions)
3766 users = self.vapi.nat44_user_dump()
3768 nsessions = nsessions + user.nsessions
3769 self.assertLess(nsessions, 2 * max_sessions)
3771 def test_mss_clamping(self):
3772 """ TCP MSS clamping """
3773 self.nat44_add_address(self.nat_addr)
3774 flags = self.config_flags.NAT_IS_INSIDE
3775 self.vapi.nat44_interface_add_del_feature(
3776 sw_if_index=self.pg0.sw_if_index,
3777 flags=flags, is_add=1)
3778 self.vapi.nat44_interface_add_del_feature(
3779 sw_if_index=self.pg1.sw_if_index,
3782 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3783 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3784 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3785 flags="S", options=[('MSS', 1400)]))
3787 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3788 self.pg0.add_stream(p)
3789 self.pg_enable_capture(self.pg_interfaces)
3791 capture = self.pg1.get_capture(1)
3792 # Negotiated MSS value greater than configured - changed
3793 self.verify_mss_value(capture[0], 1000)
3795 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3796 self.pg0.add_stream(p)
3797 self.pg_enable_capture(self.pg_interfaces)
3799 capture = self.pg1.get_capture(1)
3800 # MSS clamping disabled - negotiated MSS unchanged
3801 self.verify_mss_value(capture[0], 1400)
3803 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3804 self.pg0.add_stream(p)
3805 self.pg_enable_capture(self.pg_interfaces)
3807 capture = self.pg1.get_capture(1)
3808 # Negotiated MSS value smaller than configured - unchanged
3809 self.verify_mss_value(capture[0], 1400)
3811 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3812 def test_ha_send(self):
3813 """ Send HA session synchronization events (active) """
3814 self.nat44_add_address(self.nat_addr)
3815 flags = self.config_flags.NAT_IS_INSIDE
3816 self.vapi.nat44_interface_add_del_feature(
3817 sw_if_index=self.pg0.sw_if_index,
3818 flags=flags, is_add=1)
3819 self.vapi.nat44_interface_add_del_feature(
3820 sw_if_index=self.pg1.sw_if_index,
3822 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3825 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3826 port=12346, session_refresh_interval=10)
3827 bind_layers(UDP, HANATStateSync, sport=12345)
3830 pkts = self.create_stream_in(self.pg0, self.pg1)
3831 self.pg0.add_stream(pkts)
3832 self.pg_enable_capture(self.pg_interfaces)
3834 capture = self.pg1.get_capture(len(pkts))
3835 self.verify_capture_out(capture)
3836 # active send HA events
3837 self.vapi.nat_ha_flush()
3838 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3839 self.assertEqual(stats[0][0], 3)
3840 capture = self.pg3.get_capture(1)
3842 self.assert_packet_checksums_valid(p)
3846 hanat = p[HANATStateSync]
3848 self.logger.error(ppp("Invalid packet:", p))
3851 self.assertEqual(ip.src, self.pg3.local_ip4)
3852 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3853 self.assertEqual(udp.sport, 12345)
3854 self.assertEqual(udp.dport, 12346)
3855 self.assertEqual(hanat.version, 1)
3856 self.assertEqual(hanat.thread_index, 0)
3857 self.assertEqual(hanat.count, 3)
3858 seq = hanat.sequence_number
3859 for event in hanat.events:
3860 self.assertEqual(event.event_type, 1)
3861 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3862 self.assertEqual(event.out_addr, self.nat_addr)
3863 self.assertEqual(event.fib_index, 0)
3865 # ACK received events
3866 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3867 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3868 UDP(sport=12346, dport=12345) /
3869 HANATStateSync(sequence_number=seq, flags='ACK'))
3870 self.pg3.add_stream(ack)
3872 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3873 self.assertEqual(stats[0][0], 1)
3875 # delete one session
3876 self.pg_enable_capture(self.pg_interfaces)
3877 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3878 port=self.tcp_port_in,
3879 protocol=IP_PROTOS.tcp,
3880 flags=self.config_flags.NAT_IS_INSIDE)
3881 self.vapi.nat_ha_flush()
3882 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3883 self.assertEqual(stats[0][0], 1)
3884 capture = self.pg3.get_capture(1)
3887 hanat = p[HANATStateSync]
3889 self.logger.error(ppp("Invalid packet:", p))
3892 self.assertGreater(hanat.sequence_number, seq)
3894 # do not send ACK, active retry send HA event again
3895 self.pg_enable_capture(self.pg_interfaces)
3897 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3898 self.assertEqual(stats[0][0], 3)
3899 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3900 self.assertEqual(stats[0][0], 1)
3901 capture = self.pg3.get_capture(3)
3902 for packet in capture:
3903 self.assertEqual(packet, p)
3905 # session counters refresh
3906 pkts = self.create_stream_out(self.pg1)
3907 self.pg1.add_stream(pkts)
3908 self.pg_enable_capture(self.pg_interfaces)
3910 self.pg0.get_capture(2)
3911 self.vapi.nat_ha_flush()
3912 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3913 self.assertEqual(stats[0][0], 2)
3914 capture = self.pg3.get_capture(1)
3916 self.assert_packet_checksums_valid(p)
3920 hanat = p[HANATStateSync]
3922 self.logger.error(ppp("Invalid packet:", p))
3925 self.assertEqual(ip.src, self.pg3.local_ip4)
3926 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3927 self.assertEqual(udp.sport, 12345)
3928 self.assertEqual(udp.dport, 12346)
3929 self.assertEqual(hanat.version, 1)
3930 self.assertEqual(hanat.count, 2)
3931 seq = hanat.sequence_number
3932 for event in hanat.events:
3933 self.assertEqual(event.event_type, 3)
3934 self.assertEqual(event.out_addr, self.nat_addr)
3935 self.assertEqual(event.fib_index, 0)
3936 self.assertEqual(event.total_pkts, 2)
3937 self.assertGreater(event.total_bytes, 0)
3939 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3940 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3941 UDP(sport=12346, dport=12345) /
3942 HANATStateSync(sequence_number=seq, flags='ACK'))
3943 self.pg3.add_stream(ack)
3945 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3946 self.assertEqual(stats[0][0], 2)
3948 def test_ha_recv(self):
3949 """ Receive HA session synchronization events (passive) """
3950 self.nat44_add_address(self.nat_addr)
3951 flags = self.config_flags.NAT_IS_INSIDE
3952 self.vapi.nat44_interface_add_del_feature(
3953 sw_if_index=self.pg0.sw_if_index,
3954 flags=flags, is_add=1)
3955 self.vapi.nat44_interface_add_del_feature(
3956 sw_if_index=self.pg1.sw_if_index,
3958 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3961 bind_layers(UDP, HANATStateSync, sport=12345)
3963 self.tcp_port_out = random.randint(1025, 65535)
3964 self.udp_port_out = random.randint(1025, 65535)
3966 # send HA session add events to failover/passive
3967 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3968 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3969 UDP(sport=12346, dport=12345) /
3970 HANATStateSync(sequence_number=1, events=[
3971 Event(event_type='add', protocol='tcp',
3972 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3973 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3974 eh_addr=self.pg1.remote_ip4,
3975 ehn_addr=self.pg1.remote_ip4,
3976 eh_port=self.tcp_external_port,
3977 ehn_port=self.tcp_external_port, fib_index=0),
3978 Event(event_type='add', protocol='udp',
3979 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3980 in_port=self.udp_port_in, out_port=self.udp_port_out,
3981 eh_addr=self.pg1.remote_ip4,
3982 ehn_addr=self.pg1.remote_ip4,
3983 eh_port=self.udp_external_port,
3984 ehn_port=self.udp_external_port, fib_index=0)]))
3986 self.pg3.add_stream(p)
3987 self.pg_enable_capture(self.pg_interfaces)
3990 capture = self.pg3.get_capture(1)
3993 hanat = p[HANATStateSync]
3995 self.logger.error(ppp("Invalid packet:", p))
3998 self.assertEqual(hanat.sequence_number, 1)
3999 self.assertEqual(hanat.flags, 'ACK')
4000 self.assertEqual(hanat.version, 1)
4001 self.assertEqual(hanat.thread_index, 0)
4002 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4003 self.assertEqual(stats[0][0], 1)
4004 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4005 self.assertEqual(stats[0][0], 2)
4006 users = self.statistics.get_counter('/nat44/total-users')
4007 self.assertEqual(users[0][0], 1)
4008 sessions = self.statistics.get_counter('/nat44/total-sessions')
4009 self.assertEqual(sessions[0][0], 2)
4010 users = self.vapi.nat44_user_dump()
4011 self.assertEqual(len(users), 1)
4012 self.assertEqual(str(users[0].ip_address),
4013 self.pg0.remote_ip4)
4014 # there should be 2 sessions created by HA
4015 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4017 self.assertEqual(len(sessions), 2)
4018 for session in sessions:
4019 self.assertEqual(str(session.inside_ip_address),
4020 self.pg0.remote_ip4)
4021 self.assertEqual(str(session.outside_ip_address),
4023 self.assertIn(session.inside_port,
4024 [self.tcp_port_in, self.udp_port_in])
4025 self.assertIn(session.outside_port,
4026 [self.tcp_port_out, self.udp_port_out])
4027 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4029 # send HA session delete event to failover/passive
4030 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4031 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4032 UDP(sport=12346, dport=12345) /
4033 HANATStateSync(sequence_number=2, events=[
4034 Event(event_type='del', protocol='udp',
4035 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4036 in_port=self.udp_port_in, out_port=self.udp_port_out,
4037 eh_addr=self.pg1.remote_ip4,
4038 ehn_addr=self.pg1.remote_ip4,
4039 eh_port=self.udp_external_port,
4040 ehn_port=self.udp_external_port, fib_index=0)]))
4042 self.pg3.add_stream(p)
4043 self.pg_enable_capture(self.pg_interfaces)
4046 capture = self.pg3.get_capture(1)
4049 hanat = p[HANATStateSync]
4051 self.logger.error(ppp("Invalid packet:", p))
4054 self.assertEqual(hanat.sequence_number, 2)
4055 self.assertEqual(hanat.flags, 'ACK')
4056 self.assertEqual(hanat.version, 1)
4057 users = self.vapi.nat44_user_dump()
4058 self.assertEqual(len(users), 1)
4059 self.assertEqual(str(users[0].ip_address),
4060 self.pg0.remote_ip4)
4061 # now we should have only 1 session, 1 deleted by HA
4062 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4064 self.assertEqual(len(sessions), 1)
4065 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4066 self.assertEqual(stats[0][0], 1)
4068 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4069 self.assertEqual(stats, 2)
4071 # send HA session refresh event to failover/passive
4072 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4073 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4074 UDP(sport=12346, dport=12345) /
4075 HANATStateSync(sequence_number=3, events=[
4076 Event(event_type='refresh', protocol='tcp',
4077 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4078 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4079 eh_addr=self.pg1.remote_ip4,
4080 ehn_addr=self.pg1.remote_ip4,
4081 eh_port=self.tcp_external_port,
4082 ehn_port=self.tcp_external_port, fib_index=0,
4083 total_bytes=1024, total_pkts=2)]))
4084 self.pg3.add_stream(p)
4085 self.pg_enable_capture(self.pg_interfaces)
4088 capture = self.pg3.get_capture(1)
4091 hanat = p[HANATStateSync]
4093 self.logger.error(ppp("Invalid packet:", p))
4096 self.assertEqual(hanat.sequence_number, 3)
4097 self.assertEqual(hanat.flags, 'ACK')
4098 self.assertEqual(hanat.version, 1)
4099 users = self.vapi.nat44_user_dump()
4100 self.assertEqual(len(users), 1)
4101 self.assertEqual(str(users[0].ip_address),
4102 self.pg0.remote_ip4)
4103 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4105 self.assertEqual(len(sessions), 1)
4106 session = sessions[0]
4107 self.assertEqual(session.total_bytes, 1024)
4108 self.assertEqual(session.total_pkts, 2)
4109 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4110 self.assertEqual(stats[0][0], 1)
4112 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4113 self.assertEqual(stats, 3)
4115 # send packet to test session created by HA
4116 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4117 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4118 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4119 self.pg1.add_stream(p)
4120 self.pg_enable_capture(self.pg_interfaces)
4122 capture = self.pg0.get_capture(1)
4128 self.logger.error(ppp("Invalid packet:", p))
4131 self.assertEqual(ip.src, self.pg1.remote_ip4)
4132 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4133 self.assertEqual(tcp.sport, self.tcp_external_port)
4134 self.assertEqual(tcp.dport, self.tcp_port_in)
4137 super(TestNAT44, self).tearDown()
4139 self.vapi.cli("clear logging")
4141 def show_commands_at_teardown(self):
4142 self.logger.info(self.vapi.cli("show nat44 addresses"))
4143 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4144 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4145 self.logger.info(self.vapi.cli("show nat44 interface address"))
4146 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4147 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4148 self.logger.info(self.vapi.cli("show nat timeouts"))
4150 self.vapi.cli("show nat addr-port-assignment-alg"))
4151 self.logger.info(self.vapi.cli("show nat ha"))
4154 class TestNAT44EndpointDependent(MethodHolder):
4155 """ Endpoint-Dependent mapping and filtering test cases """
4158 def setUpConstants(cls):
4159 super(TestNAT44EndpointDependent, cls).setUpConstants()
4160 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4163 def setUpClass(cls):
4164 super(TestNAT44EndpointDependent, cls).setUpClass()
4165 cls.vapi.cli("set log class nat level debug")
4167 cls.tcp_port_in = 6303
4168 cls.tcp_port_out = 6303
4169 cls.udp_port_in = 6304
4170 cls.udp_port_out = 6304
4171 cls.icmp_id_in = 6305
4172 cls.icmp_id_out = 6305
4173 cls.nat_addr = '10.0.0.3'
4174 cls.ipfix_src_port = 4739
4175 cls.ipfix_domain_id = 1
4176 cls.tcp_external_port = 80
4178 cls.create_pg_interfaces(range(9))
4179 cls.interfaces = list(cls.pg_interfaces[0:3])
4181 for i in cls.interfaces:
4186 cls.pg0.generate_remote_hosts(3)
4187 cls.pg0.configure_ipv4_neighbors()
4191 cls.pg4.generate_remote_hosts(2)
4192 cls.pg4.config_ip4()
4193 cls.vapi.sw_interface_add_del_address(
4194 sw_if_index=cls.pg4.sw_if_index,
4195 prefix="10.0.0.1/24")
4198 cls.pg4.resolve_arp()
4199 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4200 cls.pg4.resolve_arp()
4202 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4203 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4205 cls.pg5._local_ip4 = "10.1.1.1"
4206 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4207 cls.pg5.set_table_ip4(1)
4208 cls.pg5.config_ip4()
4210 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4211 [VppRoutePath("0.0.0.0",
4212 cls.pg5.sw_if_index)],
4217 cls.pg6._local_ip4 = "10.1.2.1"
4218 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4219 cls.pg6.set_table_ip4(1)
4220 cls.pg6.config_ip4()
4223 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4224 [VppRoutePath("0.0.0.0",
4225 cls.pg6.sw_if_index)],
4228 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4229 [VppRoutePath("0.0.0.0",
4234 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4235 [VppRoutePath("0.0.0.0", 0xffffffff,
4239 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4240 [VppRoutePath(cls.pg1.local_ip4,
4241 cls.pg1.sw_if_index)],
4248 cls.pg5.resolve_arp()
4249 cls.pg6.resolve_arp()
4252 cls.pg7.config_ip4()
4253 cls.pg7.resolve_arp()
4254 cls.pg7.generate_remote_hosts(3)
4255 cls.pg7.configure_ipv4_neighbors()
4258 cls.pg8.config_ip4()
4259 cls.pg8.resolve_arp()
4262 super(TestNAT44EndpointDependent, self).setUp()
4263 self.vapi.nat_set_timeouts(
4264 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4267 def tearDownClass(cls):
4268 super(TestNAT44EndpointDependent, cls).tearDownClass()
4270 def test_frag_in_order(self):
4271 """ NAT44 translate fragments arriving in order """
4272 self.nat44_add_address(self.nat_addr)
4273 flags = self.config_flags.NAT_IS_INSIDE
4274 self.vapi.nat44_interface_add_del_feature(
4275 sw_if_index=self.pg0.sw_if_index,
4276 flags=flags, is_add=1)
4277 self.vapi.nat44_interface_add_del_feature(
4278 sw_if_index=self.pg1.sw_if_index,
4280 self.frag_in_order(proto=IP_PROTOS.tcp)
4281 self.frag_in_order(proto=IP_PROTOS.udp)
4282 self.frag_in_order(proto=IP_PROTOS.icmp)
4284 def test_frag_in_order_dont_translate(self):
4285 """ NAT44 don't translate fragments arriving in order """
4286 flags = self.config_flags.NAT_IS_INSIDE
4287 self.vapi.nat44_interface_add_del_feature(
4288 sw_if_index=self.pg0.sw_if_index,
4289 flags=flags, is_add=1)
4290 self.vapi.nat44_interface_add_del_feature(
4291 sw_if_index=self.pg1.sw_if_index,
4293 self.vapi.nat44_forwarding_enable_disable(enable=True)
4294 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4296 def test_frag_out_of_order(self):
4297 """ NAT44 translate fragments arriving out of order """
4298 self.nat44_add_address(self.nat_addr)
4299 flags = self.config_flags.NAT_IS_INSIDE
4300 self.vapi.nat44_interface_add_del_feature(
4301 sw_if_index=self.pg0.sw_if_index,
4302 flags=flags, is_add=1)
4303 self.vapi.nat44_interface_add_del_feature(
4304 sw_if_index=self.pg1.sw_if_index,
4306 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4307 self.frag_out_of_order(proto=IP_PROTOS.udp)
4308 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4310 def test_frag_out_of_order_dont_translate(self):
4311 """ NAT44 don't translate fragments arriving out of order """
4312 flags = self.config_flags.NAT_IS_INSIDE
4313 self.vapi.nat44_interface_add_del_feature(
4314 sw_if_index=self.pg0.sw_if_index,
4315 flags=flags, is_add=1)
4316 self.vapi.nat44_interface_add_del_feature(
4317 sw_if_index=self.pg1.sw_if_index,
4319 self.vapi.nat44_forwarding_enable_disable(enable=True)
4320 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4322 def test_frag_in_order_in_plus_out(self):
4323 """ in+out interface fragments in order """
4324 flags = self.config_flags.NAT_IS_INSIDE
4325 self.vapi.nat44_interface_add_del_feature(
4326 sw_if_index=self.pg0.sw_if_index,
4328 self.vapi.nat44_interface_add_del_feature(
4329 sw_if_index=self.pg0.sw_if_index,
4330 flags=flags, is_add=1)
4331 self.vapi.nat44_interface_add_del_feature(
4332 sw_if_index=self.pg1.sw_if_index,
4334 self.vapi.nat44_interface_add_del_feature(
4335 sw_if_index=self.pg1.sw_if_index,
4336 flags=flags, is_add=1)
4338 self.server = self.pg1.remote_hosts[0]
4340 self.server_in_addr = self.server.ip4
4341 self.server_out_addr = '11.11.11.11'
4342 self.server_in_port = random.randint(1025, 65535)
4343 self.server_out_port = random.randint(1025, 65535)
4345 self.nat44_add_address(self.server_out_addr)
4347 # add static mappings for server
4348 self.nat44_add_static_mapping(self.server_in_addr,
4349 self.server_out_addr,
4350 self.server_in_port,
4351 self.server_out_port,
4352 proto=IP_PROTOS.tcp)
4353 self.nat44_add_static_mapping(self.server_in_addr,
4354 self.server_out_addr,
4355 self.server_in_port,
4356 self.server_out_port,
4357 proto=IP_PROTOS.udp)
4358 self.nat44_add_static_mapping(self.server_in_addr,
4359 self.server_out_addr,
4360 proto=IP_PROTOS.icmp)
4362 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4363 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4364 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4366 def test_frag_out_of_order_in_plus_out(self):
4367 """ in+out interface fragments out of order """
4368 flags = self.config_flags.NAT_IS_INSIDE
4369 self.vapi.nat44_interface_add_del_feature(
4370 sw_if_index=self.pg0.sw_if_index,
4372 self.vapi.nat44_interface_add_del_feature(
4373 sw_if_index=self.pg0.sw_if_index,
4374 flags=flags, is_add=1)
4375 self.vapi.nat44_interface_add_del_feature(
4376 sw_if_index=self.pg1.sw_if_index,
4378 self.vapi.nat44_interface_add_del_feature(
4379 sw_if_index=self.pg1.sw_if_index,
4380 flags=flags, is_add=1)
4382 self.server = self.pg1.remote_hosts[0]
4384 self.server_in_addr = self.server.ip4
4385 self.server_out_addr = '11.11.11.11'
4386 self.server_in_port = random.randint(1025, 65535)
4387 self.server_out_port = random.randint(1025, 65535)
4389 self.nat44_add_address(self.server_out_addr)
4391 # add static mappings for server
4392 self.nat44_add_static_mapping(self.server_in_addr,
4393 self.server_out_addr,
4394 self.server_in_port,
4395 self.server_out_port,
4396 proto=IP_PROTOS.tcp)
4397 self.nat44_add_static_mapping(self.server_in_addr,
4398 self.server_out_addr,
4399 self.server_in_port,
4400 self.server_out_port,
4401 proto=IP_PROTOS.udp)
4402 self.nat44_add_static_mapping(self.server_in_addr,
4403 self.server_out_addr,
4404 proto=IP_PROTOS.icmp)
4406 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4407 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4408 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4410 def test_reass_hairpinning(self):
4411 """ NAT44 fragments hairpinning """
4412 self.server = self.pg0.remote_hosts[1]
4413 self.host_in_port = random.randint(1025, 65535)
4414 self.server_in_port = random.randint(1025, 65535)
4415 self.server_out_port = random.randint(1025, 65535)
4417 self.nat44_add_address(self.nat_addr)
4418 flags = self.config_flags.NAT_IS_INSIDE
4419 self.vapi.nat44_interface_add_del_feature(
4420 sw_if_index=self.pg0.sw_if_index,
4421 flags=flags, is_add=1)
4422 self.vapi.nat44_interface_add_del_feature(
4423 sw_if_index=self.pg1.sw_if_index,
4425 # add static mapping for server
4426 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4427 self.server_in_port,
4428 self.server_out_port,
4429 proto=IP_PROTOS.tcp)
4430 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4431 self.server_in_port,
4432 self.server_out_port,
4433 proto=IP_PROTOS.udp)
4434 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4436 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4437 self.reass_hairpinning(proto=IP_PROTOS.udp)
4438 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4440 def test_dynamic(self):
4441 """ NAT44 dynamic translation test """
4443 self.nat44_add_address(self.nat_addr)
4444 flags = self.config_flags.NAT_IS_INSIDE
4445 self.vapi.nat44_interface_add_del_feature(
4446 sw_if_index=self.pg0.sw_if_index,
4447 flags=flags, is_add=1)
4448 self.vapi.nat44_interface_add_del_feature(
4449 sw_if_index=self.pg1.sw_if_index,
4452 nat_config = self.vapi.nat_show_config()
4453 self.assertEqual(1, nat_config.endpoint_dependent)
4456 tcpn = self.statistics.get_err_counter(
4457 '/err/nat44-ed-in2out-slowpath/TCP packets')
4458 udpn = self.statistics.get_err_counter(
4459 '/err/nat44-ed-in2out-slowpath/UDP packets')
4460 icmpn = self.statistics.get_err_counter(
4461 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4462 totaln = self.statistics.get_err_counter(
4463 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4465 pkts = self.create_stream_in(self.pg0, self.pg1)
4466 self.pg0.add_stream(pkts)
4467 self.pg_enable_capture(self.pg_interfaces)
4469 capture = self.pg1.get_capture(len(pkts))
4470 self.verify_capture_out(capture)
4472 err = self.statistics.get_err_counter(
4473 '/err/nat44-ed-in2out-slowpath/TCP packets')
4474 self.assertEqual(err - tcpn, 2)
4475 err = self.statistics.get_err_counter(
4476 '/err/nat44-ed-in2out-slowpath/UDP packets')
4477 self.assertEqual(err - udpn, 1)
4478 err = self.statistics.get_err_counter(
4479 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4480 self.assertEqual(err - icmpn, 1)
4481 err = self.statistics.get_err_counter(
4482 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4483 self.assertEqual(err - totaln, 4)
4486 tcpn = self.statistics.get_err_counter(
4487 '/err/nat44-ed-out2in/TCP packets')
4488 udpn = self.statistics.get_err_counter(
4489 '/err/nat44-ed-out2in/UDP packets')
4490 icmpn = self.statistics.get_err_counter(
4491 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4492 totaln = self.statistics.get_err_counter(
4493 '/err/nat44-ed-out2in/good out2in packets processed')
4495 pkts = self.create_stream_out(self.pg1)
4496 self.pg1.add_stream(pkts)
4497 self.pg_enable_capture(self.pg_interfaces)
4499 capture = self.pg0.get_capture(len(pkts))
4500 self.verify_capture_in(capture, self.pg0)
4502 err = self.statistics.get_err_counter(
4503 '/err/nat44-ed-out2in/TCP packets')
4504 self.assertEqual(err - tcpn, 2)
4505 err = self.statistics.get_err_counter(
4506 '/err/nat44-ed-out2in/UDP packets')
4507 self.assertEqual(err - udpn, 1)
4508 err = self.statistics.get_err_counter(
4509 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4510 self.assertEqual(err - icmpn, 1)
4511 err = self.statistics.get_err_counter(
4512 '/err/nat44-ed-out2in/good out2in packets processed')
4513 self.assertEqual(err - totaln, 3)
4515 sessions = self.statistics.get_counter('/nat44/total-sessions')
4516 self.assertEqual(sessions[0][0], 3)
4518 def test_dynamic_output_feature_vrf(self):
4519 """ NAT44 dynamic translation test: output-feature, VRF"""
4521 # other then default (0)
4524 self.nat44_add_address(self.nat_addr)
4525 flags = self.config_flags.NAT_IS_INSIDE
4526 self.vapi.nat44_interface_add_del_output_feature(
4527 sw_if_index=self.pg7.sw_if_index,
4528 flags=flags, is_add=1)
4529 self.vapi.nat44_interface_add_del_output_feature(
4530 sw_if_index=self.pg8.sw_if_index,
4534 self.vapi.ip_table_add_del(is_add=1,
4535 table={'table_id': new_vrf_id})
4537 self.pg7.unconfig_ip4()
4538 self.pg7.set_table_ip4(new_vrf_id)
4539 self.pg7.config_ip4()
4540 self.pg7.resolve_arp()
4542 self.pg8.unconfig_ip4()
4543 self.pg8.set_table_ip4(new_vrf_id)
4544 self.pg8.config_ip4()
4545 self.pg8.resolve_arp()
4547 nat_config = self.vapi.nat_show_config()
4548 self.assertEqual(1, nat_config.endpoint_dependent)
4551 tcpn = self.statistics.get_err_counter(
4552 '/err/nat44-ed-in2out-slowpath/TCP packets')
4553 udpn = self.statistics.get_err_counter(
4554 '/err/nat44-ed-in2out-slowpath/UDP packets')
4555 icmpn = self.statistics.get_err_counter(
4556 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4557 totaln = self.statistics.get_err_counter(
4558 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4560 pkts = self.create_stream_in(self.pg7, self.pg8)
4561 self.pg7.add_stream(pkts)
4562 self.pg_enable_capture(self.pg_interfaces)
4564 capture = self.pg8.get_capture(len(pkts))
4565 self.verify_capture_out(capture)
4567 err = self.statistics.get_err_counter(
4568 '/err/nat44-ed-in2out-slowpath/TCP packets')
4569 self.assertEqual(err - tcpn, 2)
4570 err = self.statistics.get_err_counter(
4571 '/err/nat44-ed-in2out-slowpath/UDP packets')
4572 self.assertEqual(err - udpn, 1)
4573 err = self.statistics.get_err_counter(
4574 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4575 self.assertEqual(err - icmpn, 1)
4576 err = self.statistics.get_err_counter(
4577 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4578 self.assertEqual(err - totaln, 4)
4581 tcpn = self.statistics.get_err_counter(
4582 '/err/nat44-ed-out2in/TCP packets')
4583 udpn = self.statistics.get_err_counter(
4584 '/err/nat44-ed-out2in/UDP packets')
4585 icmpn = self.statistics.get_err_counter(
4586 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4587 totaln = self.statistics.get_err_counter(
4588 '/err/nat44-ed-out2in/good out2in packets processed')
4590 pkts = self.create_stream_out(self.pg8)
4591 self.pg8.add_stream(pkts)
4592 self.pg_enable_capture(self.pg_interfaces)
4594 capture = self.pg7.get_capture(len(pkts))
4595 self.verify_capture_in(capture, self.pg7)
4597 err = self.statistics.get_err_counter(
4598 '/err/nat44-ed-out2in/TCP packets')
4599 self.assertEqual(err - tcpn, 2)
4600 err = self.statistics.get_err_counter(
4601 '/err/nat44-ed-out2in/UDP packets')
4602 self.assertEqual(err - udpn, 1)
4603 err = self.statistics.get_err_counter(
4604 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4605 self.assertEqual(err - icmpn, 1)
4606 err = self.statistics.get_err_counter(
4607 '/err/nat44-ed-out2in/good out2in packets processed')
4608 self.assertEqual(err - totaln, 3)
4610 sessions = self.statistics.get_counter('/nat44/total-sessions')
4611 self.assertEqual(sessions[0][0], 3)
4614 self.pg7.unconfig_ip4()
4615 self.pg7.set_table_ip4(1)
4616 self.pg7.config_ip4()
4617 self.pg7.resolve_arp()
4619 self.pg8.unconfig_ip4()
4620 self.pg8.set_table_ip4(1)
4621 self.pg8.config_ip4()
4622 self.pg8.resolve_arp()
4624 self.vapi.ip_table_add_del(is_add=0,
4625 table={'table_id': new_vrf_id})
4627 def test_forwarding(self):
4628 """ NAT44 forwarding test """
4630 flags = self.config_flags.NAT_IS_INSIDE
4631 self.vapi.nat44_interface_add_del_feature(
4632 sw_if_index=self.pg0.sw_if_index,
4633 flags=flags, is_add=1)
4634 self.vapi.nat44_interface_add_del_feature(
4635 sw_if_index=self.pg1.sw_if_index,
4637 self.vapi.nat44_forwarding_enable_disable(enable=1)
4639 real_ip = self.pg0.remote_ip4
4640 alias_ip = self.nat_addr
4641 flags = self.config_flags.NAT_IS_ADDR_ONLY
4642 self.vapi.nat44_add_del_static_mapping(is_add=1,
4643 local_ip_address=real_ip,
4644 external_ip_address=alias_ip,
4645 external_sw_if_index=0xFFFFFFFF,
4649 # in2out - static mapping match
4651 pkts = self.create_stream_out(self.pg1)
4652 self.pg1.add_stream(pkts)
4653 self.pg_enable_capture(self.pg_interfaces)
4655 capture = self.pg0.get_capture(len(pkts))
4656 self.verify_capture_in(capture, self.pg0)
4658 pkts = self.create_stream_in(self.pg0, self.pg1)
4659 self.pg0.add_stream(pkts)
4660 self.pg_enable_capture(self.pg_interfaces)
4662 capture = self.pg1.get_capture(len(pkts))
4663 self.verify_capture_out(capture, same_port=True)
4665 # in2out - no static mapping match
4667 host0 = self.pg0.remote_hosts[0]
4668 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4670 pkts = self.create_stream_out(self.pg1,
4671 dst_ip=self.pg0.remote_ip4,
4672 use_inside_ports=True)
4673 self.pg1.add_stream(pkts)
4674 self.pg_enable_capture(self.pg_interfaces)
4676 capture = self.pg0.get_capture(len(pkts))
4677 self.verify_capture_in(capture, self.pg0)
4679 pkts = self.create_stream_in(self.pg0, self.pg1)
4680 self.pg0.add_stream(pkts)
4681 self.pg_enable_capture(self.pg_interfaces)
4683 capture = self.pg1.get_capture(len(pkts))
4684 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4687 self.pg0.remote_hosts[0] = host0
4689 user = self.pg0.remote_hosts[1]
4690 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4691 self.assertEqual(len(sessions), 3)
4692 self.assertTrue(sessions[0].flags &
4693 self.config_flags.NAT_IS_EXT_HOST_VALID)
4694 self.vapi.nat44_del_session(
4695 address=sessions[0].inside_ip_address,
4696 port=sessions[0].inside_port,
4697 protocol=sessions[0].protocol,
4698 flags=(self.config_flags.NAT_IS_INSIDE |
4699 self.config_flags.NAT_IS_EXT_HOST_VALID),
4700 ext_host_address=sessions[0].ext_host_address,
4701 ext_host_port=sessions[0].ext_host_port)
4702 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4703 self.assertEqual(len(sessions), 2)
4706 self.vapi.nat44_forwarding_enable_disable(enable=0)
4707 flags = self.config_flags.NAT_IS_ADDR_ONLY
4708 self.vapi.nat44_add_del_static_mapping(
4710 local_ip_address=real_ip,
4711 external_ip_address=alias_ip,
4712 external_sw_if_index=0xFFFFFFFF,
4715 def test_static_lb(self):
4716 """ NAT44 local service load balancing """
4717 external_addr_n = self.nat_addr
4720 server1 = self.pg0.remote_hosts[0]
4721 server2 = self.pg0.remote_hosts[1]
4723 locals = [{'addr': server1.ip4,
4727 {'addr': server2.ip4,
4732 self.nat44_add_address(self.nat_addr)
4733 self.vapi.nat44_add_del_lb_static_mapping(
4735 external_addr=external_addr_n,
4736 external_port=external_port,
4737 protocol=IP_PROTOS.tcp,
4738 local_num=len(locals),
4740 flags = self.config_flags.NAT_IS_INSIDE
4741 self.vapi.nat44_interface_add_del_feature(
4742 sw_if_index=self.pg0.sw_if_index,
4743 flags=flags, is_add=1)
4744 self.vapi.nat44_interface_add_del_feature(
4745 sw_if_index=self.pg1.sw_if_index,
4748 # from client to service
4749 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4750 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4751 TCP(sport=12345, dport=external_port))
4752 self.pg1.add_stream(p)
4753 self.pg_enable_capture(self.pg_interfaces)
4755 capture = self.pg0.get_capture(1)
4761 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4762 if ip.dst == server1.ip4:
4766 self.assertEqual(tcp.dport, local_port)
4767 self.assert_packet_checksums_valid(p)
4769 self.logger.error(ppp("Unexpected or invalid packet:", p))
4772 # from service back to client
4773 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4774 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4775 TCP(sport=local_port, dport=12345))
4776 self.pg0.add_stream(p)
4777 self.pg_enable_capture(self.pg_interfaces)
4779 capture = self.pg1.get_capture(1)
4784 self.assertEqual(ip.src, self.nat_addr)
4785 self.assertEqual(tcp.sport, external_port)
4786 self.assert_packet_checksums_valid(p)
4788 self.logger.error(ppp("Unexpected or invalid packet:", p))
4791 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4792 self.assertEqual(len(sessions), 1)
4793 self.assertTrue(sessions[0].flags &
4794 self.config_flags.NAT_IS_EXT_HOST_VALID)
4795 self.vapi.nat44_del_session(
4796 address=sessions[0].inside_ip_address,
4797 port=sessions[0].inside_port,
4798 protocol=sessions[0].protocol,
4799 flags=(self.config_flags.NAT_IS_INSIDE |
4800 self.config_flags.NAT_IS_EXT_HOST_VALID),
4801 ext_host_address=sessions[0].ext_host_address,
4802 ext_host_port=sessions[0].ext_host_port)
4803 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4804 self.assertEqual(len(sessions), 0)
4806 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4807 def test_static_lb_multi_clients(self):
4808 """ NAT44 local service load balancing - multiple clients"""
4810 external_addr = self.nat_addr
4813 server1 = self.pg0.remote_hosts[0]
4814 server2 = self.pg0.remote_hosts[1]
4815 server3 = self.pg0.remote_hosts[2]
4817 locals = [{'addr': server1.ip4,
4821 {'addr': server2.ip4,
4826 self.nat44_add_address(self.nat_addr)
4827 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4828 external_addr=external_addr,
4829 external_port=external_port,
4830 protocol=IP_PROTOS.tcp,
4831 local_num=len(locals),
4833 flags = self.config_flags.NAT_IS_INSIDE
4834 self.vapi.nat44_interface_add_del_feature(
4835 sw_if_index=self.pg0.sw_if_index,
4836 flags=flags, is_add=1)
4837 self.vapi.nat44_interface_add_del_feature(
4838 sw_if_index=self.pg1.sw_if_index,
4843 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4845 for client in clients:
4846 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4847 IP(src=client, dst=self.nat_addr) /
4848 TCP(sport=12345, dport=external_port))
4850 self.pg1.add_stream(pkts)
4851 self.pg_enable_capture(self.pg_interfaces)
4853 capture = self.pg0.get_capture(len(pkts))
4855 if p[IP].dst == server1.ip4:
4859 self.assertGreater(server1_n, server2_n)
4862 'addr': server3.ip4,
4869 self.vapi.nat44_lb_static_mapping_add_del_local(
4871 external_addr=external_addr,
4872 external_port=external_port,
4874 protocol=IP_PROTOS.tcp)
4878 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4880 for client in clients:
4881 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4882 IP(src=client, dst=self.nat_addr) /
4883 TCP(sport=12346, dport=external_port))
4885 self.assertGreater(len(pkts), 0)
4886 self.pg1.add_stream(pkts)
4887 self.pg_enable_capture(self.pg_interfaces)
4889 capture = self.pg0.get_capture(len(pkts))
4891 if p[IP].dst == server1.ip4:
4893 elif p[IP].dst == server2.ip4:
4897 self.assertGreater(server1_n, 0)
4898 self.assertGreater(server2_n, 0)
4899 self.assertGreater(server3_n, 0)
4902 'addr': server2.ip4,
4908 # remove one back-end
4909 self.vapi.nat44_lb_static_mapping_add_del_local(
4911 external_addr=external_addr,
4912 external_port=external_port,
4914 protocol=IP_PROTOS.tcp)
4918 self.pg1.add_stream(pkts)
4919 self.pg_enable_capture(self.pg_interfaces)
4921 capture = self.pg0.get_capture(len(pkts))
4923 if p[IP].dst == server1.ip4:
4925 elif p[IP].dst == server2.ip4:
4929 self.assertGreater(server1_n, 0)
4930 self.assertEqual(server2_n, 0)
4931 self.assertGreater(server3_n, 0)
4933 def test_static_lb_2(self):
4934 """ NAT44 local service load balancing (asymmetrical rule) """
4935 external_addr = self.nat_addr
4938 server1 = self.pg0.remote_hosts[0]
4939 server2 = self.pg0.remote_hosts[1]
4941 locals = [{'addr': server1.ip4,
4945 {'addr': server2.ip4,
4950 self.vapi.nat44_forwarding_enable_disable(enable=1)
4951 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
4952 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
4953 external_addr=external_addr,
4954 external_port=external_port,
4955 protocol=IP_PROTOS.tcp,
4956 local_num=len(locals),
4958 flags = self.config_flags.NAT_IS_INSIDE
4959 self.vapi.nat44_interface_add_del_feature(
4960 sw_if_index=self.pg0.sw_if_index,
4961 flags=flags, is_add=1)
4962 self.vapi.nat44_interface_add_del_feature(
4963 sw_if_index=self.pg1.sw_if_index,
4966 # from client to service
4967 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4968 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4969 TCP(sport=12345, dport=external_port))
4970 self.pg1.add_stream(p)
4971 self.pg_enable_capture(self.pg_interfaces)
4973 capture = self.pg0.get_capture(1)
4979 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4980 if ip.dst == server1.ip4:
4984 self.assertEqual(tcp.dport, local_port)
4985 self.assert_packet_checksums_valid(p)
4987 self.logger.error(ppp("Unexpected or invalid packet:", p))
4990 # from service back to client
4991 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4992 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4993 TCP(sport=local_port, dport=12345))
4994 self.pg0.add_stream(p)
4995 self.pg_enable_capture(self.pg_interfaces)
4997 capture = self.pg1.get_capture(1)
5002 self.assertEqual(ip.src, self.nat_addr)
5003 self.assertEqual(tcp.sport, external_port)
5004 self.assert_packet_checksums_valid(p)
5006 self.logger.error(ppp("Unexpected or invalid packet:", p))
5009 # from client to server (no translation)
5010 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5011 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5012 TCP(sport=12346, dport=local_port))
5013 self.pg1.add_stream(p)
5014 self.pg_enable_capture(self.pg_interfaces)
5016 capture = self.pg0.get_capture(1)
5022 self.assertEqual(ip.dst, server1.ip4)
5023 self.assertEqual(tcp.dport, local_port)
5024 self.assert_packet_checksums_valid(p)
5026 self.logger.error(ppp("Unexpected or invalid packet:", p))
5029 # from service back to client (no translation)
5030 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5031 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5032 TCP(sport=local_port, dport=12346))
5033 self.pg0.add_stream(p)
5034 self.pg_enable_capture(self.pg_interfaces)
5036 capture = self.pg1.get_capture(1)
5041 self.assertEqual(ip.src, server1.ip4)
5042 self.assertEqual(tcp.sport, local_port)
5043 self.assert_packet_checksums_valid(p)
5045 self.logger.error(ppp("Unexpected or invalid packet:", p))
5048 def test_lb_affinity(self):
5049 """ NAT44 local service load balancing affinity """
5050 external_addr = self.nat_addr
5053 server1 = self.pg0.remote_hosts[0]
5054 server2 = self.pg0.remote_hosts[1]
5056 locals = [{'addr': server1.ip4,
5060 {'addr': server2.ip4,
5065 self.nat44_add_address(self.nat_addr)
5066 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5067 external_addr=external_addr,
5068 external_port=external_port,
5069 protocol=IP_PROTOS.tcp,
5071 local_num=len(locals),
5073 flags = self.config_flags.NAT_IS_INSIDE
5074 self.vapi.nat44_interface_add_del_feature(
5075 sw_if_index=self.pg0.sw_if_index,
5076 flags=flags, is_add=1)
5077 self.vapi.nat44_interface_add_del_feature(
5078 sw_if_index=self.pg1.sw_if_index,
5081 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5082 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5083 TCP(sport=1025, dport=external_port))
5084 self.pg1.add_stream(p)
5085 self.pg_enable_capture(self.pg_interfaces)
5087 capture = self.pg0.get_capture(1)
5088 backend = capture[0][IP].dst
5090 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5091 self.assertEqual(len(sessions), 1)
5092 self.assertTrue(sessions[0].flags &
5093 self.config_flags.NAT_IS_EXT_HOST_VALID)
5094 self.vapi.nat44_del_session(
5095 address=sessions[0].inside_ip_address,
5096 port=sessions[0].inside_port,
5097 protocol=sessions[0].protocol,
5098 flags=(self.config_flags.NAT_IS_INSIDE |
5099 self.config_flags.NAT_IS_EXT_HOST_VALID),
5100 ext_host_address=sessions[0].ext_host_address,
5101 ext_host_port=sessions[0].ext_host_port)
5104 for port in range(1030, 1100):
5105 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5106 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5107 TCP(sport=port, dport=external_port))
5109 self.pg1.add_stream(pkts)
5110 self.pg_enable_capture(self.pg_interfaces)
5112 capture = self.pg0.get_capture(len(pkts))
5114 self.assertEqual(p[IP].dst, backend)
5116 def test_unknown_proto(self):
5117 """ NAT44 translate packet with unknown protocol """
5118 self.nat44_add_address(self.nat_addr)
5119 flags = self.config_flags.NAT_IS_INSIDE
5120 self.vapi.nat44_interface_add_del_feature(
5121 sw_if_index=self.pg0.sw_if_index,
5122 flags=flags, is_add=1)
5123 self.vapi.nat44_interface_add_del_feature(
5124 sw_if_index=self.pg1.sw_if_index,
5128 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5129 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5130 TCP(sport=self.tcp_port_in, dport=20))
5131 self.pg0.add_stream(p)
5132 self.pg_enable_capture(self.pg_interfaces)
5134 p = self.pg1.get_capture(1)
5136 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5137 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5139 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5140 TCP(sport=1234, dport=1234))
5141 self.pg0.add_stream(p)
5142 self.pg_enable_capture(self.pg_interfaces)
5144 p = self.pg1.get_capture(1)
5147 self.assertEqual(packet[IP].src, self.nat_addr)
5148 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5149 self.assertEqual(packet.haslayer(GRE), 1)
5150 self.assert_packet_checksums_valid(packet)
5152 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5156 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5157 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5159 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5160 TCP(sport=1234, dport=1234))
5161 self.pg1.add_stream(p)
5162 self.pg_enable_capture(self.pg_interfaces)
5164 p = self.pg0.get_capture(1)
5167 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5168 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5169 self.assertEqual(packet.haslayer(GRE), 1)
5170 self.assert_packet_checksums_valid(packet)
5172 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5175 def test_hairpinning_unknown_proto(self):
5176 """ NAT44 translate packet with unknown protocol - hairpinning """
5177 host = self.pg0.remote_hosts[0]
5178 server = self.pg0.remote_hosts[1]
5180 server_out_port = 8765
5181 server_nat_ip = "10.0.0.11"
5183 self.nat44_add_address(self.nat_addr)
5184 flags = self.config_flags.NAT_IS_INSIDE
5185 self.vapi.nat44_interface_add_del_feature(
5186 sw_if_index=self.pg0.sw_if_index,
5187 flags=flags, is_add=1)
5188 self.vapi.nat44_interface_add_del_feature(
5189 sw_if_index=self.pg1.sw_if_index,
5192 # add static mapping for server
5193 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5196 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5197 IP(src=host.ip4, dst=server_nat_ip) /
5198 TCP(sport=host_in_port, dport=server_out_port))
5199 self.pg0.add_stream(p)
5200 self.pg_enable_capture(self.pg_interfaces)
5202 self.pg0.get_capture(1)
5204 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5205 IP(src=host.ip4, dst=server_nat_ip) /
5207 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5208 TCP(sport=1234, dport=1234))
5209 self.pg0.add_stream(p)
5210 self.pg_enable_capture(self.pg_interfaces)
5212 p = self.pg0.get_capture(1)
5215 self.assertEqual(packet[IP].src, self.nat_addr)
5216 self.assertEqual(packet[IP].dst, server.ip4)
5217 self.assertEqual(packet.haslayer(GRE), 1)
5218 self.assert_packet_checksums_valid(packet)
5220 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5224 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5225 IP(src=server.ip4, dst=self.nat_addr) /
5227 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5228 TCP(sport=1234, dport=1234))
5229 self.pg0.add_stream(p)
5230 self.pg_enable_capture(self.pg_interfaces)
5232 p = self.pg0.get_capture(1)
5235 self.assertEqual(packet[IP].src, server_nat_ip)
5236 self.assertEqual(packet[IP].dst, host.ip4)
5237 self.assertEqual(packet.haslayer(GRE), 1)
5238 self.assert_packet_checksums_valid(packet)
5240 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5243 def test_output_feature_and_service(self):
5244 """ NAT44 interface output feature and services """
5245 external_addr = '1.2.3.4'
5249 self.vapi.nat44_forwarding_enable_disable(enable=1)
5250 self.nat44_add_address(self.nat_addr)
5251 flags = self.config_flags.NAT_IS_ADDR_ONLY
5252 self.vapi.nat44_add_del_identity_mapping(
5253 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5254 flags=flags, is_add=1)
5255 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5256 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5257 local_port, external_port,
5258 proto=IP_PROTOS.tcp, flags=flags)
5259 flags = self.config_flags.NAT_IS_INSIDE
5260 self.vapi.nat44_interface_add_del_feature(
5261 sw_if_index=self.pg0.sw_if_index,
5263 self.vapi.nat44_interface_add_del_feature(
5264 sw_if_index=self.pg0.sw_if_index,
5265 flags=flags, is_add=1)
5266 self.vapi.nat44_interface_add_del_output_feature(
5268 sw_if_index=self.pg1.sw_if_index)
5270 # from client to service
5271 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5272 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5273 TCP(sport=12345, dport=external_port))
5274 self.pg1.add_stream(p)
5275 self.pg_enable_capture(self.pg_interfaces)
5277 capture = self.pg0.get_capture(1)
5282 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5283 self.assertEqual(tcp.dport, local_port)
5284 self.assert_packet_checksums_valid(p)
5286 self.logger.error(ppp("Unexpected or invalid packet:", p))
5289 # from service back to client
5290 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5291 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5292 TCP(sport=local_port, dport=12345))
5293 self.pg0.add_stream(p)
5294 self.pg_enable_capture(self.pg_interfaces)
5296 capture = self.pg1.get_capture(1)
5301 self.assertEqual(ip.src, external_addr)
5302 self.assertEqual(tcp.sport, external_port)
5303 self.assert_packet_checksums_valid(p)
5305 self.logger.error(ppp("Unexpected or invalid packet:", p))
5308 # from local network host to external network
5309 pkts = self.create_stream_in(self.pg0, self.pg1)
5310 self.pg0.add_stream(pkts)
5311 self.pg_enable_capture(self.pg_interfaces)
5313 capture = self.pg1.get_capture(len(pkts))
5314 self.verify_capture_out(capture)
5315 pkts = self.create_stream_in(self.pg0, self.pg1)
5316 self.pg0.add_stream(pkts)
5317 self.pg_enable_capture(self.pg_interfaces)
5319 capture = self.pg1.get_capture(len(pkts))
5320 self.verify_capture_out(capture)
5322 # from external network back to local network host
5323 pkts = self.create_stream_out(self.pg1)
5324 self.pg1.add_stream(pkts)
5325 self.pg_enable_capture(self.pg_interfaces)
5327 capture = self.pg0.get_capture(len(pkts))
5328 self.verify_capture_in(capture, self.pg0)
5330 def test_output_feature_and_service2(self):
5331 """ NAT44 interface output feature and service host direct access """
5332 self.vapi.nat44_forwarding_enable_disable(enable=1)
5333 self.nat44_add_address(self.nat_addr)
5334 self.vapi.nat44_interface_add_del_output_feature(
5336 sw_if_index=self.pg1.sw_if_index)
5338 # session initiated from service host - translate
5339 pkts = self.create_stream_in(self.pg0, self.pg1)
5340 self.pg0.add_stream(pkts)
5341 self.pg_enable_capture(self.pg_interfaces)
5343 capture = self.pg1.get_capture(len(pkts))
5344 self.verify_capture_out(capture)
5346 pkts = self.create_stream_out(self.pg1)
5347 self.pg1.add_stream(pkts)
5348 self.pg_enable_capture(self.pg_interfaces)
5350 capture = self.pg0.get_capture(len(pkts))
5351 self.verify_capture_in(capture, self.pg0)
5353 # session initiated from remote host - do not translate
5354 self.tcp_port_in = 60303
5355 self.udp_port_in = 60304
5356 self.icmp_id_in = 60305
5357 pkts = self.create_stream_out(self.pg1,
5358 self.pg0.remote_ip4,
5359 use_inside_ports=True)
5360 self.pg1.add_stream(pkts)
5361 self.pg_enable_capture(self.pg_interfaces)
5363 capture = self.pg0.get_capture(len(pkts))
5364 self.verify_capture_in(capture, self.pg0)
5366 pkts = self.create_stream_in(self.pg0, self.pg1)
5367 self.pg0.add_stream(pkts)
5368 self.pg_enable_capture(self.pg_interfaces)
5370 capture = self.pg1.get_capture(len(pkts))
5371 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5374 def test_output_feature_and_service3(self):
5375 """ NAT44 interface output feature and DST NAT """
5376 external_addr = '1.2.3.4'
5380 self.vapi.nat44_forwarding_enable_disable(enable=1)
5381 self.nat44_add_address(self.nat_addr)
5382 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5383 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5384 local_port, external_port,
5385 proto=IP_PROTOS.tcp, flags=flags)
5386 flags = self.config_flags.NAT_IS_INSIDE
5387 self.vapi.nat44_interface_add_del_feature(
5388 sw_if_index=self.pg0.sw_if_index,
5390 self.vapi.nat44_interface_add_del_feature(
5391 sw_if_index=self.pg0.sw_if_index,
5392 flags=flags, is_add=1)
5393 self.vapi.nat44_interface_add_del_output_feature(
5395 sw_if_index=self.pg1.sw_if_index)
5397 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5398 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5399 TCP(sport=12345, dport=external_port))
5400 self.pg0.add_stream(p)
5401 self.pg_enable_capture(self.pg_interfaces)
5403 capture = self.pg1.get_capture(1)
5408 self.assertEqual(ip.src, self.pg0.remote_ip4)
5409 self.assertEqual(tcp.sport, 12345)
5410 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5411 self.assertEqual(tcp.dport, local_port)
5412 self.assert_packet_checksums_valid(p)
5414 self.logger.error(ppp("Unexpected or invalid packet:", p))
5417 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5418 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5419 TCP(sport=local_port, dport=12345))
5420 self.pg1.add_stream(p)
5421 self.pg_enable_capture(self.pg_interfaces)
5423 capture = self.pg0.get_capture(1)
5428 self.assertEqual(ip.src, external_addr)
5429 self.assertEqual(tcp.sport, external_port)
5430 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5431 self.assertEqual(tcp.dport, 12345)
5432 self.assert_packet_checksums_valid(p)
5434 self.logger.error(ppp("Unexpected or invalid packet:", p))
5437 def test_next_src_nat(self):
5438 """ On way back forward packet to nat44-in2out node. """
5439 twice_nat_addr = '10.0.1.3'
5442 post_twice_nat_port = 0
5444 self.vapi.nat44_forwarding_enable_disable(enable=1)
5445 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5446 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5447 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5448 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5449 local_port, external_port,
5450 proto=IP_PROTOS.tcp, vrf_id=1,
5452 self.vapi.nat44_interface_add_del_feature(
5453 sw_if_index=self.pg6.sw_if_index,
5456 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5457 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5458 TCP(sport=12345, dport=external_port))
5459 self.pg6.add_stream(p)
5460 self.pg_enable_capture(self.pg_interfaces)
5462 capture = self.pg6.get_capture(1)
5467 self.assertEqual(ip.src, twice_nat_addr)
5468 self.assertNotEqual(tcp.sport, 12345)
5469 post_twice_nat_port = tcp.sport
5470 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5471 self.assertEqual(tcp.dport, local_port)
5472 self.assert_packet_checksums_valid(p)
5474 self.logger.error(ppp("Unexpected or invalid packet:", p))
5477 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5478 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5479 TCP(sport=local_port, dport=post_twice_nat_port))
5480 self.pg6.add_stream(p)
5481 self.pg_enable_capture(self.pg_interfaces)
5483 capture = self.pg6.get_capture(1)
5488 self.assertEqual(ip.src, self.pg1.remote_ip4)
5489 self.assertEqual(tcp.sport, external_port)
5490 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5491 self.assertEqual(tcp.dport, 12345)
5492 self.assert_packet_checksums_valid(p)
5494 self.logger.error(ppp("Unexpected or invalid packet:", p))
5497 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5499 twice_nat_addr = '10.0.1.3'
5507 port_in1 = port_in + 1
5508 port_in2 = port_in + 2
5513 server1 = self.pg0.remote_hosts[0]
5514 server2 = self.pg0.remote_hosts[1]
5526 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5529 self.nat44_add_address(self.nat_addr)
5530 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5534 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5536 flags |= self.config_flags.NAT_IS_TWICE_NAT
5539 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5541 proto=IP_PROTOS.tcp,
5544 locals = [{'addr': server1.ip4,
5548 {'addr': server2.ip4,
5552 out_addr = self.nat_addr
5554 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5555 external_addr=out_addr,
5556 external_port=port_out,
5557 protocol=IP_PROTOS.tcp,
5558 local_num=len(locals),
5560 flags = self.config_flags.NAT_IS_INSIDE
5561 self.vapi.nat44_interface_add_del_feature(
5562 sw_if_index=pg0.sw_if_index,
5563 flags=flags, is_add=1)
5564 self.vapi.nat44_interface_add_del_feature(
5565 sw_if_index=pg1.sw_if_index,
5572 assert client_id is not None
5574 client = self.pg0.remote_hosts[0]
5575 elif client_id == 2:
5576 client = self.pg0.remote_hosts[1]
5578 client = pg1.remote_hosts[0]
5579 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5580 IP(src=client.ip4, dst=self.nat_addr) /
5581 TCP(sport=eh_port_out, dport=port_out))
5583 self.pg_enable_capture(self.pg_interfaces)
5585 capture = pg0.get_capture(1)
5591 if ip.dst == server1.ip4:
5597 self.assertEqual(ip.dst, server.ip4)
5599 self.assertIn(tcp.dport, [port_in1, port_in2])
5601 self.assertEqual(tcp.dport, port_in)
5603 self.assertEqual(ip.src, twice_nat_addr)
5604 self.assertNotEqual(tcp.sport, eh_port_out)
5606 self.assertEqual(ip.src, client.ip4)
5607 self.assertEqual(tcp.sport, eh_port_out)
5609 eh_port_in = tcp.sport
5610 saved_port_in = tcp.dport
5611 self.assert_packet_checksums_valid(p)
5613 self.logger.error(ppp("Unexpected or invalid packet:", p))
5616 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5617 IP(src=server.ip4, dst=eh_addr_in) /
5618 TCP(sport=saved_port_in, dport=eh_port_in))
5620 self.pg_enable_capture(self.pg_interfaces)
5622 capture = pg1.get_capture(1)
5627 self.assertEqual(ip.dst, client.ip4)
5628 self.assertEqual(ip.src, self.nat_addr)
5629 self.assertEqual(tcp.dport, eh_port_out)
5630 self.assertEqual(tcp.sport, port_out)
5631 self.assert_packet_checksums_valid(p)
5633 self.logger.error(ppp("Unexpected or invalid packet:", p))
5637 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5638 self.assertEqual(len(sessions), 1)
5639 self.assertTrue(sessions[0].flags &
5640 self.config_flags.NAT_IS_EXT_HOST_VALID)
5641 self.assertTrue(sessions[0].flags &
5642 self.config_flags.NAT_IS_TWICE_NAT)
5643 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5644 self.vapi.nat44_del_session(
5645 address=sessions[0].inside_ip_address,
5646 port=sessions[0].inside_port,
5647 protocol=sessions[0].protocol,
5648 flags=(self.config_flags.NAT_IS_INSIDE |
5649 self.config_flags.NAT_IS_EXT_HOST_VALID),
5650 ext_host_address=sessions[0].ext_host_nat_address,
5651 ext_host_port=sessions[0].ext_host_nat_port)
5652 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5653 self.assertEqual(len(sessions), 0)
5655 def test_twice_nat(self):
5657 self.twice_nat_common()
5659 def test_self_twice_nat_positive(self):
5660 """ Self Twice NAT44 (positive test) """
5661 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5663 def test_self_twice_nat_negative(self):
5664 """ Self Twice NAT44 (negative test) """
5665 self.twice_nat_common(self_twice_nat=True)
5667 def test_twice_nat_lb(self):
5668 """ Twice NAT44 local service load balancing """
5669 self.twice_nat_common(lb=True)
5671 def test_self_twice_nat_lb_positive(self):
5672 """ Self Twice NAT44 local service load balancing (positive test) """
5673 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5676 def test_self_twice_nat_lb_negative(self):
5677 """ Self Twice NAT44 local service load balancing (negative test) """
5678 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5681 def test_twice_nat_interface_addr(self):
5682 """ Acquire twice NAT44 addresses from interface """
5683 flags = self.config_flags.NAT_IS_TWICE_NAT
5684 self.vapi.nat44_add_del_interface_addr(
5686 sw_if_index=self.pg3.sw_if_index,
5689 # no address in NAT pool
5690 adresses = self.vapi.nat44_address_dump()
5691 self.assertEqual(0, len(adresses))
5693 # configure interface address and check NAT address pool
5694 self.pg3.config_ip4()
5695 adresses = self.vapi.nat44_address_dump()
5696 self.assertEqual(1, len(adresses))
5697 self.assertEqual(str(adresses[0].ip_address),
5699 self.assertEqual(adresses[0].flags, flags)
5701 # remove interface address and check NAT address pool
5702 self.pg3.unconfig_ip4()
5703 adresses = self.vapi.nat44_address_dump()
5704 self.assertEqual(0, len(adresses))
5706 def test_tcp_close(self):
5707 """ Close TCP session from inside network - output feature """
5708 self.vapi.nat44_forwarding_enable_disable(enable=1)
5709 self.nat44_add_address(self.pg1.local_ip4)
5710 twice_nat_addr = '10.0.1.3'
5711 service_ip = '192.168.16.150'
5712 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5713 flags = self.config_flags.NAT_IS_INSIDE
5714 self.vapi.nat44_interface_add_del_feature(
5715 sw_if_index=self.pg0.sw_if_index,
5717 self.vapi.nat44_interface_add_del_feature(
5718 sw_if_index=self.pg0.sw_if_index,
5719 flags=flags, is_add=1)
5720 self.vapi.nat44_interface_add_del_output_feature(
5722 sw_if_index=self.pg1.sw_if_index)
5723 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5724 self.config_flags.NAT_IS_TWICE_NAT)
5725 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5729 proto=IP_PROTOS.tcp,
5731 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5732 start_sessnum = len(sessions)
5734 # SYN packet out->in
5735 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5736 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5737 TCP(sport=33898, dport=80, flags="S"))
5738 self.pg1.add_stream(p)
5739 self.pg_enable_capture(self.pg_interfaces)
5741 capture = self.pg0.get_capture(1)
5743 tcp_port = p[TCP].sport
5745 # SYN + ACK packet in->out
5746 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5747 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5748 TCP(sport=80, dport=tcp_port, flags="SA"))
5749 self.pg0.add_stream(p)
5750 self.pg_enable_capture(self.pg_interfaces)
5752 self.pg1.get_capture(1)
5754 # ACK packet out->in
5755 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5756 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5757 TCP(sport=33898, dport=80, flags="A"))
5758 self.pg1.add_stream(p)
5759 self.pg_enable_capture(self.pg_interfaces)
5761 self.pg0.get_capture(1)
5763 # FIN packet in -> out
5764 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5765 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5766 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5767 self.pg0.add_stream(p)
5768 self.pg_enable_capture(self.pg_interfaces)
5770 self.pg1.get_capture(1)
5772 # FIN+ACK packet out -> in
5773 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5774 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5775 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5776 self.pg1.add_stream(p)
5777 self.pg_enable_capture(self.pg_interfaces)
5779 self.pg0.get_capture(1)
5781 # ACK packet in -> out
5782 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5783 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5784 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5785 self.pg0.add_stream(p)
5786 self.pg_enable_capture(self.pg_interfaces)
5788 self.pg1.get_capture(1)
5790 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5792 self.assertEqual(len(sessions) - start_sessnum, 0)
5794 def test_tcp_session_close_in(self):
5795 """ Close TCP session from inside network """
5796 self.tcp_port_out = 10505
5797 self.nat44_add_address(self.nat_addr)
5798 flags = self.config_flags.NAT_IS_TWICE_NAT
5799 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5803 proto=IP_PROTOS.tcp,
5805 flags = self.config_flags.NAT_IS_INSIDE
5806 self.vapi.nat44_interface_add_del_feature(
5807 sw_if_index=self.pg0.sw_if_index,
5808 flags=flags, is_add=1)
5809 self.vapi.nat44_interface_add_del_feature(
5810 sw_if_index=self.pg1.sw_if_index,
5813 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5814 start_sessnum = len(sessions)
5816 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5817 tcp_transitory=2, icmp=5)
5819 self.initiate_tcp_session(self.pg0, self.pg1)
5821 # FIN packet in -> out
5822 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5823 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5824 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5825 flags="FA", seq=100, ack=300))
5826 self.pg0.add_stream(p)
5827 self.pg_enable_capture(self.pg_interfaces)
5829 self.pg1.get_capture(1)
5833 # ACK packet out -> in
5834 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5835 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5836 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5837 flags="A", seq=300, ack=101))
5840 # FIN packet out -> in
5841 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5842 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5843 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5844 flags="FA", seq=300, ack=101))
5847 self.pg1.add_stream(pkts)
5848 self.pg_enable_capture(self.pg_interfaces)
5850 self.pg0.get_capture(2)
5852 # ACK packet in -> out
5853 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5854 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5855 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5856 flags="A", seq=101, ack=301))
5857 self.pg0.add_stream(p)
5858 self.pg_enable_capture(self.pg_interfaces)
5860 self.pg1.get_capture(1)
5862 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5863 self.assertEqual(len(sessions) - start_sessnum, 1)
5865 stats = self.statistics.get_counter(
5866 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5867 out2in_drops = stats[0]
5868 stats = self.statistics.get_counter(
5869 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5870 in2out_drops = stats[0]
5872 # extra FIN packet out -> in - this should be dropped
5873 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5874 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5875 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5876 flags="FA", seq=300, ack=101))
5878 self.pg1.add_stream(p)
5879 self.pg_enable_capture(self.pg_interfaces)
5881 self.pg0.assert_nothing_captured()
5883 # extra ACK packet in -> out - this should be dropped
5884 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5885 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5886 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5887 flags="A", seq=101, ack=301))
5888 self.pg0.add_stream(p)
5889 self.pg_enable_capture(self.pg_interfaces)
5891 self.pg1.assert_nothing_captured()
5893 stats = self.statistics.get_counter(
5894 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5895 self.assertEqual(stats[0] - out2in_drops, 1)
5896 stats = self.statistics.get_counter(
5897 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5898 self.assertEqual(stats[0] - in2out_drops, 1)
5901 # extra ACK packet in -> out - this will cause session to be wiped
5902 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5903 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5904 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5905 flags="A", seq=101, ack=301))
5906 self.pg0.add_stream(p)
5907 self.pg_enable_capture(self.pg_interfaces)
5909 self.pg1.assert_nothing_captured()
5910 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5911 self.assertEqual(len(sessions) - start_sessnum, 0)
5913 def test_tcp_session_close_out(self):
5914 """ Close TCP session from outside network """
5915 self.tcp_port_out = 10505
5916 self.nat44_add_address(self.nat_addr)
5917 flags = self.config_flags.NAT_IS_TWICE_NAT
5918 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5922 proto=IP_PROTOS.tcp,
5924 flags = self.config_flags.NAT_IS_INSIDE
5925 self.vapi.nat44_interface_add_del_feature(
5926 sw_if_index=self.pg0.sw_if_index,
5927 flags=flags, is_add=1)
5928 self.vapi.nat44_interface_add_del_feature(
5929 sw_if_index=self.pg1.sw_if_index,
5932 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5933 start_sessnum = len(sessions)
5935 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5936 tcp_transitory=2, icmp=5)
5938 self.initiate_tcp_session(self.pg0, self.pg1)
5940 # FIN packet out -> in
5941 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5942 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5943 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5944 flags="FA", seq=100, ack=300))
5945 self.pg1.add_stream(p)
5946 self.pg_enable_capture(self.pg_interfaces)
5948 self.pg0.get_capture(1)
5950 # FIN+ACK packet in -> out
5951 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5952 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5953 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5954 flags="FA", seq=300, ack=101))
5956 self.pg0.add_stream(p)
5957 self.pg_enable_capture(self.pg_interfaces)
5959 self.pg1.get_capture(1)
5961 # ACK packet out -> in
5962 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5963 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5964 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5965 flags="A", seq=101, ack=301))
5966 self.pg1.add_stream(p)
5967 self.pg_enable_capture(self.pg_interfaces)
5969 self.pg0.get_capture(1)
5971 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5972 self.assertEqual(len(sessions) - start_sessnum, 1)
5974 stats = self.statistics.get_counter(
5975 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5976 out2in_drops = stats[0]
5977 stats = self.statistics.get_counter(
5978 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5979 in2out_drops = stats[0]
5981 # extra FIN packet out -> in - this should be dropped
5982 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5983 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5984 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5985 flags="FA", seq=300, ack=101))
5987 self.pg1.add_stream(p)
5988 self.pg_enable_capture(self.pg_interfaces)
5990 self.pg0.assert_nothing_captured()
5992 # extra ACK packet in -> out - this should be dropped
5993 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5994 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5995 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5996 flags="A", seq=101, ack=301))
5997 self.pg0.add_stream(p)
5998 self.pg_enable_capture(self.pg_interfaces)
6000 self.pg1.assert_nothing_captured()
6002 stats = self.statistics.get_counter(
6003 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6004 self.assertEqual(stats[0] - out2in_drops, 1)
6005 stats = self.statistics.get_counter(
6006 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6007 self.assertEqual(stats[0] - in2out_drops, 1)
6010 # extra ACK packet in -> out - this will cause session to be wiped
6011 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6012 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6013 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6014 flags="A", seq=101, ack=301))
6015 self.pg0.add_stream(p)
6016 self.pg_enable_capture(self.pg_interfaces)
6018 self.pg1.assert_nothing_captured()
6019 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6020 self.assertEqual(len(sessions) - start_sessnum, 0)
6022 def test_tcp_session_close_simultaneous(self):
6023 """ Close TCP session from inside network """
6024 self.tcp_port_out = 10505
6025 self.nat44_add_address(self.nat_addr)
6026 flags = self.config_flags.NAT_IS_TWICE_NAT
6027 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6031 proto=IP_PROTOS.tcp,
6033 flags = self.config_flags.NAT_IS_INSIDE
6034 self.vapi.nat44_interface_add_del_feature(
6035 sw_if_index=self.pg0.sw_if_index,
6036 flags=flags, is_add=1)
6037 self.vapi.nat44_interface_add_del_feature(
6038 sw_if_index=self.pg1.sw_if_index,
6041 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6042 start_sessnum = len(sessions)
6044 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6045 tcp_transitory=2, icmp=5)
6047 self.initiate_tcp_session(self.pg0, self.pg1)
6049 # FIN packet in -> out
6050 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6051 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6052 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6053 flags="FA", seq=100, ack=300))
6054 self.pg0.add_stream(p)
6055 self.pg_enable_capture(self.pg_interfaces)
6057 self.pg1.get_capture(1)
6059 # FIN packet out -> in
6060 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6061 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6062 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6063 flags="FA", seq=300, ack=100))
6064 self.pg1.add_stream(p)
6065 self.pg_enable_capture(self.pg_interfaces)
6067 self.pg0.get_capture(1)
6069 # ACK packet in -> out
6070 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6071 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6072 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6073 flags="A", seq=101, ack=301))
6074 self.pg0.add_stream(p)
6075 self.pg_enable_capture(self.pg_interfaces)
6077 self.pg1.get_capture(1)
6079 # ACK packet out -> in
6080 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6081 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6082 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6083 flags="A", seq=301, ack=101))
6084 self.pg1.add_stream(p)
6085 self.pg_enable_capture(self.pg_interfaces)
6087 self.pg0.get_capture(1)
6089 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6090 self.assertEqual(len(sessions) - start_sessnum, 1)
6092 stats = self.statistics.get_counter(
6093 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6094 out2in_drops = stats[0]
6095 stats = self.statistics.get_counter(
6096 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6097 in2out_drops = stats[0]
6099 # extra FIN packet out -> in - this should be dropped
6100 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6101 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6102 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6103 flags="FA", seq=300, ack=101))
6105 self.pg1.add_stream(p)
6106 self.pg_enable_capture(self.pg_interfaces)
6108 self.pg0.assert_nothing_captured()
6110 # extra ACK packet in -> out - this should be dropped
6111 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6112 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6113 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6114 flags="A", seq=101, ack=301))
6115 self.pg0.add_stream(p)
6116 self.pg_enable_capture(self.pg_interfaces)
6118 self.pg1.assert_nothing_captured()
6120 stats = self.statistics.get_counter(
6121 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6122 self.assertEqual(stats[0] - out2in_drops, 1)
6123 stats = self.statistics.get_counter(
6124 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6125 self.assertEqual(stats[0] - in2out_drops, 1)
6128 # extra ACK packet in -> out - this will cause session to be wiped
6129 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6130 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6131 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6132 flags="A", seq=101, ack=301))
6133 self.pg0.add_stream(p)
6134 self.pg_enable_capture(self.pg_interfaces)
6136 self.pg1.assert_nothing_captured()
6137 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6138 self.assertEqual(len(sessions) - start_sessnum, 0)
6140 def test_one_armed_nat44_static(self):
6141 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6142 remote_host = self.pg4.remote_hosts[0]
6143 local_host = self.pg4.remote_hosts[1]
6148 self.vapi.nat44_forwarding_enable_disable(enable=1)
6149 self.nat44_add_address(self.nat_addr, twice_nat=1)
6150 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6151 self.config_flags.NAT_IS_TWICE_NAT)
6152 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6153 local_port, external_port,
6154 proto=IP_PROTOS.tcp, flags=flags)
6155 flags = self.config_flags.NAT_IS_INSIDE
6156 self.vapi.nat44_interface_add_del_feature(
6157 sw_if_index=self.pg4.sw_if_index,
6159 self.vapi.nat44_interface_add_del_feature(
6160 sw_if_index=self.pg4.sw_if_index,
6161 flags=flags, is_add=1)
6163 # from client to service
6164 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6165 IP(src=remote_host.ip4, dst=self.nat_addr) /
6166 TCP(sport=12345, dport=external_port))
6167 self.pg4.add_stream(p)
6168 self.pg_enable_capture(self.pg_interfaces)
6170 capture = self.pg4.get_capture(1)
6175 self.assertEqual(ip.dst, local_host.ip4)
6176 self.assertEqual(ip.src, self.nat_addr)
6177 self.assertEqual(tcp.dport, local_port)
6178 self.assertNotEqual(tcp.sport, 12345)
6179 eh_port_in = tcp.sport
6180 self.assert_packet_checksums_valid(p)
6182 self.logger.error(ppp("Unexpected or invalid packet:", p))
6185 # from service back to client
6186 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6187 IP(src=local_host.ip4, dst=self.nat_addr) /
6188 TCP(sport=local_port, dport=eh_port_in))
6189 self.pg4.add_stream(p)
6190 self.pg_enable_capture(self.pg_interfaces)
6192 capture = self.pg4.get_capture(1)
6197 self.assertEqual(ip.src, self.nat_addr)
6198 self.assertEqual(ip.dst, remote_host.ip4)
6199 self.assertEqual(tcp.sport, external_port)
6200 self.assertEqual(tcp.dport, 12345)
6201 self.assert_packet_checksums_valid(p)
6203 self.logger.error(ppp("Unexpected or invalid packet:", p))
6206 def test_static_with_port_out2(self):
6207 """ 1:1 NAPT asymmetrical rule """
6212 self.vapi.nat44_forwarding_enable_disable(enable=1)
6213 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6214 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6215 local_port, external_port,
6216 proto=IP_PROTOS.tcp, flags=flags)
6217 flags = self.config_flags.NAT_IS_INSIDE
6218 self.vapi.nat44_interface_add_del_feature(
6219 sw_if_index=self.pg0.sw_if_index,
6220 flags=flags, is_add=1)
6221 self.vapi.nat44_interface_add_del_feature(
6222 sw_if_index=self.pg1.sw_if_index,
6225 # from client to service
6226 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6227 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6228 TCP(sport=12345, dport=external_port))
6229 self.pg1.add_stream(p)
6230 self.pg_enable_capture(self.pg_interfaces)
6232 capture = self.pg0.get_capture(1)
6237 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6238 self.assertEqual(tcp.dport, local_port)
6239 self.assert_packet_checksums_valid(p)
6241 self.logger.error(ppp("Unexpected or invalid packet:", p))
6245 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6246 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6247 ICMP(type=11) / capture[0][IP])
6248 self.pg0.add_stream(p)
6249 self.pg_enable_capture(self.pg_interfaces)
6251 capture = self.pg1.get_capture(1)
6254 self.assertEqual(p[IP].src, self.nat_addr)
6256 self.assertEqual(inner.dst, self.nat_addr)
6257 self.assertEqual(inner[TCPerror].dport, external_port)
6259 self.logger.error(ppp("Unexpected or invalid packet:", p))
6262 # from service back to client
6263 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6264 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6265 TCP(sport=local_port, dport=12345))
6266 self.pg0.add_stream(p)
6267 self.pg_enable_capture(self.pg_interfaces)
6269 capture = self.pg1.get_capture(1)
6274 self.assertEqual(ip.src, self.nat_addr)
6275 self.assertEqual(tcp.sport, external_port)
6276 self.assert_packet_checksums_valid(p)
6278 self.logger.error(ppp("Unexpected or invalid packet:", p))
6282 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6283 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6284 ICMP(type=11) / capture[0][IP])
6285 self.pg1.add_stream(p)
6286 self.pg_enable_capture(self.pg_interfaces)
6288 capture = self.pg0.get_capture(1)
6291 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6293 self.assertEqual(inner.src, self.pg0.remote_ip4)
6294 self.assertEqual(inner[TCPerror].sport, local_port)
6296 self.logger.error(ppp("Unexpected or invalid packet:", p))
6299 # from client to server (no translation)
6300 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6301 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6302 TCP(sport=12346, dport=local_port))
6303 self.pg1.add_stream(p)
6304 self.pg_enable_capture(self.pg_interfaces)
6306 capture = self.pg0.get_capture(1)
6311 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6312 self.assertEqual(tcp.dport, local_port)
6313 self.assert_packet_checksums_valid(p)
6315 self.logger.error(ppp("Unexpected or invalid packet:", p))
6318 # from service back to client (no translation)
6319 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6320 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6321 TCP(sport=local_port, dport=12346))
6322 self.pg0.add_stream(p)
6323 self.pg_enable_capture(self.pg_interfaces)
6325 capture = self.pg1.get_capture(1)
6330 self.assertEqual(ip.src, self.pg0.remote_ip4)
6331 self.assertEqual(tcp.sport, local_port)
6332 self.assert_packet_checksums_valid(p)
6334 self.logger.error(ppp("Unexpected or invalid packet:", p))
6337 def test_output_feature(self):
6338 """ NAT44 interface output feature (in2out postrouting) """
6339 self.vapi.nat44_forwarding_enable_disable(enable=1)
6340 self.nat44_add_address(self.nat_addr)
6341 self.vapi.nat44_interface_add_del_feature(
6342 sw_if_index=self.pg0.sw_if_index,
6344 self.vapi.nat44_interface_add_del_output_feature(
6346 sw_if_index=self.pg1.sw_if_index)
6349 pkts = self.create_stream_in(self.pg0, self.pg1)
6350 self.pg0.add_stream(pkts)
6351 self.pg_enable_capture(self.pg_interfaces)
6353 capture = self.pg1.get_capture(len(pkts))
6354 self.verify_capture_out(capture)
6357 pkts = self.create_stream_out(self.pg1)
6358 self.pg1.add_stream(pkts)
6359 self.pg_enable_capture(self.pg_interfaces)
6361 capture = self.pg0.get_capture(len(pkts))
6362 self.verify_capture_in(capture, self.pg0)
6364 def test_output_feature_stateful_acl(self):
6365 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6366 self.nat44_add_address(self.nat_addr)
6367 self.vapi.nat44_interface_add_del_output_feature(
6368 sw_if_index=self.pg0.sw_if_index,
6369 flags=self.config_flags.NAT_IS_INSIDE,
6371 self.vapi.nat44_interface_add_del_output_feature(
6372 sw_if_index=self.pg1.sw_if_index,
6373 flags=self.config_flags.NAT_IS_OUTSIDE,
6376 # First ensure that the NAT is working sans ACL
6378 # send packets out2in, no sessions yet so packets should drop
6379 pkts_out2in = self.create_stream_out(self.pg1)
6380 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6382 # send packets into inside intf, ensure received via outside intf
6383 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6384 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6386 self.verify_capture_out(capture)
6388 # send out2in again, with sessions created it should work now
6389 pkts_out2in = self.create_stream_out(self.pg1)
6390 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6392 self.verify_capture_in(capture, self.pg0)
6394 # Create an ACL blocking everything
6395 out2in_deny_rule = AclRule(is_permit=0)
6396 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6397 out2in_acl.add_vpp_config()
6399 # create an ACL to permit/reflect everything
6400 in2out_reflect_rule = AclRule(is_permit=2)
6401 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6402 in2out_acl.add_vpp_config()
6404 # apply as input acl on interface and confirm it blocks everything
6405 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6406 n_input=1, acls=[out2in_acl])
6407 acl_if.add_vpp_config()
6408 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6411 acl_if.acls = [out2in_acl, in2out_acl]
6412 acl_if.add_vpp_config()
6413 # send in2out to generate ACL state (NAT state was created earlier)
6414 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6416 self.verify_capture_out(capture)
6418 # send out2in again. ACL state exists so it should work now.
6419 # TCP packets with the syn flag set also need the ack flag
6420 for p in pkts_out2in:
6421 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6422 p[TCP].flags |= 0x10
6423 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6425 self.verify_capture_in(capture, self.pg0)
6426 self.logger.info(self.vapi.cli("show trace"))
6428 def test_multiple_vrf(self):
6429 """ Multiple VRF setup """
6430 external_addr = '1.2.3.4'
6435 self.vapi.nat44_forwarding_enable_disable(enable=1)
6436 self.nat44_add_address(self.nat_addr)
6437 flags = self.config_flags.NAT_IS_INSIDE
6438 self.vapi.nat44_interface_add_del_feature(
6439 sw_if_index=self.pg0.sw_if_index,
6441 self.vapi.nat44_interface_add_del_feature(
6442 sw_if_index=self.pg0.sw_if_index,
6443 flags=flags, is_add=1)
6444 self.vapi.nat44_interface_add_del_output_feature(
6446 sw_if_index=self.pg1.sw_if_index)
6447 self.vapi.nat44_interface_add_del_feature(
6448 sw_if_index=self.pg5.sw_if_index,
6450 self.vapi.nat44_interface_add_del_feature(
6451 sw_if_index=self.pg5.sw_if_index,
6452 flags=flags, is_add=1)
6453 self.vapi.nat44_interface_add_del_feature(
6454 sw_if_index=self.pg6.sw_if_index,
6456 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6457 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6458 local_port, external_port, vrf_id=1,
6459 proto=IP_PROTOS.tcp, flags=flags)
6460 self.nat44_add_static_mapping(
6461 self.pg0.remote_ip4,
6462 external_sw_if_index=self.pg0.sw_if_index,
6463 local_port=local_port,
6465 external_port=external_port,
6466 proto=IP_PROTOS.tcp,
6470 # from client to service (both VRF1)
6471 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6472 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6473 TCP(sport=12345, dport=external_port))
6474 self.pg6.add_stream(p)
6475 self.pg_enable_capture(self.pg_interfaces)
6477 capture = self.pg5.get_capture(1)
6482 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6483 self.assertEqual(tcp.dport, local_port)
6484 self.assert_packet_checksums_valid(p)
6486 self.logger.error(ppp("Unexpected or invalid packet:", p))
6489 # from service back to client (both VRF1)
6490 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6491 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6492 TCP(sport=local_port, dport=12345))
6493 self.pg5.add_stream(p)
6494 self.pg_enable_capture(self.pg_interfaces)
6496 capture = self.pg6.get_capture(1)
6501 self.assertEqual(ip.src, external_addr)
6502 self.assertEqual(tcp.sport, external_port)
6503 self.assert_packet_checksums_valid(p)
6505 self.logger.error(ppp("Unexpected or invalid packet:", p))
6508 # dynamic NAT from VRF1 to VRF0 (output-feature)
6509 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6510 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6511 TCP(sport=2345, dport=22))
6512 self.pg5.add_stream(p)
6513 self.pg_enable_capture(self.pg_interfaces)
6515 capture = self.pg1.get_capture(1)
6520 self.assertEqual(ip.src, self.nat_addr)
6521 self.assertNotEqual(tcp.sport, 2345)
6522 self.assert_packet_checksums_valid(p)
6525 self.logger.error(ppp("Unexpected or invalid packet:", p))
6528 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6529 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6530 TCP(sport=22, dport=port))
6531 self.pg1.add_stream(p)
6532 self.pg_enable_capture(self.pg_interfaces)
6534 capture = self.pg5.get_capture(1)
6539 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6540 self.assertEqual(tcp.dport, 2345)
6541 self.assert_packet_checksums_valid(p)
6543 self.logger.error(ppp("Unexpected or invalid packet:", p))
6546 # from client VRF1 to service VRF0
6547 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6548 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6549 TCP(sport=12346, dport=external_port))
6550 self.pg6.add_stream(p)
6551 self.pg_enable_capture(self.pg_interfaces)
6553 capture = self.pg0.get_capture(1)
6558 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6559 self.assertEqual(tcp.dport, local_port)
6560 self.assert_packet_checksums_valid(p)
6562 self.logger.error(ppp("Unexpected or invalid packet:", p))
6565 # from service VRF0 back to client VRF1
6566 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6567 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6568 TCP(sport=local_port, dport=12346))
6569 self.pg0.add_stream(p)
6570 self.pg_enable_capture(self.pg_interfaces)
6572 capture = self.pg6.get_capture(1)
6577 self.assertEqual(ip.src, self.pg0.local_ip4)
6578 self.assertEqual(tcp.sport, external_port)
6579 self.assert_packet_checksums_valid(p)
6581 self.logger.error(ppp("Unexpected or invalid packet:", p))
6584 # from client VRF0 to service VRF1
6585 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6586 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6587 TCP(sport=12347, dport=external_port))
6588 self.pg0.add_stream(p)
6589 self.pg_enable_capture(self.pg_interfaces)
6591 capture = self.pg5.get_capture(1)
6596 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6597 self.assertEqual(tcp.dport, local_port)
6598 self.assert_packet_checksums_valid(p)
6600 self.logger.error(ppp("Unexpected or invalid packet:", p))
6603 # from service VRF1 back to client VRF0
6604 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6605 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6606 TCP(sport=local_port, dport=12347))
6607 self.pg5.add_stream(p)
6608 self.pg_enable_capture(self.pg_interfaces)
6610 capture = self.pg0.get_capture(1)
6615 self.assertEqual(ip.src, external_addr)
6616 self.assertEqual(tcp.sport, external_port)
6617 self.assert_packet_checksums_valid(p)
6619 self.logger.error(ppp("Unexpected or invalid packet:", p))
6622 # from client to server (both VRF1, no translation)
6623 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6624 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6625 TCP(sport=12348, dport=local_port))
6626 self.pg6.add_stream(p)
6627 self.pg_enable_capture(self.pg_interfaces)
6629 capture = self.pg5.get_capture(1)
6634 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6635 self.assertEqual(tcp.dport, local_port)
6636 self.assert_packet_checksums_valid(p)
6638 self.logger.error(ppp("Unexpected or invalid packet:", p))
6641 # from server back to client (both VRF1, no translation)
6642 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6643 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6644 TCP(sport=local_port, dport=12348))
6645 self.pg5.add_stream(p)
6646 self.pg_enable_capture(self.pg_interfaces)
6648 capture = self.pg6.get_capture(1)
6653 self.assertEqual(ip.src, self.pg5.remote_ip4)
6654 self.assertEqual(tcp.sport, local_port)
6655 self.assert_packet_checksums_valid(p)
6657 self.logger.error(ppp("Unexpected or invalid packet:", p))
6660 # from client VRF1 to server VRF0 (no translation)
6661 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6662 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6663 TCP(sport=local_port, dport=12349))
6664 self.pg0.add_stream(p)
6665 self.pg_enable_capture(self.pg_interfaces)
6667 capture = self.pg6.get_capture(1)
6672 self.assertEqual(ip.src, self.pg0.remote_ip4)
6673 self.assertEqual(tcp.sport, local_port)
6674 self.assert_packet_checksums_valid(p)
6676 self.logger.error(ppp("Unexpected or invalid packet:", p))
6679 # from server VRF0 back to client VRF1 (no translation)
6680 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6681 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6682 TCP(sport=local_port, dport=12349))
6683 self.pg0.add_stream(p)
6684 self.pg_enable_capture(self.pg_interfaces)
6686 capture = self.pg6.get_capture(1)
6691 self.assertEqual(ip.src, self.pg0.remote_ip4)
6692 self.assertEqual(tcp.sport, local_port)
6693 self.assert_packet_checksums_valid(p)
6695 self.logger.error(ppp("Unexpected or invalid packet:", p))
6698 # from client VRF0 to server VRF1 (no translation)
6699 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6700 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6701 TCP(sport=12344, dport=local_port))
6702 self.pg0.add_stream(p)
6703 self.pg_enable_capture(self.pg_interfaces)
6705 capture = self.pg5.get_capture(1)
6710 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6711 self.assertEqual(tcp.dport, local_port)
6712 self.assert_packet_checksums_valid(p)
6714 self.logger.error(ppp("Unexpected or invalid packet:", p))
6717 # from server VRF1 back to client VRF0 (no translation)
6718 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6719 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6720 TCP(sport=local_port, dport=12344))
6721 self.pg5.add_stream(p)
6722 self.pg_enable_capture(self.pg_interfaces)
6724 capture = self.pg0.get_capture(1)
6729 self.assertEqual(ip.src, self.pg5.remote_ip4)
6730 self.assertEqual(tcp.sport, local_port)
6731 self.assert_packet_checksums_valid(p)
6733 self.logger.error(ppp("Unexpected or invalid packet:", p))
6736 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6737 def test_session_timeout(self):
6738 """ NAT44 session timeouts """
6739 self.nat44_add_address(self.nat_addr)
6740 flags = self.config_flags.NAT_IS_INSIDE
6741 self.vapi.nat44_interface_add_del_feature(
6742 sw_if_index=self.pg0.sw_if_index,
6743 flags=flags, is_add=1)
6744 self.vapi.nat44_interface_add_del_feature(
6745 sw_if_index=self.pg1.sw_if_index,
6747 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6748 tcp_transitory=240, icmp=5)
6752 for i in range(0, max_sessions):
6753 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6754 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6755 IP(src=src, dst=self.pg1.remote_ip4) /
6756 ICMP(id=1025, type='echo-request'))
6758 self.pg0.add_stream(pkts)
6759 self.pg_enable_capture(self.pg_interfaces)
6761 self.pg1.get_capture(max_sessions)
6766 for i in range(0, max_sessions):
6767 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6768 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6769 IP(src=src, dst=self.pg1.remote_ip4) /
6770 ICMP(id=1026, type='echo-request'))
6772 self.pg0.add_stream(pkts)
6773 self.pg_enable_capture(self.pg_interfaces)
6775 self.pg1.get_capture(max_sessions)
6778 users = self.vapi.nat44_user_dump()
6780 nsessions = nsessions + user.nsessions
6781 self.assertLess(nsessions, 2 * max_sessions)
6783 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6784 def test_session_rst_timeout(self):
6785 """ NAT44 session RST timeouts """
6786 self.nat44_add_address(self.nat_addr)
6787 flags = self.config_flags.NAT_IS_INSIDE
6788 self.vapi.nat44_interface_add_del_feature(
6789 sw_if_index=self.pg0.sw_if_index,
6790 flags=flags, is_add=1)
6791 self.vapi.nat44_interface_add_del_feature(
6792 sw_if_index=self.pg1.sw_if_index,
6794 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6795 tcp_transitory=5, icmp=60)
6797 self.initiate_tcp_session(self.pg0, self.pg1)
6798 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6799 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6800 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6802 self.pg0.add_stream(p)
6803 self.pg_enable_capture(self.pg_interfaces)
6805 self.pg1.get_capture(1)
6809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6810 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6811 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6813 self.pg0.add_stream(p)
6814 self.pg_enable_capture(self.pg_interfaces)
6816 self.pg1.get_capture(1)
6818 def test_syslog_sess(self):
6819 """ Test syslog session creation and deletion """
6820 self.vapi.syslog_set_filter(
6821 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6822 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6823 self.nat44_add_address(self.nat_addr)
6824 flags = self.config_flags.NAT_IS_INSIDE
6825 self.vapi.nat44_interface_add_del_feature(
6826 sw_if_index=self.pg0.sw_if_index,
6827 flags=flags, is_add=1)
6828 self.vapi.nat44_interface_add_del_feature(
6829 sw_if_index=self.pg1.sw_if_index,
6832 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6833 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6834 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6835 self.pg0.add_stream(p)
6836 self.pg_enable_capture(self.pg_interfaces)
6838 capture = self.pg1.get_capture(1)
6839 self.tcp_port_out = capture[0][TCP].sport
6840 capture = self.pg2.get_capture(1)
6841 self.verify_syslog_sess(capture[0][Raw].load)
6843 self.pg_enable_capture(self.pg_interfaces)
6845 self.nat44_add_address(self.nat_addr, is_add=0)
6846 capture = self.pg2.get_capture(1)
6847 self.verify_syslog_sess(capture[0][Raw].load, False)
6850 super(TestNAT44EndpointDependent, self).tearDown()
6851 if not self.vpp_dead:
6853 self.vapi.cli("clear logging")
6855 def show_commands_at_teardown(self):
6856 self.logger.info(self.vapi.cli("show nat44 addresses"))
6857 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6858 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6859 self.logger.info(self.vapi.cli("show nat44 interface address"))
6860 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6861 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6862 self.logger.info(self.vapi.cli("show nat timeouts"))
6865 class TestNAT44Out2InDPO(MethodHolder):
6866 """ NAT44 Test Cases using out2in DPO """
6869 def setUpConstants(cls):
6870 super(TestNAT44Out2InDPO, cls).setUpConstants()
6871 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6874 def setUpClass(cls):
6875 super(TestNAT44Out2InDPO, cls).setUpClass()
6876 cls.vapi.cli("set log class nat level debug")
6878 cls.tcp_port_in = 6303
6879 cls.tcp_port_out = 6303
6880 cls.udp_port_in = 6304
6881 cls.udp_port_out = 6304
6882 cls.icmp_id_in = 6305
6883 cls.icmp_id_out = 6305
6884 cls.nat_addr = '10.0.0.3'
6885 cls.dst_ip4 = '192.168.70.1'
6887 cls.create_pg_interfaces(range(2))
6890 cls.pg0.config_ip4()
6891 cls.pg0.resolve_arp()
6894 cls.pg1.config_ip6()
6895 cls.pg1.resolve_ndp()
6897 r1 = VppIpRoute(cls, "::", 0,
6898 [VppRoutePath(cls.pg1.remote_ip6,
6899 cls.pg1.sw_if_index)],
6904 def tearDownClass(cls):
6905 super(TestNAT44Out2InDPO, cls).tearDownClass()
6907 def configure_xlat(self):
6908 self.dst_ip6_pfx = '1:2:3::'
6909 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6911 self.dst_ip6_pfx_len = 96
6912 self.src_ip6_pfx = '4:5:6::'
6913 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6915 self.src_ip6_pfx_len = 96
6916 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6917 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6918 '\x00\x00\x00\x00', 0)
6920 @unittest.skip('Temporary disabled')
6921 def test_464xlat_ce(self):
6922 """ Test 464XLAT CE with NAT44 """
6924 nat_config = self.vapi.nat_show_config()
6925 self.assertEqual(1, nat_config.out2in_dpo)
6927 self.configure_xlat()
6929 flags = self.config_flags.NAT_IS_INSIDE
6930 self.vapi.nat44_interface_add_del_feature(
6931 sw_if_index=self.pg0.sw_if_index,
6932 flags=flags, is_add=1)
6933 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6934 last_ip_address=self.nat_addr_n,
6935 vrf_id=0xFFFFFFFF, is_add=1)
6937 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6938 self.dst_ip6_pfx_len)
6939 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6940 self.src_ip6_pfx_len)
6943 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6944 self.pg0.add_stream(pkts)
6945 self.pg_enable_capture(self.pg_interfaces)
6947 capture = self.pg1.get_capture(len(pkts))
6948 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6951 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6953 self.pg1.add_stream(pkts)
6954 self.pg_enable_capture(self.pg_interfaces)
6956 capture = self.pg0.get_capture(len(pkts))
6957 self.verify_capture_in(capture, self.pg0)
6959 self.vapi.nat44_interface_add_del_feature(
6960 sw_if_index=self.pg0.sw_if_index,
6962 self.vapi.nat44_add_del_address_range(
6963 first_ip_address=self.nat_addr_n,
6964 last_ip_address=self.nat_addr_n,
6967 @unittest.skip('Temporary disabled')
6968 def test_464xlat_ce_no_nat(self):
6969 """ Test 464XLAT CE without NAT44 """
6971 self.configure_xlat()
6973 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6974 self.dst_ip6_pfx_len)
6975 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6976 self.src_ip6_pfx_len)
6978 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6979 self.pg0.add_stream(pkts)
6980 self.pg_enable_capture(self.pg_interfaces)
6982 capture = self.pg1.get_capture(len(pkts))
6983 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6984 nat_ip=out_dst_ip6, same_port=True)
6986 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6987 self.pg1.add_stream(pkts)
6988 self.pg_enable_capture(self.pg_interfaces)
6990 capture = self.pg0.get_capture(len(pkts))
6991 self.verify_capture_in(capture, self.pg0)
6994 class TestDeterministicNAT(MethodHolder):
6995 """ Deterministic NAT Test Cases """
6998 def setUpConstants(cls):
6999 super(TestDeterministicNAT, cls).setUpConstants()
7000 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7003 def setUpClass(cls):
7004 super(TestDeterministicNAT, cls).setUpClass()
7005 cls.vapi.cli("set log class nat level debug")
7007 cls.tcp_port_in = 6303
7008 cls.tcp_external_port = 6303
7009 cls.udp_port_in = 6304
7010 cls.udp_external_port = 6304
7011 cls.icmp_id_in = 6305
7012 cls.nat_addr = '10.0.0.3'
7014 cls.create_pg_interfaces(range(3))
7015 cls.interfaces = list(cls.pg_interfaces)
7017 for i in cls.interfaces:
7022 cls.pg0.generate_remote_hosts(2)
7023 cls.pg0.configure_ipv4_neighbors()
7026 def tearDownClass(cls):
7027 super(TestDeterministicNAT, cls).tearDownClass()
7029 def create_stream_in(self, in_if, out_if, ttl=64):
7031 Create packet stream for inside network
7033 :param in_if: Inside interface
7034 :param out_if: Outside interface
7035 :param ttl: TTL of generated packets
7039 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7040 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7041 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7045 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7046 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7047 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7051 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7052 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7053 ICMP(id=self.icmp_id_in, type='echo-request'))
7058 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7060 Create packet stream for outside network
7062 :param out_if: Outside interface
7063 :param dst_ip: Destination IP address (Default use global NAT address)
7064 :param ttl: TTL of generated packets
7067 dst_ip = self.nat_addr
7070 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7071 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7072 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7076 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7077 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7078 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7082 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7083 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7084 ICMP(id=self.icmp_external_id, type='echo-reply'))
7089 def verify_capture_out(self, capture, nat_ip=None):
7091 Verify captured packets on outside network
7093 :param capture: Captured packets
7094 :param nat_ip: Translated IP address (Default use global NAT address)
7095 :param same_port: Source port number is not translated (Default False)
7098 nat_ip = self.nat_addr
7099 for packet in capture:
7101 self.assertEqual(packet[IP].src, nat_ip)
7102 if packet.haslayer(TCP):
7103 self.tcp_port_out = packet[TCP].sport
7104 elif packet.haslayer(UDP):
7105 self.udp_port_out = packet[UDP].sport
7107 self.icmp_external_id = packet[ICMP].id
7109 self.logger.error(ppp("Unexpected or invalid packet "
7110 "(outside network):", packet))
7113 def test_deterministic_mode(self):
7114 """ NAT plugin run deterministic mode """
7115 in_addr = '172.16.255.0'
7116 out_addr = '172.17.255.50'
7117 in_addr_t = '172.16.255.20'
7121 nat_config = self.vapi.nat_show_config()
7122 self.assertEqual(1, nat_config.deterministic)
7124 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7125 in_plen=in_plen, out_addr=out_addr,
7128 rep1 = self.vapi.nat_det_forward(in_addr_t)
7129 self.assertEqual(str(rep1.out_addr), out_addr)
7130 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7132 self.assertEqual(str(rep2.in_addr), in_addr_t)
7134 deterministic_mappings = self.vapi.nat_det_map_dump()
7135 self.assertEqual(len(deterministic_mappings), 1)
7136 dsm = deterministic_mappings[0]
7137 self.assertEqual(in_addr, str(dsm.in_addr))
7138 self.assertEqual(in_plen, dsm.in_plen)
7139 self.assertEqual(out_addr, str(dsm.out_addr))
7140 self.assertEqual(out_plen, dsm.out_plen)
7142 self.clear_nat_det()
7143 deterministic_mappings = self.vapi.nat_det_map_dump()
7144 self.assertEqual(len(deterministic_mappings), 0)
7146 def test_set_timeouts(self):
7147 """ Set deterministic NAT timeouts """
7148 timeouts_before = self.vapi.nat_get_timeouts()
7150 self.vapi.nat_set_timeouts(
7151 udp=timeouts_before.udp + 10,
7152 tcp_established=timeouts_before.tcp_established + 10,
7153 tcp_transitory=timeouts_before.tcp_transitory + 10,
7154 icmp=timeouts_before.icmp + 10)
7156 timeouts_after = self.vapi.nat_get_timeouts()
7158 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7159 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7160 self.assertNotEqual(timeouts_before.tcp_established,
7161 timeouts_after.tcp_established)
7162 self.assertNotEqual(timeouts_before.tcp_transitory,
7163 timeouts_after.tcp_transitory)
7165 def test_det_in(self):
7166 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7168 nat_ip = "10.0.0.10"
7170 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7172 out_addr=socket.inet_aton(nat_ip),
7175 flags = self.config_flags.NAT_IS_INSIDE
7176 self.vapi.nat44_interface_add_del_feature(
7177 sw_if_index=self.pg0.sw_if_index,
7178 flags=flags, is_add=1)
7179 self.vapi.nat44_interface_add_del_feature(
7180 sw_if_index=self.pg1.sw_if_index,
7184 pkts = self.create_stream_in(self.pg0, self.pg1)
7185 self.pg0.add_stream(pkts)
7186 self.pg_enable_capture(self.pg_interfaces)
7188 capture = self.pg1.get_capture(len(pkts))
7189 self.verify_capture_out(capture, nat_ip)
7192 pkts = self.create_stream_out(self.pg1, nat_ip)
7193 self.pg1.add_stream(pkts)
7194 self.pg_enable_capture(self.pg_interfaces)
7196 capture = self.pg0.get_capture(len(pkts))
7197 self.verify_capture_in(capture, self.pg0)
7200 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7201 self.assertEqual(len(sessions), 3)
7205 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7206 self.assertEqual(s.in_port, self.tcp_port_in)
7207 self.assertEqual(s.out_port, self.tcp_port_out)
7208 self.assertEqual(s.ext_port, self.tcp_external_port)
7212 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7213 self.assertEqual(s.in_port, self.udp_port_in)
7214 self.assertEqual(s.out_port, self.udp_port_out)
7215 self.assertEqual(s.ext_port, self.udp_external_port)
7219 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7220 self.assertEqual(s.in_port, self.icmp_id_in)
7221 self.assertEqual(s.out_port, self.icmp_external_id)
7223 def test_multiple_users(self):
7224 """ Deterministic NAT multiple users """
7226 nat_ip = "10.0.0.10"
7228 external_port = 6303
7230 host0 = self.pg0.remote_hosts[0]
7231 host1 = self.pg0.remote_hosts[1]
7233 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7234 out_addr=socket.inet_aton(nat_ip),
7236 flags = self.config_flags.NAT_IS_INSIDE
7237 self.vapi.nat44_interface_add_del_feature(
7238 sw_if_index=self.pg0.sw_if_index,
7239 flags=flags, is_add=1)
7240 self.vapi.nat44_interface_add_del_feature(
7241 sw_if_index=self.pg1.sw_if_index,
7245 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7246 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7247 TCP(sport=port_in, dport=external_port))
7248 self.pg0.add_stream(p)
7249 self.pg_enable_capture(self.pg_interfaces)
7251 capture = self.pg1.get_capture(1)
7256 self.assertEqual(ip.src, nat_ip)
7257 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7258 self.assertEqual(tcp.dport, external_port)
7259 port_out0 = tcp.sport
7261 self.logger.error(ppp("Unexpected or invalid packet:", p))
7265 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7266 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7267 TCP(sport=port_in, dport=external_port))
7268 self.pg0.add_stream(p)
7269 self.pg_enable_capture(self.pg_interfaces)
7271 capture = self.pg1.get_capture(1)
7276 self.assertEqual(ip.src, nat_ip)
7277 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7278 self.assertEqual(tcp.dport, external_port)
7279 port_out1 = tcp.sport
7281 self.logger.error(ppp("Unexpected or invalid packet:", p))
7284 dms = self.vapi.nat_det_map_dump()
7285 self.assertEqual(1, len(dms))
7286 self.assertEqual(2, dms[0].ses_num)
7289 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7290 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7291 TCP(sport=external_port, dport=port_out0))
7292 self.pg1.add_stream(p)
7293 self.pg_enable_capture(self.pg_interfaces)
7295 capture = self.pg0.get_capture(1)
7300 self.assertEqual(ip.src, self.pg1.remote_ip4)
7301 self.assertEqual(ip.dst, host0.ip4)
7302 self.assertEqual(tcp.dport, port_in)
7303 self.assertEqual(tcp.sport, external_port)
7305 self.logger.error(ppp("Unexpected or invalid packet:", p))
7309 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7310 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7311 TCP(sport=external_port, dport=port_out1))
7312 self.pg1.add_stream(p)
7313 self.pg_enable_capture(self.pg_interfaces)
7315 capture = self.pg0.get_capture(1)
7320 self.assertEqual(ip.src, self.pg1.remote_ip4)
7321 self.assertEqual(ip.dst, host1.ip4)
7322 self.assertEqual(tcp.dport, port_in)
7323 self.assertEqual(tcp.sport, external_port)
7325 self.logger.error(ppp("Unexpected or invalid packet", p))
7328 # session close api test
7329 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7331 self.pg1.remote_ip4,
7333 dms = self.vapi.nat_det_map_dump()
7334 self.assertEqual(dms[0].ses_num, 1)
7336 self.vapi.nat_det_close_session_in(host0.ip4,
7338 self.pg1.remote_ip4,
7340 dms = self.vapi.nat_det_map_dump()
7341 self.assertEqual(dms[0].ses_num, 0)
7343 def test_tcp_session_close_detection_in(self):
7344 """ Deterministic NAT TCP session close from inside network """
7345 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7347 out_addr=socket.inet_aton(self.nat_addr),
7349 flags = self.config_flags.NAT_IS_INSIDE
7350 self.vapi.nat44_interface_add_del_feature(
7351 sw_if_index=self.pg0.sw_if_index,
7352 flags=flags, is_add=1)
7353 self.vapi.nat44_interface_add_del_feature(
7354 sw_if_index=self.pg1.sw_if_index,
7357 self.initiate_tcp_session(self.pg0, self.pg1)
7359 # close the session from inside
7361 # FIN packet in -> out
7362 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7363 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7364 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7366 self.pg0.add_stream(p)
7367 self.pg_enable_capture(self.pg_interfaces)
7369 self.pg1.get_capture(1)
7373 # ACK packet out -> in
7374 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7375 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7376 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7380 # FIN packet out -> in
7381 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7382 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7383 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7387 self.pg1.add_stream(pkts)
7388 self.pg_enable_capture(self.pg_interfaces)
7390 self.pg0.get_capture(2)
7392 # ACK packet in -> out
7393 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7394 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7395 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7397 self.pg0.add_stream(p)
7398 self.pg_enable_capture(self.pg_interfaces)
7400 self.pg1.get_capture(1)
7402 # Check if deterministic NAT44 closed the session
7403 dms = self.vapi.nat_det_map_dump()
7404 self.assertEqual(0, dms[0].ses_num)
7406 self.logger.error("TCP session termination failed")
7409 def test_tcp_session_close_detection_out(self):
7410 """ Deterministic NAT TCP session close from outside network """
7411 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7413 out_addr=socket.inet_aton(self.nat_addr),
7415 flags = self.config_flags.NAT_IS_INSIDE
7416 self.vapi.nat44_interface_add_del_feature(
7417 sw_if_index=self.pg0.sw_if_index,
7418 flags=flags, is_add=1)
7419 self.vapi.nat44_interface_add_del_feature(
7420 sw_if_index=self.pg1.sw_if_index,
7423 self.initiate_tcp_session(self.pg0, self.pg1)
7425 # close the session from outside
7427 # FIN packet out -> in
7428 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7429 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7430 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7432 self.pg1.add_stream(p)
7433 self.pg_enable_capture(self.pg_interfaces)
7435 self.pg0.get_capture(1)
7439 # ACK packet in -> out
7440 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7441 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7442 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7446 # ACK packet in -> out
7447 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7448 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7449 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7453 self.pg0.add_stream(pkts)
7454 self.pg_enable_capture(self.pg_interfaces)
7456 self.pg1.get_capture(2)
7458 # ACK packet out -> in
7459 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7460 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7461 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7463 self.pg1.add_stream(p)
7464 self.pg_enable_capture(self.pg_interfaces)
7466 self.pg0.get_capture(1)
7468 # Check if deterministic NAT44 closed the session
7469 dms = self.vapi.nat_det_map_dump()
7470 self.assertEqual(0, dms[0].ses_num)
7472 self.logger.error("TCP session termination failed")
7475 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7476 def test_session_timeout(self):
7477 """ Deterministic NAT session timeouts """
7478 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7480 out_addr=socket.inet_aton(self.nat_addr),
7482 flags = self.config_flags.NAT_IS_INSIDE
7483 self.vapi.nat44_interface_add_del_feature(
7484 sw_if_index=self.pg0.sw_if_index,
7485 flags=flags, is_add=1)
7486 self.vapi.nat44_interface_add_del_feature(
7487 sw_if_index=self.pg1.sw_if_index,
7490 self.initiate_tcp_session(self.pg0, self.pg1)
7491 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7493 pkts = self.create_stream_in(self.pg0, self.pg1)
7494 self.pg0.add_stream(pkts)
7495 self.pg_enable_capture(self.pg_interfaces)
7497 capture = self.pg1.get_capture(len(pkts))
7500 dms = self.vapi.nat_det_map_dump()
7501 self.assertEqual(0, dms[0].ses_num)
7503 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7504 def test_session_limit_per_user(self):
7505 """ Deterministic NAT maximum sessions per user limit """
7506 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7508 out_addr=socket.inet_aton(self.nat_addr),
7510 flags = self.config_flags.NAT_IS_INSIDE
7511 self.vapi.nat44_interface_add_del_feature(
7512 sw_if_index=self.pg0.sw_if_index,
7513 flags=flags, is_add=1)
7514 self.vapi.nat44_interface_add_del_feature(
7515 sw_if_index=self.pg1.sw_if_index,
7517 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7518 src_address=self.pg2.local_ip4,
7520 template_interval=10)
7521 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7525 for port in range(1025, 2025):
7526 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7527 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7528 UDP(sport=port, dport=port))
7531 self.pg0.add_stream(pkts)
7532 self.pg_enable_capture(self.pg_interfaces)
7534 capture = self.pg1.get_capture(len(pkts))
7536 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7537 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7538 UDP(sport=3001, dport=3002))
7539 self.pg0.add_stream(p)
7540 self.pg_enable_capture(self.pg_interfaces)
7542 capture = self.pg1.assert_nothing_captured()
7544 # verify ICMP error packet
7545 capture = self.pg0.get_capture(1)
7547 self.assertTrue(p.haslayer(ICMP))
7549 self.assertEqual(icmp.type, 3)
7550 self.assertEqual(icmp.code, 1)
7551 self.assertTrue(icmp.haslayer(IPerror))
7552 inner_ip = icmp[IPerror]
7553 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7554 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7556 dms = self.vapi.nat_det_map_dump()
7558 self.assertEqual(1000, dms[0].ses_num)
7560 # verify IPFIX logging
7561 self.vapi.ipfix_flush()
7563 capture = self.pg2.get_capture(2)
7564 ipfix = IPFIXDecoder()
7565 # first load template
7567 self.assertTrue(p.haslayer(IPFIX))
7568 if p.haslayer(Template):
7569 ipfix.add_template(p.getlayer(Template))
7570 # verify events in data set
7572 if p.haslayer(Data):
7573 data = ipfix.decode_data_set(p.getlayer(Set))
7574 self.verify_ipfix_max_entries_per_user(data,
7576 self.pg0.remote_ip4)
7578 def clear_nat_det(self):
7580 Clear deterministic NAT configuration.
7582 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7584 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7585 tcp_transitory=240, icmp=60)
7586 deterministic_mappings = self.vapi.nat_det_map_dump()
7587 for dsm in deterministic_mappings:
7588 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7589 in_plen=dsm.in_plen,
7590 out_addr=dsm.out_addr,
7591 out_plen=dsm.out_plen)
7593 interfaces = self.vapi.nat44_interface_dump()
7594 for intf in interfaces:
7595 self.vapi.nat44_interface_add_del_feature(
7596 sw_if_index=intf.sw_if_index,
7600 super(TestDeterministicNAT, self).tearDown()
7601 if not self.vpp_dead:
7602 self.clear_nat_det()
7604 def show_commands_at_teardown(self):
7605 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7606 self.logger.info(self.vapi.cli("show nat timeouts"))
7608 self.vapi.cli("show nat44 deterministic mappings"))
7610 self.vapi.cli("show nat44 deterministic sessions"))
7613 class TestNAT64(MethodHolder):
7614 """ NAT64 Test Cases """
7617 def setUpConstants(cls):
7618 super(TestNAT64, cls).setUpConstants()
7619 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7620 "nat64 st hash buckets 256", "}"])
7623 def setUpClass(cls):
7624 super(TestNAT64, cls).setUpClass()
7626 cls.tcp_port_in = 6303
7627 cls.tcp_port_out = 6303
7628 cls.udp_port_in = 6304
7629 cls.udp_port_out = 6304
7630 cls.icmp_id_in = 6305
7631 cls.icmp_id_out = 6305
7632 cls.tcp_external_port = 80
7633 cls.nat_addr = '10.0.0.3'
7634 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7636 cls.vrf1_nat_addr = '10.0.10.3'
7637 cls.ipfix_src_port = 4739
7638 cls.ipfix_domain_id = 1
7640 cls.create_pg_interfaces(range(6))
7641 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7642 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7643 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7645 cls.vapi.ip_table_add_del(is_add=1,
7646 table={'table_id': cls.vrf1_id,
7649 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7651 cls.pg0.generate_remote_hosts(2)
7653 for i in cls.ip6_interfaces:
7656 i.configure_ipv6_neighbors()
7658 for i in cls.ip4_interfaces:
7664 cls.pg3.config_ip4()
7665 cls.pg3.resolve_arp()
7666 cls.pg3.config_ip6()
7667 cls.pg3.configure_ipv6_neighbors()
7670 cls.pg5.config_ip6()
7673 def tearDownClass(cls):
7674 super(TestNAT64, cls).tearDownClass()
7676 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7677 """ NAT64 inside interface handles Neighbor Advertisement """
7679 flags = self.config_flags.NAT_IS_INSIDE
7680 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7681 sw_if_index=self.pg5.sw_if_index)
7684 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7685 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7686 ICMPv6EchoRequest())
7688 self.pg5.add_stream(pkts)
7689 self.pg_enable_capture(self.pg_interfaces)
7692 # Wait for Neighbor Solicitation
7693 capture = self.pg5.get_capture(len(pkts))
7696 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7697 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7698 tgt = packet[ICMPv6ND_NS].tgt
7700 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7703 # Send Neighbor Advertisement
7704 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7705 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7706 ICMPv6ND_NA(tgt=tgt) /
7707 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7709 self.pg5.add_stream(pkts)
7710 self.pg_enable_capture(self.pg_interfaces)
7713 # Try to send ping again
7715 self.pg5.add_stream(pkts)
7716 self.pg_enable_capture(self.pg_interfaces)
7719 # Wait for ping reply
7720 capture = self.pg5.get_capture(len(pkts))
7723 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7724 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7725 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7727 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7730 def test_pool(self):
7731 """ Add/delete address to NAT64 pool """
7732 nat_addr = '1.2.3.4'
7734 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7736 vrf_id=0xFFFFFFFF, is_add=1)
7738 addresses = self.vapi.nat64_pool_addr_dump()
7739 self.assertEqual(len(addresses), 1)
7740 self.assertEqual(str(addresses[0].address), nat_addr)
7742 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7744 vrf_id=0xFFFFFFFF, is_add=0)
7746 addresses = self.vapi.nat64_pool_addr_dump()
7747 self.assertEqual(len(addresses), 0)
7749 def test_interface(self):
7750 """ Enable/disable NAT64 feature on the interface """
7751 flags = self.config_flags.NAT_IS_INSIDE
7752 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7753 sw_if_index=self.pg0.sw_if_index)
7754 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7755 sw_if_index=self.pg1.sw_if_index)
7757 interfaces = self.vapi.nat64_interface_dump()
7758 self.assertEqual(len(interfaces), 2)
7761 for intf in interfaces:
7762 if intf.sw_if_index == self.pg0.sw_if_index:
7763 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7765 elif intf.sw_if_index == self.pg1.sw_if_index:
7766 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7768 self.assertTrue(pg0_found)
7769 self.assertTrue(pg1_found)
7771 features = self.vapi.cli("show interface features pg0")
7772 self.assertIn('nat64-in2out', features)
7773 features = self.vapi.cli("show interface features pg1")
7774 self.assertIn('nat64-out2in', features)
7776 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7777 sw_if_index=self.pg0.sw_if_index)
7778 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7779 sw_if_index=self.pg1.sw_if_index)
7781 interfaces = self.vapi.nat64_interface_dump()
7782 self.assertEqual(len(interfaces), 0)
7784 def test_static_bib(self):
7785 """ Add/delete static BIB entry """
7786 in_addr = '2001:db8:85a3::8a2e:370:7334'
7787 out_addr = '10.1.1.3'
7790 proto = IP_PROTOS.tcp
7792 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7793 i_port=in_port, o_port=out_port,
7794 proto=proto, vrf_id=0, is_add=1)
7795 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7798 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7800 self.assertEqual(str(bibe.i_addr), in_addr)
7801 self.assertEqual(str(bibe.o_addr), out_addr)
7802 self.assertEqual(bibe.i_port, in_port)
7803 self.assertEqual(bibe.o_port, out_port)
7804 self.assertEqual(static_bib_num, 1)
7805 bibs = self.statistics.get_counter('/nat64/total-bibs')
7806 self.assertEqual(bibs[0][0], 1)
7808 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7809 i_port=in_port, o_port=out_port,
7810 proto=proto, vrf_id=0, is_add=0)
7811 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7814 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7816 self.assertEqual(static_bib_num, 0)
7817 bibs = self.statistics.get_counter('/nat64/total-bibs')
7818 self.assertEqual(bibs[0][0], 0)
7820 def test_set_timeouts(self):
7821 """ Set NAT64 timeouts """
7822 # verify default values
7823 timeouts = self.vapi.nat_get_timeouts()
7824 self.assertEqual(timeouts.udp, 300)
7825 self.assertEqual(timeouts.icmp, 60)
7826 self.assertEqual(timeouts.tcp_transitory, 240)
7827 self.assertEqual(timeouts.tcp_established, 7440)
7829 # set and verify custom values
7830 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7831 tcp_transitory=250, icmp=30)
7832 timeouts = self.vapi.nat_get_timeouts()
7833 self.assertEqual(timeouts.udp, 200)
7834 self.assertEqual(timeouts.icmp, 30)
7835 self.assertEqual(timeouts.tcp_transitory, 250)
7836 self.assertEqual(timeouts.tcp_established, 7450)
7838 def test_dynamic(self):
7839 """ NAT64 dynamic translation test """
7840 self.tcp_port_in = 6303
7841 self.udp_port_in = 6304
7842 self.icmp_id_in = 6305
7844 ses_num_start = self.nat64_get_ses_num()
7846 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7847 end_addr=self.nat_addr,
7850 flags = self.config_flags.NAT_IS_INSIDE
7851 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7852 sw_if_index=self.pg0.sw_if_index)
7853 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7854 sw_if_index=self.pg1.sw_if_index)
7857 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7858 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7859 icmpn = self.statistics.get_err_counter(
7860 '/err/nat64-in2out/ICMP packets')
7861 totaln = self.statistics.get_err_counter(
7862 '/err/nat64-in2out/good in2out packets processed')
7864 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7865 self.pg0.add_stream(pkts)
7866 self.pg_enable_capture(self.pg_interfaces)
7868 capture = self.pg1.get_capture(len(pkts))
7869 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7870 dst_ip=self.pg1.remote_ip4)
7872 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7873 self.assertEqual(err - tcpn, 1)
7874 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7875 self.assertEqual(err - udpn, 1)
7876 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7877 self.assertEqual(err - icmpn, 1)
7878 err = self.statistics.get_err_counter(
7879 '/err/nat64-in2out/good in2out packets processed')
7880 self.assertEqual(err - totaln, 3)
7883 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7884 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7885 icmpn = self.statistics.get_err_counter(
7886 '/err/nat64-out2in/ICMP packets')
7887 totaln = self.statistics.get_err_counter(
7888 '/err/nat64-out2in/good out2in packets processed')
7890 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7891 self.pg1.add_stream(pkts)
7892 self.pg_enable_capture(self.pg_interfaces)
7894 capture = self.pg0.get_capture(len(pkts))
7895 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7896 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7898 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7899 self.assertEqual(err - tcpn, 2)
7900 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7901 self.assertEqual(err - udpn, 1)
7902 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7903 self.assertEqual(err - icmpn, 1)
7904 err = self.statistics.get_err_counter(
7905 '/err/nat64-out2in/good out2in packets processed')
7906 self.assertEqual(err - totaln, 4)
7908 bibs = self.statistics.get_counter('/nat64/total-bibs')
7909 self.assertEqual(bibs[0][0], 3)
7910 sessions = self.statistics.get_counter('/nat64/total-sessions')
7911 self.assertEqual(sessions[0][0], 3)
7914 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7915 self.pg0.add_stream(pkts)
7916 self.pg_enable_capture(self.pg_interfaces)
7918 capture = self.pg1.get_capture(len(pkts))
7919 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7920 dst_ip=self.pg1.remote_ip4)
7923 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7924 self.pg1.add_stream(pkts)
7925 self.pg_enable_capture(self.pg_interfaces)
7927 capture = self.pg0.get_capture(len(pkts))
7928 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7930 ses_num_end = self.nat64_get_ses_num()
7932 self.assertEqual(ses_num_end - ses_num_start, 3)
7934 # tenant with specific VRF
7935 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7936 end_addr=self.vrf1_nat_addr,
7937 vrf_id=self.vrf1_id, is_add=1)
7938 flags = self.config_flags.NAT_IS_INSIDE
7939 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7940 sw_if_index=self.pg2.sw_if_index)
7942 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7943 self.pg2.add_stream(pkts)
7944 self.pg_enable_capture(self.pg_interfaces)
7946 capture = self.pg1.get_capture(len(pkts))
7947 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7948 dst_ip=self.pg1.remote_ip4)
7950 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7951 self.pg1.add_stream(pkts)
7952 self.pg_enable_capture(self.pg_interfaces)
7954 capture = self.pg2.get_capture(len(pkts))
7955 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7957 def test_static(self):
7958 """ NAT64 static translation test """
7959 self.tcp_port_in = 60303
7960 self.udp_port_in = 60304
7961 self.icmp_id_in = 60305
7962 self.tcp_port_out = 60303
7963 self.udp_port_out = 60304
7964 self.icmp_id_out = 60305
7966 ses_num_start = self.nat64_get_ses_num()
7968 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7969 end_addr=self.nat_addr,
7972 flags = self.config_flags.NAT_IS_INSIDE
7973 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7974 sw_if_index=self.pg0.sw_if_index)
7975 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7976 sw_if_index=self.pg1.sw_if_index)
7978 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7979 o_addr=self.nat_addr,
7980 i_port=self.tcp_port_in,
7981 o_port=self.tcp_port_out,
7982 proto=IP_PROTOS.tcp, vrf_id=0,
7984 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7985 o_addr=self.nat_addr,
7986 i_port=self.udp_port_in,
7987 o_port=self.udp_port_out,
7988 proto=IP_PROTOS.udp, vrf_id=0,
7990 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7991 o_addr=self.nat_addr,
7992 i_port=self.icmp_id_in,
7993 o_port=self.icmp_id_out,
7994 proto=IP_PROTOS.icmp, vrf_id=0,
7998 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7999 self.pg0.add_stream(pkts)
8000 self.pg_enable_capture(self.pg_interfaces)
8002 capture = self.pg1.get_capture(len(pkts))
8003 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8004 dst_ip=self.pg1.remote_ip4, same_port=True)
8007 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8008 self.pg1.add_stream(pkts)
8009 self.pg_enable_capture(self.pg_interfaces)
8011 capture = self.pg0.get_capture(len(pkts))
8012 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8013 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8015 ses_num_end = self.nat64_get_ses_num()
8017 self.assertEqual(ses_num_end - ses_num_start, 3)
8019 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8020 def test_session_timeout(self):
8021 """ NAT64 session timeout """
8022 self.icmp_id_in = 1234
8023 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8024 end_addr=self.nat_addr,
8027 flags = self.config_flags.NAT_IS_INSIDE
8028 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8029 sw_if_index=self.pg0.sw_if_index)
8030 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8031 sw_if_index=self.pg1.sw_if_index)
8032 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8036 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8037 self.pg0.add_stream(pkts)
8038 self.pg_enable_capture(self.pg_interfaces)
8040 capture = self.pg1.get_capture(len(pkts))
8042 ses_num_before_timeout = self.nat64_get_ses_num()
8046 # ICMP and TCP session after timeout
8047 ses_num_after_timeout = self.nat64_get_ses_num()
8048 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8050 def test_icmp_error(self):
8051 """ NAT64 ICMP Error message translation """
8052 self.tcp_port_in = 6303
8053 self.udp_port_in = 6304
8054 self.icmp_id_in = 6305
8056 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8057 end_addr=self.nat_addr,
8060 flags = self.config_flags.NAT_IS_INSIDE
8061 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8062 sw_if_index=self.pg0.sw_if_index)
8063 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8064 sw_if_index=self.pg1.sw_if_index)
8066 # send some packets to create sessions
8067 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8068 self.pg0.add_stream(pkts)
8069 self.pg_enable_capture(self.pg_interfaces)
8071 capture_ip4 = self.pg1.get_capture(len(pkts))
8072 self.verify_capture_out(capture_ip4,
8073 nat_ip=self.nat_addr,
8074 dst_ip=self.pg1.remote_ip4)
8076 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8077 self.pg1.add_stream(pkts)
8078 self.pg_enable_capture(self.pg_interfaces)
8080 capture_ip6 = self.pg0.get_capture(len(pkts))
8081 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8082 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8083 self.pg0.remote_ip6)
8086 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8087 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8088 ICMPv6DestUnreach(code=1) /
8089 packet[IPv6] for packet in capture_ip6]
8090 self.pg0.add_stream(pkts)
8091 self.pg_enable_capture(self.pg_interfaces)
8093 capture = self.pg1.get_capture(len(pkts))
8094 for packet in capture:
8096 self.assertEqual(packet[IP].src, self.nat_addr)
8097 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8098 self.assertEqual(packet[ICMP].type, 3)
8099 self.assertEqual(packet[ICMP].code, 13)
8100 inner = packet[IPerror]
8101 self.assertEqual(inner.src, self.pg1.remote_ip4)
8102 self.assertEqual(inner.dst, self.nat_addr)
8103 self.assert_packet_checksums_valid(packet)
8104 if inner.haslayer(TCPerror):
8105 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8106 elif inner.haslayer(UDPerror):
8107 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8109 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8111 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8115 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8116 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8117 ICMP(type=3, code=13) /
8118 packet[IP] for packet in capture_ip4]
8119 self.pg1.add_stream(pkts)
8120 self.pg_enable_capture(self.pg_interfaces)
8122 capture = self.pg0.get_capture(len(pkts))
8123 for packet in capture:
8125 self.assertEqual(packet[IPv6].src, ip.src)
8126 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8127 icmp = packet[ICMPv6DestUnreach]
8128 self.assertEqual(icmp.code, 1)
8129 inner = icmp[IPerror6]
8130 self.assertEqual(inner.src, self.pg0.remote_ip6)
8131 self.assertEqual(inner.dst, ip.src)
8132 self.assert_icmpv6_checksum_valid(packet)
8133 if inner.haslayer(TCPerror):
8134 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8135 elif inner.haslayer(UDPerror):
8136 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8138 self.assertEqual(inner[ICMPv6EchoRequest].id,
8141 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8144 def test_hairpinning(self):
8145 """ NAT64 hairpinning """
8147 client = self.pg0.remote_hosts[0]
8148 server = self.pg0.remote_hosts[1]
8149 server_tcp_in_port = 22
8150 server_tcp_out_port = 4022
8151 server_udp_in_port = 23
8152 server_udp_out_port = 4023
8153 client_tcp_in_port = 1234
8154 client_udp_in_port = 1235
8155 client_tcp_out_port = 0
8156 client_udp_out_port = 0
8157 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8158 nat_addr_ip6 = ip.src
8160 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8161 end_addr=self.nat_addr,
8164 flags = self.config_flags.NAT_IS_INSIDE
8165 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8166 sw_if_index=self.pg0.sw_if_index)
8167 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8168 sw_if_index=self.pg1.sw_if_index)
8170 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8171 o_addr=self.nat_addr,
8172 i_port=server_tcp_in_port,
8173 o_port=server_tcp_out_port,
8174 proto=IP_PROTOS.tcp, vrf_id=0,
8176 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8177 o_addr=self.nat_addr,
8178 i_port=server_udp_in_port,
8179 o_port=server_udp_out_port,
8180 proto=IP_PROTOS.udp, vrf_id=0,
8185 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8186 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8187 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8189 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8190 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8191 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8193 self.pg0.add_stream(pkts)
8194 self.pg_enable_capture(self.pg_interfaces)
8196 capture = self.pg0.get_capture(len(pkts))
8197 for packet in capture:
8199 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8200 self.assertEqual(packet[IPv6].dst, server.ip6)
8201 self.assert_packet_checksums_valid(packet)
8202 if packet.haslayer(TCP):
8203 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8204 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8205 client_tcp_out_port = packet[TCP].sport
8207 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8208 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8209 client_udp_out_port = packet[UDP].sport
8211 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8216 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8217 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8218 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8220 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8221 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8222 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8224 self.pg0.add_stream(pkts)
8225 self.pg_enable_capture(self.pg_interfaces)
8227 capture = self.pg0.get_capture(len(pkts))
8228 for packet in capture:
8230 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8231 self.assertEqual(packet[IPv6].dst, client.ip6)
8232 self.assert_packet_checksums_valid(packet)
8233 if packet.haslayer(TCP):
8234 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8235 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8237 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8238 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8240 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8245 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8246 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8247 ICMPv6DestUnreach(code=1) /
8248 packet[IPv6] for packet in capture]
8249 self.pg0.add_stream(pkts)
8250 self.pg_enable_capture(self.pg_interfaces)
8252 capture = self.pg0.get_capture(len(pkts))
8253 for packet in capture:
8255 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8256 self.assertEqual(packet[IPv6].dst, server.ip6)
8257 icmp = packet[ICMPv6DestUnreach]
8258 self.assertEqual(icmp.code, 1)
8259 inner = icmp[IPerror6]
8260 self.assertEqual(inner.src, server.ip6)
8261 self.assertEqual(inner.dst, nat_addr_ip6)
8262 self.assert_packet_checksums_valid(packet)
8263 if inner.haslayer(TCPerror):
8264 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8265 self.assertEqual(inner[TCPerror].dport,
8266 client_tcp_out_port)
8268 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8269 self.assertEqual(inner[UDPerror].dport,
8270 client_udp_out_port)
8272 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8275 def test_prefix(self):
8276 """ NAT64 Network-Specific Prefix """
8278 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8279 end_addr=self.nat_addr,
8282 flags = self.config_flags.NAT_IS_INSIDE
8283 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8284 sw_if_index=self.pg0.sw_if_index)
8285 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8286 sw_if_index=self.pg1.sw_if_index)
8287 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8288 end_addr=self.vrf1_nat_addr,
8289 vrf_id=self.vrf1_id, is_add=1)
8290 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8291 sw_if_index=self.pg2.sw_if_index)
8294 global_pref64 = "2001:db8::"
8295 global_pref64_len = 32
8296 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8297 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8300 prefix = self.vapi.nat64_prefix_dump()
8301 self.assertEqual(len(prefix), 1)
8302 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8303 self.assertEqual(prefix[0].vrf_id, 0)
8305 # Add tenant specific prefix
8306 vrf1_pref64 = "2001:db8:122:300::"
8307 vrf1_pref64_len = 56
8308 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8309 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8310 vrf_id=self.vrf1_id, is_add=1)
8312 prefix = self.vapi.nat64_prefix_dump()
8313 self.assertEqual(len(prefix), 2)
8316 pkts = self.create_stream_in_ip6(self.pg0,
8319 plen=global_pref64_len)
8320 self.pg0.add_stream(pkts)
8321 self.pg_enable_capture(self.pg_interfaces)
8323 capture = self.pg1.get_capture(len(pkts))
8324 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8325 dst_ip=self.pg1.remote_ip4)
8327 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8328 self.pg1.add_stream(pkts)
8329 self.pg_enable_capture(self.pg_interfaces)
8331 capture = self.pg0.get_capture(len(pkts))
8332 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8335 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8337 # Tenant specific prefix
8338 pkts = self.create_stream_in_ip6(self.pg2,
8341 plen=vrf1_pref64_len)
8342 self.pg2.add_stream(pkts)
8343 self.pg_enable_capture(self.pg_interfaces)
8345 capture = self.pg1.get_capture(len(pkts))
8346 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8347 dst_ip=self.pg1.remote_ip4)
8349 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8350 self.pg1.add_stream(pkts)
8351 self.pg_enable_capture(self.pg_interfaces)
8353 capture = self.pg2.get_capture(len(pkts))
8354 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8357 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8359 def test_unknown_proto(self):
8360 """ NAT64 translate packet with unknown protocol """
8362 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8363 end_addr=self.nat_addr,
8366 flags = self.config_flags.NAT_IS_INSIDE
8367 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8368 sw_if_index=self.pg0.sw_if_index)
8369 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8370 sw_if_index=self.pg1.sw_if_index)
8371 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8374 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8375 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8376 TCP(sport=self.tcp_port_in, dport=20))
8377 self.pg0.add_stream(p)
8378 self.pg_enable_capture(self.pg_interfaces)
8380 p = self.pg1.get_capture(1)
8382 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8383 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8385 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8386 TCP(sport=1234, dport=1234))
8387 self.pg0.add_stream(p)
8388 self.pg_enable_capture(self.pg_interfaces)
8390 p = self.pg1.get_capture(1)
8393 self.assertEqual(packet[IP].src, self.nat_addr)
8394 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8395 self.assertEqual(packet.haslayer(GRE), 1)
8396 self.assert_packet_checksums_valid(packet)
8398 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8402 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8403 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8405 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8406 TCP(sport=1234, dport=1234))
8407 self.pg1.add_stream(p)
8408 self.pg_enable_capture(self.pg_interfaces)
8410 p = self.pg0.get_capture(1)
8413 self.assertEqual(packet[IPv6].src, remote_ip6)
8414 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8415 self.assertEqual(packet[IPv6].nh, 47)
8417 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8420 def test_hairpinning_unknown_proto(self):
8421 """ NAT64 translate packet with unknown protocol - hairpinning """
8423 client = self.pg0.remote_hosts[0]
8424 server = self.pg0.remote_hosts[1]
8425 server_tcp_in_port = 22
8426 server_tcp_out_port = 4022
8427 client_tcp_in_port = 1234
8428 client_tcp_out_port = 1235
8429 server_nat_ip = "10.0.0.100"
8430 client_nat_ip = "10.0.0.110"
8431 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8432 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8434 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8435 end_addr=client_nat_ip,
8438 flags = self.config_flags.NAT_IS_INSIDE
8439 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8440 sw_if_index=self.pg0.sw_if_index)
8441 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8442 sw_if_index=self.pg1.sw_if_index)
8444 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8445 o_addr=server_nat_ip,
8446 i_port=server_tcp_in_port,
8447 o_port=server_tcp_out_port,
8448 proto=IP_PROTOS.tcp, vrf_id=0,
8451 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8452 o_addr=server_nat_ip, i_port=0,
8454 proto=IP_PROTOS.gre, vrf_id=0,
8457 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8458 o_addr=client_nat_ip,
8459 i_port=client_tcp_in_port,
8460 o_port=client_tcp_out_port,
8461 proto=IP_PROTOS.tcp, vrf_id=0,
8465 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8466 IPv6(src=client.ip6, dst=server_nat_ip6) /
8467 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8468 self.pg0.add_stream(p)
8469 self.pg_enable_capture(self.pg_interfaces)
8471 p = self.pg0.get_capture(1)
8473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8474 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8476 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8477 TCP(sport=1234, dport=1234))
8478 self.pg0.add_stream(p)
8479 self.pg_enable_capture(self.pg_interfaces)
8481 p = self.pg0.get_capture(1)
8484 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8485 self.assertEqual(packet[IPv6].dst, server.ip6)
8486 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8488 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8492 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8493 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8495 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8496 TCP(sport=1234, dport=1234))
8497 self.pg0.add_stream(p)
8498 self.pg_enable_capture(self.pg_interfaces)
8500 p = self.pg0.get_capture(1)
8503 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8504 self.assertEqual(packet[IPv6].dst, client.ip6)
8505 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8507 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8510 def test_one_armed_nat64(self):
8511 """ One armed NAT64 """
8513 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8517 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8518 end_addr=self.nat_addr,
8521 flags = self.config_flags.NAT_IS_INSIDE
8522 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8523 sw_if_index=self.pg3.sw_if_index)
8524 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8525 sw_if_index=self.pg3.sw_if_index)
8528 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8529 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8530 TCP(sport=12345, dport=80))
8531 self.pg3.add_stream(p)
8532 self.pg_enable_capture(self.pg_interfaces)
8534 capture = self.pg3.get_capture(1)
8539 self.assertEqual(ip.src, self.nat_addr)
8540 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8541 self.assertNotEqual(tcp.sport, 12345)
8542 external_port = tcp.sport
8543 self.assertEqual(tcp.dport, 80)
8544 self.assert_packet_checksums_valid(p)
8546 self.logger.error(ppp("Unexpected or invalid packet:", p))
8550 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8551 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8552 TCP(sport=80, dport=external_port))
8553 self.pg3.add_stream(p)
8554 self.pg_enable_capture(self.pg_interfaces)
8556 capture = self.pg3.get_capture(1)
8561 self.assertEqual(ip.src, remote_host_ip6)
8562 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8563 self.assertEqual(tcp.sport, 80)
8564 self.assertEqual(tcp.dport, 12345)
8565 self.assert_packet_checksums_valid(p)
8567 self.logger.error(ppp("Unexpected or invalid packet:", p))
8570 def test_frag_in_order(self):
8571 """ NAT64 translate fragments arriving in order """
8572 self.tcp_port_in = random.randint(1025, 65535)
8574 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8575 end_addr=self.nat_addr,
8578 flags = self.config_flags.NAT_IS_INSIDE
8579 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8580 sw_if_index=self.pg0.sw_if_index)
8581 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8582 sw_if_index=self.pg1.sw_if_index)
8586 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8587 self.tcp_port_in, 20, data)
8588 self.pg0.add_stream(pkts)
8589 self.pg_enable_capture(self.pg_interfaces)
8591 frags = self.pg1.get_capture(len(pkts))
8592 p = self.reass_frags_and_verify(frags,
8594 self.pg1.remote_ip4)
8595 self.assertEqual(p[TCP].dport, 20)
8596 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8597 self.tcp_port_out = p[TCP].sport
8598 self.assertEqual(data, p[Raw].load)
8601 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8602 pkts = self.create_stream_frag(self.pg1,
8607 self.pg1.add_stream(pkts)
8608 self.pg_enable_capture(self.pg_interfaces)
8610 frags = self.pg0.get_capture(len(pkts))
8611 self.logger.debug(ppc("Captured:", frags))
8612 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8613 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8614 self.assertEqual(p[TCP].sport, 20)
8615 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8616 self.assertEqual(data, p[Raw].load)
8618 def test_reass_hairpinning(self):
8619 """ NAT64 fragments hairpinning """
8621 server = self.pg0.remote_hosts[1]
8622 server_in_port = random.randint(1025, 65535)
8623 server_out_port = random.randint(1025, 65535)
8624 client_in_port = random.randint(1025, 65535)
8625 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8626 nat_addr_ip6 = ip.src
8628 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8629 end_addr=self.nat_addr,
8632 flags = self.config_flags.NAT_IS_INSIDE
8633 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8634 sw_if_index=self.pg0.sw_if_index)
8635 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8636 sw_if_index=self.pg1.sw_if_index)
8638 # add static BIB entry for server
8639 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8640 o_addr=self.nat_addr,
8641 i_port=server_in_port,
8642 o_port=server_out_port,
8643 proto=IP_PROTOS.tcp, vrf_id=0,
8646 # send packet from host to server
8647 pkts = self.create_stream_frag_ip6(self.pg0,
8652 self.pg0.add_stream(pkts)
8653 self.pg_enable_capture(self.pg_interfaces)
8655 frags = self.pg0.get_capture(len(pkts))
8656 self.logger.debug(ppc("Captured:", frags))
8657 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8658 self.assertNotEqual(p[TCP].sport, client_in_port)
8659 self.assertEqual(p[TCP].dport, server_in_port)
8660 self.assertEqual(data, p[Raw].load)
8662 def test_frag_out_of_order(self):
8663 """ NAT64 translate fragments arriving out of order """
8664 self.tcp_port_in = random.randint(1025, 65535)
8666 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8667 end_addr=self.nat_addr,
8670 flags = self.config_flags.NAT_IS_INSIDE
8671 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8672 sw_if_index=self.pg0.sw_if_index)
8673 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8674 sw_if_index=self.pg1.sw_if_index)
8678 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8679 self.tcp_port_in, 20, data)
8681 self.pg0.add_stream(pkts)
8682 self.pg_enable_capture(self.pg_interfaces)
8684 frags = self.pg1.get_capture(len(pkts))
8685 p = self.reass_frags_and_verify(frags,
8687 self.pg1.remote_ip4)
8688 self.assertEqual(p[TCP].dport, 20)
8689 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8690 self.tcp_port_out = p[TCP].sport
8691 self.assertEqual(data, p[Raw].load)
8694 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8695 pkts = self.create_stream_frag(self.pg1,
8701 self.pg1.add_stream(pkts)
8702 self.pg_enable_capture(self.pg_interfaces)
8704 frags = self.pg0.get_capture(len(pkts))
8705 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8706 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8707 self.assertEqual(p[TCP].sport, 20)
8708 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8709 self.assertEqual(data, p[Raw].load)
8711 def test_interface_addr(self):
8712 """ Acquire NAT64 pool addresses from interface """
8713 self.vapi.nat64_add_del_interface_addr(
8715 sw_if_index=self.pg4.sw_if_index)
8717 # no address in NAT64 pool
8718 addresses = self.vapi.nat44_address_dump()
8719 self.assertEqual(0, len(addresses))
8721 # configure interface address and check NAT64 address pool
8722 self.pg4.config_ip4()
8723 addresses = self.vapi.nat64_pool_addr_dump()
8724 self.assertEqual(len(addresses), 1)
8726 self.assertEqual(str(addresses[0].address),
8729 # remove interface address and check NAT64 address pool
8730 self.pg4.unconfig_ip4()
8731 addresses = self.vapi.nat64_pool_addr_dump()
8732 self.assertEqual(0, len(addresses))
8734 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8735 def test_ipfix_max_bibs_sessions(self):
8736 """ IPFIX logging maximum session and BIB entries exceeded """
8739 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8743 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8744 end_addr=self.nat_addr,
8747 flags = self.config_flags.NAT_IS_INSIDE
8748 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8749 sw_if_index=self.pg0.sw_if_index)
8750 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8751 sw_if_index=self.pg1.sw_if_index)
8755 for i in range(0, max_bibs):
8756 src = "fd01:aa::%x" % (i)
8757 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8758 IPv6(src=src, dst=remote_host_ip6) /
8759 TCP(sport=12345, dport=80))
8761 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8762 IPv6(src=src, dst=remote_host_ip6) /
8763 TCP(sport=12345, dport=22))
8765 self.pg0.add_stream(pkts)
8766 self.pg_enable_capture(self.pg_interfaces)
8768 self.pg1.get_capture(max_sessions)
8770 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8771 src_address=self.pg3.local_ip4,
8773 template_interval=10)
8774 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8775 src_port=self.ipfix_src_port,
8778 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8779 IPv6(src=src, dst=remote_host_ip6) /
8780 TCP(sport=12345, dport=25))
8781 self.pg0.add_stream(p)
8782 self.pg_enable_capture(self.pg_interfaces)
8784 self.pg1.assert_nothing_captured()
8786 self.vapi.ipfix_flush()
8787 capture = self.pg3.get_capture(7)
8788 ipfix = IPFIXDecoder()
8789 # first load template
8791 self.assertTrue(p.haslayer(IPFIX))
8792 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8793 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8794 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8795 self.assertEqual(p[UDP].dport, 4739)
8796 self.assertEqual(p[IPFIX].observationDomainID,
8797 self.ipfix_domain_id)
8798 if p.haslayer(Template):
8799 ipfix.add_template(p.getlayer(Template))
8800 # verify events in data set
8802 if p.haslayer(Data):
8803 data = ipfix.decode_data_set(p.getlayer(Set))
8804 self.verify_ipfix_max_sessions(data, max_sessions)
8806 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8807 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8808 TCP(sport=12345, dport=80))
8809 self.pg0.add_stream(p)
8810 self.pg_enable_capture(self.pg_interfaces)
8812 self.pg1.assert_nothing_captured()
8814 self.vapi.ipfix_flush()
8815 capture = self.pg3.get_capture(1)
8816 # verify events in data set
8818 self.assertTrue(p.haslayer(IPFIX))
8819 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8820 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8821 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8822 self.assertEqual(p[UDP].dport, 4739)
8823 self.assertEqual(p[IPFIX].observationDomainID,
8824 self.ipfix_domain_id)
8825 if p.haslayer(Data):
8826 data = ipfix.decode_data_set(p.getlayer(Set))
8827 self.verify_ipfix_max_bibs(data, max_bibs)
8829 def test_ipfix_bib_ses(self):
8830 """ IPFIX logging NAT64 BIB/session create and delete events """
8831 self.tcp_port_in = random.randint(1025, 65535)
8832 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8836 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8837 end_addr=self.nat_addr,
8840 flags = self.config_flags.NAT_IS_INSIDE
8841 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8842 sw_if_index=self.pg0.sw_if_index)
8843 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8844 sw_if_index=self.pg1.sw_if_index)
8845 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8846 src_address=self.pg3.local_ip4,
8848 template_interval=10)
8849 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8850 src_port=self.ipfix_src_port,
8854 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8855 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8856 TCP(sport=self.tcp_port_in, dport=25))
8857 self.pg0.add_stream(p)
8858 self.pg_enable_capture(self.pg_interfaces)
8860 p = self.pg1.get_capture(1)
8861 self.tcp_port_out = p[0][TCP].sport
8862 self.vapi.ipfix_flush()
8863 capture = self.pg3.get_capture(8)
8864 ipfix = IPFIXDecoder()
8865 # first load template
8867 self.assertTrue(p.haslayer(IPFIX))
8868 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8869 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8870 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8871 self.assertEqual(p[UDP].dport, 4739)
8872 self.assertEqual(p[IPFIX].observationDomainID,
8873 self.ipfix_domain_id)
8874 if p.haslayer(Template):
8875 ipfix.add_template(p.getlayer(Template))
8876 # verify events in data set
8878 if p.haslayer(Data):
8879 data = ipfix.decode_data_set(p.getlayer(Set))
8880 if scapy.compat.orb(data[0][230]) == 10:
8881 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
8882 elif scapy.compat.orb(data[0][230]) == 6:
8883 self.verify_ipfix_nat64_ses(data,
8885 self.pg0.remote_ip6,
8886 self.pg1.remote_ip4,
8889 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8892 self.pg_enable_capture(self.pg_interfaces)
8893 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8894 end_addr=self.nat_addr,
8897 self.vapi.ipfix_flush()
8898 capture = self.pg3.get_capture(2)
8899 # verify events in data set
8901 self.assertTrue(p.haslayer(IPFIX))
8902 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8903 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8904 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8905 self.assertEqual(p[UDP].dport, 4739)
8906 self.assertEqual(p[IPFIX].observationDomainID,
8907 self.ipfix_domain_id)
8908 if p.haslayer(Data):
8909 data = ipfix.decode_data_set(p.getlayer(Set))
8910 if scapy.compat.orb(data[0][230]) == 11:
8911 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
8912 elif scapy.compat.orb(data[0][230]) == 7:
8913 self.verify_ipfix_nat64_ses(data,
8915 self.pg0.remote_ip6,
8916 self.pg1.remote_ip4,
8919 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8921 def test_syslog_sess(self):
8922 """ Test syslog session creation and deletion """
8923 self.tcp_port_in = random.randint(1025, 65535)
8924 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8928 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8929 end_addr=self.nat_addr,
8932 flags = self.config_flags.NAT_IS_INSIDE
8933 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8934 sw_if_index=self.pg0.sw_if_index)
8935 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8936 sw_if_index=self.pg1.sw_if_index)
8937 self.vapi.syslog_set_filter(
8938 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8939 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
8941 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8942 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8943 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8944 self.pg0.add_stream(p)
8945 self.pg_enable_capture(self.pg_interfaces)
8947 p = self.pg1.get_capture(1)
8948 self.tcp_port_out = p[0][TCP].sport
8949 capture = self.pg3.get_capture(1)
8950 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8952 self.pg_enable_capture(self.pg_interfaces)
8954 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8955 end_addr=self.nat_addr,
8958 capture = self.pg3.get_capture(1)
8959 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8961 def nat64_get_ses_num(self):
8963 Return number of active NAT64 sessions.
8965 st = self.vapi.nat64_st_dump(proto=255)
8968 def clear_nat64(self):
8970 Clear NAT64 configuration.
8972 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8973 src_port=self.ipfix_src_port,
8975 self.ipfix_src_port = 4739
8976 self.ipfix_domain_id = 1
8978 self.vapi.syslog_set_filter(
8979 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
8981 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8982 tcp_transitory=240, icmp=60)
8984 interfaces = self.vapi.nat64_interface_dump()
8985 for intf in interfaces:
8986 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
8987 sw_if_index=intf.sw_if_index)
8989 bib = self.vapi.nat64_bib_dump(proto=255)
8991 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8992 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9000 adresses = self.vapi.nat64_pool_addr_dump()
9001 for addr in adresses:
9002 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9003 end_addr=addr.address,
9007 prefixes = self.vapi.nat64_prefix_dump()
9008 for prefix in prefixes:
9009 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9010 vrf_id=prefix.vrf_id, is_add=0)
9012 bibs = self.statistics.get_counter('/nat64/total-bibs')
9013 self.assertEqual(bibs[0][0], 0)
9014 sessions = self.statistics.get_counter('/nat64/total-sessions')
9015 self.assertEqual(sessions[0][0], 0)
9018 super(TestNAT64, self).tearDown()
9019 if not self.vpp_dead:
9022 def show_commands_at_teardown(self):
9023 self.logger.info(self.vapi.cli("show nat64 pool"))
9024 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9025 self.logger.info(self.vapi.cli("show nat64 prefix"))
9026 self.logger.info(self.vapi.cli("show nat64 bib all"))
9027 self.logger.info(self.vapi.cli("show nat64 session table all"))
9030 class TestNAT66(MethodHolder):
9031 """ NAT66 Test Cases """
9034 def setUpClass(cls):
9035 super(TestNAT66, cls).setUpClass()
9037 cls.nat_addr = 'fd01:ff::2'
9039 cls.create_pg_interfaces(range(2))
9040 cls.interfaces = list(cls.pg_interfaces)
9042 for i in cls.interfaces:
9045 i.configure_ipv6_neighbors()
9048 def tearDownClass(cls):
9049 super(TestNAT66, cls).tearDownClass()
9051 def test_static(self):
9052 """ 1:1 NAT66 test """
9053 flags = self.config_flags.NAT_IS_INSIDE
9054 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9055 sw_if_index=self.pg0.sw_if_index)
9056 self.vapi.nat66_add_del_interface(is_add=1,
9057 sw_if_index=self.pg1.sw_if_index)
9058 self.vapi.nat66_add_del_static_mapping(
9059 local_ip_address=self.pg0.remote_ip6,
9060 external_ip_address=self.nat_addr,
9065 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9066 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9069 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9070 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9073 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9074 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9075 ICMPv6EchoRequest())
9077 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9078 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9079 GRE() / IP() / TCP())
9081 self.pg0.add_stream(pkts)
9082 self.pg_enable_capture(self.pg_interfaces)
9084 capture = self.pg1.get_capture(len(pkts))
9086 for packet in capture:
9088 self.assertEqual(packet[IPv6].src, self.nat_addr)
9089 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9090 self.assert_packet_checksums_valid(packet)
9092 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9097 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9098 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9101 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9102 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9105 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9106 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9109 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9110 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9111 GRE() / IP() / TCP())
9113 self.pg1.add_stream(pkts)
9114 self.pg_enable_capture(self.pg_interfaces)
9116 capture = self.pg0.get_capture(len(pkts))
9117 for packet in capture:
9119 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9120 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9121 self.assert_packet_checksums_valid(packet)
9123 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9126 sm = self.vapi.nat66_static_mapping_dump()
9127 self.assertEqual(len(sm), 1)
9128 self.assertEqual(sm[0].total_pkts, 8)
9130 def test_check_no_translate(self):
9131 """ NAT66 translate only when egress interface is outside interface """
9132 flags = self.config_flags.NAT_IS_INSIDE
9133 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9134 sw_if_index=self.pg0.sw_if_index)
9135 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9136 sw_if_index=self.pg1.sw_if_index)
9137 self.vapi.nat66_add_del_static_mapping(
9138 local_ip_address=self.pg0.remote_ip6,
9139 external_ip_address=self.nat_addr,
9143 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9144 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9146 self.pg0.add_stream([p])
9147 self.pg_enable_capture(self.pg_interfaces)
9149 capture = self.pg1.get_capture(1)
9152 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9153 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9155 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9158 def clear_nat66(self):
9160 Clear NAT66 configuration.
9162 interfaces = self.vapi.nat66_interface_dump()
9163 for intf in interfaces:
9164 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9165 sw_if_index=intf.sw_if_index)
9167 static_mappings = self.vapi.nat66_static_mapping_dump()
9168 for sm in static_mappings:
9169 self.vapi.nat66_add_del_static_mapping(
9170 local_ip_address=sm.local_ip_address,
9171 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9175 super(TestNAT66, self).tearDown()
9178 def show_commands_at_teardown(self):
9179 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9180 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9183 if __name__ == '__main__':
9184 unittest.main(testRunner=VppTestRunner)