8 from framework import VppTestCase, VppTestRunner, running_extended_tests
11 from scapy.layers.inet import IP, TCP, UDP, ICMP
12 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
13 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
14 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
15 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
16 from scapy.layers.l2 import Ether, ARP, GRE
17 from scapy.data import IP_PROTOS
18 from scapy.packet import bind_layers, Raw
20 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
21 from time import sleep
22 from util import ip4_range
23 from vpp_papi import mac_pton
24 from syslog_rfc5424_parser import SyslogMessage, ParseError
25 from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
26 from io import BytesIO
27 from vpp_papi import VppEnum
28 from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
29 from vpp_neighbor import VppNeighbor
30 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
31 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
33 from ipaddress import IPv6Network
34 from util import ppc, ppp
35 from socket import inet_pton, AF_INET
36 from vpp_acl import AclRule, VppAcl, VppAclInterface
39 # NAT HA protocol event data
42 fields_desc = [ByteEnumField("event_type", None,
43 {1: "add", 2: "del", 3: "refresh"}),
44 ByteEnumField("protocol", None,
45 {0: "udp", 1: "tcp", 2: "icmp"}),
46 ShortField("flags", 0),
47 IPField("in_addr", None),
48 IPField("out_addr", None),
49 ShortField("in_port", None),
50 ShortField("out_port", None),
51 IPField("eh_addr", None),
52 IPField("ehn_addr", None),
53 ShortField("eh_port", None),
54 ShortField("ehn_port", None),
55 IntField("fib_index", None),
56 IntField("total_pkts", 0),
57 LongField("total_bytes", 0)]
59 def extract_padding(self, s):
63 # NAT HA protocol header
64 class HANATStateSync(Packet):
65 name = "HA NAT state sync"
66 fields_desc = [XByteField("version", 1),
67 FlagsField("flags", 0, 8, ['ACK']),
68 FieldLenField("count", None, count_of="events"),
69 IntField("sequence_number", 1),
70 IntField("thread_index", 0),
71 PacketListField("events", [], Event,
72 count_from=lambda pkt: pkt.count)]
75 class MethodHolder(VppTestCase):
76 """ NAT create capture and verify method holder """
79 def config_flags(self):
80 return VppEnum.vl_api_nat_config_flags_t
83 def SYSLOG_SEVERITY(self):
84 return VppEnum.vl_api_syslog_severity_t
86 def clear_nat44(self):
88 Clear NAT44 configuration.
90 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
91 if self.pg7.has_ip4_config:
92 self.pg7.unconfig_ip4()
94 self.vapi.nat44_forwarding_enable_disable(enable=0)
96 interfaces = self.vapi.nat44_interface_addr_dump()
97 for intf in interfaces:
98 self.vapi.nat44_add_del_interface_addr(
100 sw_if_index=intf.sw_if_index,
103 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
104 src_port=self.ipfix_src_port,
106 self.ipfix_src_port = 4739
107 self.ipfix_domain_id = 1
109 self.vapi.syslog_set_filter(
110 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
112 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
114 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
115 session_refresh_interval=10)
117 interfaces = self.vapi.nat44_interface_dump()
118 for intf in interfaces:
119 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
120 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
121 self.vapi.nat44_interface_add_del_feature(
122 sw_if_index=intf.sw_if_index)
123 self.vapi.nat44_interface_add_del_feature(
124 sw_if_index=intf.sw_if_index,
127 interfaces = self.vapi.nat44_interface_output_feature_dump()
128 for intf in interfaces:
129 self.vapi.nat44_interface_add_del_output_feature(
132 sw_if_index=intf.sw_if_index)
133 static_mappings = self.vapi.nat44_static_mapping_dump()
134 for sm in static_mappings:
135 self.vapi.nat44_add_del_static_mapping(
137 local_ip_address=sm.local_ip_address,
138 external_ip_address=sm.external_ip_address,
139 external_sw_if_index=sm.external_sw_if_index,
140 local_port=sm.local_port,
141 external_port=sm.external_port,
143 protocol=sm.protocol,
144 flags=sm.flags, tag=sm.tag)
146 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
147 for lb_sm in lb_static_mappings:
148 self.vapi.nat44_add_del_lb_static_mapping(
151 external_addr=lb_sm.external_addr,
152 external_port=lb_sm.external_port,
153 protocol=lb_sm.protocol,
154 local_num=0, locals=[],
157 identity_mappings = self.vapi.nat44_identity_mapping_dump()
158 for id_m in identity_mappings:
159 self.vapi.nat44_add_del_identity_mapping(
160 ip_address=id_m.ip_address,
161 sw_if_index=id_m.sw_if_index,
165 protocol=id_m.protocol)
167 addresses = self.vapi.nat44_address_dump()
168 for addr in addresses:
169 self.vapi.nat44_add_del_address_range(
170 first_ip_address=addr.ip_address,
171 last_ip_address=addr.ip_address,
172 vrf_id=0xFFFFFFFF, flags=addr.flags)
174 self.verify_no_nat44_user()
175 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
176 tcp_transitory=240, icmp=60)
177 self.vapi.nat_set_addr_and_port_alloc_alg()
178 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
180 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
181 local_port=0, external_port=0, vrf_id=0,
182 is_add=1, external_sw_if_index=0xFFFFFFFF,
183 proto=0, tag="", flags=0):
185 Add/delete NAT44 static mapping
187 :param local_ip: Local IP address
188 :param external_ip: External IP address
189 :param local_port: Local port number (Optional)
190 :param external_port: External port number (Optional)
191 :param vrf_id: VRF ID (Default 0)
192 :param is_add: 1 if add, 0 if delete (Default add)
193 :param external_sw_if_index: External interface instead of IP address
194 :param proto: IP protocol (Mandatory if port specified)
195 :param tag: Opaque string tag
196 :param flags: NAT configuration flags
199 if not (local_port and external_port):
200 flags |= self.config_flags.NAT_IS_ADDR_ONLY
202 self.vapi.nat44_add_del_static_mapping(
204 local_ip_address=local_ip,
205 external_ip_address=external_ip,
206 external_sw_if_index=external_sw_if_index,
207 local_port=local_port,
208 external_port=external_port,
209 vrf_id=vrf_id, protocol=proto,
213 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
215 Add/delete NAT44 address
217 :param ip: IP address
218 :param is_add: 1 if add, 0 if delete (Default add)
219 :param twice_nat: twice NAT address for external hosts
221 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
222 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
228 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
230 Create packet stream for inside network
232 :param in_if: Inside interface
233 :param out_if: Outside interface
234 :param dst_ip: Destination address
235 :param ttl: TTL of generated packets
238 dst_ip = out_if.remote_ip4
242 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
243 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
244 TCP(sport=self.tcp_port_in, dport=20))
248 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
249 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
250 UDP(sport=self.udp_port_in, dport=20))
254 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
255 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
256 ICMP(id=self.icmp_id_in, type='echo-request'))
261 def compose_ip6(self, ip4, pref, plen):
263 Compose IPv4-embedded IPv6 addresses
265 :param ip4: IPv4 address
266 :param pref: IPv6 prefix
267 :param plen: IPv6 prefix length
268 :returns: IPv4-embedded IPv6 addresses
270 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
271 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
286 pref_n[10] = ip4_n[3]
290 pref_n[10] = ip4_n[2]
291 pref_n[11] = ip4_n[3]
294 pref_n[10] = ip4_n[1]
295 pref_n[11] = ip4_n[2]
296 pref_n[12] = ip4_n[3]
298 pref_n[12] = ip4_n[0]
299 pref_n[13] = ip4_n[1]
300 pref_n[14] = ip4_n[2]
301 pref_n[15] = ip4_n[3]
302 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
303 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
305 def extract_ip4(self, ip6, plen):
307 Extract IPv4 address embedded in IPv6 addresses
309 :param ip6: IPv6 address
310 :param plen: IPv6 prefix length
311 :returns: extracted IPv4 address
313 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
345 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
347 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
349 Create IPv6 packet stream for inside network
351 :param in_if: Inside interface
352 :param out_if: Outside interface
353 :param ttl: Hop Limit of generated packets
354 :param pref: NAT64 prefix
355 :param plen: NAT64 prefix length
359 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
361 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
364 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
365 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
366 TCP(sport=self.tcp_port_in, dport=20))
370 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
371 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
372 UDP(sport=self.udp_port_in, dport=20))
376 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
377 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
378 ICMPv6EchoRequest(id=self.icmp_id_in))
383 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
384 use_inside_ports=False):
386 Create packet stream for outside network
388 :param out_if: Outside interface
389 :param dst_ip: Destination IP address (Default use global NAT address)
390 :param ttl: TTL of generated packets
391 :param use_inside_ports: Use inside NAT ports as destination ports
392 instead of outside ports
395 dst_ip = self.nat_addr
396 if not use_inside_ports:
397 tcp_port = self.tcp_port_out
398 udp_port = self.udp_port_out
399 icmp_id = self.icmp_id_out
401 tcp_port = self.tcp_port_in
402 udp_port = self.udp_port_in
403 icmp_id = self.icmp_id_in
406 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
407 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
408 TCP(dport=tcp_port, sport=20))
412 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
413 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
414 UDP(dport=udp_port, sport=20))
418 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
419 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
420 ICMP(id=icmp_id, type='echo-reply'))
425 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
427 Create packet stream for outside network
429 :param out_if: Outside interface
430 :param dst_ip: Destination IP address (Default use global NAT address)
431 :param hl: HL of generated packets
435 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
436 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
437 TCP(dport=self.tcp_port_out, sport=20))
441 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
442 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
443 UDP(dport=self.udp_port_out, sport=20))
447 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
448 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
449 ICMPv6EchoReply(id=self.icmp_id_out))
454 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
455 dst_ip=None, is_ip6=False):
457 Verify captured packets on outside network
459 :param capture: Captured packets
460 :param nat_ip: Translated IP address (Default use global NAT address)
461 :param same_port: Source port number is not translated (Default False)
462 :param dst_ip: Destination IP address (Default do not verify)
463 :param is_ip6: If L3 protocol is IPv6 (Default False)
467 ICMP46 = ICMPv6EchoRequest
472 nat_ip = self.nat_addr
473 for packet in capture:
476 self.assert_packet_checksums_valid(packet)
477 self.assertEqual(packet[IP46].src, nat_ip)
478 if dst_ip is not None:
479 self.assertEqual(packet[IP46].dst, dst_ip)
480 if packet.haslayer(TCP):
482 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
485 packet[TCP].sport, self.tcp_port_in)
486 self.tcp_port_out = packet[TCP].sport
487 self.assert_packet_checksums_valid(packet)
488 elif packet.haslayer(UDP):
490 self.assertEqual(packet[UDP].sport, self.udp_port_in)
493 packet[UDP].sport, self.udp_port_in)
494 self.udp_port_out = packet[UDP].sport
497 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
499 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
500 self.icmp_id_out = packet[ICMP46].id
501 self.assert_packet_checksums_valid(packet)
503 self.logger.error(ppp("Unexpected or invalid packet "
504 "(outside network):", packet))
507 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
510 Verify captured packets on outside network
512 :param capture: Captured packets
513 :param nat_ip: Translated IP address
514 :param same_port: Source port number is not translated (Default False)
515 :param dst_ip: Destination IP address (Default do not verify)
517 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
520 def verify_capture_in(self, capture, in_if):
522 Verify captured packets on inside network
524 :param capture: Captured packets
525 :param in_if: Inside interface
527 for packet in capture:
529 self.assert_packet_checksums_valid(packet)
530 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
531 if packet.haslayer(TCP):
532 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
533 elif packet.haslayer(UDP):
534 self.assertEqual(packet[UDP].dport, self.udp_port_in)
536 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
538 self.logger.error(ppp("Unexpected or invalid packet "
539 "(inside network):", packet))
542 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
544 Verify captured IPv6 packets on inside network
546 :param capture: Captured packets
547 :param src_ip: Source IP
548 :param dst_ip: Destination IP address
550 for packet in capture:
552 self.assertEqual(packet[IPv6].src, src_ip)
553 self.assertEqual(packet[IPv6].dst, dst_ip)
554 self.assert_packet_checksums_valid(packet)
555 if packet.haslayer(TCP):
556 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
557 elif packet.haslayer(UDP):
558 self.assertEqual(packet[UDP].dport, self.udp_port_in)
560 self.assertEqual(packet[ICMPv6EchoReply].id,
563 self.logger.error(ppp("Unexpected or invalid packet "
564 "(inside network):", packet))
567 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
569 Verify captured packet that don't have to be translated
571 :param capture: Captured packets
572 :param ingress_if: Ingress interface
573 :param egress_if: Egress interface
575 for packet in capture:
577 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
578 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
579 if packet.haslayer(TCP):
580 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
581 elif packet.haslayer(UDP):
582 self.assertEqual(packet[UDP].sport, self.udp_port_in)
584 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
586 self.logger.error(ppp("Unexpected or invalid packet "
587 "(inside network):", packet))
590 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
593 Verify captured packets with ICMP errors on outside network
595 :param capture: Captured packets
596 :param src_ip: Translated IP address or IP address of VPP
597 (Default use global NAT address)
598 :param icmp_type: Type of error ICMP packet
599 we are expecting (Default 11)
602 src_ip = self.nat_addr
603 for packet in capture:
605 self.assertEqual(packet[IP].src, src_ip)
606 self.assertEqual(packet.haslayer(ICMP), 1)
608 self.assertEqual(icmp.type, icmp_type)
609 self.assertTrue(icmp.haslayer(IPerror))
610 inner_ip = icmp[IPerror]
611 if inner_ip.haslayer(TCPerror):
612 self.assertEqual(inner_ip[TCPerror].dport,
614 elif inner_ip.haslayer(UDPerror):
615 self.assertEqual(inner_ip[UDPerror].dport,
618 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
620 self.logger.error(ppp("Unexpected or invalid packet "
621 "(outside network):", packet))
624 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
626 Verify captured packets with ICMP errors on inside network
628 :param capture: Captured packets
629 :param in_if: Inside interface
630 :param icmp_type: Type of error ICMP packet
631 we are expecting (Default 11)
633 for packet in capture:
635 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
636 self.assertEqual(packet.haslayer(ICMP), 1)
638 self.assertEqual(icmp.type, icmp_type)
639 self.assertTrue(icmp.haslayer(IPerror))
640 inner_ip = icmp[IPerror]
641 if inner_ip.haslayer(TCPerror):
642 self.assertEqual(inner_ip[TCPerror].sport,
644 elif inner_ip.haslayer(UDPerror):
645 self.assertEqual(inner_ip[UDPerror].sport,
648 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
650 self.logger.error(ppp("Unexpected or invalid packet "
651 "(inside network):", packet))
654 def create_stream_frag(self, src_if, dst, sport, dport, data,
655 proto=IP_PROTOS.tcp, echo_reply=False):
657 Create fragmented packet stream
659 :param src_if: Source interface
660 :param dst: Destination IPv4 address
661 :param sport: Source port
662 :param dport: Destination port
663 :param data: Payload data
664 :param proto: protocol (TCP, UDP, ICMP)
665 :param echo_reply: use echo_reply if protocol is ICMP
668 if proto == IP_PROTOS.tcp:
669 p = (IP(src=src_if.remote_ip4, dst=dst) /
670 TCP(sport=sport, dport=dport) /
672 p = p.__class__(scapy.compat.raw(p))
673 chksum = p[TCP].chksum
674 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
675 elif proto == IP_PROTOS.udp:
676 proto_header = UDP(sport=sport, dport=dport)
677 elif proto == IP_PROTOS.icmp:
679 proto_header = ICMP(id=sport, type='echo-request')
681 proto_header = ICMP(id=sport, type='echo-reply')
683 raise Exception("Unsupported protocol")
684 id = random.randint(0, 65535)
686 if proto == IP_PROTOS.tcp:
689 raw = Raw(data[0:16])
690 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
691 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
695 if proto == IP_PROTOS.tcp:
696 raw = Raw(data[4:20])
698 raw = Raw(data[16:32])
699 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
700 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
704 if proto == IP_PROTOS.tcp:
708 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
709 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
715 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
716 pref=None, plen=0, frag_size=128):
718 Create fragmented packet stream
720 :param src_if: Source interface
721 :param dst: Destination IPv4 address
722 :param sport: Source TCP port
723 :param dport: Destination TCP port
724 :param data: Payload data
725 :param pref: NAT64 prefix
726 :param plen: NAT64 prefix length
727 :param fragsize: size of fragments
731 dst_ip6 = ''.join(['64:ff9b::', dst])
733 dst_ip6 = self.compose_ip6(dst, pref, plen)
735 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
736 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
737 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
738 TCP(sport=sport, dport=dport) /
741 return fragment6(p, frag_size)
743 def reass_frags_and_verify(self, frags, src, dst):
745 Reassemble and verify fragmented packet
747 :param frags: Captured fragments
748 :param src: Source IPv4 address to verify
749 :param dst: Destination IPv4 address to verify
751 :returns: Reassembled IPv4 packet
755 self.assertEqual(p[IP].src, src)
756 self.assertEqual(p[IP].dst, dst)
757 self.assert_ip_checksum_valid(p)
758 buffer.seek(p[IP].frag * 8)
759 buffer.write(bytes(p[IP].payload))
760 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
761 proto=frags[0][IP].proto)
762 if ip.proto == IP_PROTOS.tcp:
763 p = (ip / TCP(buffer.getvalue()))
764 self.logger.debug(ppp("Reassembled:", p))
765 self.assert_tcp_checksum_valid(p)
766 elif ip.proto == IP_PROTOS.udp:
767 p = (ip / UDP(buffer.getvalue()[:8]) /
768 Raw(buffer.getvalue()[8:]))
769 elif ip.proto == IP_PROTOS.icmp:
770 p = (ip / ICMP(buffer.getvalue()))
773 def reass_frags_and_verify_ip6(self, frags, src, dst):
775 Reassemble and verify fragmented packet
777 :param frags: Captured fragments
778 :param src: Source IPv6 address to verify
779 :param dst: Destination IPv6 address to verify
781 :returns: Reassembled IPv6 packet
785 self.assertEqual(p[IPv6].src, src)
786 self.assertEqual(p[IPv6].dst, dst)
787 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
788 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
789 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
790 nh=frags[0][IPv6ExtHdrFragment].nh)
791 if ip.nh == IP_PROTOS.tcp:
792 p = (ip / TCP(buffer.getvalue()))
793 elif ip.nh == IP_PROTOS.udp:
794 p = (ip / UDP(buffer.getvalue()))
795 self.logger.debug(ppp("Reassembled:", p))
796 self.assert_packet_checksums_valid(p)
799 def initiate_tcp_session(self, in_if, out_if):
801 Initiates TCP session
803 :param in_if: Inside interface
804 :param out_if: Outside interface
808 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
809 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
810 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
813 self.pg_enable_capture(self.pg_interfaces)
815 capture = out_if.get_capture(1)
817 self.tcp_port_out = p[TCP].sport
819 # SYN + ACK packet out->in
820 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
821 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
822 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
825 self.pg_enable_capture(self.pg_interfaces)
830 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
831 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
832 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
835 self.pg_enable_capture(self.pg_interfaces)
837 out_if.get_capture(1)
840 self.logger.error("TCP 3 way handshake failed")
843 def verify_ipfix_nat44_ses(self, data):
845 Verify IPFIX NAT44 session create/delete event
847 :param data: Decoded IPFIX data records
849 nat44_ses_create_num = 0
850 nat44_ses_delete_num = 0
851 self.assertEqual(6, len(data))
854 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
855 if scapy.compat.orb(record[230]) == 4:
856 nat44_ses_create_num += 1
858 nat44_ses_delete_num += 1
860 self.assertEqual(self.pg0.remote_ip4n, record[8])
861 # postNATSourceIPv4Address
862 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
865 self.assertEqual(struct.pack("!I", 0), record[234])
866 # protocolIdentifier/sourceTransportPort
867 # /postNAPTSourceTransportPort
868 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
869 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
870 self.assertEqual(struct.pack("!H", self.icmp_id_out),
872 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
873 self.assertEqual(struct.pack("!H", self.tcp_port_in),
875 self.assertEqual(struct.pack("!H", self.tcp_port_out),
877 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
878 self.assertEqual(struct.pack("!H", self.udp_port_in),
880 self.assertEqual(struct.pack("!H", self.udp_port_out),
883 self.fail("Invalid protocol")
884 self.assertEqual(3, nat44_ses_create_num)
885 self.assertEqual(3, nat44_ses_delete_num)
887 def verify_ipfix_addr_exhausted(self, data):
889 Verify IPFIX NAT addresses event
891 :param data: Decoded IPFIX data records
893 self.assertEqual(1, len(data))
896 self.assertEqual(scapy.compat.orb(record[230]), 3)
898 self.assertEqual(struct.pack("!I", 0), record[283])
900 def verify_ipfix_max_sessions(self, data, limit):
902 Verify IPFIX maximum session entries exceeded event
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum session entries that can be created.
907 self.assertEqual(1, len(data))
910 self.assertEqual(scapy.compat.orb(record[230]), 13)
911 # natQuotaExceededEvent
912 self.assertEqual(struct.pack("I", 1), record[466])
914 self.assertEqual(struct.pack("I", limit), record[471])
916 def verify_ipfix_max_bibs(self, data, limit):
918 Verify IPFIX maximum BIB entries exceeded event
920 :param data: Decoded IPFIX data records
921 :param limit: Number of maximum BIB entries that can be created.
923 self.assertEqual(1, len(data))
926 self.assertEqual(scapy.compat.orb(record[230]), 13)
927 # natQuotaExceededEvent
928 self.assertEqual(struct.pack("I", 2), record[466])
930 self.assertEqual(struct.pack("I", limit), record[472])
932 def verify_ipfix_bib(self, data, is_create, src_addr):
934 Verify IPFIX NAT64 BIB create and delete events
936 :param data: Decoded IPFIX data records
937 :param is_create: Create event if nonzero value otherwise delete event
938 :param src_addr: IPv6 source address
940 self.assertEqual(1, len(data))
944 self.assertEqual(scapy.compat.orb(record[230]), 10)
946 self.assertEqual(scapy.compat.orb(record[230]), 11)
948 self.assertEqual(src_addr, record[27])
949 # postNATSourceIPv4Address
950 self.assertEqual(self.nat_addr_n, record[225])
952 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
954 self.assertEqual(struct.pack("!I", 0), record[234])
955 # sourceTransportPort
956 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
957 # postNAPTSourceTransportPort
958 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
960 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
963 Verify IPFIX NAT64 session create and delete events
965 :param data: Decoded IPFIX data records
966 :param is_create: Create event if nonzero value otherwise delete event
967 :param src_addr: IPv6 source address
968 :param dst_addr: IPv4 destination address
969 :param dst_port: destination TCP port
971 self.assertEqual(1, len(data))
975 self.assertEqual(scapy.compat.orb(record[230]), 6)
977 self.assertEqual(scapy.compat.orb(record[230]), 7)
979 self.assertEqual(src_addr, record[27])
980 # destinationIPv6Address
981 self.assertEqual(socket.inet_pton(socket.AF_INET6,
982 self.compose_ip6(dst_addr,
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
988 # postNATDestinationIPv4Address
989 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
992 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
994 self.assertEqual(struct.pack("!I", 0), record[234])
995 # sourceTransportPort
996 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
997 # postNAPTSourceTransportPort
998 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
999 # destinationTransportPort
1000 self.assertEqual(struct.pack("!H", dst_port), record[11])
1001 # postNAPTDestinationTransportPort
1002 self.assertEqual(struct.pack("!H", dst_port), record[228])
1004 def verify_no_nat44_user(self):
1005 """ Verify that there is no NAT44 user """
1006 users = self.vapi.nat44_user_dump()
1007 self.assertEqual(len(users), 0)
1008 users = self.statistics.get_counter('/nat44/total-users')
1009 self.assertEqual(users[0][0], 0)
1010 sessions = self.statistics.get_counter('/nat44/total-sessions')
1011 self.assertEqual(sessions[0][0], 0)
1013 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1015 Verify IPFIX maximum entries per user exceeded event
1017 :param data: Decoded IPFIX data records
1018 :param limit: Number of maximum entries per user
1019 :param src_addr: IPv4 source address
1021 self.assertEqual(1, len(data))
1024 self.assertEqual(scapy.compat.orb(record[230]), 13)
1025 # natQuotaExceededEvent
1026 self.assertEqual(struct.pack("I", 3), record[466])
1028 self.assertEqual(struct.pack("I", limit), record[473])
1030 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1032 def verify_syslog_apmap(self, data, is_add=True):
1033 message = data.decode('utf-8')
1035 message = SyslogMessage.parse(message)
1036 except ParseError as e:
1037 self.logger.error(e)
1040 self.assertEqual(message.severity, SyslogSeverity.info)
1041 self.assertEqual(message.appname, 'NAT')
1042 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1043 sd_params = message.sd.get('napmap')
1044 self.assertTrue(sd_params is not None)
1045 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1046 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1047 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1048 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1049 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1050 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1051 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1052 self.assertTrue(sd_params.get('SSUBIX') is not None)
1053 self.assertEqual(sd_params.get('SVLAN'), '0')
1055 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1056 message = data.decode('utf-8')
1058 message = SyslogMessage.parse(message)
1059 except ParseError as e:
1060 self.logger.error(e)
1063 self.assertEqual(message.severity, SyslogSeverity.info)
1064 self.assertEqual(message.appname, 'NAT')
1065 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1066 sd_params = message.sd.get('nsess')
1067 self.assertTrue(sd_params is not None)
1069 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1070 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1072 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1073 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1074 self.assertTrue(sd_params.get('SSUBIX') is not None)
1075 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1076 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1078 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1079 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1080 self.assertEqual(sd_params.get('SVLAN'), '0')
1081 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1082 self.assertEqual(sd_params.get('XDPORT'),
1083 "%d" % self.tcp_external_port)
1085 def verify_mss_value(self, pkt, mss):
1087 Verify TCP MSS value
1092 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1093 raise TypeError("Not a TCP/IP packet")
1095 for option in pkt[TCP].options:
1096 if option[0] == 'MSS':
1097 self.assertEqual(option[1], mss)
1098 self.assert_tcp_checksum_valid(pkt)
1101 def proto2layer(proto):
1102 if proto == IP_PROTOS.tcp:
1104 elif proto == IP_PROTOS.udp:
1106 elif proto == IP_PROTOS.icmp:
1109 raise Exception("Unsupported protocol")
1111 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1112 layer = self.proto2layer(proto)
1114 if proto == IP_PROTOS.tcp:
1115 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1117 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1118 self.port_in = random.randint(1025, 65535)
1121 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1122 self.port_in, 20, data, proto)
1123 self.pg0.add_stream(pkts)
1124 self.pg_enable_capture(self.pg_interfaces)
1126 frags = self.pg1.get_capture(len(pkts))
1127 if not dont_translate:
1128 p = self.reass_frags_and_verify(frags,
1130 self.pg1.remote_ip4)
1132 p = self.reass_frags_and_verify(frags,
1133 self.pg0.remote_ip4,
1134 self.pg1.remote_ip4)
1135 if proto != IP_PROTOS.icmp:
1136 if not dont_translate:
1137 self.assertEqual(p[layer].dport, 20)
1138 self.assertNotEqual(p[layer].sport, self.port_in)
1140 self.assertEqual(p[layer].sport, self.port_in)
1142 if not dont_translate:
1143 self.assertNotEqual(p[layer].id, self.port_in)
1145 self.assertEqual(p[layer].id, self.port_in)
1146 self.assertEqual(data, p[Raw].load)
1149 if not dont_translate:
1150 dst_addr = self.nat_addr
1152 dst_addr = self.pg0.remote_ip4
1153 if proto != IP_PROTOS.icmp:
1155 dport = p[layer].sport
1159 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
1160 proto, echo_reply=True)
1161 self.pg1.add_stream(pkts)
1162 self.pg_enable_capture(self.pg_interfaces)
1164 frags = self.pg0.get_capture(len(pkts))
1165 p = self.reass_frags_and_verify(frags,
1166 self.pg1.remote_ip4,
1167 self.pg0.remote_ip4)
1168 if proto != IP_PROTOS.icmp:
1169 self.assertEqual(p[layer].sport, 20)
1170 self.assertEqual(p[layer].dport, self.port_in)
1172 self.assertEqual(p[layer].id, self.port_in)
1173 self.assertEqual(data, p[Raw].load)
1175 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1176 layer = self.proto2layer(proto)
1178 if proto == IP_PROTOS.tcp:
1179 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1181 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1182 self.port_in = random.randint(1025, 65535)
1186 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1187 self.port_in, self.server_out_port,
1189 self.pg0.add_stream(pkts)
1190 self.pg_enable_capture(self.pg_interfaces)
1192 frags = self.pg1.get_capture(len(pkts))
1193 p = self.reass_frags_and_verify(frags,
1194 self.pg0.remote_ip4,
1195 self.server_in_addr)
1196 if proto != IP_PROTOS.icmp:
1197 self.assertEqual(p[layer].sport, self.port_in)
1198 self.assertEqual(p[layer].dport, self.server_in_port)
1200 self.assertEqual(p[layer].id, self.port_in)
1201 self.assertEqual(data, p[Raw].load)
1204 if proto != IP_PROTOS.icmp:
1205 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1206 self.server_in_port,
1207 p[layer].sport, data, proto)
1209 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1210 p[layer].id, 0, data, proto,
1212 self.pg1.add_stream(pkts)
1213 self.pg_enable_capture(self.pg_interfaces)
1215 frags = self.pg0.get_capture(len(pkts))
1216 p = self.reass_frags_and_verify(frags,
1217 self.server_out_addr,
1218 self.pg0.remote_ip4)
1219 if proto != IP_PROTOS.icmp:
1220 self.assertEqual(p[layer].sport, self.server_out_port)
1221 self.assertEqual(p[layer].dport, self.port_in)
1223 self.assertEqual(p[layer].id, self.port_in)
1224 self.assertEqual(data, p[Raw].load)
1226 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1227 layer = self.proto2layer(proto)
1229 if proto == IP_PROTOS.tcp:
1230 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1232 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1234 # send packet from host to server
1235 pkts = self.create_stream_frag(self.pg0,
1238 self.server_out_port,
1241 self.pg0.add_stream(pkts)
1242 self.pg_enable_capture(self.pg_interfaces)
1244 frags = self.pg0.get_capture(len(pkts))
1245 p = self.reass_frags_and_verify(frags,
1248 if proto != IP_PROTOS.icmp:
1249 self.assertNotEqual(p[layer].sport, self.host_in_port)
1250 self.assertEqual(p[layer].dport, self.server_in_port)
1252 self.assertNotEqual(p[layer].id, self.host_in_port)
1253 self.assertEqual(data, p[Raw].load)
1255 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1256 layer = self.proto2layer(proto)
1258 if proto == IP_PROTOS.tcp:
1259 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1261 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1262 self.port_in = random.randint(1025, 65535)
1266 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1267 self.port_in, 20, data, proto)
1269 self.pg0.add_stream(pkts)
1270 self.pg_enable_capture(self.pg_interfaces)
1272 frags = self.pg1.get_capture(len(pkts))
1273 if not dont_translate:
1274 p = self.reass_frags_and_verify(frags,
1276 self.pg1.remote_ip4)
1278 p = self.reass_frags_and_verify(frags,
1279 self.pg0.remote_ip4,
1280 self.pg1.remote_ip4)
1281 if proto != IP_PROTOS.icmp:
1282 if not dont_translate:
1283 self.assertEqual(p[layer].dport, 20)
1284 self.assertNotEqual(p[layer].sport, self.port_in)
1286 self.assertEqual(p[layer].sport, self.port_in)
1288 if not dont_translate:
1289 self.assertNotEqual(p[layer].id, self.port_in)
1291 self.assertEqual(p[layer].id, self.port_in)
1292 self.assertEqual(data, p[Raw].load)
1295 if not dont_translate:
1296 dst_addr = self.nat_addr
1298 dst_addr = self.pg0.remote_ip4
1299 if proto != IP_PROTOS.icmp:
1301 dport = p[layer].sport
1305 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1306 data, proto, echo_reply=True)
1308 self.pg1.add_stream(pkts)
1309 self.pg_enable_capture(self.pg_interfaces)
1311 frags = self.pg0.get_capture(len(pkts))
1312 p = self.reass_frags_and_verify(frags,
1313 self.pg1.remote_ip4,
1314 self.pg0.remote_ip4)
1315 if proto != IP_PROTOS.icmp:
1316 self.assertEqual(p[layer].sport, 20)
1317 self.assertEqual(p[layer].dport, self.port_in)
1319 self.assertEqual(p[layer].id, self.port_in)
1320 self.assertEqual(data, p[Raw].load)
1322 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1323 layer = self.proto2layer(proto)
1325 if proto == IP_PROTOS.tcp:
1326 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1328 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1329 self.port_in = random.randint(1025, 65535)
1333 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1334 self.port_in, self.server_out_port,
1337 self.pg0.add_stream(pkts)
1338 self.pg_enable_capture(self.pg_interfaces)
1340 frags = self.pg1.get_capture(len(pkts))
1341 p = self.reass_frags_and_verify(frags,
1342 self.pg0.remote_ip4,
1343 self.server_in_addr)
1344 if proto != IP_PROTOS.icmp:
1345 self.assertEqual(p[layer].dport, self.server_in_port)
1346 self.assertEqual(p[layer].sport, self.port_in)
1347 self.assertEqual(p[layer].dport, self.server_in_port)
1349 self.assertEqual(p[layer].id, self.port_in)
1350 self.assertEqual(data, p[Raw].load)
1353 if proto != IP_PROTOS.icmp:
1354 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1355 self.server_in_port,
1356 p[layer].sport, data, proto)
1358 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1359 p[layer].id, 0, data, proto,
1362 self.pg1.add_stream(pkts)
1363 self.pg_enable_capture(self.pg_interfaces)
1365 frags = self.pg0.get_capture(len(pkts))
1366 p = self.reass_frags_and_verify(frags,
1367 self.server_out_addr,
1368 self.pg0.remote_ip4)
1369 if proto != IP_PROTOS.icmp:
1370 self.assertEqual(p[layer].sport, self.server_out_port)
1371 self.assertEqual(p[layer].dport, self.port_in)
1373 self.assertEqual(p[layer].id, self.port_in)
1374 self.assertEqual(data, p[Raw].load)
1377 class TestNAT44(MethodHolder):
1378 """ NAT44 Test Cases """
1381 def setUpClass(cls):
1382 super(TestNAT44, cls).setUpClass()
1383 cls.vapi.cli("set log class nat level debug")
1385 cls.tcp_port_in = 6303
1386 cls.tcp_port_out = 6303
1387 cls.udp_port_in = 6304
1388 cls.udp_port_out = 6304
1389 cls.icmp_id_in = 6305
1390 cls.icmp_id_out = 6305
1391 cls.nat_addr = '10.0.0.3'
1392 cls.ipfix_src_port = 4739
1393 cls.ipfix_domain_id = 1
1394 cls.tcp_external_port = 80
1395 cls.udp_external_port = 69
1397 cls.create_pg_interfaces(range(10))
1398 cls.interfaces = list(cls.pg_interfaces[0:4])
1400 for i in cls.interfaces:
1405 cls.pg0.generate_remote_hosts(3)
1406 cls.pg0.configure_ipv4_neighbors()
1408 cls.pg1.generate_remote_hosts(1)
1409 cls.pg1.configure_ipv4_neighbors()
1411 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1412 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1413 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1415 cls.pg4._local_ip4 = "172.16.255.1"
1416 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1417 cls.pg4.set_table_ip4(10)
1418 cls.pg5._local_ip4 = "172.17.255.3"
1419 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1420 cls.pg5.set_table_ip4(10)
1421 cls.pg6._local_ip4 = "172.16.255.1"
1422 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1423 cls.pg6.set_table_ip4(20)
1424 for i in cls.overlapping_interfaces:
1432 cls.pg9.generate_remote_hosts(2)
1433 cls.pg9.config_ip4()
1434 cls.vapi.sw_interface_add_del_address(
1435 sw_if_index=cls.pg9.sw_if_index,
1436 prefix="10.0.0.1/24")
1439 cls.pg9.resolve_arp()
1440 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1441 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1442 cls.pg9.resolve_arp()
1445 def tearDownClass(cls):
1446 super(TestNAT44, cls).tearDownClass()
1448 def test_dynamic(self):
1449 """ NAT44 dynamic translation test """
1450 self.nat44_add_address(self.nat_addr)
1451 flags = self.config_flags.NAT_IS_INSIDE
1452 self.vapi.nat44_interface_add_del_feature(
1453 sw_if_index=self.pg0.sw_if_index,
1454 flags=flags, is_add=1)
1455 self.vapi.nat44_interface_add_del_feature(
1456 sw_if_index=self.pg1.sw_if_index,
1460 tcpn = self.statistics.get_err_counter(
1461 '/err/nat44-in2out-slowpath/TCP packets')
1462 udpn = self.statistics.get_err_counter(
1463 '/err/nat44-in2out-slowpath/UDP packets')
1464 icmpn = self.statistics.get_err_counter(
1465 '/err/nat44-in2out-slowpath/ICMP packets')
1466 totaln = self.statistics.get_err_counter(
1467 '/err/nat44-in2out-slowpath/good in2out packets processed')
1469 pkts = self.create_stream_in(self.pg0, self.pg1)
1470 self.pg0.add_stream(pkts)
1471 self.pg_enable_capture(self.pg_interfaces)
1473 capture = self.pg1.get_capture(len(pkts))
1474 self.verify_capture_out(capture)
1476 err = self.statistics.get_err_counter(
1477 '/err/nat44-in2out-slowpath/TCP packets')
1478 self.assertEqual(err - tcpn, 2)
1479 err = self.statistics.get_err_counter(
1480 '/err/nat44-in2out-slowpath/UDP packets')
1481 self.assertEqual(err - udpn, 1)
1482 err = self.statistics.get_err_counter(
1483 '/err/nat44-in2out-slowpath/ICMP packets')
1484 self.assertEqual(err - icmpn, 1)
1485 err = self.statistics.get_err_counter(
1486 '/err/nat44-in2out-slowpath/good in2out packets processed')
1487 self.assertEqual(err - totaln, 4)
1490 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1491 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1492 icmpn = self.statistics.get_err_counter(
1493 '/err/nat44-out2in/ICMP packets')
1494 totaln = self.statistics.get_err_counter(
1495 '/err/nat44-out2in/good out2in packets processed')
1497 pkts = self.create_stream_out(self.pg1)
1498 self.pg1.add_stream(pkts)
1499 self.pg_enable_capture(self.pg_interfaces)
1501 capture = self.pg0.get_capture(len(pkts))
1502 self.verify_capture_in(capture, self.pg0)
1504 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1505 self.assertEqual(err - tcpn, 2)
1506 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1507 self.assertEqual(err - udpn, 1)
1508 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1509 self.assertEqual(err - icmpn, 1)
1510 err = self.statistics.get_err_counter(
1511 '/err/nat44-out2in/good out2in packets processed')
1512 self.assertEqual(err - totaln, 4)
1514 users = self.statistics.get_counter('/nat44/total-users')
1515 self.assertEqual(users[0][0], 1)
1516 sessions = self.statistics.get_counter('/nat44/total-sessions')
1517 self.assertEqual(sessions[0][0], 3)
1519 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1520 """ NAT44 handling of client packets with TTL=1 """
1522 self.nat44_add_address(self.nat_addr)
1523 flags = self.config_flags.NAT_IS_INSIDE
1524 self.vapi.nat44_interface_add_del_feature(
1525 sw_if_index=self.pg0.sw_if_index,
1526 flags=flags, is_add=1)
1527 self.vapi.nat44_interface_add_del_feature(
1528 sw_if_index=self.pg1.sw_if_index,
1531 # Client side - generate traffic
1532 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1533 self.pg0.add_stream(pkts)
1534 self.pg_enable_capture(self.pg_interfaces)
1537 # Client side - verify ICMP type 11 packets
1538 capture = self.pg0.get_capture(len(pkts))
1539 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1541 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1542 """ NAT44 handling of server packets with TTL=1 """
1544 self.nat44_add_address(self.nat_addr)
1545 flags = self.config_flags.NAT_IS_INSIDE
1546 self.vapi.nat44_interface_add_del_feature(
1547 sw_if_index=self.pg0.sw_if_index,
1548 flags=flags, is_add=1)
1549 self.vapi.nat44_interface_add_del_feature(
1550 sw_if_index=self.pg1.sw_if_index,
1553 # Client side - create sessions
1554 pkts = self.create_stream_in(self.pg0, self.pg1)
1555 self.pg0.add_stream(pkts)
1556 self.pg_enable_capture(self.pg_interfaces)
1559 # Server side - generate traffic
1560 capture = self.pg1.get_capture(len(pkts))
1561 self.verify_capture_out(capture)
1562 pkts = self.create_stream_out(self.pg1, ttl=1)
1563 self.pg1.add_stream(pkts)
1564 self.pg_enable_capture(self.pg_interfaces)
1567 # Server side - verify ICMP type 11 packets
1568 capture = self.pg1.get_capture(len(pkts))
1569 self.verify_capture_out_with_icmp_errors(capture,
1570 src_ip=self.pg1.local_ip4)
1572 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1573 """ NAT44 handling of error responses to client packets with TTL=2 """
1575 self.nat44_add_address(self.nat_addr)
1576 flags = self.config_flags.NAT_IS_INSIDE
1577 self.vapi.nat44_interface_add_del_feature(
1578 sw_if_index=self.pg0.sw_if_index,
1579 flags=flags, is_add=1)
1580 self.vapi.nat44_interface_add_del_feature(
1581 sw_if_index=self.pg1.sw_if_index,
1584 # Client side - generate traffic
1585 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1586 self.pg0.add_stream(pkts)
1587 self.pg_enable_capture(self.pg_interfaces)
1590 # Server side - simulate ICMP type 11 response
1591 capture = self.pg1.get_capture(len(pkts))
1592 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1593 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1594 ICMP(type=11) / packet[IP] for packet in capture]
1595 self.pg1.add_stream(pkts)
1596 self.pg_enable_capture(self.pg_interfaces)
1599 # Client side - verify ICMP type 11 packets
1600 capture = self.pg0.get_capture(len(pkts))
1601 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1603 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1604 """ NAT44 handling of error responses to server packets with TTL=2 """
1606 self.nat44_add_address(self.nat_addr)
1607 flags = self.config_flags.NAT_IS_INSIDE
1608 self.vapi.nat44_interface_add_del_feature(
1609 sw_if_index=self.pg0.sw_if_index,
1610 flags=flags, is_add=1)
1611 self.vapi.nat44_interface_add_del_feature(
1612 sw_if_index=self.pg1.sw_if_index,
1615 # Client side - create sessions
1616 pkts = self.create_stream_in(self.pg0, self.pg1)
1617 self.pg0.add_stream(pkts)
1618 self.pg_enable_capture(self.pg_interfaces)
1621 # Server side - generate traffic
1622 capture = self.pg1.get_capture(len(pkts))
1623 self.verify_capture_out(capture)
1624 pkts = self.create_stream_out(self.pg1, ttl=2)
1625 self.pg1.add_stream(pkts)
1626 self.pg_enable_capture(self.pg_interfaces)
1629 # Client side - simulate ICMP type 11 response
1630 capture = self.pg0.get_capture(len(pkts))
1631 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1632 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1633 ICMP(type=11) / packet[IP] for packet in capture]
1634 self.pg0.add_stream(pkts)
1635 self.pg_enable_capture(self.pg_interfaces)
1638 # Server side - verify ICMP type 11 packets
1639 capture = self.pg1.get_capture(len(pkts))
1640 self.verify_capture_out_with_icmp_errors(capture)
1642 def test_ping_out_interface_from_outside(self):
1643 """ Ping NAT44 out interface from outside network """
1645 self.nat44_add_address(self.nat_addr)
1646 flags = self.config_flags.NAT_IS_INSIDE
1647 self.vapi.nat44_interface_add_del_feature(
1648 sw_if_index=self.pg0.sw_if_index,
1649 flags=flags, is_add=1)
1650 self.vapi.nat44_interface_add_del_feature(
1651 sw_if_index=self.pg1.sw_if_index,
1654 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1655 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1656 ICMP(id=self.icmp_id_out, type='echo-request'))
1658 self.pg1.add_stream(pkts)
1659 self.pg_enable_capture(self.pg_interfaces)
1661 capture = self.pg1.get_capture(len(pkts))
1664 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1665 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1666 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1667 self.assertEqual(packet[ICMP].type, 0) # echo reply
1669 self.logger.error(ppp("Unexpected or invalid packet "
1670 "(outside network):", packet))
1673 def test_ping_internal_host_from_outside(self):
1674 """ Ping internal host from outside network """
1676 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1677 flags = self.config_flags.NAT_IS_INSIDE
1678 self.vapi.nat44_interface_add_del_feature(
1679 sw_if_index=self.pg0.sw_if_index,
1680 flags=flags, is_add=1)
1681 self.vapi.nat44_interface_add_del_feature(
1682 sw_if_index=self.pg1.sw_if_index,
1686 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1687 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1688 ICMP(id=self.icmp_id_out, type='echo-request'))
1689 self.pg1.add_stream(pkt)
1690 self.pg_enable_capture(self.pg_interfaces)
1692 capture = self.pg0.get_capture(1)
1693 self.verify_capture_in(capture, self.pg0)
1694 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1697 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1698 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1699 ICMP(id=self.icmp_id_in, type='echo-reply'))
1700 self.pg0.add_stream(pkt)
1701 self.pg_enable_capture(self.pg_interfaces)
1703 capture = self.pg1.get_capture(1)
1704 self.verify_capture_out(capture, same_port=True)
1705 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1707 def test_forwarding(self):
1708 """ NAT44 forwarding test """
1710 flags = self.config_flags.NAT_IS_INSIDE
1711 self.vapi.nat44_interface_add_del_feature(
1712 sw_if_index=self.pg0.sw_if_index,
1713 flags=flags, is_add=1)
1714 self.vapi.nat44_interface_add_del_feature(
1715 sw_if_index=self.pg1.sw_if_index,
1717 self.vapi.nat44_forwarding_enable_disable(enable=1)
1719 real_ip = self.pg0.remote_ip4
1720 alias_ip = self.nat_addr
1721 flags = self.config_flags.NAT_IS_ADDR_ONLY
1722 self.vapi.nat44_add_del_static_mapping(is_add=1,
1723 local_ip_address=real_ip,
1724 external_ip_address=alias_ip,
1725 external_sw_if_index=0xFFFFFFFF,
1729 # static mapping match
1731 pkts = self.create_stream_out(self.pg1)
1732 self.pg1.add_stream(pkts)
1733 self.pg_enable_capture(self.pg_interfaces)
1735 capture = self.pg0.get_capture(len(pkts))
1736 self.verify_capture_in(capture, self.pg0)
1738 pkts = self.create_stream_in(self.pg0, self.pg1)
1739 self.pg0.add_stream(pkts)
1740 self.pg_enable_capture(self.pg_interfaces)
1742 capture = self.pg1.get_capture(len(pkts))
1743 self.verify_capture_out(capture, same_port=True)
1745 # no static mapping match
1747 host0 = self.pg0.remote_hosts[0]
1748 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1750 pkts = self.create_stream_out(self.pg1,
1751 dst_ip=self.pg0.remote_ip4,
1752 use_inside_ports=True)
1753 self.pg1.add_stream(pkts)
1754 self.pg_enable_capture(self.pg_interfaces)
1756 capture = self.pg0.get_capture(len(pkts))
1757 self.verify_capture_in(capture, self.pg0)
1759 pkts = self.create_stream_in(self.pg0, self.pg1)
1760 self.pg0.add_stream(pkts)
1761 self.pg_enable_capture(self.pg_interfaces)
1763 capture = self.pg1.get_capture(len(pkts))
1764 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1767 self.pg0.remote_hosts[0] = host0
1770 self.vapi.nat44_forwarding_enable_disable(enable=0)
1771 flags = self.config_flags.NAT_IS_ADDR_ONLY
1772 self.vapi.nat44_add_del_static_mapping(
1774 local_ip_address=real_ip,
1775 external_ip_address=alias_ip,
1776 external_sw_if_index=0xFFFFFFFF,
1779 def test_static_in(self):
1780 """ 1:1 NAT initialized from inside network """
1782 nat_ip = "10.0.0.10"
1783 self.tcp_port_out = 6303
1784 self.udp_port_out = 6304
1785 self.icmp_id_out = 6305
1787 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1788 flags = self.config_flags.NAT_IS_INSIDE
1789 self.vapi.nat44_interface_add_del_feature(
1790 sw_if_index=self.pg0.sw_if_index,
1791 flags=flags, is_add=1)
1792 self.vapi.nat44_interface_add_del_feature(
1793 sw_if_index=self.pg1.sw_if_index,
1795 sm = self.vapi.nat44_static_mapping_dump()
1796 self.assertEqual(len(sm), 1)
1797 self.assertEqual(sm[0].tag, '')
1798 self.assertEqual(sm[0].protocol, 0)
1799 self.assertEqual(sm[0].local_port, 0)
1800 self.assertEqual(sm[0].external_port, 0)
1803 pkts = self.create_stream_in(self.pg0, self.pg1)
1804 self.pg0.add_stream(pkts)
1805 self.pg_enable_capture(self.pg_interfaces)
1807 capture = self.pg1.get_capture(len(pkts))
1808 self.verify_capture_out(capture, nat_ip, True)
1811 pkts = self.create_stream_out(self.pg1, nat_ip)
1812 self.pg1.add_stream(pkts)
1813 self.pg_enable_capture(self.pg_interfaces)
1815 capture = self.pg0.get_capture(len(pkts))
1816 self.verify_capture_in(capture, self.pg0)
1818 def test_static_out(self):
1819 """ 1:1 NAT initialized from outside network """
1821 nat_ip = "10.0.0.20"
1822 self.tcp_port_out = 6303
1823 self.udp_port_out = 6304
1824 self.icmp_id_out = 6305
1827 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1828 flags = self.config_flags.NAT_IS_INSIDE
1829 self.vapi.nat44_interface_add_del_feature(
1830 sw_if_index=self.pg0.sw_if_index,
1831 flags=flags, is_add=1)
1832 self.vapi.nat44_interface_add_del_feature(
1833 sw_if_index=self.pg1.sw_if_index,
1835 sm = self.vapi.nat44_static_mapping_dump()
1836 self.assertEqual(len(sm), 1)
1837 self.assertEqual(sm[0].tag, tag)
1840 pkts = self.create_stream_out(self.pg1, nat_ip)
1841 self.pg1.add_stream(pkts)
1842 self.pg_enable_capture(self.pg_interfaces)
1844 capture = self.pg0.get_capture(len(pkts))
1845 self.verify_capture_in(capture, self.pg0)
1848 pkts = self.create_stream_in(self.pg0, self.pg1)
1849 self.pg0.add_stream(pkts)
1850 self.pg_enable_capture(self.pg_interfaces)
1852 capture = self.pg1.get_capture(len(pkts))
1853 self.verify_capture_out(capture, nat_ip, True)
1855 def test_static_with_port_in(self):
1856 """ 1:1 NAPT initialized from inside network """
1858 self.tcp_port_out = 3606
1859 self.udp_port_out = 3607
1860 self.icmp_id_out = 3608
1862 self.nat44_add_address(self.nat_addr)
1863 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1864 self.tcp_port_in, self.tcp_port_out,
1865 proto=IP_PROTOS.tcp)
1866 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1867 self.udp_port_in, self.udp_port_out,
1868 proto=IP_PROTOS.udp)
1869 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1870 self.icmp_id_in, self.icmp_id_out,
1871 proto=IP_PROTOS.icmp)
1872 flags = self.config_flags.NAT_IS_INSIDE
1873 self.vapi.nat44_interface_add_del_feature(
1874 sw_if_index=self.pg0.sw_if_index,
1875 flags=flags, is_add=1)
1876 self.vapi.nat44_interface_add_del_feature(
1877 sw_if_index=self.pg1.sw_if_index,
1881 pkts = self.create_stream_in(self.pg0, self.pg1)
1882 self.pg0.add_stream(pkts)
1883 self.pg_enable_capture(self.pg_interfaces)
1885 capture = self.pg1.get_capture(len(pkts))
1886 self.verify_capture_out(capture)
1889 pkts = self.create_stream_out(self.pg1)
1890 self.pg1.add_stream(pkts)
1891 self.pg_enable_capture(self.pg_interfaces)
1893 capture = self.pg0.get_capture(len(pkts))
1894 self.verify_capture_in(capture, self.pg0)
1896 def test_static_with_port_out(self):
1897 """ 1:1 NAPT initialized from outside network """
1899 self.tcp_port_out = 30606
1900 self.udp_port_out = 30607
1901 self.icmp_id_out = 30608
1903 self.nat44_add_address(self.nat_addr)
1904 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1905 self.tcp_port_in, self.tcp_port_out,
1906 proto=IP_PROTOS.tcp)
1907 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1908 self.udp_port_in, self.udp_port_out,
1909 proto=IP_PROTOS.udp)
1910 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1911 self.icmp_id_in, self.icmp_id_out,
1912 proto=IP_PROTOS.icmp)
1913 flags = self.config_flags.NAT_IS_INSIDE
1914 self.vapi.nat44_interface_add_del_feature(
1915 sw_if_index=self.pg0.sw_if_index,
1916 flags=flags, is_add=1)
1917 self.vapi.nat44_interface_add_del_feature(
1918 sw_if_index=self.pg1.sw_if_index,
1922 pkts = self.create_stream_out(self.pg1)
1923 self.pg1.add_stream(pkts)
1924 self.pg_enable_capture(self.pg_interfaces)
1926 capture = self.pg0.get_capture(len(pkts))
1927 self.verify_capture_in(capture, self.pg0)
1930 pkts = self.create_stream_in(self.pg0, self.pg1)
1931 self.pg0.add_stream(pkts)
1932 self.pg_enable_capture(self.pg_interfaces)
1934 capture = self.pg1.get_capture(len(pkts))
1935 self.verify_capture_out(capture)
1937 def test_static_vrf_aware(self):
1938 """ 1:1 NAT VRF awareness """
1940 nat_ip1 = "10.0.0.30"
1941 nat_ip2 = "10.0.0.40"
1942 self.tcp_port_out = 6303
1943 self.udp_port_out = 6304
1944 self.icmp_id_out = 6305
1946 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1948 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1950 flags = self.config_flags.NAT_IS_INSIDE
1951 self.vapi.nat44_interface_add_del_feature(
1952 sw_if_index=self.pg3.sw_if_index,
1954 self.vapi.nat44_interface_add_del_feature(
1955 sw_if_index=self.pg0.sw_if_index,
1956 flags=flags, is_add=1)
1957 self.vapi.nat44_interface_add_del_feature(
1958 sw_if_index=self.pg4.sw_if_index,
1959 flags=flags, is_add=1)
1961 # inside interface VRF match NAT44 static mapping VRF
1962 pkts = self.create_stream_in(self.pg4, self.pg3)
1963 self.pg4.add_stream(pkts)
1964 self.pg_enable_capture(self.pg_interfaces)
1966 capture = self.pg3.get_capture(len(pkts))
1967 self.verify_capture_out(capture, nat_ip1, True)
1969 # inside interface VRF don't match NAT44 static mapping VRF (packets
1971 pkts = self.create_stream_in(self.pg0, self.pg3)
1972 self.pg0.add_stream(pkts)
1973 self.pg_enable_capture(self.pg_interfaces)
1975 self.pg3.assert_nothing_captured()
1977 def test_dynamic_to_static(self):
1978 """ Switch from dynamic translation to 1:1NAT """
1979 nat_ip = "10.0.0.10"
1980 self.tcp_port_out = 6303
1981 self.udp_port_out = 6304
1982 self.icmp_id_out = 6305
1984 self.nat44_add_address(self.nat_addr)
1985 flags = self.config_flags.NAT_IS_INSIDE
1986 self.vapi.nat44_interface_add_del_feature(
1987 sw_if_index=self.pg0.sw_if_index,
1988 flags=flags, is_add=1)
1989 self.vapi.nat44_interface_add_del_feature(
1990 sw_if_index=self.pg1.sw_if_index,
1994 pkts = self.create_stream_in(self.pg0, self.pg1)
1995 self.pg0.add_stream(pkts)
1996 self.pg_enable_capture(self.pg_interfaces)
1998 capture = self.pg1.get_capture(len(pkts))
1999 self.verify_capture_out(capture)
2002 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2003 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2004 self.assertEqual(len(sessions), 0)
2005 pkts = self.create_stream_in(self.pg0, self.pg1)
2006 self.pg0.add_stream(pkts)
2007 self.pg_enable_capture(self.pg_interfaces)
2009 capture = self.pg1.get_capture(len(pkts))
2010 self.verify_capture_out(capture, nat_ip, True)
2012 def test_identity_nat(self):
2013 """ Identity NAT """
2014 flags = self.config_flags.NAT_IS_ADDR_ONLY
2015 self.vapi.nat44_add_del_identity_mapping(
2016 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2017 flags=flags, is_add=1)
2018 flags = self.config_flags.NAT_IS_INSIDE
2019 self.vapi.nat44_interface_add_del_feature(
2020 sw_if_index=self.pg0.sw_if_index,
2021 flags=flags, is_add=1)
2022 self.vapi.nat44_interface_add_del_feature(
2023 sw_if_index=self.pg1.sw_if_index,
2026 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2027 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2028 TCP(sport=12345, dport=56789))
2029 self.pg1.add_stream(p)
2030 self.pg_enable_capture(self.pg_interfaces)
2032 capture = self.pg0.get_capture(1)
2037 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2038 self.assertEqual(ip.src, self.pg1.remote_ip4)
2039 self.assertEqual(tcp.dport, 56789)
2040 self.assertEqual(tcp.sport, 12345)
2041 self.assert_packet_checksums_valid(p)
2043 self.logger.error(ppp("Unexpected or invalid packet:", p))
2046 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2047 self.assertEqual(len(sessions), 0)
2048 flags = self.config_flags.NAT_IS_ADDR_ONLY
2049 self.vapi.nat44_add_del_identity_mapping(
2050 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2051 flags=flags, vrf_id=1, is_add=1)
2052 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2053 self.assertEqual(len(identity_mappings), 2)
2055 def test_multiple_inside_interfaces(self):
2056 """ NAT44 multiple non-overlapping address space inside interfaces """
2058 self.nat44_add_address(self.nat_addr)
2059 flags = self.config_flags.NAT_IS_INSIDE
2060 self.vapi.nat44_interface_add_del_feature(
2061 sw_if_index=self.pg0.sw_if_index,
2062 flags=flags, is_add=1)
2063 self.vapi.nat44_interface_add_del_feature(
2064 sw_if_index=self.pg1.sw_if_index,
2065 flags=flags, is_add=1)
2066 self.vapi.nat44_interface_add_del_feature(
2067 sw_if_index=self.pg3.sw_if_index,
2070 # between two NAT44 inside interfaces (no translation)
2071 pkts = self.create_stream_in(self.pg0, self.pg1)
2072 self.pg0.add_stream(pkts)
2073 self.pg_enable_capture(self.pg_interfaces)
2075 capture = self.pg1.get_capture(len(pkts))
2076 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2078 # from NAT44 inside to interface without NAT44 feature (no translation)
2079 pkts = self.create_stream_in(self.pg0, self.pg2)
2080 self.pg0.add_stream(pkts)
2081 self.pg_enable_capture(self.pg_interfaces)
2083 capture = self.pg2.get_capture(len(pkts))
2084 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2086 # in2out 1st interface
2087 pkts = self.create_stream_in(self.pg0, self.pg3)
2088 self.pg0.add_stream(pkts)
2089 self.pg_enable_capture(self.pg_interfaces)
2091 capture = self.pg3.get_capture(len(pkts))
2092 self.verify_capture_out(capture)
2094 # out2in 1st interface
2095 pkts = self.create_stream_out(self.pg3)
2096 self.pg3.add_stream(pkts)
2097 self.pg_enable_capture(self.pg_interfaces)
2099 capture = self.pg0.get_capture(len(pkts))
2100 self.verify_capture_in(capture, self.pg0)
2102 # in2out 2nd interface
2103 pkts = self.create_stream_in(self.pg1, self.pg3)
2104 self.pg1.add_stream(pkts)
2105 self.pg_enable_capture(self.pg_interfaces)
2107 capture = self.pg3.get_capture(len(pkts))
2108 self.verify_capture_out(capture)
2110 # out2in 2nd interface
2111 pkts = self.create_stream_out(self.pg3)
2112 self.pg3.add_stream(pkts)
2113 self.pg_enable_capture(self.pg_interfaces)
2115 capture = self.pg1.get_capture(len(pkts))
2116 self.verify_capture_in(capture, self.pg1)
2118 def test_inside_overlapping_interfaces(self):
2119 """ NAT44 multiple inside interfaces with overlapping address space """
2121 static_nat_ip = "10.0.0.10"
2122 self.nat44_add_address(self.nat_addr)
2123 flags = self.config_flags.NAT_IS_INSIDE
2124 self.vapi.nat44_interface_add_del_feature(
2125 sw_if_index=self.pg3.sw_if_index,
2127 self.vapi.nat44_interface_add_del_feature(
2128 sw_if_index=self.pg4.sw_if_index,
2129 flags=flags, is_add=1)
2130 self.vapi.nat44_interface_add_del_feature(
2131 sw_if_index=self.pg5.sw_if_index,
2132 flags=flags, is_add=1)
2133 self.vapi.nat44_interface_add_del_feature(
2134 sw_if_index=self.pg6.sw_if_index,
2135 flags=flags, is_add=1)
2136 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2139 # between NAT44 inside interfaces with same VRF (no translation)
2140 pkts = self.create_stream_in(self.pg4, self.pg5)
2141 self.pg4.add_stream(pkts)
2142 self.pg_enable_capture(self.pg_interfaces)
2144 capture = self.pg5.get_capture(len(pkts))
2145 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2147 # between NAT44 inside interfaces with different VRF (hairpinning)
2148 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2149 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2150 TCP(sport=1234, dport=5678))
2151 self.pg4.add_stream(p)
2152 self.pg_enable_capture(self.pg_interfaces)
2154 capture = self.pg6.get_capture(1)
2159 self.assertEqual(ip.src, self.nat_addr)
2160 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2161 self.assertNotEqual(tcp.sport, 1234)
2162 self.assertEqual(tcp.dport, 5678)
2164 self.logger.error(ppp("Unexpected or invalid packet:", p))
2167 # in2out 1st interface
2168 pkts = self.create_stream_in(self.pg4, self.pg3)
2169 self.pg4.add_stream(pkts)
2170 self.pg_enable_capture(self.pg_interfaces)
2172 capture = self.pg3.get_capture(len(pkts))
2173 self.verify_capture_out(capture)
2175 # out2in 1st interface
2176 pkts = self.create_stream_out(self.pg3)
2177 self.pg3.add_stream(pkts)
2178 self.pg_enable_capture(self.pg_interfaces)
2180 capture = self.pg4.get_capture(len(pkts))
2181 self.verify_capture_in(capture, self.pg4)
2183 # in2out 2nd interface
2184 pkts = self.create_stream_in(self.pg5, self.pg3)
2185 self.pg5.add_stream(pkts)
2186 self.pg_enable_capture(self.pg_interfaces)
2188 capture = self.pg3.get_capture(len(pkts))
2189 self.verify_capture_out(capture)
2191 # out2in 2nd interface
2192 pkts = self.create_stream_out(self.pg3)
2193 self.pg3.add_stream(pkts)
2194 self.pg_enable_capture(self.pg_interfaces)
2196 capture = self.pg5.get_capture(len(pkts))
2197 self.verify_capture_in(capture, self.pg5)
2200 addresses = self.vapi.nat44_address_dump()
2201 self.assertEqual(len(addresses), 1)
2202 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2203 self.assertEqual(len(sessions), 3)
2204 for session in sessions:
2205 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2206 self.assertEqual(str(session.inside_ip_address),
2207 self.pg5.remote_ip4)
2208 self.assertEqual(session.outside_ip_address,
2209 addresses[0].ip_address)
2210 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2211 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2212 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2213 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2214 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2215 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2216 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2217 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2218 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2220 # in2out 3rd interface
2221 pkts = self.create_stream_in(self.pg6, self.pg3)
2222 self.pg6.add_stream(pkts)
2223 self.pg_enable_capture(self.pg_interfaces)
2225 capture = self.pg3.get_capture(len(pkts))
2226 self.verify_capture_out(capture, static_nat_ip, True)
2228 # out2in 3rd interface
2229 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2230 self.pg3.add_stream(pkts)
2231 self.pg_enable_capture(self.pg_interfaces)
2233 capture = self.pg6.get_capture(len(pkts))
2234 self.verify_capture_in(capture, self.pg6)
2236 # general user and session dump verifications
2237 users = self.vapi.nat44_user_dump()
2238 self.assertGreaterEqual(len(users), 3)
2239 addresses = self.vapi.nat44_address_dump()
2240 self.assertEqual(len(addresses), 1)
2242 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2244 for session in sessions:
2245 self.assertEqual(user.ip_address, session.inside_ip_address)
2246 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2247 self.assertTrue(session.protocol in
2248 [IP_PROTOS.tcp, IP_PROTOS.udp,
2250 self.assertFalse(session.flags &
2251 self.config_flags.NAT_IS_EXT_HOST_VALID)
2254 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2255 self.assertGreaterEqual(len(sessions), 4)
2256 for session in sessions:
2257 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2258 self.assertEqual(str(session.inside_ip_address),
2259 self.pg4.remote_ip4)
2260 self.assertEqual(session.outside_ip_address,
2261 addresses[0].ip_address)
2264 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2265 self.assertGreaterEqual(len(sessions), 3)
2266 for session in sessions:
2267 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2268 self.assertEqual(str(session.inside_ip_address),
2269 self.pg6.remote_ip4)
2270 self.assertEqual(str(session.outside_ip_address),
2272 self.assertTrue(session.inside_port in
2273 [self.tcp_port_in, self.udp_port_in,
2276 def test_hairpinning(self):
2277 """ NAT44 hairpinning - 1:1 NAPT """
2279 host = self.pg0.remote_hosts[0]
2280 server = self.pg0.remote_hosts[1]
2283 server_in_port = 5678
2284 server_out_port = 8765
2286 self.nat44_add_address(self.nat_addr)
2287 flags = self.config_flags.NAT_IS_INSIDE
2288 self.vapi.nat44_interface_add_del_feature(
2289 sw_if_index=self.pg0.sw_if_index,
2290 flags=flags, is_add=1)
2291 self.vapi.nat44_interface_add_del_feature(
2292 sw_if_index=self.pg1.sw_if_index,
2295 # add static mapping for server
2296 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2297 server_in_port, server_out_port,
2298 proto=IP_PROTOS.tcp)
2300 # send packet from host to server
2301 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2302 IP(src=host.ip4, dst=self.nat_addr) /
2303 TCP(sport=host_in_port, dport=server_out_port))
2304 self.pg0.add_stream(p)
2305 self.pg_enable_capture(self.pg_interfaces)
2307 capture = self.pg0.get_capture(1)
2312 self.assertEqual(ip.src, self.nat_addr)
2313 self.assertEqual(ip.dst, server.ip4)
2314 self.assertNotEqual(tcp.sport, host_in_port)
2315 self.assertEqual(tcp.dport, server_in_port)
2316 self.assert_packet_checksums_valid(p)
2317 host_out_port = tcp.sport
2319 self.logger.error(ppp("Unexpected or invalid packet:", p))
2322 # send reply from server to host
2323 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2324 IP(src=server.ip4, dst=self.nat_addr) /
2325 TCP(sport=server_in_port, dport=host_out_port))
2326 self.pg0.add_stream(p)
2327 self.pg_enable_capture(self.pg_interfaces)
2329 capture = self.pg0.get_capture(1)
2334 self.assertEqual(ip.src, self.nat_addr)
2335 self.assertEqual(ip.dst, host.ip4)
2336 self.assertEqual(tcp.sport, server_out_port)
2337 self.assertEqual(tcp.dport, host_in_port)
2338 self.assert_packet_checksums_valid(p)
2340 self.logger.error(ppp("Unexpected or invalid packet:", p))
2343 def test_hairpinning2(self):
2344 """ NAT44 hairpinning - 1:1 NAT"""
2346 server1_nat_ip = "10.0.0.10"
2347 server2_nat_ip = "10.0.0.11"
2348 host = self.pg0.remote_hosts[0]
2349 server1 = self.pg0.remote_hosts[1]
2350 server2 = self.pg0.remote_hosts[2]
2351 server_tcp_port = 22
2352 server_udp_port = 20
2354 self.nat44_add_address(self.nat_addr)
2355 flags = self.config_flags.NAT_IS_INSIDE
2356 self.vapi.nat44_interface_add_del_feature(
2357 sw_if_index=self.pg0.sw_if_index,
2358 flags=flags, is_add=1)
2359 self.vapi.nat44_interface_add_del_feature(
2360 sw_if_index=self.pg1.sw_if_index,
2363 # add static mapping for servers
2364 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2365 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2369 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2370 IP(src=host.ip4, dst=server1_nat_ip) /
2371 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2373 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2374 IP(src=host.ip4, dst=server1_nat_ip) /
2375 UDP(sport=self.udp_port_in, dport=server_udp_port))
2377 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2378 IP(src=host.ip4, dst=server1_nat_ip) /
2379 ICMP(id=self.icmp_id_in, type='echo-request'))
2381 self.pg0.add_stream(pkts)
2382 self.pg_enable_capture(self.pg_interfaces)
2384 capture = self.pg0.get_capture(len(pkts))
2385 for packet in capture:
2387 self.assertEqual(packet[IP].src, self.nat_addr)
2388 self.assertEqual(packet[IP].dst, server1.ip4)
2389 if packet.haslayer(TCP):
2390 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2391 self.assertEqual(packet[TCP].dport, server_tcp_port)
2392 self.tcp_port_out = packet[TCP].sport
2393 self.assert_packet_checksums_valid(packet)
2394 elif packet.haslayer(UDP):
2395 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2396 self.assertEqual(packet[UDP].dport, server_udp_port)
2397 self.udp_port_out = packet[UDP].sport
2399 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2400 self.icmp_id_out = packet[ICMP].id
2402 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2407 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2408 IP(src=server1.ip4, dst=self.nat_addr) /
2409 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2411 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2412 IP(src=server1.ip4, dst=self.nat_addr) /
2413 UDP(sport=server_udp_port, dport=self.udp_port_out))
2415 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2416 IP(src=server1.ip4, dst=self.nat_addr) /
2417 ICMP(id=self.icmp_id_out, type='echo-reply'))
2419 self.pg0.add_stream(pkts)
2420 self.pg_enable_capture(self.pg_interfaces)
2422 capture = self.pg0.get_capture(len(pkts))
2423 for packet in capture:
2425 self.assertEqual(packet[IP].src, server1_nat_ip)
2426 self.assertEqual(packet[IP].dst, host.ip4)
2427 if packet.haslayer(TCP):
2428 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2429 self.assertEqual(packet[TCP].sport, server_tcp_port)
2430 self.assert_packet_checksums_valid(packet)
2431 elif packet.haslayer(UDP):
2432 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2433 self.assertEqual(packet[UDP].sport, server_udp_port)
2435 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2437 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2440 # server2 to server1
2442 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2443 IP(src=server2.ip4, dst=server1_nat_ip) /
2444 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2446 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2447 IP(src=server2.ip4, dst=server1_nat_ip) /
2448 UDP(sport=self.udp_port_in, dport=server_udp_port))
2450 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2451 IP(src=server2.ip4, dst=server1_nat_ip) /
2452 ICMP(id=self.icmp_id_in, type='echo-request'))
2454 self.pg0.add_stream(pkts)
2455 self.pg_enable_capture(self.pg_interfaces)
2457 capture = self.pg0.get_capture(len(pkts))
2458 for packet in capture:
2460 self.assertEqual(packet[IP].src, server2_nat_ip)
2461 self.assertEqual(packet[IP].dst, server1.ip4)
2462 if packet.haslayer(TCP):
2463 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2464 self.assertEqual(packet[TCP].dport, server_tcp_port)
2465 self.tcp_port_out = packet[TCP].sport
2466 self.assert_packet_checksums_valid(packet)
2467 elif packet.haslayer(UDP):
2468 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2469 self.assertEqual(packet[UDP].dport, server_udp_port)
2470 self.udp_port_out = packet[UDP].sport
2472 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2473 self.icmp_id_out = packet[ICMP].id
2475 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2478 # server1 to server2
2480 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2481 IP(src=server1.ip4, dst=server2_nat_ip) /
2482 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2484 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2485 IP(src=server1.ip4, dst=server2_nat_ip) /
2486 UDP(sport=server_udp_port, dport=self.udp_port_out))
2488 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2489 IP(src=server1.ip4, dst=server2_nat_ip) /
2490 ICMP(id=self.icmp_id_out, type='echo-reply'))
2492 self.pg0.add_stream(pkts)
2493 self.pg_enable_capture(self.pg_interfaces)
2495 capture = self.pg0.get_capture(len(pkts))
2496 for packet in capture:
2498 self.assertEqual(packet[IP].src, server1_nat_ip)
2499 self.assertEqual(packet[IP].dst, server2.ip4)
2500 if packet.haslayer(TCP):
2501 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2502 self.assertEqual(packet[TCP].sport, server_tcp_port)
2503 self.assert_packet_checksums_valid(packet)
2504 elif packet.haslayer(UDP):
2505 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2506 self.assertEqual(packet[UDP].sport, server_udp_port)
2508 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2510 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2513 def test_interface_addr(self):
2514 """ Acquire NAT44 addresses from interface """
2515 self.vapi.nat44_add_del_interface_addr(
2517 sw_if_index=self.pg7.sw_if_index)
2519 # no address in NAT pool
2520 addresses = self.vapi.nat44_address_dump()
2521 self.assertEqual(0, len(addresses))
2523 # configure interface address and check NAT address pool
2524 self.pg7.config_ip4()
2525 addresses = self.vapi.nat44_address_dump()
2526 self.assertEqual(1, len(addresses))
2527 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2529 # remove interface address and check NAT address pool
2530 self.pg7.unconfig_ip4()
2531 addresses = self.vapi.nat44_address_dump()
2532 self.assertEqual(0, len(addresses))
2534 def test_interface_addr_static_mapping(self):
2535 """ Static mapping with addresses from interface """
2538 self.vapi.nat44_add_del_interface_addr(
2540 sw_if_index=self.pg7.sw_if_index)
2541 self.nat44_add_static_mapping(
2543 external_sw_if_index=self.pg7.sw_if_index,
2546 # static mappings with external interface
2547 static_mappings = self.vapi.nat44_static_mapping_dump()
2548 self.assertEqual(1, len(static_mappings))
2549 self.assertEqual(self.pg7.sw_if_index,
2550 static_mappings[0].external_sw_if_index)
2551 self.assertEqual(static_mappings[0].tag, tag)
2553 # configure interface address and check static mappings
2554 self.pg7.config_ip4()
2555 static_mappings = self.vapi.nat44_static_mapping_dump()
2556 self.assertEqual(2, len(static_mappings))
2558 for sm in static_mappings:
2559 if sm.external_sw_if_index == 0xFFFFFFFF:
2560 self.assertEqual(str(sm.external_ip_address),
2562 self.assertEqual(sm.tag, tag)
2564 self.assertTrue(resolved)
2566 # remove interface address and check static mappings
2567 self.pg7.unconfig_ip4()
2568 static_mappings = self.vapi.nat44_static_mapping_dump()
2569 self.assertEqual(1, len(static_mappings))
2570 self.assertEqual(self.pg7.sw_if_index,
2571 static_mappings[0].external_sw_if_index)
2572 self.assertEqual(static_mappings[0].tag, tag)
2574 # configure interface address again and check static mappings
2575 self.pg7.config_ip4()
2576 static_mappings = self.vapi.nat44_static_mapping_dump()
2577 self.assertEqual(2, len(static_mappings))
2579 for sm in static_mappings:
2580 if sm.external_sw_if_index == 0xFFFFFFFF:
2581 self.assertEqual(str(sm.external_ip_address),
2583 self.assertEqual(sm.tag, tag)
2585 self.assertTrue(resolved)
2587 # remove static mapping
2588 self.nat44_add_static_mapping(
2590 external_sw_if_index=self.pg7.sw_if_index,
2593 static_mappings = self.vapi.nat44_static_mapping_dump()
2594 self.assertEqual(0, len(static_mappings))
2596 def test_interface_addr_identity_nat(self):
2597 """ Identity NAT with addresses from interface """
2600 self.vapi.nat44_add_del_interface_addr(
2602 sw_if_index=self.pg7.sw_if_index)
2603 self.vapi.nat44_add_del_identity_mapping(
2605 sw_if_index=self.pg7.sw_if_index,
2607 protocol=IP_PROTOS.tcp,
2610 # identity mappings with external interface
2611 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2612 self.assertEqual(1, len(identity_mappings))
2613 self.assertEqual(self.pg7.sw_if_index,
2614 identity_mappings[0].sw_if_index)
2616 # configure interface address and check identity mappings
2617 self.pg7.config_ip4()
2618 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2620 self.assertEqual(2, len(identity_mappings))
2621 for sm in identity_mappings:
2622 if sm.sw_if_index == 0xFFFFFFFF:
2623 self.assertEqual(str(identity_mappings[0].ip_address),
2625 self.assertEqual(port, identity_mappings[0].port)
2626 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2628 self.assertTrue(resolved)
2630 # remove interface address and check identity mappings
2631 self.pg7.unconfig_ip4()
2632 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2633 self.assertEqual(1, len(identity_mappings))
2634 self.assertEqual(self.pg7.sw_if_index,
2635 identity_mappings[0].sw_if_index)
2637 def test_ipfix_nat44_sess(self):
2638 """ IPFIX logging NAT44 session created/deleted """
2639 self.ipfix_domain_id = 10
2640 self.ipfix_src_port = 20202
2641 collector_port = 30303
2642 bind_layers(UDP, IPFIX, dport=30303)
2643 self.nat44_add_address(self.nat_addr)
2644 flags = self.config_flags.NAT_IS_INSIDE
2645 self.vapi.nat44_interface_add_del_feature(
2646 sw_if_index=self.pg0.sw_if_index,
2647 flags=flags, is_add=1)
2648 self.vapi.nat44_interface_add_del_feature(
2649 sw_if_index=self.pg1.sw_if_index,
2651 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2652 src_address=self.pg3.local_ip4,
2654 template_interval=10,
2655 collector_port=collector_port)
2656 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2657 src_port=self.ipfix_src_port,
2660 pkts = self.create_stream_in(self.pg0, self.pg1)
2661 self.pg0.add_stream(pkts)
2662 self.pg_enable_capture(self.pg_interfaces)
2664 capture = self.pg1.get_capture(len(pkts))
2665 self.verify_capture_out(capture)
2666 self.nat44_add_address(self.nat_addr, is_add=0)
2667 self.vapi.ipfix_flush()
2668 capture = self.pg3.get_capture(7)
2669 ipfix = IPFIXDecoder()
2670 # first load template
2672 self.assertTrue(p.haslayer(IPFIX))
2673 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2674 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2675 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2676 self.assertEqual(p[UDP].dport, collector_port)
2677 self.assertEqual(p[IPFIX].observationDomainID,
2678 self.ipfix_domain_id)
2679 if p.haslayer(Template):
2680 ipfix.add_template(p.getlayer(Template))
2681 # verify events in data set
2683 if p.haslayer(Data):
2684 data = ipfix.decode_data_set(p.getlayer(Set))
2685 self.verify_ipfix_nat44_ses(data)
2687 def test_ipfix_addr_exhausted(self):
2688 """ IPFIX logging NAT addresses exhausted """
2689 flags = self.config_flags.NAT_IS_INSIDE
2690 self.vapi.nat44_interface_add_del_feature(
2691 sw_if_index=self.pg0.sw_if_index,
2692 flags=flags, is_add=1)
2693 self.vapi.nat44_interface_add_del_feature(
2694 sw_if_index=self.pg1.sw_if_index,
2696 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2697 src_address=self.pg3.local_ip4,
2699 template_interval=10)
2700 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2701 src_port=self.ipfix_src_port,
2704 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2705 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2707 self.pg0.add_stream(p)
2708 self.pg_enable_capture(self.pg_interfaces)
2710 self.pg1.assert_nothing_captured()
2712 self.vapi.ipfix_flush()
2713 capture = self.pg3.get_capture(7)
2714 ipfix = IPFIXDecoder()
2715 # first load template
2717 self.assertTrue(p.haslayer(IPFIX))
2718 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2719 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2720 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2721 self.assertEqual(p[UDP].dport, 4739)
2722 self.assertEqual(p[IPFIX].observationDomainID,
2723 self.ipfix_domain_id)
2724 if p.haslayer(Template):
2725 ipfix.add_template(p.getlayer(Template))
2726 # verify events in data set
2728 if p.haslayer(Data):
2729 data = ipfix.decode_data_set(p.getlayer(Set))
2730 self.verify_ipfix_addr_exhausted(data)
2732 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2733 def test_ipfix_max_sessions(self):
2734 """ IPFIX logging maximum session entries exceeded """
2735 self.nat44_add_address(self.nat_addr)
2736 flags = self.config_flags.NAT_IS_INSIDE
2737 self.vapi.nat44_interface_add_del_feature(
2738 sw_if_index=self.pg0.sw_if_index,
2739 flags=flags, is_add=1)
2740 self.vapi.nat44_interface_add_del_feature(
2741 sw_if_index=self.pg1.sw_if_index,
2744 nat44_config = self.vapi.nat_show_config()
2745 max_sessions = 10 * nat44_config.translation_buckets
2748 for i in range(0, max_sessions):
2749 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2750 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2751 IP(src=src, dst=self.pg1.remote_ip4) /
2754 self.pg0.add_stream(pkts)
2755 self.pg_enable_capture(self.pg_interfaces)
2758 self.pg1.get_capture(max_sessions)
2759 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2760 src_address=self.pg3.local_ip4,
2762 template_interval=10)
2763 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2764 src_port=self.ipfix_src_port,
2767 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2768 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2770 self.pg0.add_stream(p)
2771 self.pg_enable_capture(self.pg_interfaces)
2773 self.pg1.assert_nothing_captured()
2775 self.vapi.ipfix_flush()
2776 capture = self.pg3.get_capture(7)
2777 ipfix = IPFIXDecoder()
2778 # first load template
2780 self.assertTrue(p.haslayer(IPFIX))
2781 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2782 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2783 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2784 self.assertEqual(p[UDP].dport, 4739)
2785 self.assertEqual(p[IPFIX].observationDomainID,
2786 self.ipfix_domain_id)
2787 if p.haslayer(Template):
2788 ipfix.add_template(p.getlayer(Template))
2789 # verify events in data set
2791 if p.haslayer(Data):
2792 data = ipfix.decode_data_set(p.getlayer(Set))
2793 self.verify_ipfix_max_sessions(data, max_sessions)
2795 def test_syslog_apmap(self):
2796 """ Test syslog address and port mapping creation and deletion """
2797 self.vapi.syslog_set_filter(
2798 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2799 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2800 self.nat44_add_address(self.nat_addr)
2801 flags = self.config_flags.NAT_IS_INSIDE
2802 self.vapi.nat44_interface_add_del_feature(
2803 sw_if_index=self.pg0.sw_if_index,
2804 flags=flags, is_add=1)
2805 self.vapi.nat44_interface_add_del_feature(
2806 sw_if_index=self.pg1.sw_if_index,
2809 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2810 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2811 TCP(sport=self.tcp_port_in, dport=20))
2812 self.pg0.add_stream(p)
2813 self.pg_enable_capture(self.pg_interfaces)
2815 capture = self.pg1.get_capture(1)
2816 self.tcp_port_out = capture[0][TCP].sport
2817 capture = self.pg3.get_capture(1)
2818 self.verify_syslog_apmap(capture[0][Raw].load)
2820 self.pg_enable_capture(self.pg_interfaces)
2822 self.nat44_add_address(self.nat_addr, is_add=0)
2823 capture = self.pg3.get_capture(1)
2824 self.verify_syslog_apmap(capture[0][Raw].load, False)
2826 def test_pool_addr_fib(self):
2827 """ NAT44 add pool addresses to FIB """
2828 static_addr = '10.0.0.10'
2829 self.nat44_add_address(self.nat_addr)
2830 flags = self.config_flags.NAT_IS_INSIDE
2831 self.vapi.nat44_interface_add_del_feature(
2832 sw_if_index=self.pg0.sw_if_index,
2833 flags=flags, is_add=1)
2834 self.vapi.nat44_interface_add_del_feature(
2835 sw_if_index=self.pg1.sw_if_index,
2837 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2840 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2841 ARP(op=ARP.who_has, pdst=self.nat_addr,
2842 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2843 self.pg1.add_stream(p)
2844 self.pg_enable_capture(self.pg_interfaces)
2846 capture = self.pg1.get_capture(1)
2847 self.assertTrue(capture[0].haslayer(ARP))
2848 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2851 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2852 ARP(op=ARP.who_has, pdst=static_addr,
2853 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2854 self.pg1.add_stream(p)
2855 self.pg_enable_capture(self.pg_interfaces)
2857 capture = self.pg1.get_capture(1)
2858 self.assertTrue(capture[0].haslayer(ARP))
2859 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2861 # send ARP to non-NAT44 interface
2862 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2863 ARP(op=ARP.who_has, pdst=self.nat_addr,
2864 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2865 self.pg2.add_stream(p)
2866 self.pg_enable_capture(self.pg_interfaces)
2868 self.pg1.assert_nothing_captured()
2870 # remove addresses and verify
2871 self.nat44_add_address(self.nat_addr, is_add=0)
2872 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2875 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2876 ARP(op=ARP.who_has, pdst=self.nat_addr,
2877 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2878 self.pg1.add_stream(p)
2879 self.pg_enable_capture(self.pg_interfaces)
2881 self.pg1.assert_nothing_captured()
2883 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2884 ARP(op=ARP.who_has, pdst=static_addr,
2885 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2886 self.pg1.add_stream(p)
2887 self.pg_enable_capture(self.pg_interfaces)
2889 self.pg1.assert_nothing_captured()
2891 def test_vrf_mode(self):
2892 """ NAT44 tenant VRF aware address pool mode """
2896 nat_ip1 = "10.0.0.10"
2897 nat_ip2 = "10.0.0.11"
2899 self.pg0.unconfig_ip4()
2900 self.pg1.unconfig_ip4()
2901 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2902 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2903 self.pg0.set_table_ip4(vrf_id1)
2904 self.pg1.set_table_ip4(vrf_id2)
2905 self.pg0.config_ip4()
2906 self.pg1.config_ip4()
2907 self.pg0.resolve_arp()
2908 self.pg1.resolve_arp()
2910 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2911 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2912 flags = self.config_flags.NAT_IS_INSIDE
2913 self.vapi.nat44_interface_add_del_feature(
2914 sw_if_index=self.pg0.sw_if_index,
2915 flags=flags, is_add=1)
2916 self.vapi.nat44_interface_add_del_feature(
2917 sw_if_index=self.pg1.sw_if_index,
2918 flags=flags, is_add=1)
2919 self.vapi.nat44_interface_add_del_feature(
2920 sw_if_index=self.pg2.sw_if_index,
2925 pkts = self.create_stream_in(self.pg0, self.pg2)
2926 self.pg0.add_stream(pkts)
2927 self.pg_enable_capture(self.pg_interfaces)
2929 capture = self.pg2.get_capture(len(pkts))
2930 self.verify_capture_out(capture, nat_ip1)
2933 pkts = self.create_stream_in(self.pg1, self.pg2)
2934 self.pg1.add_stream(pkts)
2935 self.pg_enable_capture(self.pg_interfaces)
2937 capture = self.pg2.get_capture(len(pkts))
2938 self.verify_capture_out(capture, nat_ip2)
2941 self.pg0.unconfig_ip4()
2942 self.pg1.unconfig_ip4()
2943 self.pg0.set_table_ip4(0)
2944 self.pg1.set_table_ip4(0)
2945 self.pg0.config_ip4()
2946 self.pg1.config_ip4()
2947 self.pg0.resolve_arp()
2948 self.pg1.resolve_arp()
2949 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2950 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2952 def test_vrf_feature_independent(self):
2953 """ NAT44 tenant VRF independent address pool mode """
2955 nat_ip1 = "10.0.0.10"
2956 nat_ip2 = "10.0.0.11"
2958 self.nat44_add_address(nat_ip1)
2959 self.nat44_add_address(nat_ip2, vrf_id=99)
2960 flags = self.config_flags.NAT_IS_INSIDE
2961 self.vapi.nat44_interface_add_del_feature(
2962 sw_if_index=self.pg0.sw_if_index,
2963 flags=flags, is_add=1)
2964 self.vapi.nat44_interface_add_del_feature(
2965 sw_if_index=self.pg1.sw_if_index,
2966 flags=flags, is_add=1)
2967 self.vapi.nat44_interface_add_del_feature(
2968 sw_if_index=self.pg2.sw_if_index,
2972 pkts = self.create_stream_in(self.pg0, self.pg2)
2973 self.pg0.add_stream(pkts)
2974 self.pg_enable_capture(self.pg_interfaces)
2976 capture = self.pg2.get_capture(len(pkts))
2977 self.verify_capture_out(capture, nat_ip1)
2980 pkts = self.create_stream_in(self.pg1, self.pg2)
2981 self.pg1.add_stream(pkts)
2982 self.pg_enable_capture(self.pg_interfaces)
2984 capture = self.pg2.get_capture(len(pkts))
2985 self.verify_capture_out(capture, nat_ip1)
2987 def create_routes_and_neigbors(self):
2988 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
2989 [VppRoutePath(self.pg7.remote_ip4,
2990 self.pg7.sw_if_index)])
2991 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
2992 [VppRoutePath(self.pg8.remote_ip4,
2993 self.pg8.sw_if_index)])
2997 n1 = VppNeighbor(self,
2998 self.pg7.sw_if_index,
2999 self.pg7.remote_mac,
3000 self.pg7.remote_ip4,
3002 n2 = VppNeighbor(self,
3003 self.pg8.sw_if_index,
3004 self.pg8.remote_mac,
3005 self.pg8.remote_ip4,
3010 def test_dynamic_ipless_interfaces(self):
3011 """ NAT44 interfaces without configured IP address """
3012 self.create_routes_and_neigbors()
3013 self.nat44_add_address(self.nat_addr)
3014 flags = self.config_flags.NAT_IS_INSIDE
3015 self.vapi.nat44_interface_add_del_feature(
3016 sw_if_index=self.pg7.sw_if_index,
3017 flags=flags, is_add=1)
3018 self.vapi.nat44_interface_add_del_feature(
3019 sw_if_index=self.pg8.sw_if_index,
3023 pkts = self.create_stream_in(self.pg7, self.pg8)
3024 self.pg7.add_stream(pkts)
3025 self.pg_enable_capture(self.pg_interfaces)
3027 capture = self.pg8.get_capture(len(pkts))
3028 self.verify_capture_out(capture)
3031 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3032 self.pg8.add_stream(pkts)
3033 self.pg_enable_capture(self.pg_interfaces)
3035 capture = self.pg7.get_capture(len(pkts))
3036 self.verify_capture_in(capture, self.pg7)
3038 def test_static_ipless_interfaces(self):
3039 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3041 self.create_routes_and_neigbors()
3042 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3043 flags = self.config_flags.NAT_IS_INSIDE
3044 self.vapi.nat44_interface_add_del_feature(
3045 sw_if_index=self.pg7.sw_if_index,
3046 flags=flags, is_add=1)
3047 self.vapi.nat44_interface_add_del_feature(
3048 sw_if_index=self.pg8.sw_if_index,
3052 pkts = self.create_stream_out(self.pg8)
3053 self.pg8.add_stream(pkts)
3054 self.pg_enable_capture(self.pg_interfaces)
3056 capture = self.pg7.get_capture(len(pkts))
3057 self.verify_capture_in(capture, self.pg7)
3060 pkts = self.create_stream_in(self.pg7, self.pg8)
3061 self.pg7.add_stream(pkts)
3062 self.pg_enable_capture(self.pg_interfaces)
3064 capture = self.pg8.get_capture(len(pkts))
3065 self.verify_capture_out(capture, self.nat_addr, True)
3067 def test_static_with_port_ipless_interfaces(self):
3068 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3070 self.tcp_port_out = 30606
3071 self.udp_port_out = 30607
3072 self.icmp_id_out = 30608
3074 self.create_routes_and_neigbors()
3075 self.nat44_add_address(self.nat_addr)
3076 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3077 self.tcp_port_in, self.tcp_port_out,
3078 proto=IP_PROTOS.tcp)
3079 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3080 self.udp_port_in, self.udp_port_out,
3081 proto=IP_PROTOS.udp)
3082 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3083 self.icmp_id_in, self.icmp_id_out,
3084 proto=IP_PROTOS.icmp)
3085 flags = self.config_flags.NAT_IS_INSIDE
3086 self.vapi.nat44_interface_add_del_feature(
3087 sw_if_index=self.pg7.sw_if_index,
3088 flags=flags, is_add=1)
3089 self.vapi.nat44_interface_add_del_feature(
3090 sw_if_index=self.pg8.sw_if_index,
3094 pkts = self.create_stream_out(self.pg8)
3095 self.pg8.add_stream(pkts)
3096 self.pg_enable_capture(self.pg_interfaces)
3098 capture = self.pg7.get_capture(len(pkts))
3099 self.verify_capture_in(capture, self.pg7)
3102 pkts = self.create_stream_in(self.pg7, self.pg8)
3103 self.pg7.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg8.get_capture(len(pkts))
3107 self.verify_capture_out(capture)
3109 def test_static_unknown_proto(self):
3110 """ 1:1 NAT translate packet with unknown protocol """
3111 nat_ip = "10.0.0.10"
3112 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3113 flags = self.config_flags.NAT_IS_INSIDE
3114 self.vapi.nat44_interface_add_del_feature(
3115 sw_if_index=self.pg0.sw_if_index,
3116 flags=flags, is_add=1)
3117 self.vapi.nat44_interface_add_del_feature(
3118 sw_if_index=self.pg1.sw_if_index,
3122 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3123 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3125 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3126 TCP(sport=1234, dport=1234))
3127 self.pg0.add_stream(p)
3128 self.pg_enable_capture(self.pg_interfaces)
3130 p = self.pg1.get_capture(1)
3133 self.assertEqual(packet[IP].src, nat_ip)
3134 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3135 self.assertEqual(packet.haslayer(GRE), 1)
3136 self.assert_packet_checksums_valid(packet)
3138 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3142 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3143 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3145 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3146 TCP(sport=1234, dport=1234))
3147 self.pg1.add_stream(p)
3148 self.pg_enable_capture(self.pg_interfaces)
3150 p = self.pg0.get_capture(1)
3153 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3154 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3155 self.assertEqual(packet.haslayer(GRE), 1)
3156 self.assert_packet_checksums_valid(packet)
3158 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3161 def test_hairpinning_static_unknown_proto(self):
3162 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3164 host = self.pg0.remote_hosts[0]
3165 server = self.pg0.remote_hosts[1]
3167 host_nat_ip = "10.0.0.10"
3168 server_nat_ip = "10.0.0.11"
3170 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3171 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3172 flags = self.config_flags.NAT_IS_INSIDE
3173 self.vapi.nat44_interface_add_del_feature(
3174 sw_if_index=self.pg0.sw_if_index,
3175 flags=flags, is_add=1)
3176 self.vapi.nat44_interface_add_del_feature(
3177 sw_if_index=self.pg1.sw_if_index,
3181 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3182 IP(src=host.ip4, dst=server_nat_ip) /
3184 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3185 TCP(sport=1234, dport=1234))
3186 self.pg0.add_stream(p)
3187 self.pg_enable_capture(self.pg_interfaces)
3189 p = self.pg0.get_capture(1)
3192 self.assertEqual(packet[IP].src, host_nat_ip)
3193 self.assertEqual(packet[IP].dst, server.ip4)
3194 self.assertEqual(packet.haslayer(GRE), 1)
3195 self.assert_packet_checksums_valid(packet)
3197 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3201 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3202 IP(src=server.ip4, dst=host_nat_ip) /
3204 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3205 TCP(sport=1234, dport=1234))
3206 self.pg0.add_stream(p)
3207 self.pg_enable_capture(self.pg_interfaces)
3209 p = self.pg0.get_capture(1)
3212 self.assertEqual(packet[IP].src, server_nat_ip)
3213 self.assertEqual(packet[IP].dst, host.ip4)
3214 self.assertEqual(packet.haslayer(GRE), 1)
3215 self.assert_packet_checksums_valid(packet)
3217 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3220 def test_output_feature(self):
3221 """ NAT44 interface output feature (in2out postrouting) """
3222 self.nat44_add_address(self.nat_addr)
3223 flags = self.config_flags.NAT_IS_INSIDE
3224 self.vapi.nat44_interface_add_del_output_feature(
3225 is_add=1, flags=flags,
3226 sw_if_index=self.pg0.sw_if_index)
3227 self.vapi.nat44_interface_add_del_output_feature(
3228 is_add=1, flags=flags,
3229 sw_if_index=self.pg1.sw_if_index)
3230 self.vapi.nat44_interface_add_del_output_feature(
3232 sw_if_index=self.pg3.sw_if_index)
3235 pkts = self.create_stream_in(self.pg0, self.pg3)
3236 self.pg0.add_stream(pkts)
3237 self.pg_enable_capture(self.pg_interfaces)
3239 capture = self.pg3.get_capture(len(pkts))
3240 self.verify_capture_out(capture)
3243 pkts = self.create_stream_out(self.pg3)
3244 self.pg3.add_stream(pkts)
3245 self.pg_enable_capture(self.pg_interfaces)
3247 capture = self.pg0.get_capture(len(pkts))
3248 self.verify_capture_in(capture, self.pg0)
3250 # from non-NAT interface to NAT inside interface
3251 pkts = self.create_stream_in(self.pg2, self.pg0)
3252 self.pg2.add_stream(pkts)
3253 self.pg_enable_capture(self.pg_interfaces)
3255 capture = self.pg0.get_capture(len(pkts))
3256 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3258 def test_output_feature_vrf_aware(self):
3259 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3260 nat_ip_vrf10 = "10.0.0.10"
3261 nat_ip_vrf20 = "10.0.0.20"
3263 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3264 [VppRoutePath(self.pg3.remote_ip4,
3265 self.pg3.sw_if_index)],
3267 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3268 [VppRoutePath(self.pg3.remote_ip4,
3269 self.pg3.sw_if_index)],
3274 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3275 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3276 flags = self.config_flags.NAT_IS_INSIDE
3277 self.vapi.nat44_interface_add_del_output_feature(
3278 is_add=1, flags=flags,
3279 sw_if_index=self.pg4.sw_if_index)
3280 self.vapi.nat44_interface_add_del_output_feature(
3281 is_add=1, flags=flags,
3282 sw_if_index=self.pg6.sw_if_index)
3283 self.vapi.nat44_interface_add_del_output_feature(
3285 sw_if_index=self.pg3.sw_if_index)
3288 pkts = self.create_stream_in(self.pg4, self.pg3)
3289 self.pg4.add_stream(pkts)
3290 self.pg_enable_capture(self.pg_interfaces)
3292 capture = self.pg3.get_capture(len(pkts))
3293 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3296 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3297 self.pg3.add_stream(pkts)
3298 self.pg_enable_capture(self.pg_interfaces)
3300 capture = self.pg4.get_capture(len(pkts))
3301 self.verify_capture_in(capture, self.pg4)
3304 pkts = self.create_stream_in(self.pg6, self.pg3)
3305 self.pg6.add_stream(pkts)
3306 self.pg_enable_capture(self.pg_interfaces)
3308 capture = self.pg3.get_capture(len(pkts))
3309 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3312 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3313 self.pg3.add_stream(pkts)
3314 self.pg_enable_capture(self.pg_interfaces)
3316 capture = self.pg6.get_capture(len(pkts))
3317 self.verify_capture_in(capture, self.pg6)
3319 def test_output_feature_hairpinning(self):
3320 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3321 host = self.pg0.remote_hosts[0]
3322 server = self.pg0.remote_hosts[1]
3325 server_in_port = 5678
3326 server_out_port = 8765
3328 self.nat44_add_address(self.nat_addr)
3329 flags = self.config_flags.NAT_IS_INSIDE
3330 self.vapi.nat44_interface_add_del_output_feature(
3331 is_add=1, flags=flags,
3332 sw_if_index=self.pg0.sw_if_index)
3333 self.vapi.nat44_interface_add_del_output_feature(
3335 sw_if_index=self.pg1.sw_if_index)
3337 # add static mapping for server
3338 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3339 server_in_port, server_out_port,
3340 proto=IP_PROTOS.tcp)
3342 # send packet from host to server
3343 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3344 IP(src=host.ip4, dst=self.nat_addr) /
3345 TCP(sport=host_in_port, dport=server_out_port))
3346 self.pg0.add_stream(p)
3347 self.pg_enable_capture(self.pg_interfaces)
3349 capture = self.pg0.get_capture(1)
3354 self.assertEqual(ip.src, self.nat_addr)
3355 self.assertEqual(ip.dst, server.ip4)
3356 self.assertNotEqual(tcp.sport, host_in_port)
3357 self.assertEqual(tcp.dport, server_in_port)
3358 self.assert_packet_checksums_valid(p)
3359 host_out_port = tcp.sport
3361 self.logger.error(ppp("Unexpected or invalid packet:", p))
3364 # send reply from server to host
3365 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3366 IP(src=server.ip4, dst=self.nat_addr) /
3367 TCP(sport=server_in_port, dport=host_out_port))
3368 self.pg0.add_stream(p)
3369 self.pg_enable_capture(self.pg_interfaces)
3371 capture = self.pg0.get_capture(1)
3376 self.assertEqual(ip.src, self.nat_addr)
3377 self.assertEqual(ip.dst, host.ip4)
3378 self.assertEqual(tcp.sport, server_out_port)
3379 self.assertEqual(tcp.dport, host_in_port)
3380 self.assert_packet_checksums_valid(p)
3382 self.logger.error(ppp("Unexpected or invalid packet:", p))
3385 def test_one_armed_nat44(self):
3386 """ One armed NAT44 """
3387 remote_host = self.pg9.remote_hosts[0]
3388 local_host = self.pg9.remote_hosts[1]
3391 self.nat44_add_address(self.nat_addr)
3392 flags = self.config_flags.NAT_IS_INSIDE
3393 self.vapi.nat44_interface_add_del_feature(
3394 sw_if_index=self.pg9.sw_if_index,
3396 self.vapi.nat44_interface_add_del_feature(
3397 sw_if_index=self.pg9.sw_if_index,
3398 flags=flags, is_add=1)
3401 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3402 IP(src=local_host.ip4, dst=remote_host.ip4) /
3403 TCP(sport=12345, dport=80))
3404 self.pg9.add_stream(p)
3405 self.pg_enable_capture(self.pg_interfaces)
3407 capture = self.pg9.get_capture(1)
3412 self.assertEqual(ip.src, self.nat_addr)
3413 self.assertEqual(ip.dst, remote_host.ip4)
3414 self.assertNotEqual(tcp.sport, 12345)
3415 external_port = tcp.sport
3416 self.assertEqual(tcp.dport, 80)
3417 self.assert_packet_checksums_valid(p)
3419 self.logger.error(ppp("Unexpected or invalid packet:", p))
3423 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3424 IP(src=remote_host.ip4, dst=self.nat_addr) /
3425 TCP(sport=80, dport=external_port))
3426 self.pg9.add_stream(p)
3427 self.pg_enable_capture(self.pg_interfaces)
3429 capture = self.pg9.get_capture(1)
3434 self.assertEqual(ip.src, remote_host.ip4)
3435 self.assertEqual(ip.dst, local_host.ip4)
3436 self.assertEqual(tcp.sport, 80)
3437 self.assertEqual(tcp.dport, 12345)
3438 self.assert_packet_checksums_valid(p)
3440 self.logger.error(ppp("Unexpected or invalid packet:", p))
3443 err = self.statistics.get_err_counter(
3444 '/err/nat44-classify/next in2out')
3445 self.assertEqual(err, 1)
3446 err = self.statistics.get_err_counter(
3447 '/err/nat44-classify/next out2in')
3448 self.assertEqual(err, 1)
3450 def test_del_session(self):
3451 """ Delete NAT44 session """
3452 self.nat44_add_address(self.nat_addr)
3453 flags = self.config_flags.NAT_IS_INSIDE
3454 self.vapi.nat44_interface_add_del_feature(
3455 sw_if_index=self.pg0.sw_if_index,
3456 flags=flags, is_add=1)
3457 self.vapi.nat44_interface_add_del_feature(
3458 sw_if_index=self.pg1.sw_if_index,
3461 pkts = self.create_stream_in(self.pg0, self.pg1)
3462 self.pg0.add_stream(pkts)
3463 self.pg_enable_capture(self.pg_interfaces)
3465 self.pg1.get_capture(len(pkts))
3467 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3468 nsessions = len(sessions)
3470 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3471 port=sessions[0].inside_port,
3472 protocol=sessions[0].protocol,
3473 flags=self.config_flags.NAT_IS_INSIDE)
3474 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3475 port=sessions[1].outside_port,
3476 protocol=sessions[1].protocol)
3478 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3479 self.assertEqual(nsessions - len(sessions), 2)
3481 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3482 port=sessions[0].inside_port,
3483 protocol=sessions[0].protocol,
3484 flags=self.config_flags.NAT_IS_INSIDE)
3486 self.verify_no_nat44_user()
3488 def test_frag_in_order(self):
3489 """ NAT44 translate fragments arriving in order """
3491 self.nat44_add_address(self.nat_addr)
3492 flags = self.config_flags.NAT_IS_INSIDE
3493 self.vapi.nat44_interface_add_del_feature(
3494 sw_if_index=self.pg0.sw_if_index,
3495 flags=flags, is_add=1)
3496 self.vapi.nat44_interface_add_del_feature(
3497 sw_if_index=self.pg1.sw_if_index,
3500 self.frag_in_order(proto=IP_PROTOS.tcp)
3501 self.frag_in_order(proto=IP_PROTOS.udp)
3502 self.frag_in_order(proto=IP_PROTOS.icmp)
3504 def test_frag_forwarding(self):
3505 """ NAT44 forwarding fragment test """
3506 self.vapi.nat44_add_del_interface_addr(
3508 sw_if_index=self.pg1.sw_if_index)
3509 flags = self.config_flags.NAT_IS_INSIDE
3510 self.vapi.nat44_interface_add_del_feature(
3511 sw_if_index=self.pg0.sw_if_index,
3512 flags=flags, is_add=1)
3513 self.vapi.nat44_interface_add_del_feature(
3514 sw_if_index=self.pg1.sw_if_index,
3516 self.vapi.nat44_forwarding_enable_disable(enable=1)
3518 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3519 pkts = self.create_stream_frag(self.pg1,
3520 self.pg0.remote_ip4,
3524 proto=IP_PROTOS.udp)
3525 self.pg1.add_stream(pkts)
3526 self.pg_enable_capture(self.pg_interfaces)
3528 frags = self.pg0.get_capture(len(pkts))
3529 p = self.reass_frags_and_verify(frags,
3530 self.pg1.remote_ip4,
3531 self.pg0.remote_ip4)
3532 self.assertEqual(p[UDP].sport, 4789)
3533 self.assertEqual(p[UDP].dport, 4789)
3534 self.assertEqual(data, p[Raw].load)
3536 def test_reass_hairpinning(self):
3537 """ NAT44 fragments hairpinning """
3539 self.server = self.pg0.remote_hosts[1]
3540 self.host_in_port = random.randint(1025, 65535)
3541 self.server_in_port = random.randint(1025, 65535)
3542 self.server_out_port = random.randint(1025, 65535)
3544 self.nat44_add_address(self.nat_addr)
3545 flags = self.config_flags.NAT_IS_INSIDE
3546 self.vapi.nat44_interface_add_del_feature(
3547 sw_if_index=self.pg0.sw_if_index,
3548 flags=flags, is_add=1)
3549 self.vapi.nat44_interface_add_del_feature(
3550 sw_if_index=self.pg1.sw_if_index,
3552 # add static mapping for server
3553 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3554 self.server_in_port,
3555 self.server_out_port,
3556 proto=IP_PROTOS.tcp)
3557 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3558 self.server_in_port,
3559 self.server_out_port,
3560 proto=IP_PROTOS.udp)
3561 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3563 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3564 self.reass_hairpinning(proto=IP_PROTOS.udp)
3565 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3567 def test_frag_out_of_order(self):
3568 """ NAT44 translate fragments arriving out of order """
3570 self.nat44_add_address(self.nat_addr)
3571 flags = self.config_flags.NAT_IS_INSIDE
3572 self.vapi.nat44_interface_add_del_feature(
3573 sw_if_index=self.pg0.sw_if_index,
3574 flags=flags, is_add=1)
3575 self.vapi.nat44_interface_add_del_feature(
3576 sw_if_index=self.pg1.sw_if_index,
3579 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3580 self.frag_out_of_order(proto=IP_PROTOS.udp)
3581 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3583 def test_port_restricted(self):
3584 """ Port restricted NAT44 (MAP-E CE) """
3585 self.nat44_add_address(self.nat_addr)
3586 flags = self.config_flags.NAT_IS_INSIDE
3587 self.vapi.nat44_interface_add_del_feature(
3588 sw_if_index=self.pg0.sw_if_index,
3589 flags=flags, is_add=1)
3590 self.vapi.nat44_interface_add_del_feature(
3591 sw_if_index=self.pg1.sw_if_index,
3593 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3598 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3599 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3600 TCP(sport=4567, dport=22))
3601 self.pg0.add_stream(p)
3602 self.pg_enable_capture(self.pg_interfaces)
3604 capture = self.pg1.get_capture(1)
3609 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3610 self.assertEqual(ip.src, self.nat_addr)
3611 self.assertEqual(tcp.dport, 22)
3612 self.assertNotEqual(tcp.sport, 4567)
3613 self.assertEqual((tcp.sport >> 6) & 63, 10)
3614 self.assert_packet_checksums_valid(p)
3616 self.logger.error(ppp("Unexpected or invalid packet:", p))
3619 def test_port_range(self):
3620 """ External address port range """
3621 self.nat44_add_address(self.nat_addr)
3622 flags = self.config_flags.NAT_IS_INSIDE
3623 self.vapi.nat44_interface_add_del_feature(
3624 sw_if_index=self.pg0.sw_if_index,
3625 flags=flags, is_add=1)
3626 self.vapi.nat44_interface_add_del_feature(
3627 sw_if_index=self.pg1.sw_if_index,
3629 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3634 for port in range(0, 5):
3635 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3636 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3637 TCP(sport=1125 + port))
3639 self.pg0.add_stream(pkts)
3640 self.pg_enable_capture(self.pg_interfaces)
3642 capture = self.pg1.get_capture(3)
3645 self.assertGreaterEqual(tcp.sport, 1025)
3646 self.assertLessEqual(tcp.sport, 1027)
3648 def test_multiple_outside_vrf(self):
3649 """ Multiple outside VRF """
3653 self.pg1.unconfig_ip4()
3654 self.pg2.unconfig_ip4()
3655 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3656 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3657 self.pg1.set_table_ip4(vrf_id1)
3658 self.pg2.set_table_ip4(vrf_id2)
3659 self.pg1.config_ip4()
3660 self.pg2.config_ip4()
3661 self.pg1.resolve_arp()
3662 self.pg2.resolve_arp()
3664 self.nat44_add_address(self.nat_addr)
3665 flags = self.config_flags.NAT_IS_INSIDE
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg0.sw_if_index,
3668 flags=flags, is_add=1)
3669 self.vapi.nat44_interface_add_del_feature(
3670 sw_if_index=self.pg1.sw_if_index,
3672 self.vapi.nat44_interface_add_del_feature(
3673 sw_if_index=self.pg2.sw_if_index,
3678 pkts = self.create_stream_in(self.pg0, self.pg1)
3679 self.pg0.add_stream(pkts)
3680 self.pg_enable_capture(self.pg_interfaces)
3682 capture = self.pg1.get_capture(len(pkts))
3683 self.verify_capture_out(capture, self.nat_addr)
3685 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3686 self.pg1.add_stream(pkts)
3687 self.pg_enable_capture(self.pg_interfaces)
3689 capture = self.pg0.get_capture(len(pkts))
3690 self.verify_capture_in(capture, self.pg0)
3692 self.tcp_port_in = 60303
3693 self.udp_port_in = 60304
3694 self.icmp_id_in = 60305
3697 pkts = self.create_stream_in(self.pg0, self.pg2)
3698 self.pg0.add_stream(pkts)
3699 self.pg_enable_capture(self.pg_interfaces)
3701 capture = self.pg2.get_capture(len(pkts))
3702 self.verify_capture_out(capture, self.nat_addr)
3704 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3705 self.pg2.add_stream(pkts)
3706 self.pg_enable_capture(self.pg_interfaces)
3708 capture = self.pg0.get_capture(len(pkts))
3709 self.verify_capture_in(capture, self.pg0)
3712 self.nat44_add_address(self.nat_addr, is_add=0)
3713 self.pg1.unconfig_ip4()
3714 self.pg2.unconfig_ip4()
3715 self.pg1.set_table_ip4(0)
3716 self.pg2.set_table_ip4(0)
3717 self.pg1.config_ip4()
3718 self.pg2.config_ip4()
3719 self.pg1.resolve_arp()
3720 self.pg2.resolve_arp()
3722 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3723 def test_session_timeout(self):
3724 """ NAT44 session timeouts """
3725 self.nat44_add_address(self.nat_addr)
3726 flags = self.config_flags.NAT_IS_INSIDE
3727 self.vapi.nat44_interface_add_del_feature(
3728 sw_if_index=self.pg0.sw_if_index,
3729 flags=flags, is_add=1)
3730 self.vapi.nat44_interface_add_del_feature(
3731 sw_if_index=self.pg1.sw_if_index,
3733 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3734 tcp_transitory=240, icmp=60)
3738 for i in range(0, max_sessions):
3739 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3740 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3741 IP(src=src, dst=self.pg1.remote_ip4) /
3742 UDP(sport=1025, dport=53))
3744 self.pg0.add_stream(pkts)
3745 self.pg_enable_capture(self.pg_interfaces)
3747 self.pg1.get_capture(max_sessions)
3752 for i in range(0, max_sessions):
3753 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3754 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3755 IP(src=src, dst=self.pg1.remote_ip4) /
3756 UDP(sport=1026, dport=53))
3758 self.pg0.add_stream(pkts)
3759 self.pg_enable_capture(self.pg_interfaces)
3761 self.pg1.get_capture(max_sessions)
3764 users = self.vapi.nat44_user_dump()
3766 nsessions = nsessions + user.nsessions
3767 self.assertLess(nsessions, 2 * max_sessions)
3769 def test_mss_clamping(self):
3770 """ TCP MSS clamping """
3771 self.nat44_add_address(self.nat_addr)
3772 flags = self.config_flags.NAT_IS_INSIDE
3773 self.vapi.nat44_interface_add_del_feature(
3774 sw_if_index=self.pg0.sw_if_index,
3775 flags=flags, is_add=1)
3776 self.vapi.nat44_interface_add_del_feature(
3777 sw_if_index=self.pg1.sw_if_index,
3780 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3781 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3782 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3783 flags="S", options=[('MSS', 1400)]))
3785 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3786 self.pg0.add_stream(p)
3787 self.pg_enable_capture(self.pg_interfaces)
3789 capture = self.pg1.get_capture(1)
3790 # Negotiated MSS value greater than configured - changed
3791 self.verify_mss_value(capture[0], 1000)
3793 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3794 self.pg0.add_stream(p)
3795 self.pg_enable_capture(self.pg_interfaces)
3797 capture = self.pg1.get_capture(1)
3798 # MSS clamping disabled - negotiated MSS unchanged
3799 self.verify_mss_value(capture[0], 1400)
3801 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3802 self.pg0.add_stream(p)
3803 self.pg_enable_capture(self.pg_interfaces)
3805 capture = self.pg1.get_capture(1)
3806 # Negotiated MSS value smaller than configured - unchanged
3807 self.verify_mss_value(capture[0], 1400)
3809 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3810 def test_ha_send(self):
3811 """ Send HA session synchronization events (active) """
3812 self.nat44_add_address(self.nat_addr)
3813 flags = self.config_flags.NAT_IS_INSIDE
3814 self.vapi.nat44_interface_add_del_feature(
3815 sw_if_index=self.pg0.sw_if_index,
3816 flags=flags, is_add=1)
3817 self.vapi.nat44_interface_add_del_feature(
3818 sw_if_index=self.pg1.sw_if_index,
3820 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3823 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3824 port=12346, session_refresh_interval=10)
3825 bind_layers(UDP, HANATStateSync, sport=12345)
3828 pkts = self.create_stream_in(self.pg0, self.pg1)
3829 self.pg0.add_stream(pkts)
3830 self.pg_enable_capture(self.pg_interfaces)
3832 capture = self.pg1.get_capture(len(pkts))
3833 self.verify_capture_out(capture)
3834 # active send HA events
3835 self.vapi.nat_ha_flush()
3836 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3837 self.assertEqual(stats[0][0], 3)
3838 capture = self.pg3.get_capture(1)
3840 self.assert_packet_checksums_valid(p)
3844 hanat = p[HANATStateSync]
3846 self.logger.error(ppp("Invalid packet:", p))
3849 self.assertEqual(ip.src, self.pg3.local_ip4)
3850 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3851 self.assertEqual(udp.sport, 12345)
3852 self.assertEqual(udp.dport, 12346)
3853 self.assertEqual(hanat.version, 1)
3854 self.assertEqual(hanat.thread_index, 0)
3855 self.assertEqual(hanat.count, 3)
3856 seq = hanat.sequence_number
3857 for event in hanat.events:
3858 self.assertEqual(event.event_type, 1)
3859 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3860 self.assertEqual(event.out_addr, self.nat_addr)
3861 self.assertEqual(event.fib_index, 0)
3863 # ACK received events
3864 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3865 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3866 UDP(sport=12346, dport=12345) /
3867 HANATStateSync(sequence_number=seq, flags='ACK'))
3868 self.pg3.add_stream(ack)
3870 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3871 self.assertEqual(stats[0][0], 1)
3873 # delete one session
3874 self.pg_enable_capture(self.pg_interfaces)
3875 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3876 port=self.tcp_port_in,
3877 protocol=IP_PROTOS.tcp,
3878 flags=self.config_flags.NAT_IS_INSIDE)
3879 self.vapi.nat_ha_flush()
3880 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3881 self.assertEqual(stats[0][0], 1)
3882 capture = self.pg3.get_capture(1)
3885 hanat = p[HANATStateSync]
3887 self.logger.error(ppp("Invalid packet:", p))
3890 self.assertGreater(hanat.sequence_number, seq)
3892 # do not send ACK, active retry send HA event again
3893 self.pg_enable_capture(self.pg_interfaces)
3895 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3896 self.assertEqual(stats[0][0], 3)
3897 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3898 self.assertEqual(stats[0][0], 1)
3899 capture = self.pg3.get_capture(3)
3900 for packet in capture:
3901 self.assertEqual(packet, p)
3903 # session counters refresh
3904 pkts = self.create_stream_out(self.pg1)
3905 self.pg1.add_stream(pkts)
3906 self.pg_enable_capture(self.pg_interfaces)
3908 self.pg0.get_capture(2)
3909 self.vapi.nat_ha_flush()
3910 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3911 self.assertEqual(stats[0][0], 2)
3912 capture = self.pg3.get_capture(1)
3914 self.assert_packet_checksums_valid(p)
3918 hanat = p[HANATStateSync]
3920 self.logger.error(ppp("Invalid packet:", p))
3923 self.assertEqual(ip.src, self.pg3.local_ip4)
3924 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3925 self.assertEqual(udp.sport, 12345)
3926 self.assertEqual(udp.dport, 12346)
3927 self.assertEqual(hanat.version, 1)
3928 self.assertEqual(hanat.count, 2)
3929 seq = hanat.sequence_number
3930 for event in hanat.events:
3931 self.assertEqual(event.event_type, 3)
3932 self.assertEqual(event.out_addr, self.nat_addr)
3933 self.assertEqual(event.fib_index, 0)
3934 self.assertEqual(event.total_pkts, 2)
3935 self.assertGreater(event.total_bytes, 0)
3937 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3938 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3939 UDP(sport=12346, dport=12345) /
3940 HANATStateSync(sequence_number=seq, flags='ACK'))
3941 self.pg3.add_stream(ack)
3943 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3944 self.assertEqual(stats[0][0], 2)
3946 def test_ha_recv(self):
3947 """ Receive HA session synchronization events (passive) """
3948 self.nat44_add_address(self.nat_addr)
3949 flags = self.config_flags.NAT_IS_INSIDE
3950 self.vapi.nat44_interface_add_del_feature(
3951 sw_if_index=self.pg0.sw_if_index,
3952 flags=flags, is_add=1)
3953 self.vapi.nat44_interface_add_del_feature(
3954 sw_if_index=self.pg1.sw_if_index,
3956 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3959 bind_layers(UDP, HANATStateSync, sport=12345)
3961 self.tcp_port_out = random.randint(1025, 65535)
3962 self.udp_port_out = random.randint(1025, 65535)
3964 # send HA session add events to failover/passive
3965 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3966 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3967 UDP(sport=12346, dport=12345) /
3968 HANATStateSync(sequence_number=1, events=[
3969 Event(event_type='add', protocol='tcp',
3970 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3971 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
3972 eh_addr=self.pg1.remote_ip4,
3973 ehn_addr=self.pg1.remote_ip4,
3974 eh_port=self.tcp_external_port,
3975 ehn_port=self.tcp_external_port, fib_index=0),
3976 Event(event_type='add', protocol='udp',
3977 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
3978 in_port=self.udp_port_in, out_port=self.udp_port_out,
3979 eh_addr=self.pg1.remote_ip4,
3980 ehn_addr=self.pg1.remote_ip4,
3981 eh_port=self.udp_external_port,
3982 ehn_port=self.udp_external_port, fib_index=0)]))
3984 self.pg3.add_stream(p)
3985 self.pg_enable_capture(self.pg_interfaces)
3988 capture = self.pg3.get_capture(1)
3991 hanat = p[HANATStateSync]
3993 self.logger.error(ppp("Invalid packet:", p))
3996 self.assertEqual(hanat.sequence_number, 1)
3997 self.assertEqual(hanat.flags, 'ACK')
3998 self.assertEqual(hanat.version, 1)
3999 self.assertEqual(hanat.thread_index, 0)
4000 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4001 self.assertEqual(stats[0][0], 1)
4002 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4003 self.assertEqual(stats[0][0], 2)
4004 users = self.statistics.get_counter('/nat44/total-users')
4005 self.assertEqual(users[0][0], 1)
4006 sessions = self.statistics.get_counter('/nat44/total-sessions')
4007 self.assertEqual(sessions[0][0], 2)
4008 users = self.vapi.nat44_user_dump()
4009 self.assertEqual(len(users), 1)
4010 self.assertEqual(str(users[0].ip_address),
4011 self.pg0.remote_ip4)
4012 # there should be 2 sessions created by HA
4013 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4015 self.assertEqual(len(sessions), 2)
4016 for session in sessions:
4017 self.assertEqual(str(session.inside_ip_address),
4018 self.pg0.remote_ip4)
4019 self.assertEqual(str(session.outside_ip_address),
4021 self.assertIn(session.inside_port,
4022 [self.tcp_port_in, self.udp_port_in])
4023 self.assertIn(session.outside_port,
4024 [self.tcp_port_out, self.udp_port_out])
4025 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4027 # send HA session delete event to failover/passive
4028 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4029 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4030 UDP(sport=12346, dport=12345) /
4031 HANATStateSync(sequence_number=2, events=[
4032 Event(event_type='del', protocol='udp',
4033 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4034 in_port=self.udp_port_in, out_port=self.udp_port_out,
4035 eh_addr=self.pg1.remote_ip4,
4036 ehn_addr=self.pg1.remote_ip4,
4037 eh_port=self.udp_external_port,
4038 ehn_port=self.udp_external_port, fib_index=0)]))
4040 self.pg3.add_stream(p)
4041 self.pg_enable_capture(self.pg_interfaces)
4044 capture = self.pg3.get_capture(1)
4047 hanat = p[HANATStateSync]
4049 self.logger.error(ppp("Invalid packet:", p))
4052 self.assertEqual(hanat.sequence_number, 2)
4053 self.assertEqual(hanat.flags, 'ACK')
4054 self.assertEqual(hanat.version, 1)
4055 users = self.vapi.nat44_user_dump()
4056 self.assertEqual(len(users), 1)
4057 self.assertEqual(str(users[0].ip_address),
4058 self.pg0.remote_ip4)
4059 # now we should have only 1 session, 1 deleted by HA
4060 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4062 self.assertEqual(len(sessions), 1)
4063 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4064 self.assertEqual(stats[0][0], 1)
4066 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4067 self.assertEqual(stats, 2)
4069 # send HA session refresh event to failover/passive
4070 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4071 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4072 UDP(sport=12346, dport=12345) /
4073 HANATStateSync(sequence_number=3, events=[
4074 Event(event_type='refresh', protocol='tcp',
4075 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4076 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4077 eh_addr=self.pg1.remote_ip4,
4078 ehn_addr=self.pg1.remote_ip4,
4079 eh_port=self.tcp_external_port,
4080 ehn_port=self.tcp_external_port, fib_index=0,
4081 total_bytes=1024, total_pkts=2)]))
4082 self.pg3.add_stream(p)
4083 self.pg_enable_capture(self.pg_interfaces)
4086 capture = self.pg3.get_capture(1)
4089 hanat = p[HANATStateSync]
4091 self.logger.error(ppp("Invalid packet:", p))
4094 self.assertEqual(hanat.sequence_number, 3)
4095 self.assertEqual(hanat.flags, 'ACK')
4096 self.assertEqual(hanat.version, 1)
4097 users = self.vapi.nat44_user_dump()
4098 self.assertEqual(len(users), 1)
4099 self.assertEqual(str(users[0].ip_address),
4100 self.pg0.remote_ip4)
4101 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4103 self.assertEqual(len(sessions), 1)
4104 session = sessions[0]
4105 self.assertEqual(session.total_bytes, 1024)
4106 self.assertEqual(session.total_pkts, 2)
4107 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4108 self.assertEqual(stats[0][0], 1)
4110 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4111 self.assertEqual(stats, 3)
4113 # send packet to test session created by HA
4114 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4115 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4116 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4117 self.pg1.add_stream(p)
4118 self.pg_enable_capture(self.pg_interfaces)
4120 capture = self.pg0.get_capture(1)
4126 self.logger.error(ppp("Invalid packet:", p))
4129 self.assertEqual(ip.src, self.pg1.remote_ip4)
4130 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4131 self.assertEqual(tcp.sport, self.tcp_external_port)
4132 self.assertEqual(tcp.dport, self.tcp_port_in)
4135 super(TestNAT44, self).tearDown()
4137 self.vapi.cli("clear logging")
4139 def show_commands_at_teardown(self):
4140 self.logger.info(self.vapi.cli("show nat44 addresses"))
4141 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4142 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4143 self.logger.info(self.vapi.cli("show nat44 interface address"))
4144 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4145 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4146 self.logger.info(self.vapi.cli("show nat timeouts"))
4148 self.vapi.cli("show nat addr-port-assignment-alg"))
4149 self.logger.info(self.vapi.cli("show nat ha"))
4152 class TestNAT44EndpointDependent(MethodHolder):
4153 """ Endpoint-Dependent mapping and filtering test cases """
4156 def setUpConstants(cls):
4157 super(TestNAT44EndpointDependent, cls).setUpConstants()
4158 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4161 def setUpClass(cls):
4162 super(TestNAT44EndpointDependent, cls).setUpClass()
4163 cls.vapi.cli("set log class nat level debug")
4165 cls.tcp_port_in = 6303
4166 cls.tcp_port_out = 6303
4167 cls.udp_port_in = 6304
4168 cls.udp_port_out = 6304
4169 cls.icmp_id_in = 6305
4170 cls.icmp_id_out = 6305
4171 cls.nat_addr = '10.0.0.3'
4172 cls.ipfix_src_port = 4739
4173 cls.ipfix_domain_id = 1
4174 cls.tcp_external_port = 80
4176 cls.create_pg_interfaces(range(9))
4177 cls.interfaces = list(cls.pg_interfaces[0:3])
4179 for i in cls.interfaces:
4184 cls.pg0.generate_remote_hosts(3)
4185 cls.pg0.configure_ipv4_neighbors()
4189 cls.pg4.generate_remote_hosts(2)
4190 cls.pg4.config_ip4()
4191 cls.vapi.sw_interface_add_del_address(
4192 sw_if_index=cls.pg4.sw_if_index,
4193 prefix="10.0.0.1/24")
4196 cls.pg4.resolve_arp()
4197 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4198 cls.pg4.resolve_arp()
4200 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4201 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4203 cls.pg5._local_ip4 = "10.1.1.1"
4204 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4205 cls.pg5.set_table_ip4(1)
4206 cls.pg5.config_ip4()
4208 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4209 [VppRoutePath("0.0.0.0",
4210 cls.pg5.sw_if_index)],
4215 cls.pg6._local_ip4 = "10.1.2.1"
4216 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4217 cls.pg6.set_table_ip4(1)
4218 cls.pg6.config_ip4()
4221 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4222 [VppRoutePath("0.0.0.0",
4223 cls.pg6.sw_if_index)],
4226 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4227 [VppRoutePath("0.0.0.0",
4232 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4233 [VppRoutePath("0.0.0.0", 0xffffffff,
4237 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4238 [VppRoutePath(cls.pg1.local_ip4,
4239 cls.pg1.sw_if_index)],
4246 cls.pg5.resolve_arp()
4247 cls.pg6.resolve_arp()
4250 cls.pg7.config_ip4()
4251 cls.pg7.resolve_arp()
4252 cls.pg7.generate_remote_hosts(3)
4253 cls.pg7.configure_ipv4_neighbors()
4256 cls.pg8.config_ip4()
4257 cls.pg8.resolve_arp()
4260 super(TestNAT44EndpointDependent, self).setUp()
4261 self.vapi.nat_set_timeouts(
4262 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4265 def tearDownClass(cls):
4266 super(TestNAT44EndpointDependent, cls).tearDownClass()
4268 def test_frag_in_order(self):
4269 """ NAT44 translate fragments arriving in order """
4270 self.nat44_add_address(self.nat_addr)
4271 flags = self.config_flags.NAT_IS_INSIDE
4272 self.vapi.nat44_interface_add_del_feature(
4273 sw_if_index=self.pg0.sw_if_index,
4274 flags=flags, is_add=1)
4275 self.vapi.nat44_interface_add_del_feature(
4276 sw_if_index=self.pg1.sw_if_index,
4278 self.frag_in_order(proto=IP_PROTOS.tcp)
4279 self.frag_in_order(proto=IP_PROTOS.udp)
4280 self.frag_in_order(proto=IP_PROTOS.icmp)
4282 def test_frag_in_order_dont_translate(self):
4283 """ NAT44 don't translate fragments arriving in order """
4284 flags = self.config_flags.NAT_IS_INSIDE
4285 self.vapi.nat44_interface_add_del_feature(
4286 sw_if_index=self.pg0.sw_if_index,
4287 flags=flags, is_add=1)
4288 self.vapi.nat44_interface_add_del_feature(
4289 sw_if_index=self.pg1.sw_if_index,
4291 self.vapi.nat44_forwarding_enable_disable(enable=True)
4292 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4294 def test_frag_out_of_order(self):
4295 """ NAT44 translate fragments arriving out of order """
4296 self.nat44_add_address(self.nat_addr)
4297 flags = self.config_flags.NAT_IS_INSIDE
4298 self.vapi.nat44_interface_add_del_feature(
4299 sw_if_index=self.pg0.sw_if_index,
4300 flags=flags, is_add=1)
4301 self.vapi.nat44_interface_add_del_feature(
4302 sw_if_index=self.pg1.sw_if_index,
4304 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4305 self.frag_out_of_order(proto=IP_PROTOS.udp)
4306 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4308 def test_frag_out_of_order_dont_translate(self):
4309 """ NAT44 don't translate fragments arriving out of order """
4310 flags = self.config_flags.NAT_IS_INSIDE
4311 self.vapi.nat44_interface_add_del_feature(
4312 sw_if_index=self.pg0.sw_if_index,
4313 flags=flags, is_add=1)
4314 self.vapi.nat44_interface_add_del_feature(
4315 sw_if_index=self.pg1.sw_if_index,
4317 self.vapi.nat44_forwarding_enable_disable(enable=True)
4318 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4320 def test_frag_in_order_in_plus_out(self):
4321 """ in+out interface fragments in order """
4322 flags = self.config_flags.NAT_IS_INSIDE
4323 self.vapi.nat44_interface_add_del_feature(
4324 sw_if_index=self.pg0.sw_if_index,
4326 self.vapi.nat44_interface_add_del_feature(
4327 sw_if_index=self.pg0.sw_if_index,
4328 flags=flags, is_add=1)
4329 self.vapi.nat44_interface_add_del_feature(
4330 sw_if_index=self.pg1.sw_if_index,
4332 self.vapi.nat44_interface_add_del_feature(
4333 sw_if_index=self.pg1.sw_if_index,
4334 flags=flags, is_add=1)
4336 self.server = self.pg1.remote_hosts[0]
4338 self.server_in_addr = self.server.ip4
4339 self.server_out_addr = '11.11.11.11'
4340 self.server_in_port = random.randint(1025, 65535)
4341 self.server_out_port = random.randint(1025, 65535)
4343 self.nat44_add_address(self.server_out_addr)
4345 # add static mappings for server
4346 self.nat44_add_static_mapping(self.server_in_addr,
4347 self.server_out_addr,
4348 self.server_in_port,
4349 self.server_out_port,
4350 proto=IP_PROTOS.tcp)
4351 self.nat44_add_static_mapping(self.server_in_addr,
4352 self.server_out_addr,
4353 self.server_in_port,
4354 self.server_out_port,
4355 proto=IP_PROTOS.udp)
4356 self.nat44_add_static_mapping(self.server_in_addr,
4357 self.server_out_addr,
4358 proto=IP_PROTOS.icmp)
4360 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4361 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4362 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4364 def test_frag_out_of_order_in_plus_out(self):
4365 """ in+out interface fragments out of order """
4366 flags = self.config_flags.NAT_IS_INSIDE
4367 self.vapi.nat44_interface_add_del_feature(
4368 sw_if_index=self.pg0.sw_if_index,
4370 self.vapi.nat44_interface_add_del_feature(
4371 sw_if_index=self.pg0.sw_if_index,
4372 flags=flags, is_add=1)
4373 self.vapi.nat44_interface_add_del_feature(
4374 sw_if_index=self.pg1.sw_if_index,
4376 self.vapi.nat44_interface_add_del_feature(
4377 sw_if_index=self.pg1.sw_if_index,
4378 flags=flags, is_add=1)
4380 self.server = self.pg1.remote_hosts[0]
4382 self.server_in_addr = self.server.ip4
4383 self.server_out_addr = '11.11.11.11'
4384 self.server_in_port = random.randint(1025, 65535)
4385 self.server_out_port = random.randint(1025, 65535)
4387 self.nat44_add_address(self.server_out_addr)
4389 # add static mappings for server
4390 self.nat44_add_static_mapping(self.server_in_addr,
4391 self.server_out_addr,
4392 self.server_in_port,
4393 self.server_out_port,
4394 proto=IP_PROTOS.tcp)
4395 self.nat44_add_static_mapping(self.server_in_addr,
4396 self.server_out_addr,
4397 self.server_in_port,
4398 self.server_out_port,
4399 proto=IP_PROTOS.udp)
4400 self.nat44_add_static_mapping(self.server_in_addr,
4401 self.server_out_addr,
4402 proto=IP_PROTOS.icmp)
4404 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4405 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4406 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4408 def test_reass_hairpinning(self):
4409 """ NAT44 fragments hairpinning """
4410 self.server = self.pg0.remote_hosts[1]
4411 self.host_in_port = random.randint(1025, 65535)
4412 self.server_in_port = random.randint(1025, 65535)
4413 self.server_out_port = random.randint(1025, 65535)
4415 self.nat44_add_address(self.nat_addr)
4416 flags = self.config_flags.NAT_IS_INSIDE
4417 self.vapi.nat44_interface_add_del_feature(
4418 sw_if_index=self.pg0.sw_if_index,
4419 flags=flags, is_add=1)
4420 self.vapi.nat44_interface_add_del_feature(
4421 sw_if_index=self.pg1.sw_if_index,
4423 # add static mapping for server
4424 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4425 self.server_in_port,
4426 self.server_out_port,
4427 proto=IP_PROTOS.tcp)
4428 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4429 self.server_in_port,
4430 self.server_out_port,
4431 proto=IP_PROTOS.udp)
4432 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4434 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4435 self.reass_hairpinning(proto=IP_PROTOS.udp)
4436 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4438 def test_dynamic(self):
4439 """ NAT44 dynamic translation test """
4441 self.nat44_add_address(self.nat_addr)
4442 flags = self.config_flags.NAT_IS_INSIDE
4443 self.vapi.nat44_interface_add_del_feature(
4444 sw_if_index=self.pg0.sw_if_index,
4445 flags=flags, is_add=1)
4446 self.vapi.nat44_interface_add_del_feature(
4447 sw_if_index=self.pg1.sw_if_index,
4450 nat_config = self.vapi.nat_show_config()
4451 self.assertEqual(1, nat_config.endpoint_dependent)
4454 tcpn = self.statistics.get_err_counter(
4455 '/err/nat44-ed-in2out-slowpath/TCP packets')
4456 udpn = self.statistics.get_err_counter(
4457 '/err/nat44-ed-in2out-slowpath/UDP packets')
4458 icmpn = self.statistics.get_err_counter(
4459 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4460 totaln = self.statistics.get_err_counter(
4461 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4463 pkts = self.create_stream_in(self.pg0, self.pg1)
4464 self.pg0.add_stream(pkts)
4465 self.pg_enable_capture(self.pg_interfaces)
4467 capture = self.pg1.get_capture(len(pkts))
4468 self.verify_capture_out(capture)
4470 err = self.statistics.get_err_counter(
4471 '/err/nat44-ed-in2out-slowpath/TCP packets')
4472 self.assertEqual(err - tcpn, 2)
4473 err = self.statistics.get_err_counter(
4474 '/err/nat44-ed-in2out-slowpath/UDP packets')
4475 self.assertEqual(err - udpn, 1)
4476 err = self.statistics.get_err_counter(
4477 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4478 self.assertEqual(err - icmpn, 1)
4479 err = self.statistics.get_err_counter(
4480 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4481 self.assertEqual(err - totaln, 4)
4484 tcpn = self.statistics.get_err_counter(
4485 '/err/nat44-ed-out2in/TCP packets')
4486 udpn = self.statistics.get_err_counter(
4487 '/err/nat44-ed-out2in/UDP packets')
4488 icmpn = self.statistics.get_err_counter(
4489 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4490 totaln = self.statistics.get_err_counter(
4491 '/err/nat44-ed-out2in/good out2in packets processed')
4493 pkts = self.create_stream_out(self.pg1)
4494 self.pg1.add_stream(pkts)
4495 self.pg_enable_capture(self.pg_interfaces)
4497 capture = self.pg0.get_capture(len(pkts))
4498 self.verify_capture_in(capture, self.pg0)
4500 err = self.statistics.get_err_counter(
4501 '/err/nat44-ed-out2in/TCP packets')
4502 self.assertEqual(err - tcpn, 2)
4503 err = self.statistics.get_err_counter(
4504 '/err/nat44-ed-out2in/UDP packets')
4505 self.assertEqual(err - udpn, 1)
4506 err = self.statistics.get_err_counter(
4507 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4508 self.assertEqual(err - icmpn, 1)
4509 err = self.statistics.get_err_counter(
4510 '/err/nat44-ed-out2in/good out2in packets processed')
4511 self.assertEqual(err - totaln, 3)
4513 sessions = self.statistics.get_counter('/nat44/total-sessions')
4514 self.assertEqual(sessions[0][0], 3)
4516 def test_dynamic_output_feature_vrf(self):
4517 """ NAT44 dynamic translation test: output-feature, VRF"""
4519 # other then default (0)
4522 self.nat44_add_address(self.nat_addr)
4523 flags = self.config_flags.NAT_IS_INSIDE
4524 self.vapi.nat44_interface_add_del_output_feature(
4525 sw_if_index=self.pg7.sw_if_index,
4526 flags=flags, is_add=1)
4527 self.vapi.nat44_interface_add_del_output_feature(
4528 sw_if_index=self.pg8.sw_if_index,
4532 self.vapi.ip_table_add_del(is_add=1,
4533 table={'table_id': new_vrf_id})
4535 self.pg7.unconfig_ip4()
4536 self.pg7.set_table_ip4(new_vrf_id)
4537 self.pg7.config_ip4()
4538 self.pg7.resolve_arp()
4540 self.pg8.unconfig_ip4()
4541 self.pg8.set_table_ip4(new_vrf_id)
4542 self.pg8.config_ip4()
4543 self.pg8.resolve_arp()
4545 nat_config = self.vapi.nat_show_config()
4546 self.assertEqual(1, nat_config.endpoint_dependent)
4549 tcpn = self.statistics.get_err_counter(
4550 '/err/nat44-ed-in2out-slowpath/TCP packets')
4551 udpn = self.statistics.get_err_counter(
4552 '/err/nat44-ed-in2out-slowpath/UDP packets')
4553 icmpn = self.statistics.get_err_counter(
4554 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4555 totaln = self.statistics.get_err_counter(
4556 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4558 pkts = self.create_stream_in(self.pg7, self.pg8)
4559 self.pg7.add_stream(pkts)
4560 self.pg_enable_capture(self.pg_interfaces)
4562 capture = self.pg8.get_capture(len(pkts))
4563 self.verify_capture_out(capture)
4565 err = self.statistics.get_err_counter(
4566 '/err/nat44-ed-in2out-slowpath/TCP packets')
4567 self.assertEqual(err - tcpn, 2)
4568 err = self.statistics.get_err_counter(
4569 '/err/nat44-ed-in2out-slowpath/UDP packets')
4570 self.assertEqual(err - udpn, 1)
4571 err = self.statistics.get_err_counter(
4572 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4573 self.assertEqual(err - icmpn, 1)
4574 err = self.statistics.get_err_counter(
4575 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4576 self.assertEqual(err - totaln, 4)
4579 tcpn = self.statistics.get_err_counter(
4580 '/err/nat44-ed-out2in/TCP packets')
4581 udpn = self.statistics.get_err_counter(
4582 '/err/nat44-ed-out2in/UDP packets')
4583 icmpn = self.statistics.get_err_counter(
4584 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4585 totaln = self.statistics.get_err_counter(
4586 '/err/nat44-ed-out2in/good out2in packets processed')
4588 pkts = self.create_stream_out(self.pg8)
4589 self.pg8.add_stream(pkts)
4590 self.pg_enable_capture(self.pg_interfaces)
4592 capture = self.pg7.get_capture(len(pkts))
4593 self.verify_capture_in(capture, self.pg7)
4595 err = self.statistics.get_err_counter(
4596 '/err/nat44-ed-out2in/TCP packets')
4597 self.assertEqual(err - tcpn, 2)
4598 err = self.statistics.get_err_counter(
4599 '/err/nat44-ed-out2in/UDP packets')
4600 self.assertEqual(err - udpn, 1)
4601 err = self.statistics.get_err_counter(
4602 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4603 self.assertEqual(err - icmpn, 1)
4604 err = self.statistics.get_err_counter(
4605 '/err/nat44-ed-out2in/good out2in packets processed')
4606 self.assertEqual(err - totaln, 3)
4608 sessions = self.statistics.get_counter('/nat44/total-sessions')
4609 self.assertEqual(sessions[0][0], 3)
4612 self.pg7.unconfig_ip4()
4613 self.pg7.set_table_ip4(1)
4614 self.pg7.config_ip4()
4615 self.pg7.resolve_arp()
4617 self.pg8.unconfig_ip4()
4618 self.pg8.set_table_ip4(1)
4619 self.pg8.config_ip4()
4620 self.pg8.resolve_arp()
4622 self.vapi.ip_table_add_del(is_add=0,
4623 table={'table_id': new_vrf_id})
4625 def test_forwarding(self):
4626 """ NAT44 forwarding test """
4628 flags = self.config_flags.NAT_IS_INSIDE
4629 self.vapi.nat44_interface_add_del_feature(
4630 sw_if_index=self.pg0.sw_if_index,
4631 flags=flags, is_add=1)
4632 self.vapi.nat44_interface_add_del_feature(
4633 sw_if_index=self.pg1.sw_if_index,
4635 self.vapi.nat44_forwarding_enable_disable(enable=1)
4637 real_ip = self.pg0.remote_ip4
4638 alias_ip = self.nat_addr
4639 flags = self.config_flags.NAT_IS_ADDR_ONLY
4640 self.vapi.nat44_add_del_static_mapping(is_add=1,
4641 local_ip_address=real_ip,
4642 external_ip_address=alias_ip,
4643 external_sw_if_index=0xFFFFFFFF,
4647 # in2out - static mapping match
4649 pkts = self.create_stream_out(self.pg1)
4650 self.pg1.add_stream(pkts)
4651 self.pg_enable_capture(self.pg_interfaces)
4653 capture = self.pg0.get_capture(len(pkts))
4654 self.verify_capture_in(capture, self.pg0)
4656 pkts = self.create_stream_in(self.pg0, self.pg1)
4657 self.pg0.add_stream(pkts)
4658 self.pg_enable_capture(self.pg_interfaces)
4660 capture = self.pg1.get_capture(len(pkts))
4661 self.verify_capture_out(capture, same_port=True)
4663 # in2out - no static mapping match
4665 host0 = self.pg0.remote_hosts[0]
4666 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4668 pkts = self.create_stream_out(self.pg1,
4669 dst_ip=self.pg0.remote_ip4,
4670 use_inside_ports=True)
4671 self.pg1.add_stream(pkts)
4672 self.pg_enable_capture(self.pg_interfaces)
4674 capture = self.pg0.get_capture(len(pkts))
4675 self.verify_capture_in(capture, self.pg0)
4677 pkts = self.create_stream_in(self.pg0, self.pg1)
4678 self.pg0.add_stream(pkts)
4679 self.pg_enable_capture(self.pg_interfaces)
4681 capture = self.pg1.get_capture(len(pkts))
4682 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4685 self.pg0.remote_hosts[0] = host0
4687 user = self.pg0.remote_hosts[1]
4688 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4689 self.assertEqual(len(sessions), 3)
4690 self.assertTrue(sessions[0].flags &
4691 self.config_flags.NAT_IS_EXT_HOST_VALID)
4692 self.vapi.nat44_del_session(
4693 address=sessions[0].inside_ip_address,
4694 port=sessions[0].inside_port,
4695 protocol=sessions[0].protocol,
4696 flags=(self.config_flags.NAT_IS_INSIDE |
4697 self.config_flags.NAT_IS_EXT_HOST_VALID),
4698 ext_host_address=sessions[0].ext_host_address,
4699 ext_host_port=sessions[0].ext_host_port)
4700 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4701 self.assertEqual(len(sessions), 2)
4704 self.vapi.nat44_forwarding_enable_disable(enable=0)
4705 flags = self.config_flags.NAT_IS_ADDR_ONLY
4706 self.vapi.nat44_add_del_static_mapping(
4708 local_ip_address=real_ip,
4709 external_ip_address=alias_ip,
4710 external_sw_if_index=0xFFFFFFFF,
4713 def test_static_lb(self):
4714 """ NAT44 local service load balancing """
4715 external_addr_n = self.nat_addr
4718 server1 = self.pg0.remote_hosts[0]
4719 server2 = self.pg0.remote_hosts[1]
4721 locals = [{'addr': server1.ip4,
4725 {'addr': server2.ip4,
4730 self.nat44_add_address(self.nat_addr)
4731 self.vapi.nat44_add_del_lb_static_mapping(
4733 external_addr=external_addr_n,
4734 external_port=external_port,
4735 protocol=IP_PROTOS.tcp,
4736 local_num=len(locals),
4738 flags = self.config_flags.NAT_IS_INSIDE
4739 self.vapi.nat44_interface_add_del_feature(
4740 sw_if_index=self.pg0.sw_if_index,
4741 flags=flags, is_add=1)
4742 self.vapi.nat44_interface_add_del_feature(
4743 sw_if_index=self.pg1.sw_if_index,
4746 # from client to service
4747 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4748 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4749 TCP(sport=12345, dport=external_port))
4750 self.pg1.add_stream(p)
4751 self.pg_enable_capture(self.pg_interfaces)
4753 capture = self.pg0.get_capture(1)
4759 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4760 if ip.dst == server1.ip4:
4764 self.assertEqual(tcp.dport, local_port)
4765 self.assert_packet_checksums_valid(p)
4767 self.logger.error(ppp("Unexpected or invalid packet:", p))
4770 # from service back to client
4771 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4772 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4773 TCP(sport=local_port, dport=12345))
4774 self.pg0.add_stream(p)
4775 self.pg_enable_capture(self.pg_interfaces)
4777 capture = self.pg1.get_capture(1)
4782 self.assertEqual(ip.src, self.nat_addr)
4783 self.assertEqual(tcp.sport, external_port)
4784 self.assert_packet_checksums_valid(p)
4786 self.logger.error(ppp("Unexpected or invalid packet:", p))
4789 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4790 self.assertEqual(len(sessions), 1)
4791 self.assertTrue(sessions[0].flags &
4792 self.config_flags.NAT_IS_EXT_HOST_VALID)
4793 self.vapi.nat44_del_session(
4794 address=sessions[0].inside_ip_address,
4795 port=sessions[0].inside_port,
4796 protocol=sessions[0].protocol,
4797 flags=(self.config_flags.NAT_IS_INSIDE |
4798 self.config_flags.NAT_IS_EXT_HOST_VALID),
4799 ext_host_address=sessions[0].ext_host_address,
4800 ext_host_port=sessions[0].ext_host_port)
4801 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4802 self.assertEqual(len(sessions), 0)
4804 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4805 def test_static_lb_multi_clients(self):
4806 """ NAT44 local service load balancing - multiple clients"""
4808 external_addr = self.nat_addr
4811 server1 = self.pg0.remote_hosts[0]
4812 server2 = self.pg0.remote_hosts[1]
4813 server3 = self.pg0.remote_hosts[2]
4815 locals = [{'addr': server1.ip4,
4819 {'addr': server2.ip4,
4824 self.nat44_add_address(self.nat_addr)
4825 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4826 external_addr=external_addr,
4827 external_port=external_port,
4828 protocol=IP_PROTOS.tcp,
4829 local_num=len(locals),
4831 flags = self.config_flags.NAT_IS_INSIDE
4832 self.vapi.nat44_interface_add_del_feature(
4833 sw_if_index=self.pg0.sw_if_index,
4834 flags=flags, is_add=1)
4835 self.vapi.nat44_interface_add_del_feature(
4836 sw_if_index=self.pg1.sw_if_index,
4841 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4843 for client in clients:
4844 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4845 IP(src=client, dst=self.nat_addr) /
4846 TCP(sport=12345, dport=external_port))
4848 self.pg1.add_stream(pkts)
4849 self.pg_enable_capture(self.pg_interfaces)
4851 capture = self.pg0.get_capture(len(pkts))
4853 if p[IP].dst == server1.ip4:
4857 self.assertGreater(server1_n, server2_n)
4860 'addr': server3.ip4,
4867 self.vapi.nat44_lb_static_mapping_add_del_local(
4869 external_addr=external_addr,
4870 external_port=external_port,
4872 protocol=IP_PROTOS.tcp)
4876 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4878 for client in clients:
4879 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4880 IP(src=client, dst=self.nat_addr) /
4881 TCP(sport=12346, dport=external_port))
4883 self.assertGreater(len(pkts), 0)
4884 self.pg1.add_stream(pkts)
4885 self.pg_enable_capture(self.pg_interfaces)
4887 capture = self.pg0.get_capture(len(pkts))
4889 if p[IP].dst == server1.ip4:
4891 elif p[IP].dst == server2.ip4:
4895 self.assertGreater(server1_n, 0)
4896 self.assertGreater(server2_n, 0)
4897 self.assertGreater(server3_n, 0)
4900 'addr': server2.ip4,
4906 # remove one back-end
4907 self.vapi.nat44_lb_static_mapping_add_del_local(
4909 external_addr=external_addr,
4910 external_port=external_port,
4912 protocol=IP_PROTOS.tcp)
4916 self.pg1.add_stream(pkts)
4917 self.pg_enable_capture(self.pg_interfaces)
4919 capture = self.pg0.get_capture(len(pkts))
4921 if p[IP].dst == server1.ip4:
4923 elif p[IP].dst == server2.ip4:
4927 self.assertGreater(server1_n, 0)
4928 self.assertEqual(server2_n, 0)
4929 self.assertGreater(server3_n, 0)
4931 def test_static_lb_2(self):
4932 """ NAT44 local service load balancing (asymmetrical rule) """
4933 external_addr = self.nat_addr
4936 server1 = self.pg0.remote_hosts[0]
4937 server2 = self.pg0.remote_hosts[1]
4939 locals = [{'addr': server1.ip4,
4943 {'addr': server2.ip4,
4948 self.vapi.nat44_forwarding_enable_disable(enable=1)
4949 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
4950 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
4951 external_addr=external_addr,
4952 external_port=external_port,
4953 protocol=IP_PROTOS.tcp,
4954 local_num=len(locals),
4956 flags = self.config_flags.NAT_IS_INSIDE
4957 self.vapi.nat44_interface_add_del_feature(
4958 sw_if_index=self.pg0.sw_if_index,
4959 flags=flags, is_add=1)
4960 self.vapi.nat44_interface_add_del_feature(
4961 sw_if_index=self.pg1.sw_if_index,
4964 # from client to service
4965 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4966 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4967 TCP(sport=12345, dport=external_port))
4968 self.pg1.add_stream(p)
4969 self.pg_enable_capture(self.pg_interfaces)
4971 capture = self.pg0.get_capture(1)
4977 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4978 if ip.dst == server1.ip4:
4982 self.assertEqual(tcp.dport, local_port)
4983 self.assert_packet_checksums_valid(p)
4985 self.logger.error(ppp("Unexpected or invalid packet:", p))
4988 # from service back to client
4989 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4990 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4991 TCP(sport=local_port, dport=12345))
4992 self.pg0.add_stream(p)
4993 self.pg_enable_capture(self.pg_interfaces)
4995 capture = self.pg1.get_capture(1)
5000 self.assertEqual(ip.src, self.nat_addr)
5001 self.assertEqual(tcp.sport, external_port)
5002 self.assert_packet_checksums_valid(p)
5004 self.logger.error(ppp("Unexpected or invalid packet:", p))
5007 # from client to server (no translation)
5008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5009 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5010 TCP(sport=12346, dport=local_port))
5011 self.pg1.add_stream(p)
5012 self.pg_enable_capture(self.pg_interfaces)
5014 capture = self.pg0.get_capture(1)
5020 self.assertEqual(ip.dst, server1.ip4)
5021 self.assertEqual(tcp.dport, local_port)
5022 self.assert_packet_checksums_valid(p)
5024 self.logger.error(ppp("Unexpected or invalid packet:", p))
5027 # from service back to client (no translation)
5028 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5029 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5030 TCP(sport=local_port, dport=12346))
5031 self.pg0.add_stream(p)
5032 self.pg_enable_capture(self.pg_interfaces)
5034 capture = self.pg1.get_capture(1)
5039 self.assertEqual(ip.src, server1.ip4)
5040 self.assertEqual(tcp.sport, local_port)
5041 self.assert_packet_checksums_valid(p)
5043 self.logger.error(ppp("Unexpected or invalid packet:", p))
5046 def test_lb_affinity(self):
5047 """ NAT44 local service load balancing affinity """
5048 external_addr = self.nat_addr
5051 server1 = self.pg0.remote_hosts[0]
5052 server2 = self.pg0.remote_hosts[1]
5054 locals = [{'addr': server1.ip4,
5058 {'addr': server2.ip4,
5063 self.nat44_add_address(self.nat_addr)
5064 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5065 external_addr=external_addr,
5066 external_port=external_port,
5067 protocol=IP_PROTOS.tcp,
5069 local_num=len(locals),
5071 flags = self.config_flags.NAT_IS_INSIDE
5072 self.vapi.nat44_interface_add_del_feature(
5073 sw_if_index=self.pg0.sw_if_index,
5074 flags=flags, is_add=1)
5075 self.vapi.nat44_interface_add_del_feature(
5076 sw_if_index=self.pg1.sw_if_index,
5079 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5080 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5081 TCP(sport=1025, dport=external_port))
5082 self.pg1.add_stream(p)
5083 self.pg_enable_capture(self.pg_interfaces)
5085 capture = self.pg0.get_capture(1)
5086 backend = capture[0][IP].dst
5088 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5089 self.assertEqual(len(sessions), 1)
5090 self.assertTrue(sessions[0].flags &
5091 self.config_flags.NAT_IS_EXT_HOST_VALID)
5092 self.vapi.nat44_del_session(
5093 address=sessions[0].inside_ip_address,
5094 port=sessions[0].inside_port,
5095 protocol=sessions[0].protocol,
5096 flags=(self.config_flags.NAT_IS_INSIDE |
5097 self.config_flags.NAT_IS_EXT_HOST_VALID),
5098 ext_host_address=sessions[0].ext_host_address,
5099 ext_host_port=sessions[0].ext_host_port)
5102 for port in range(1030, 1100):
5103 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5104 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5105 TCP(sport=port, dport=external_port))
5107 self.pg1.add_stream(pkts)
5108 self.pg_enable_capture(self.pg_interfaces)
5110 capture = self.pg0.get_capture(len(pkts))
5112 self.assertEqual(p[IP].dst, backend)
5114 def test_unknown_proto(self):
5115 """ NAT44 translate packet with unknown protocol """
5116 self.nat44_add_address(self.nat_addr)
5117 flags = self.config_flags.NAT_IS_INSIDE
5118 self.vapi.nat44_interface_add_del_feature(
5119 sw_if_index=self.pg0.sw_if_index,
5120 flags=flags, is_add=1)
5121 self.vapi.nat44_interface_add_del_feature(
5122 sw_if_index=self.pg1.sw_if_index,
5126 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5127 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5128 TCP(sport=self.tcp_port_in, dport=20))
5129 self.pg0.add_stream(p)
5130 self.pg_enable_capture(self.pg_interfaces)
5132 p = self.pg1.get_capture(1)
5134 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5135 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5137 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5138 TCP(sport=1234, dport=1234))
5139 self.pg0.add_stream(p)
5140 self.pg_enable_capture(self.pg_interfaces)
5142 p = self.pg1.get_capture(1)
5145 self.assertEqual(packet[IP].src, self.nat_addr)
5146 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5147 self.assertEqual(packet.haslayer(GRE), 1)
5148 self.assert_packet_checksums_valid(packet)
5150 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5154 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5157 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5158 TCP(sport=1234, dport=1234))
5159 self.pg1.add_stream(p)
5160 self.pg_enable_capture(self.pg_interfaces)
5162 p = self.pg0.get_capture(1)
5165 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5166 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5167 self.assertEqual(packet.haslayer(GRE), 1)
5168 self.assert_packet_checksums_valid(packet)
5170 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5173 def test_hairpinning_unknown_proto(self):
5174 """ NAT44 translate packet with unknown protocol - hairpinning """
5175 host = self.pg0.remote_hosts[0]
5176 server = self.pg0.remote_hosts[1]
5178 server_out_port = 8765
5179 server_nat_ip = "10.0.0.11"
5181 self.nat44_add_address(self.nat_addr)
5182 flags = self.config_flags.NAT_IS_INSIDE
5183 self.vapi.nat44_interface_add_del_feature(
5184 sw_if_index=self.pg0.sw_if_index,
5185 flags=flags, is_add=1)
5186 self.vapi.nat44_interface_add_del_feature(
5187 sw_if_index=self.pg1.sw_if_index,
5190 # add static mapping for server
5191 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5194 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5195 IP(src=host.ip4, dst=server_nat_ip) /
5196 TCP(sport=host_in_port, dport=server_out_port))
5197 self.pg0.add_stream(p)
5198 self.pg_enable_capture(self.pg_interfaces)
5200 self.pg0.get_capture(1)
5202 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5203 IP(src=host.ip4, dst=server_nat_ip) /
5205 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5206 TCP(sport=1234, dport=1234))
5207 self.pg0.add_stream(p)
5208 self.pg_enable_capture(self.pg_interfaces)
5210 p = self.pg0.get_capture(1)
5213 self.assertEqual(packet[IP].src, self.nat_addr)
5214 self.assertEqual(packet[IP].dst, server.ip4)
5215 self.assertEqual(packet.haslayer(GRE), 1)
5216 self.assert_packet_checksums_valid(packet)
5218 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5222 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5223 IP(src=server.ip4, dst=self.nat_addr) /
5225 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5226 TCP(sport=1234, dport=1234))
5227 self.pg0.add_stream(p)
5228 self.pg_enable_capture(self.pg_interfaces)
5230 p = self.pg0.get_capture(1)
5233 self.assertEqual(packet[IP].src, server_nat_ip)
5234 self.assertEqual(packet[IP].dst, host.ip4)
5235 self.assertEqual(packet.haslayer(GRE), 1)
5236 self.assert_packet_checksums_valid(packet)
5238 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5241 def test_output_feature_and_service(self):
5242 """ NAT44 interface output feature and services """
5243 external_addr = '1.2.3.4'
5247 self.vapi.nat44_forwarding_enable_disable(enable=1)
5248 self.nat44_add_address(self.nat_addr)
5249 flags = self.config_flags.NAT_IS_ADDR_ONLY
5250 self.vapi.nat44_add_del_identity_mapping(
5251 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5252 flags=flags, is_add=1)
5253 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5254 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5255 local_port, external_port,
5256 proto=IP_PROTOS.tcp, flags=flags)
5257 flags = self.config_flags.NAT_IS_INSIDE
5258 self.vapi.nat44_interface_add_del_feature(
5259 sw_if_index=self.pg0.sw_if_index,
5261 self.vapi.nat44_interface_add_del_feature(
5262 sw_if_index=self.pg0.sw_if_index,
5263 flags=flags, is_add=1)
5264 self.vapi.nat44_interface_add_del_output_feature(
5266 sw_if_index=self.pg1.sw_if_index)
5268 # from client to service
5269 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5270 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5271 TCP(sport=12345, dport=external_port))
5272 self.pg1.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5275 capture = self.pg0.get_capture(1)
5280 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5281 self.assertEqual(tcp.dport, local_port)
5282 self.assert_packet_checksums_valid(p)
5284 self.logger.error(ppp("Unexpected or invalid packet:", p))
5287 # from service back to client
5288 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5289 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5290 TCP(sport=local_port, dport=12345))
5291 self.pg0.add_stream(p)
5292 self.pg_enable_capture(self.pg_interfaces)
5294 capture = self.pg1.get_capture(1)
5299 self.assertEqual(ip.src, external_addr)
5300 self.assertEqual(tcp.sport, external_port)
5301 self.assert_packet_checksums_valid(p)
5303 self.logger.error(ppp("Unexpected or invalid packet:", p))
5306 # from local network host to external network
5307 pkts = self.create_stream_in(self.pg0, self.pg1)
5308 self.pg0.add_stream(pkts)
5309 self.pg_enable_capture(self.pg_interfaces)
5311 capture = self.pg1.get_capture(len(pkts))
5312 self.verify_capture_out(capture)
5313 pkts = self.create_stream_in(self.pg0, self.pg1)
5314 self.pg0.add_stream(pkts)
5315 self.pg_enable_capture(self.pg_interfaces)
5317 capture = self.pg1.get_capture(len(pkts))
5318 self.verify_capture_out(capture)
5320 # from external network back to local network host
5321 pkts = self.create_stream_out(self.pg1)
5322 self.pg1.add_stream(pkts)
5323 self.pg_enable_capture(self.pg_interfaces)
5325 capture = self.pg0.get_capture(len(pkts))
5326 self.verify_capture_in(capture, self.pg0)
5328 def test_output_feature_and_service2(self):
5329 """ NAT44 interface output feature and service host direct access """
5330 self.vapi.nat44_forwarding_enable_disable(enable=1)
5331 self.nat44_add_address(self.nat_addr)
5332 self.vapi.nat44_interface_add_del_output_feature(
5334 sw_if_index=self.pg1.sw_if_index)
5336 # session initiated from service host - translate
5337 pkts = self.create_stream_in(self.pg0, self.pg1)
5338 self.pg0.add_stream(pkts)
5339 self.pg_enable_capture(self.pg_interfaces)
5341 capture = self.pg1.get_capture(len(pkts))
5342 self.verify_capture_out(capture)
5344 pkts = self.create_stream_out(self.pg1)
5345 self.pg1.add_stream(pkts)
5346 self.pg_enable_capture(self.pg_interfaces)
5348 capture = self.pg0.get_capture(len(pkts))
5349 self.verify_capture_in(capture, self.pg0)
5351 # session initiated from remote host - do not translate
5352 self.tcp_port_in = 60303
5353 self.udp_port_in = 60304
5354 self.icmp_id_in = 60305
5355 pkts = self.create_stream_out(self.pg1,
5356 self.pg0.remote_ip4,
5357 use_inside_ports=True)
5358 self.pg1.add_stream(pkts)
5359 self.pg_enable_capture(self.pg_interfaces)
5361 capture = self.pg0.get_capture(len(pkts))
5362 self.verify_capture_in(capture, self.pg0)
5364 pkts = self.create_stream_in(self.pg0, self.pg1)
5365 self.pg0.add_stream(pkts)
5366 self.pg_enable_capture(self.pg_interfaces)
5368 capture = self.pg1.get_capture(len(pkts))
5369 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5372 def test_output_feature_and_service3(self):
5373 """ NAT44 interface output feature and DST NAT """
5374 external_addr = '1.2.3.4'
5378 self.vapi.nat44_forwarding_enable_disable(enable=1)
5379 self.nat44_add_address(self.nat_addr)
5380 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5381 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5382 local_port, external_port,
5383 proto=IP_PROTOS.tcp, flags=flags)
5384 flags = self.config_flags.NAT_IS_INSIDE
5385 self.vapi.nat44_interface_add_del_feature(
5386 sw_if_index=self.pg0.sw_if_index,
5388 self.vapi.nat44_interface_add_del_feature(
5389 sw_if_index=self.pg0.sw_if_index,
5390 flags=flags, is_add=1)
5391 self.vapi.nat44_interface_add_del_output_feature(
5393 sw_if_index=self.pg1.sw_if_index)
5395 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5396 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5397 TCP(sport=12345, dport=external_port))
5398 self.pg0.add_stream(p)
5399 self.pg_enable_capture(self.pg_interfaces)
5401 capture = self.pg1.get_capture(1)
5406 self.assertEqual(ip.src, self.pg0.remote_ip4)
5407 self.assertEqual(tcp.sport, 12345)
5408 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5409 self.assertEqual(tcp.dport, local_port)
5410 self.assert_packet_checksums_valid(p)
5412 self.logger.error(ppp("Unexpected or invalid packet:", p))
5415 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5416 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5417 TCP(sport=local_port, dport=12345))
5418 self.pg1.add_stream(p)
5419 self.pg_enable_capture(self.pg_interfaces)
5421 capture = self.pg0.get_capture(1)
5426 self.assertEqual(ip.src, external_addr)
5427 self.assertEqual(tcp.sport, external_port)
5428 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5429 self.assertEqual(tcp.dport, 12345)
5430 self.assert_packet_checksums_valid(p)
5432 self.logger.error(ppp("Unexpected or invalid packet:", p))
5435 def test_next_src_nat(self):
5436 """ On way back forward packet to nat44-in2out node. """
5437 twice_nat_addr = '10.0.1.3'
5440 post_twice_nat_port = 0
5442 self.vapi.nat44_forwarding_enable_disable(enable=1)
5443 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5444 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5445 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5446 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5447 local_port, external_port,
5448 proto=IP_PROTOS.tcp, vrf_id=1,
5450 self.vapi.nat44_interface_add_del_feature(
5451 sw_if_index=self.pg6.sw_if_index,
5454 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5455 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5456 TCP(sport=12345, dport=external_port))
5457 self.pg6.add_stream(p)
5458 self.pg_enable_capture(self.pg_interfaces)
5460 capture = self.pg6.get_capture(1)
5465 self.assertEqual(ip.src, twice_nat_addr)
5466 self.assertNotEqual(tcp.sport, 12345)
5467 post_twice_nat_port = tcp.sport
5468 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5469 self.assertEqual(tcp.dport, local_port)
5470 self.assert_packet_checksums_valid(p)
5472 self.logger.error(ppp("Unexpected or invalid packet:", p))
5475 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5476 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5477 TCP(sport=local_port, dport=post_twice_nat_port))
5478 self.pg6.add_stream(p)
5479 self.pg_enable_capture(self.pg_interfaces)
5481 capture = self.pg6.get_capture(1)
5486 self.assertEqual(ip.src, self.pg1.remote_ip4)
5487 self.assertEqual(tcp.sport, external_port)
5488 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5489 self.assertEqual(tcp.dport, 12345)
5490 self.assert_packet_checksums_valid(p)
5492 self.logger.error(ppp("Unexpected or invalid packet:", p))
5495 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5497 twice_nat_addr = '10.0.1.3'
5505 port_in1 = port_in + 1
5506 port_in2 = port_in + 2
5511 server1 = self.pg0.remote_hosts[0]
5512 server2 = self.pg0.remote_hosts[1]
5524 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5527 self.nat44_add_address(self.nat_addr)
5528 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5532 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5534 flags |= self.config_flags.NAT_IS_TWICE_NAT
5537 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5539 proto=IP_PROTOS.tcp,
5542 locals = [{'addr': server1.ip4,
5546 {'addr': server2.ip4,
5550 out_addr = self.nat_addr
5552 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5553 external_addr=out_addr,
5554 external_port=port_out,
5555 protocol=IP_PROTOS.tcp,
5556 local_num=len(locals),
5558 flags = self.config_flags.NAT_IS_INSIDE
5559 self.vapi.nat44_interface_add_del_feature(
5560 sw_if_index=pg0.sw_if_index,
5561 flags=flags, is_add=1)
5562 self.vapi.nat44_interface_add_del_feature(
5563 sw_if_index=pg1.sw_if_index,
5570 assert client_id is not None
5572 client = self.pg0.remote_hosts[0]
5573 elif client_id == 2:
5574 client = self.pg0.remote_hosts[1]
5576 client = pg1.remote_hosts[0]
5577 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5578 IP(src=client.ip4, dst=self.nat_addr) /
5579 TCP(sport=eh_port_out, dport=port_out))
5581 self.pg_enable_capture(self.pg_interfaces)
5583 capture = pg0.get_capture(1)
5589 if ip.dst == server1.ip4:
5595 self.assertEqual(ip.dst, server.ip4)
5597 self.assertIn(tcp.dport, [port_in1, port_in2])
5599 self.assertEqual(tcp.dport, port_in)
5601 self.assertEqual(ip.src, twice_nat_addr)
5602 self.assertNotEqual(tcp.sport, eh_port_out)
5604 self.assertEqual(ip.src, client.ip4)
5605 self.assertEqual(tcp.sport, eh_port_out)
5607 eh_port_in = tcp.sport
5608 saved_port_in = tcp.dport
5609 self.assert_packet_checksums_valid(p)
5611 self.logger.error(ppp("Unexpected or invalid packet:", p))
5614 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5615 IP(src=server.ip4, dst=eh_addr_in) /
5616 TCP(sport=saved_port_in, dport=eh_port_in))
5618 self.pg_enable_capture(self.pg_interfaces)
5620 capture = pg1.get_capture(1)
5625 self.assertEqual(ip.dst, client.ip4)
5626 self.assertEqual(ip.src, self.nat_addr)
5627 self.assertEqual(tcp.dport, eh_port_out)
5628 self.assertEqual(tcp.sport, port_out)
5629 self.assert_packet_checksums_valid(p)
5631 self.logger.error(ppp("Unexpected or invalid packet:", p))
5635 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5636 self.assertEqual(len(sessions), 1)
5637 self.assertTrue(sessions[0].flags &
5638 self.config_flags.NAT_IS_EXT_HOST_VALID)
5639 self.assertTrue(sessions[0].flags &
5640 self.config_flags.NAT_IS_TWICE_NAT)
5641 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5642 self.vapi.nat44_del_session(
5643 address=sessions[0].inside_ip_address,
5644 port=sessions[0].inside_port,
5645 protocol=sessions[0].protocol,
5646 flags=(self.config_flags.NAT_IS_INSIDE |
5647 self.config_flags.NAT_IS_EXT_HOST_VALID),
5648 ext_host_address=sessions[0].ext_host_nat_address,
5649 ext_host_port=sessions[0].ext_host_nat_port)
5650 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5651 self.assertEqual(len(sessions), 0)
5653 def test_twice_nat(self):
5655 self.twice_nat_common()
5657 def test_self_twice_nat_positive(self):
5658 """ Self Twice NAT44 (positive test) """
5659 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5661 def test_self_twice_nat_negative(self):
5662 """ Self Twice NAT44 (negative test) """
5663 self.twice_nat_common(self_twice_nat=True)
5665 def test_twice_nat_lb(self):
5666 """ Twice NAT44 local service load balancing """
5667 self.twice_nat_common(lb=True)
5669 def test_self_twice_nat_lb_positive(self):
5670 """ Self Twice NAT44 local service load balancing (positive test) """
5671 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5674 def test_self_twice_nat_lb_negative(self):
5675 """ Self Twice NAT44 local service load balancing (negative test) """
5676 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5679 def test_twice_nat_interface_addr(self):
5680 """ Acquire twice NAT44 addresses from interface """
5681 flags = self.config_flags.NAT_IS_TWICE_NAT
5682 self.vapi.nat44_add_del_interface_addr(
5684 sw_if_index=self.pg3.sw_if_index,
5687 # no address in NAT pool
5688 adresses = self.vapi.nat44_address_dump()
5689 self.assertEqual(0, len(adresses))
5691 # configure interface address and check NAT address pool
5692 self.pg3.config_ip4()
5693 adresses = self.vapi.nat44_address_dump()
5694 self.assertEqual(1, len(adresses))
5695 self.assertEqual(str(adresses[0].ip_address),
5697 self.assertEqual(adresses[0].flags, flags)
5699 # remove interface address and check NAT address pool
5700 self.pg3.unconfig_ip4()
5701 adresses = self.vapi.nat44_address_dump()
5702 self.assertEqual(0, len(adresses))
5704 def test_tcp_close(self):
5705 """ Close TCP session from inside network - output feature """
5706 self.vapi.nat44_forwarding_enable_disable(enable=1)
5707 self.nat44_add_address(self.pg1.local_ip4)
5708 twice_nat_addr = '10.0.1.3'
5709 service_ip = '192.168.16.150'
5710 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5711 flags = self.config_flags.NAT_IS_INSIDE
5712 self.vapi.nat44_interface_add_del_feature(
5713 sw_if_index=self.pg0.sw_if_index,
5715 self.vapi.nat44_interface_add_del_feature(
5716 sw_if_index=self.pg0.sw_if_index,
5717 flags=flags, is_add=1)
5718 self.vapi.nat44_interface_add_del_output_feature(
5720 sw_if_index=self.pg1.sw_if_index)
5721 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5722 self.config_flags.NAT_IS_TWICE_NAT)
5723 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5727 proto=IP_PROTOS.tcp,
5729 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5730 start_sessnum = len(sessions)
5732 # SYN packet out->in
5733 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5734 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5735 TCP(sport=33898, dport=80, flags="S"))
5736 self.pg1.add_stream(p)
5737 self.pg_enable_capture(self.pg_interfaces)
5739 capture = self.pg0.get_capture(1)
5741 tcp_port = p[TCP].sport
5743 # SYN + ACK packet in->out
5744 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5745 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5746 TCP(sport=80, dport=tcp_port, flags="SA"))
5747 self.pg0.add_stream(p)
5748 self.pg_enable_capture(self.pg_interfaces)
5750 self.pg1.get_capture(1)
5752 # ACK packet out->in
5753 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5754 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5755 TCP(sport=33898, dport=80, flags="A"))
5756 self.pg1.add_stream(p)
5757 self.pg_enable_capture(self.pg_interfaces)
5759 self.pg0.get_capture(1)
5761 # FIN packet in -> out
5762 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5763 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5764 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5765 self.pg0.add_stream(p)
5766 self.pg_enable_capture(self.pg_interfaces)
5768 self.pg1.get_capture(1)
5770 # FIN+ACK packet out -> in
5771 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5772 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5773 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5774 self.pg1.add_stream(p)
5775 self.pg_enable_capture(self.pg_interfaces)
5777 self.pg0.get_capture(1)
5779 # ACK packet in -> out
5780 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5781 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5782 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5783 self.pg0.add_stream(p)
5784 self.pg_enable_capture(self.pg_interfaces)
5786 self.pg1.get_capture(1)
5788 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5790 self.assertEqual(len(sessions) - start_sessnum, 0)
5792 def test_tcp_session_close_in(self):
5793 """ Close TCP session from inside network """
5794 self.tcp_port_out = 10505
5795 self.nat44_add_address(self.nat_addr)
5796 flags = self.config_flags.NAT_IS_TWICE_NAT
5797 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5801 proto=IP_PROTOS.tcp,
5803 flags = self.config_flags.NAT_IS_INSIDE
5804 self.vapi.nat44_interface_add_del_feature(
5805 sw_if_index=self.pg0.sw_if_index,
5806 flags=flags, is_add=1)
5807 self.vapi.nat44_interface_add_del_feature(
5808 sw_if_index=self.pg1.sw_if_index,
5811 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5812 start_sessnum = len(sessions)
5814 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5815 tcp_transitory=2, icmp=5)
5817 self.initiate_tcp_session(self.pg0, self.pg1)
5819 # FIN packet in -> out
5820 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5821 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5822 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5823 flags="FA", seq=100, ack=300))
5824 self.pg0.add_stream(p)
5825 self.pg_enable_capture(self.pg_interfaces)
5827 self.pg1.get_capture(1)
5831 # ACK packet out -> in
5832 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5833 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5834 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5835 flags="A", seq=300, ack=101))
5838 # FIN packet out -> in
5839 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5840 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5841 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5842 flags="FA", seq=300, ack=101))
5845 self.pg1.add_stream(pkts)
5846 self.pg_enable_capture(self.pg_interfaces)
5848 self.pg0.get_capture(2)
5850 # ACK packet in -> out
5851 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5852 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5853 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5854 flags="A", seq=101, ack=301))
5855 self.pg0.add_stream(p)
5856 self.pg_enable_capture(self.pg_interfaces)
5858 self.pg1.get_capture(1)
5860 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5861 self.assertEqual(len(sessions) - start_sessnum, 1)
5863 stats = self.statistics.get_counter(
5864 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5865 out2in_drops = stats[0]
5866 stats = self.statistics.get_counter(
5867 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5868 in2out_drops = stats[0]
5870 # extra FIN packet out -> in - this should be dropped
5871 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5872 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5873 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5874 flags="FA", seq=300, ack=101))
5876 self.pg1.add_stream(p)
5877 self.pg_enable_capture(self.pg_interfaces)
5879 self.pg0.assert_nothing_captured()
5881 # extra ACK packet in -> out - this should be dropped
5882 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5883 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5884 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5885 flags="A", seq=101, ack=301))
5886 self.pg0.add_stream(p)
5887 self.pg_enable_capture(self.pg_interfaces)
5889 self.pg1.assert_nothing_captured()
5891 stats = self.statistics.get_counter(
5892 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5893 self.assertEqual(stats[0] - out2in_drops, 1)
5894 stats = self.statistics.get_counter(
5895 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5896 self.assertEqual(stats[0] - in2out_drops, 1)
5899 # extra ACK packet in -> out - this will cause session to be wiped
5900 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5901 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5902 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5903 flags="A", seq=101, ack=301))
5904 self.pg0.add_stream(p)
5905 self.pg_enable_capture(self.pg_interfaces)
5907 self.pg1.assert_nothing_captured()
5908 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5909 self.assertEqual(len(sessions) - start_sessnum, 0)
5911 def test_tcp_session_close_out(self):
5912 """ Close TCP session from outside network """
5913 self.tcp_port_out = 10505
5914 self.nat44_add_address(self.nat_addr)
5915 flags = self.config_flags.NAT_IS_TWICE_NAT
5916 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5920 proto=IP_PROTOS.tcp,
5922 flags = self.config_flags.NAT_IS_INSIDE
5923 self.vapi.nat44_interface_add_del_feature(
5924 sw_if_index=self.pg0.sw_if_index,
5925 flags=flags, is_add=1)
5926 self.vapi.nat44_interface_add_del_feature(
5927 sw_if_index=self.pg1.sw_if_index,
5930 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5931 start_sessnum = len(sessions)
5933 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5934 tcp_transitory=2, icmp=5)
5936 self.initiate_tcp_session(self.pg0, self.pg1)
5938 # FIN packet out -> in
5939 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5940 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5941 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5942 flags="FA", seq=100, ack=300))
5943 self.pg1.add_stream(p)
5944 self.pg_enable_capture(self.pg_interfaces)
5946 self.pg0.get_capture(1)
5948 # FIN+ACK packet in -> out
5949 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5950 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5951 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5952 flags="FA", seq=300, ack=101))
5954 self.pg0.add_stream(p)
5955 self.pg_enable_capture(self.pg_interfaces)
5957 self.pg1.get_capture(1)
5959 # ACK packet out -> in
5960 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5961 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5962 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5963 flags="A", seq=101, ack=301))
5964 self.pg1.add_stream(p)
5965 self.pg_enable_capture(self.pg_interfaces)
5967 self.pg0.get_capture(1)
5969 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5970 self.assertEqual(len(sessions) - start_sessnum, 1)
5972 stats = self.statistics.get_counter(
5973 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5974 out2in_drops = stats[0]
5975 stats = self.statistics.get_counter(
5976 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5977 in2out_drops = stats[0]
5979 # extra FIN packet out -> in - this should be dropped
5980 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5981 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5982 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5983 flags="FA", seq=300, ack=101))
5985 self.pg1.add_stream(p)
5986 self.pg_enable_capture(self.pg_interfaces)
5988 self.pg0.assert_nothing_captured()
5990 # extra ACK packet in -> out - this should be dropped
5991 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5992 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5993 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5994 flags="A", seq=101, ack=301))
5995 self.pg0.add_stream(p)
5996 self.pg_enable_capture(self.pg_interfaces)
5998 self.pg1.assert_nothing_captured()
6000 stats = self.statistics.get_counter(
6001 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6002 self.assertEqual(stats[0] - out2in_drops, 1)
6003 stats = self.statistics.get_counter(
6004 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6005 self.assertEqual(stats[0] - in2out_drops, 1)
6008 # extra ACK packet in -> out - this will cause session to be wiped
6009 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6010 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6011 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6012 flags="A", seq=101, ack=301))
6013 self.pg0.add_stream(p)
6014 self.pg_enable_capture(self.pg_interfaces)
6016 self.pg1.assert_nothing_captured()
6017 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6018 self.assertEqual(len(sessions) - start_sessnum, 0)
6020 def test_tcp_session_close_simultaneous(self):
6021 """ Close TCP session from inside network """
6022 self.tcp_port_out = 10505
6023 self.nat44_add_address(self.nat_addr)
6024 flags = self.config_flags.NAT_IS_TWICE_NAT
6025 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6029 proto=IP_PROTOS.tcp,
6031 flags = self.config_flags.NAT_IS_INSIDE
6032 self.vapi.nat44_interface_add_del_feature(
6033 sw_if_index=self.pg0.sw_if_index,
6034 flags=flags, is_add=1)
6035 self.vapi.nat44_interface_add_del_feature(
6036 sw_if_index=self.pg1.sw_if_index,
6039 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6040 start_sessnum = len(sessions)
6042 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6043 tcp_transitory=2, icmp=5)
6045 self.initiate_tcp_session(self.pg0, self.pg1)
6047 # FIN packet in -> out
6048 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6049 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6050 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6051 flags="FA", seq=100, ack=300))
6052 self.pg0.add_stream(p)
6053 self.pg_enable_capture(self.pg_interfaces)
6055 self.pg1.get_capture(1)
6057 # FIN packet out -> in
6058 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6059 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6060 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6061 flags="FA", seq=300, ack=100))
6062 self.pg1.add_stream(p)
6063 self.pg_enable_capture(self.pg_interfaces)
6065 self.pg0.get_capture(1)
6067 # ACK packet in -> out
6068 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6069 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6070 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6071 flags="A", seq=101, ack=301))
6072 self.pg0.add_stream(p)
6073 self.pg_enable_capture(self.pg_interfaces)
6075 self.pg1.get_capture(1)
6077 # ACK packet out -> in
6078 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6079 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6080 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6081 flags="A", seq=301, ack=101))
6082 self.pg1.add_stream(p)
6083 self.pg_enable_capture(self.pg_interfaces)
6085 self.pg0.get_capture(1)
6087 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6088 self.assertEqual(len(sessions) - start_sessnum, 1)
6090 stats = self.statistics.get_counter(
6091 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6092 out2in_drops = stats[0]
6093 stats = self.statistics.get_counter(
6094 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6095 in2out_drops = stats[0]
6097 # extra FIN packet out -> in - this should be dropped
6098 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6099 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6100 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6101 flags="FA", seq=300, ack=101))
6103 self.pg1.add_stream(p)
6104 self.pg_enable_capture(self.pg_interfaces)
6106 self.pg0.assert_nothing_captured()
6108 # extra ACK packet in -> out - this should be dropped
6109 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6110 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6111 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6112 flags="A", seq=101, ack=301))
6113 self.pg0.add_stream(p)
6114 self.pg_enable_capture(self.pg_interfaces)
6116 self.pg1.assert_nothing_captured()
6118 stats = self.statistics.get_counter(
6119 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6120 self.assertEqual(stats[0] - out2in_drops, 1)
6121 stats = self.statistics.get_counter(
6122 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6123 self.assertEqual(stats[0] - in2out_drops, 1)
6126 # extra ACK packet in -> out - this will cause session to be wiped
6127 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6128 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6129 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6130 flags="A", seq=101, ack=301))
6131 self.pg0.add_stream(p)
6132 self.pg_enable_capture(self.pg_interfaces)
6134 self.pg1.assert_nothing_captured()
6135 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6136 self.assertEqual(len(sessions) - start_sessnum, 0)
6138 def test_one_armed_nat44_static(self):
6139 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6140 remote_host = self.pg4.remote_hosts[0]
6141 local_host = self.pg4.remote_hosts[1]
6146 self.vapi.nat44_forwarding_enable_disable(enable=1)
6147 self.nat44_add_address(self.nat_addr, twice_nat=1)
6148 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6149 self.config_flags.NAT_IS_TWICE_NAT)
6150 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6151 local_port, external_port,
6152 proto=IP_PROTOS.tcp, flags=flags)
6153 flags = self.config_flags.NAT_IS_INSIDE
6154 self.vapi.nat44_interface_add_del_feature(
6155 sw_if_index=self.pg4.sw_if_index,
6157 self.vapi.nat44_interface_add_del_feature(
6158 sw_if_index=self.pg4.sw_if_index,
6159 flags=flags, is_add=1)
6161 # from client to service
6162 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6163 IP(src=remote_host.ip4, dst=self.nat_addr) /
6164 TCP(sport=12345, dport=external_port))
6165 self.pg4.add_stream(p)
6166 self.pg_enable_capture(self.pg_interfaces)
6168 capture = self.pg4.get_capture(1)
6173 self.assertEqual(ip.dst, local_host.ip4)
6174 self.assertEqual(ip.src, self.nat_addr)
6175 self.assertEqual(tcp.dport, local_port)
6176 self.assertNotEqual(tcp.sport, 12345)
6177 eh_port_in = tcp.sport
6178 self.assert_packet_checksums_valid(p)
6180 self.logger.error(ppp("Unexpected or invalid packet:", p))
6183 # from service back to client
6184 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6185 IP(src=local_host.ip4, dst=self.nat_addr) /
6186 TCP(sport=local_port, dport=eh_port_in))
6187 self.pg4.add_stream(p)
6188 self.pg_enable_capture(self.pg_interfaces)
6190 capture = self.pg4.get_capture(1)
6195 self.assertEqual(ip.src, self.nat_addr)
6196 self.assertEqual(ip.dst, remote_host.ip4)
6197 self.assertEqual(tcp.sport, external_port)
6198 self.assertEqual(tcp.dport, 12345)
6199 self.assert_packet_checksums_valid(p)
6201 self.logger.error(ppp("Unexpected or invalid packet:", p))
6204 def test_static_with_port_out2(self):
6205 """ 1:1 NAPT asymmetrical rule """
6210 self.vapi.nat44_forwarding_enable_disable(enable=1)
6211 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6212 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6213 local_port, external_port,
6214 proto=IP_PROTOS.tcp, flags=flags)
6215 flags = self.config_flags.NAT_IS_INSIDE
6216 self.vapi.nat44_interface_add_del_feature(
6217 sw_if_index=self.pg0.sw_if_index,
6218 flags=flags, is_add=1)
6219 self.vapi.nat44_interface_add_del_feature(
6220 sw_if_index=self.pg1.sw_if_index,
6223 # from client to service
6224 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6225 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6226 TCP(sport=12345, dport=external_port))
6227 self.pg1.add_stream(p)
6228 self.pg_enable_capture(self.pg_interfaces)
6230 capture = self.pg0.get_capture(1)
6235 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6236 self.assertEqual(tcp.dport, local_port)
6237 self.assert_packet_checksums_valid(p)
6239 self.logger.error(ppp("Unexpected or invalid packet:", p))
6243 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6244 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6245 ICMP(type=11) / capture[0][IP])
6246 self.pg0.add_stream(p)
6247 self.pg_enable_capture(self.pg_interfaces)
6249 capture = self.pg1.get_capture(1)
6252 self.assertEqual(p[IP].src, self.nat_addr)
6254 self.assertEqual(inner.dst, self.nat_addr)
6255 self.assertEqual(inner[TCPerror].dport, external_port)
6257 self.logger.error(ppp("Unexpected or invalid packet:", p))
6260 # from service back to client
6261 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6262 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6263 TCP(sport=local_port, dport=12345))
6264 self.pg0.add_stream(p)
6265 self.pg_enable_capture(self.pg_interfaces)
6267 capture = self.pg1.get_capture(1)
6272 self.assertEqual(ip.src, self.nat_addr)
6273 self.assertEqual(tcp.sport, external_port)
6274 self.assert_packet_checksums_valid(p)
6276 self.logger.error(ppp("Unexpected or invalid packet:", p))
6280 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6281 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6282 ICMP(type=11) / capture[0][IP])
6283 self.pg1.add_stream(p)
6284 self.pg_enable_capture(self.pg_interfaces)
6286 capture = self.pg0.get_capture(1)
6289 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6291 self.assertEqual(inner.src, self.pg0.remote_ip4)
6292 self.assertEqual(inner[TCPerror].sport, local_port)
6294 self.logger.error(ppp("Unexpected or invalid packet:", p))
6297 # from client to server (no translation)
6298 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6299 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6300 TCP(sport=12346, dport=local_port))
6301 self.pg1.add_stream(p)
6302 self.pg_enable_capture(self.pg_interfaces)
6304 capture = self.pg0.get_capture(1)
6309 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6310 self.assertEqual(tcp.dport, local_port)
6311 self.assert_packet_checksums_valid(p)
6313 self.logger.error(ppp("Unexpected or invalid packet:", p))
6316 # from service back to client (no translation)
6317 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6318 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6319 TCP(sport=local_port, dport=12346))
6320 self.pg0.add_stream(p)
6321 self.pg_enable_capture(self.pg_interfaces)
6323 capture = self.pg1.get_capture(1)
6328 self.assertEqual(ip.src, self.pg0.remote_ip4)
6329 self.assertEqual(tcp.sport, local_port)
6330 self.assert_packet_checksums_valid(p)
6332 self.logger.error(ppp("Unexpected or invalid packet:", p))
6335 def test_output_feature(self):
6336 """ NAT44 interface output feature (in2out postrouting) """
6337 self.vapi.nat44_forwarding_enable_disable(enable=1)
6338 self.nat44_add_address(self.nat_addr)
6339 self.vapi.nat44_interface_add_del_feature(
6340 sw_if_index=self.pg0.sw_if_index,
6342 self.vapi.nat44_interface_add_del_output_feature(
6344 sw_if_index=self.pg1.sw_if_index)
6347 pkts = self.create_stream_in(self.pg0, self.pg1)
6348 self.pg0.add_stream(pkts)
6349 self.pg_enable_capture(self.pg_interfaces)
6351 capture = self.pg1.get_capture(len(pkts))
6352 self.verify_capture_out(capture)
6355 pkts = self.create_stream_out(self.pg1)
6356 self.pg1.add_stream(pkts)
6357 self.pg_enable_capture(self.pg_interfaces)
6359 capture = self.pg0.get_capture(len(pkts))
6360 self.verify_capture_in(capture, self.pg0)
6362 def test_output_feature_stateful_acl(self):
6363 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6364 self.nat44_add_address(self.nat_addr)
6365 self.vapi.nat44_interface_add_del_output_feature(
6366 sw_if_index=self.pg0.sw_if_index,
6367 flags=self.config_flags.NAT_IS_INSIDE,
6369 self.vapi.nat44_interface_add_del_output_feature(
6370 sw_if_index=self.pg1.sw_if_index,
6371 flags=self.config_flags.NAT_IS_OUTSIDE,
6374 # First ensure that the NAT is working sans ACL
6376 # send packets out2in, no sessions yet so packets should drop
6377 pkts_out2in = self.create_stream_out(self.pg1)
6378 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6380 # send packets into inside intf, ensure received via outside intf
6381 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6382 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6384 self.verify_capture_out(capture)
6386 # send out2in again, with sessions created it should work now
6387 pkts_out2in = self.create_stream_out(self.pg1)
6388 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6390 self.verify_capture_in(capture, self.pg0)
6392 # Create an ACL blocking everything
6393 out2in_deny_rule = AclRule(is_permit=0)
6394 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6395 out2in_acl.add_vpp_config()
6397 # create an ACL to permit/reflect everything
6398 in2out_reflect_rule = AclRule(is_permit=2)
6399 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6400 in2out_acl.add_vpp_config()
6402 # apply as input acl on interface and confirm it blocks everything
6403 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6404 n_input=1, acls=[out2in_acl])
6405 acl_if.add_vpp_config()
6406 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6409 acl_if.acls = [out2in_acl, in2out_acl]
6410 acl_if.add_vpp_config()
6411 # send in2out to generate ACL state (NAT state was created earlier)
6412 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6414 self.verify_capture_out(capture)
6416 # send out2in again. ACL state exists so it should work now.
6417 # TCP packets with the syn flag set also need the ack flag
6418 for p in pkts_out2in:
6419 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6420 p[TCP].flags |= 0x10
6421 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6423 self.verify_capture_in(capture, self.pg0)
6424 self.logger.info(self.vapi.cli("show trace"))
6426 def test_multiple_vrf(self):
6427 """ Multiple VRF setup """
6428 external_addr = '1.2.3.4'
6433 self.vapi.nat44_forwarding_enable_disable(enable=1)
6434 self.nat44_add_address(self.nat_addr)
6435 flags = self.config_flags.NAT_IS_INSIDE
6436 self.vapi.nat44_interface_add_del_feature(
6437 sw_if_index=self.pg0.sw_if_index,
6439 self.vapi.nat44_interface_add_del_feature(
6440 sw_if_index=self.pg0.sw_if_index,
6441 flags=flags, is_add=1)
6442 self.vapi.nat44_interface_add_del_output_feature(
6444 sw_if_index=self.pg1.sw_if_index)
6445 self.vapi.nat44_interface_add_del_feature(
6446 sw_if_index=self.pg5.sw_if_index,
6448 self.vapi.nat44_interface_add_del_feature(
6449 sw_if_index=self.pg5.sw_if_index,
6450 flags=flags, is_add=1)
6451 self.vapi.nat44_interface_add_del_feature(
6452 sw_if_index=self.pg6.sw_if_index,
6454 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6455 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6456 local_port, external_port, vrf_id=1,
6457 proto=IP_PROTOS.tcp, flags=flags)
6458 self.nat44_add_static_mapping(
6459 self.pg0.remote_ip4,
6460 external_sw_if_index=self.pg0.sw_if_index,
6461 local_port=local_port,
6463 external_port=external_port,
6464 proto=IP_PROTOS.tcp,
6468 # from client to service (both VRF1)
6469 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6470 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6471 TCP(sport=12345, dport=external_port))
6472 self.pg6.add_stream(p)
6473 self.pg_enable_capture(self.pg_interfaces)
6475 capture = self.pg5.get_capture(1)
6480 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6481 self.assertEqual(tcp.dport, local_port)
6482 self.assert_packet_checksums_valid(p)
6484 self.logger.error(ppp("Unexpected or invalid packet:", p))
6487 # from service back to client (both VRF1)
6488 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6489 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6490 TCP(sport=local_port, dport=12345))
6491 self.pg5.add_stream(p)
6492 self.pg_enable_capture(self.pg_interfaces)
6494 capture = self.pg6.get_capture(1)
6499 self.assertEqual(ip.src, external_addr)
6500 self.assertEqual(tcp.sport, external_port)
6501 self.assert_packet_checksums_valid(p)
6503 self.logger.error(ppp("Unexpected or invalid packet:", p))
6506 # dynamic NAT from VRF1 to VRF0 (output-feature)
6507 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6508 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6509 TCP(sport=2345, dport=22))
6510 self.pg5.add_stream(p)
6511 self.pg_enable_capture(self.pg_interfaces)
6513 capture = self.pg1.get_capture(1)
6518 self.assertEqual(ip.src, self.nat_addr)
6519 self.assertNotEqual(tcp.sport, 2345)
6520 self.assert_packet_checksums_valid(p)
6523 self.logger.error(ppp("Unexpected or invalid packet:", p))
6526 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6527 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6528 TCP(sport=22, dport=port))
6529 self.pg1.add_stream(p)
6530 self.pg_enable_capture(self.pg_interfaces)
6532 capture = self.pg5.get_capture(1)
6537 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6538 self.assertEqual(tcp.dport, 2345)
6539 self.assert_packet_checksums_valid(p)
6541 self.logger.error(ppp("Unexpected or invalid packet:", p))
6544 # from client VRF1 to service VRF0
6545 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6546 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6547 TCP(sport=12346, dport=external_port))
6548 self.pg6.add_stream(p)
6549 self.pg_enable_capture(self.pg_interfaces)
6551 capture = self.pg0.get_capture(1)
6556 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6557 self.assertEqual(tcp.dport, local_port)
6558 self.assert_packet_checksums_valid(p)
6560 self.logger.error(ppp("Unexpected or invalid packet:", p))
6563 # from service VRF0 back to client VRF1
6564 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6565 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6566 TCP(sport=local_port, dport=12346))
6567 self.pg0.add_stream(p)
6568 self.pg_enable_capture(self.pg_interfaces)
6570 capture = self.pg6.get_capture(1)
6575 self.assertEqual(ip.src, self.pg0.local_ip4)
6576 self.assertEqual(tcp.sport, external_port)
6577 self.assert_packet_checksums_valid(p)
6579 self.logger.error(ppp("Unexpected or invalid packet:", p))
6582 # from client VRF0 to service VRF1
6583 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6584 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6585 TCP(sport=12347, dport=external_port))
6586 self.pg0.add_stream(p)
6587 self.pg_enable_capture(self.pg_interfaces)
6589 capture = self.pg5.get_capture(1)
6594 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6595 self.assertEqual(tcp.dport, local_port)
6596 self.assert_packet_checksums_valid(p)
6598 self.logger.error(ppp("Unexpected or invalid packet:", p))
6601 # from service VRF1 back to client VRF0
6602 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6603 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6604 TCP(sport=local_port, dport=12347))
6605 self.pg5.add_stream(p)
6606 self.pg_enable_capture(self.pg_interfaces)
6608 capture = self.pg0.get_capture(1)
6613 self.assertEqual(ip.src, external_addr)
6614 self.assertEqual(tcp.sport, external_port)
6615 self.assert_packet_checksums_valid(p)
6617 self.logger.error(ppp("Unexpected or invalid packet:", p))
6620 # from client to server (both VRF1, no translation)
6621 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6622 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6623 TCP(sport=12348, dport=local_port))
6624 self.pg6.add_stream(p)
6625 self.pg_enable_capture(self.pg_interfaces)
6627 capture = self.pg5.get_capture(1)
6632 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6633 self.assertEqual(tcp.dport, local_port)
6634 self.assert_packet_checksums_valid(p)
6636 self.logger.error(ppp("Unexpected or invalid packet:", p))
6639 # from server back to client (both VRF1, no translation)
6640 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6641 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6642 TCP(sport=local_port, dport=12348))
6643 self.pg5.add_stream(p)
6644 self.pg_enable_capture(self.pg_interfaces)
6646 capture = self.pg6.get_capture(1)
6651 self.assertEqual(ip.src, self.pg5.remote_ip4)
6652 self.assertEqual(tcp.sport, local_port)
6653 self.assert_packet_checksums_valid(p)
6655 self.logger.error(ppp("Unexpected or invalid packet:", p))
6658 # from client VRF1 to server VRF0 (no translation)
6659 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6660 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6661 TCP(sport=local_port, dport=12349))
6662 self.pg0.add_stream(p)
6663 self.pg_enable_capture(self.pg_interfaces)
6665 capture = self.pg6.get_capture(1)
6670 self.assertEqual(ip.src, self.pg0.remote_ip4)
6671 self.assertEqual(tcp.sport, local_port)
6672 self.assert_packet_checksums_valid(p)
6674 self.logger.error(ppp("Unexpected or invalid packet:", p))
6677 # from server VRF0 back to client VRF1 (no translation)
6678 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6679 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6680 TCP(sport=local_port, dport=12349))
6681 self.pg0.add_stream(p)
6682 self.pg_enable_capture(self.pg_interfaces)
6684 capture = self.pg6.get_capture(1)
6689 self.assertEqual(ip.src, self.pg0.remote_ip4)
6690 self.assertEqual(tcp.sport, local_port)
6691 self.assert_packet_checksums_valid(p)
6693 self.logger.error(ppp("Unexpected or invalid packet:", p))
6696 # from client VRF0 to server VRF1 (no translation)
6697 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6698 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6699 TCP(sport=12344, dport=local_port))
6700 self.pg0.add_stream(p)
6701 self.pg_enable_capture(self.pg_interfaces)
6703 capture = self.pg5.get_capture(1)
6708 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6709 self.assertEqual(tcp.dport, local_port)
6710 self.assert_packet_checksums_valid(p)
6712 self.logger.error(ppp("Unexpected or invalid packet:", p))
6715 # from server VRF1 back to client VRF0 (no translation)
6716 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6717 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6718 TCP(sport=local_port, dport=12344))
6719 self.pg5.add_stream(p)
6720 self.pg_enable_capture(self.pg_interfaces)
6722 capture = self.pg0.get_capture(1)
6727 self.assertEqual(ip.src, self.pg5.remote_ip4)
6728 self.assertEqual(tcp.sport, local_port)
6729 self.assert_packet_checksums_valid(p)
6731 self.logger.error(ppp("Unexpected or invalid packet:", p))
6734 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6735 def test_session_timeout(self):
6736 """ NAT44 session timeouts """
6737 self.nat44_add_address(self.nat_addr)
6738 flags = self.config_flags.NAT_IS_INSIDE
6739 self.vapi.nat44_interface_add_del_feature(
6740 sw_if_index=self.pg0.sw_if_index,
6741 flags=flags, is_add=1)
6742 self.vapi.nat44_interface_add_del_feature(
6743 sw_if_index=self.pg1.sw_if_index,
6745 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6746 tcp_transitory=240, icmp=5)
6750 for i in range(0, max_sessions):
6751 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6752 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6753 IP(src=src, dst=self.pg1.remote_ip4) /
6754 ICMP(id=1025, type='echo-request'))
6756 self.pg0.add_stream(pkts)
6757 self.pg_enable_capture(self.pg_interfaces)
6759 self.pg1.get_capture(max_sessions)
6764 for i in range(0, max_sessions):
6765 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6766 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6767 IP(src=src, dst=self.pg1.remote_ip4) /
6768 ICMP(id=1026, type='echo-request'))
6770 self.pg0.add_stream(pkts)
6771 self.pg_enable_capture(self.pg_interfaces)
6773 self.pg1.get_capture(max_sessions)
6776 users = self.vapi.nat44_user_dump()
6778 nsessions = nsessions + user.nsessions
6779 self.assertLess(nsessions, 2 * max_sessions)
6781 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6782 def test_session_rst_timeout(self):
6783 """ NAT44 session RST timeouts """
6784 self.nat44_add_address(self.nat_addr)
6785 flags = self.config_flags.NAT_IS_INSIDE
6786 self.vapi.nat44_interface_add_del_feature(
6787 sw_if_index=self.pg0.sw_if_index,
6788 flags=flags, is_add=1)
6789 self.vapi.nat44_interface_add_del_feature(
6790 sw_if_index=self.pg1.sw_if_index,
6792 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6793 tcp_transitory=5, icmp=60)
6795 self.initiate_tcp_session(self.pg0, self.pg1)
6796 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6797 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6798 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6800 self.pg0.add_stream(p)
6801 self.pg_enable_capture(self.pg_interfaces)
6803 self.pg1.get_capture(1)
6807 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6808 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6809 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6811 self.pg0.add_stream(p)
6812 self.pg_enable_capture(self.pg_interfaces)
6814 self.pg1.get_capture(1)
6816 def test_syslog_sess(self):
6817 """ Test syslog session creation and deletion """
6818 self.vapi.syslog_set_filter(
6819 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6820 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6821 self.nat44_add_address(self.nat_addr)
6822 flags = self.config_flags.NAT_IS_INSIDE
6823 self.vapi.nat44_interface_add_del_feature(
6824 sw_if_index=self.pg0.sw_if_index,
6825 flags=flags, is_add=1)
6826 self.vapi.nat44_interface_add_del_feature(
6827 sw_if_index=self.pg1.sw_if_index,
6830 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6831 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6832 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6833 self.pg0.add_stream(p)
6834 self.pg_enable_capture(self.pg_interfaces)
6836 capture = self.pg1.get_capture(1)
6837 self.tcp_port_out = capture[0][TCP].sport
6838 capture = self.pg2.get_capture(1)
6839 self.verify_syslog_sess(capture[0][Raw].load)
6841 self.pg_enable_capture(self.pg_interfaces)
6843 self.nat44_add_address(self.nat_addr, is_add=0)
6844 capture = self.pg2.get_capture(1)
6845 self.verify_syslog_sess(capture[0][Raw].load, False)
6848 super(TestNAT44EndpointDependent, self).tearDown()
6849 if not self.vpp_dead:
6851 self.vapi.cli("clear logging")
6853 def show_commands_at_teardown(self):
6854 self.logger.info(self.vapi.cli("show nat44 addresses"))
6855 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6856 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6857 self.logger.info(self.vapi.cli("show nat44 interface address"))
6858 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6859 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6860 self.logger.info(self.vapi.cli("show nat timeouts"))
6863 class TestNAT44Out2InDPO(MethodHolder):
6864 """ NAT44 Test Cases using out2in DPO """
6867 def setUpConstants(cls):
6868 super(TestNAT44Out2InDPO, cls).setUpConstants()
6869 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6872 def setUpClass(cls):
6873 super(TestNAT44Out2InDPO, cls).setUpClass()
6874 cls.vapi.cli("set log class nat level debug")
6876 cls.tcp_port_in = 6303
6877 cls.tcp_port_out = 6303
6878 cls.udp_port_in = 6304
6879 cls.udp_port_out = 6304
6880 cls.icmp_id_in = 6305
6881 cls.icmp_id_out = 6305
6882 cls.nat_addr = '10.0.0.3'
6883 cls.dst_ip4 = '192.168.70.1'
6885 cls.create_pg_interfaces(range(2))
6888 cls.pg0.config_ip4()
6889 cls.pg0.resolve_arp()
6892 cls.pg1.config_ip6()
6893 cls.pg1.resolve_ndp()
6895 r1 = VppIpRoute(cls, "::", 0,
6896 [VppRoutePath(cls.pg1.remote_ip6,
6897 cls.pg1.sw_if_index)],
6902 def tearDownClass(cls):
6903 super(TestNAT44Out2InDPO, cls).tearDownClass()
6905 def configure_xlat(self):
6906 self.dst_ip6_pfx = '1:2:3::'
6907 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6909 self.dst_ip6_pfx_len = 96
6910 self.src_ip6_pfx = '4:5:6::'
6911 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6913 self.src_ip6_pfx_len = 96
6914 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6915 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6916 '\x00\x00\x00\x00', 0)
6918 @unittest.skip('Temporary disabled')
6919 def test_464xlat_ce(self):
6920 """ Test 464XLAT CE with NAT44 """
6922 nat_config = self.vapi.nat_show_config()
6923 self.assertEqual(1, nat_config.out2in_dpo)
6925 self.configure_xlat()
6927 flags = self.config_flags.NAT_IS_INSIDE
6928 self.vapi.nat44_interface_add_del_feature(
6929 sw_if_index=self.pg0.sw_if_index,
6930 flags=flags, is_add=1)
6931 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6932 last_ip_address=self.nat_addr_n,
6933 vrf_id=0xFFFFFFFF, is_add=1)
6935 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6936 self.dst_ip6_pfx_len)
6937 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6938 self.src_ip6_pfx_len)
6941 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6942 self.pg0.add_stream(pkts)
6943 self.pg_enable_capture(self.pg_interfaces)
6945 capture = self.pg1.get_capture(len(pkts))
6946 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6949 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6951 self.pg1.add_stream(pkts)
6952 self.pg_enable_capture(self.pg_interfaces)
6954 capture = self.pg0.get_capture(len(pkts))
6955 self.verify_capture_in(capture, self.pg0)
6957 self.vapi.nat44_interface_add_del_feature(
6958 sw_if_index=self.pg0.sw_if_index,
6960 self.vapi.nat44_add_del_address_range(
6961 first_ip_address=self.nat_addr_n,
6962 last_ip_address=self.nat_addr_n,
6965 @unittest.skip('Temporary disabled')
6966 def test_464xlat_ce_no_nat(self):
6967 """ Test 464XLAT CE without NAT44 """
6969 self.configure_xlat()
6971 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6972 self.dst_ip6_pfx_len)
6973 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6974 self.src_ip6_pfx_len)
6976 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6977 self.pg0.add_stream(pkts)
6978 self.pg_enable_capture(self.pg_interfaces)
6980 capture = self.pg1.get_capture(len(pkts))
6981 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6982 nat_ip=out_dst_ip6, same_port=True)
6984 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6985 self.pg1.add_stream(pkts)
6986 self.pg_enable_capture(self.pg_interfaces)
6988 capture = self.pg0.get_capture(len(pkts))
6989 self.verify_capture_in(capture, self.pg0)
6992 class TestDeterministicNAT(MethodHolder):
6993 """ Deterministic NAT Test Cases """
6996 def setUpConstants(cls):
6997 super(TestDeterministicNAT, cls).setUpConstants()
6998 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7001 def setUpClass(cls):
7002 super(TestDeterministicNAT, cls).setUpClass()
7003 cls.vapi.cli("set log class nat level debug")
7005 cls.tcp_port_in = 6303
7006 cls.tcp_external_port = 6303
7007 cls.udp_port_in = 6304
7008 cls.udp_external_port = 6304
7009 cls.icmp_id_in = 6305
7010 cls.nat_addr = '10.0.0.3'
7012 cls.create_pg_interfaces(range(3))
7013 cls.interfaces = list(cls.pg_interfaces)
7015 for i in cls.interfaces:
7020 cls.pg0.generate_remote_hosts(2)
7021 cls.pg0.configure_ipv4_neighbors()
7024 def tearDownClass(cls):
7025 super(TestDeterministicNAT, cls).tearDownClass()
7027 def create_stream_in(self, in_if, out_if, ttl=64):
7029 Create packet stream for inside network
7031 :param in_if: Inside interface
7032 :param out_if: Outside interface
7033 :param ttl: TTL of generated packets
7037 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7038 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7039 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7043 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7044 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7045 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7049 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7050 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7051 ICMP(id=self.icmp_id_in, type='echo-request'))
7056 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7058 Create packet stream for outside network
7060 :param out_if: Outside interface
7061 :param dst_ip: Destination IP address (Default use global NAT address)
7062 :param ttl: TTL of generated packets
7065 dst_ip = self.nat_addr
7068 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7069 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7070 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7074 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7075 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7076 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7080 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7081 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7082 ICMP(id=self.icmp_external_id, type='echo-reply'))
7087 def verify_capture_out(self, capture, nat_ip=None):
7089 Verify captured packets on outside network
7091 :param capture: Captured packets
7092 :param nat_ip: Translated IP address (Default use global NAT address)
7093 :param same_port: Source port number is not translated (Default False)
7096 nat_ip = self.nat_addr
7097 for packet in capture:
7099 self.assertEqual(packet[IP].src, nat_ip)
7100 if packet.haslayer(TCP):
7101 self.tcp_port_out = packet[TCP].sport
7102 elif packet.haslayer(UDP):
7103 self.udp_port_out = packet[UDP].sport
7105 self.icmp_external_id = packet[ICMP].id
7107 self.logger.error(ppp("Unexpected or invalid packet "
7108 "(outside network):", packet))
7111 def test_deterministic_mode(self):
7112 """ NAT plugin run deterministic mode """
7113 in_addr = '172.16.255.0'
7114 out_addr = '172.17.255.50'
7115 in_addr_t = '172.16.255.20'
7119 nat_config = self.vapi.nat_show_config()
7120 self.assertEqual(1, nat_config.deterministic)
7122 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7123 in_plen=in_plen, out_addr=out_addr,
7126 rep1 = self.vapi.nat_det_forward(in_addr_t)
7127 self.assertEqual(str(rep1.out_addr), out_addr)
7128 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7130 self.assertEqual(str(rep2.in_addr), in_addr_t)
7132 deterministic_mappings = self.vapi.nat_det_map_dump()
7133 self.assertEqual(len(deterministic_mappings), 1)
7134 dsm = deterministic_mappings[0]
7135 self.assertEqual(in_addr, str(dsm.in_addr))
7136 self.assertEqual(in_plen, dsm.in_plen)
7137 self.assertEqual(out_addr, str(dsm.out_addr))
7138 self.assertEqual(out_plen, dsm.out_plen)
7140 self.clear_nat_det()
7141 deterministic_mappings = self.vapi.nat_det_map_dump()
7142 self.assertEqual(len(deterministic_mappings), 0)
7144 def test_set_timeouts(self):
7145 """ Set deterministic NAT timeouts """
7146 timeouts_before = self.vapi.nat_get_timeouts()
7148 self.vapi.nat_set_timeouts(
7149 udp=timeouts_before.udp + 10,
7150 tcp_established=timeouts_before.tcp_established + 10,
7151 tcp_transitory=timeouts_before.tcp_transitory + 10,
7152 icmp=timeouts_before.icmp + 10)
7154 timeouts_after = self.vapi.nat_get_timeouts()
7156 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7157 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7158 self.assertNotEqual(timeouts_before.tcp_established,
7159 timeouts_after.tcp_established)
7160 self.assertNotEqual(timeouts_before.tcp_transitory,
7161 timeouts_after.tcp_transitory)
7163 def test_det_in(self):
7164 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7166 nat_ip = "10.0.0.10"
7168 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7170 out_addr=socket.inet_aton(nat_ip),
7173 flags = self.config_flags.NAT_IS_INSIDE
7174 self.vapi.nat44_interface_add_del_feature(
7175 sw_if_index=self.pg0.sw_if_index,
7176 flags=flags, is_add=1)
7177 self.vapi.nat44_interface_add_del_feature(
7178 sw_if_index=self.pg1.sw_if_index,
7182 pkts = self.create_stream_in(self.pg0, self.pg1)
7183 self.pg0.add_stream(pkts)
7184 self.pg_enable_capture(self.pg_interfaces)
7186 capture = self.pg1.get_capture(len(pkts))
7187 self.verify_capture_out(capture, nat_ip)
7190 pkts = self.create_stream_out(self.pg1, nat_ip)
7191 self.pg1.add_stream(pkts)
7192 self.pg_enable_capture(self.pg_interfaces)
7194 capture = self.pg0.get_capture(len(pkts))
7195 self.verify_capture_in(capture, self.pg0)
7198 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7199 self.assertEqual(len(sessions), 3)
7203 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7204 self.assertEqual(s.in_port, self.tcp_port_in)
7205 self.assertEqual(s.out_port, self.tcp_port_out)
7206 self.assertEqual(s.ext_port, self.tcp_external_port)
7210 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7211 self.assertEqual(s.in_port, self.udp_port_in)
7212 self.assertEqual(s.out_port, self.udp_port_out)
7213 self.assertEqual(s.ext_port, self.udp_external_port)
7217 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7218 self.assertEqual(s.in_port, self.icmp_id_in)
7219 self.assertEqual(s.out_port, self.icmp_external_id)
7221 def test_multiple_users(self):
7222 """ Deterministic NAT multiple users """
7224 nat_ip = "10.0.0.10"
7226 external_port = 6303
7228 host0 = self.pg0.remote_hosts[0]
7229 host1 = self.pg0.remote_hosts[1]
7231 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7232 out_addr=socket.inet_aton(nat_ip),
7234 flags = self.config_flags.NAT_IS_INSIDE
7235 self.vapi.nat44_interface_add_del_feature(
7236 sw_if_index=self.pg0.sw_if_index,
7237 flags=flags, is_add=1)
7238 self.vapi.nat44_interface_add_del_feature(
7239 sw_if_index=self.pg1.sw_if_index,
7243 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7244 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7245 TCP(sport=port_in, dport=external_port))
7246 self.pg0.add_stream(p)
7247 self.pg_enable_capture(self.pg_interfaces)
7249 capture = self.pg1.get_capture(1)
7254 self.assertEqual(ip.src, nat_ip)
7255 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7256 self.assertEqual(tcp.dport, external_port)
7257 port_out0 = tcp.sport
7259 self.logger.error(ppp("Unexpected or invalid packet:", p))
7263 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7264 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7265 TCP(sport=port_in, dport=external_port))
7266 self.pg0.add_stream(p)
7267 self.pg_enable_capture(self.pg_interfaces)
7269 capture = self.pg1.get_capture(1)
7274 self.assertEqual(ip.src, nat_ip)
7275 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7276 self.assertEqual(tcp.dport, external_port)
7277 port_out1 = tcp.sport
7279 self.logger.error(ppp("Unexpected or invalid packet:", p))
7282 dms = self.vapi.nat_det_map_dump()
7283 self.assertEqual(1, len(dms))
7284 self.assertEqual(2, dms[0].ses_num)
7287 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7288 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7289 TCP(sport=external_port, dport=port_out0))
7290 self.pg1.add_stream(p)
7291 self.pg_enable_capture(self.pg_interfaces)
7293 capture = self.pg0.get_capture(1)
7298 self.assertEqual(ip.src, self.pg1.remote_ip4)
7299 self.assertEqual(ip.dst, host0.ip4)
7300 self.assertEqual(tcp.dport, port_in)
7301 self.assertEqual(tcp.sport, external_port)
7303 self.logger.error(ppp("Unexpected or invalid packet:", p))
7307 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7308 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7309 TCP(sport=external_port, dport=port_out1))
7310 self.pg1.add_stream(p)
7311 self.pg_enable_capture(self.pg_interfaces)
7313 capture = self.pg0.get_capture(1)
7318 self.assertEqual(ip.src, self.pg1.remote_ip4)
7319 self.assertEqual(ip.dst, host1.ip4)
7320 self.assertEqual(tcp.dport, port_in)
7321 self.assertEqual(tcp.sport, external_port)
7323 self.logger.error(ppp("Unexpected or invalid packet", p))
7326 # session close api test
7327 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7329 self.pg1.remote_ip4,
7331 dms = self.vapi.nat_det_map_dump()
7332 self.assertEqual(dms[0].ses_num, 1)
7334 self.vapi.nat_det_close_session_in(host0.ip4,
7336 self.pg1.remote_ip4,
7338 dms = self.vapi.nat_det_map_dump()
7339 self.assertEqual(dms[0].ses_num, 0)
7341 def test_tcp_session_close_detection_in(self):
7342 """ Deterministic NAT TCP session close from inside network """
7343 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7345 out_addr=socket.inet_aton(self.nat_addr),
7347 flags = self.config_flags.NAT_IS_INSIDE
7348 self.vapi.nat44_interface_add_del_feature(
7349 sw_if_index=self.pg0.sw_if_index,
7350 flags=flags, is_add=1)
7351 self.vapi.nat44_interface_add_del_feature(
7352 sw_if_index=self.pg1.sw_if_index,
7355 self.initiate_tcp_session(self.pg0, self.pg1)
7357 # close the session from inside
7359 # FIN packet in -> out
7360 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7361 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7362 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7364 self.pg0.add_stream(p)
7365 self.pg_enable_capture(self.pg_interfaces)
7367 self.pg1.get_capture(1)
7371 # ACK packet out -> in
7372 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7373 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7374 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7378 # FIN packet out -> in
7379 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7380 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7381 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7385 self.pg1.add_stream(pkts)
7386 self.pg_enable_capture(self.pg_interfaces)
7388 self.pg0.get_capture(2)
7390 # ACK packet in -> out
7391 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7392 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7393 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7395 self.pg0.add_stream(p)
7396 self.pg_enable_capture(self.pg_interfaces)
7398 self.pg1.get_capture(1)
7400 # Check if deterministic NAT44 closed the session
7401 dms = self.vapi.nat_det_map_dump()
7402 self.assertEqual(0, dms[0].ses_num)
7404 self.logger.error("TCP session termination failed")
7407 def test_tcp_session_close_detection_out(self):
7408 """ Deterministic NAT TCP session close from outside network """
7409 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7411 out_addr=socket.inet_aton(self.nat_addr),
7413 flags = self.config_flags.NAT_IS_INSIDE
7414 self.vapi.nat44_interface_add_del_feature(
7415 sw_if_index=self.pg0.sw_if_index,
7416 flags=flags, is_add=1)
7417 self.vapi.nat44_interface_add_del_feature(
7418 sw_if_index=self.pg1.sw_if_index,
7421 self.initiate_tcp_session(self.pg0, self.pg1)
7423 # close the session from outside
7425 # FIN packet out -> in
7426 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7427 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7428 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7430 self.pg1.add_stream(p)
7431 self.pg_enable_capture(self.pg_interfaces)
7433 self.pg0.get_capture(1)
7437 # ACK packet in -> out
7438 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7439 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7440 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7444 # ACK packet in -> out
7445 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7446 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7447 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7451 self.pg0.add_stream(pkts)
7452 self.pg_enable_capture(self.pg_interfaces)
7454 self.pg1.get_capture(2)
7456 # ACK packet out -> in
7457 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7458 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7459 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7461 self.pg1.add_stream(p)
7462 self.pg_enable_capture(self.pg_interfaces)
7464 self.pg0.get_capture(1)
7466 # Check if deterministic NAT44 closed the session
7467 dms = self.vapi.nat_det_map_dump()
7468 self.assertEqual(0, dms[0].ses_num)
7470 self.logger.error("TCP session termination failed")
7473 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7474 def test_session_timeout(self):
7475 """ Deterministic NAT session timeouts """
7476 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7478 out_addr=socket.inet_aton(self.nat_addr),
7480 flags = self.config_flags.NAT_IS_INSIDE
7481 self.vapi.nat44_interface_add_del_feature(
7482 sw_if_index=self.pg0.sw_if_index,
7483 flags=flags, is_add=1)
7484 self.vapi.nat44_interface_add_del_feature(
7485 sw_if_index=self.pg1.sw_if_index,
7488 self.initiate_tcp_session(self.pg0, self.pg1)
7489 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7491 pkts = self.create_stream_in(self.pg0, self.pg1)
7492 self.pg0.add_stream(pkts)
7493 self.pg_enable_capture(self.pg_interfaces)
7495 capture = self.pg1.get_capture(len(pkts))
7498 dms = self.vapi.nat_det_map_dump()
7499 self.assertEqual(0, dms[0].ses_num)
7501 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7502 def test_session_limit_per_user(self):
7503 """ Deterministic NAT maximum sessions per user limit """
7504 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7506 out_addr=socket.inet_aton(self.nat_addr),
7508 flags = self.config_flags.NAT_IS_INSIDE
7509 self.vapi.nat44_interface_add_del_feature(
7510 sw_if_index=self.pg0.sw_if_index,
7511 flags=flags, is_add=1)
7512 self.vapi.nat44_interface_add_del_feature(
7513 sw_if_index=self.pg1.sw_if_index,
7515 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7516 src_address=self.pg2.local_ip4,
7518 template_interval=10)
7519 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7523 for port in range(1025, 2025):
7524 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7525 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7526 UDP(sport=port, dport=port))
7529 self.pg0.add_stream(pkts)
7530 self.pg_enable_capture(self.pg_interfaces)
7532 capture = self.pg1.get_capture(len(pkts))
7534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7536 UDP(sport=3001, dport=3002))
7537 self.pg0.add_stream(p)
7538 self.pg_enable_capture(self.pg_interfaces)
7540 capture = self.pg1.assert_nothing_captured()
7542 # verify ICMP error packet
7543 capture = self.pg0.get_capture(1)
7545 self.assertTrue(p.haslayer(ICMP))
7547 self.assertEqual(icmp.type, 3)
7548 self.assertEqual(icmp.code, 1)
7549 self.assertTrue(icmp.haslayer(IPerror))
7550 inner_ip = icmp[IPerror]
7551 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7552 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7554 dms = self.vapi.nat_det_map_dump()
7556 self.assertEqual(1000, dms[0].ses_num)
7558 # verify IPFIX logging
7559 self.vapi.ipfix_flush()
7561 capture = self.pg2.get_capture(2)
7562 ipfix = IPFIXDecoder()
7563 # first load template
7565 self.assertTrue(p.haslayer(IPFIX))
7566 if p.haslayer(Template):
7567 ipfix.add_template(p.getlayer(Template))
7568 # verify events in data set
7570 if p.haslayer(Data):
7571 data = ipfix.decode_data_set(p.getlayer(Set))
7572 self.verify_ipfix_max_entries_per_user(data,
7574 self.pg0.remote_ip4)
7576 def clear_nat_det(self):
7578 Clear deterministic NAT configuration.
7580 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7582 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7583 tcp_transitory=240, icmp=60)
7584 deterministic_mappings = self.vapi.nat_det_map_dump()
7585 for dsm in deterministic_mappings:
7586 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7587 in_plen=dsm.in_plen,
7588 out_addr=dsm.out_addr,
7589 out_plen=dsm.out_plen)
7591 interfaces = self.vapi.nat44_interface_dump()
7592 for intf in interfaces:
7593 self.vapi.nat44_interface_add_del_feature(
7594 sw_if_index=intf.sw_if_index,
7598 super(TestDeterministicNAT, self).tearDown()
7599 if not self.vpp_dead:
7600 self.clear_nat_det()
7602 def show_commands_at_teardown(self):
7603 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7604 self.logger.info(self.vapi.cli("show nat timeouts"))
7606 self.vapi.cli("show nat44 deterministic mappings"))
7608 self.vapi.cli("show nat44 deterministic sessions"))
7611 class TestNAT64(MethodHolder):
7612 """ NAT64 Test Cases """
7615 def setUpConstants(cls):
7616 super(TestNAT64, cls).setUpConstants()
7617 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7618 "nat64 st hash buckets 256", "}"])
7621 def setUpClass(cls):
7622 super(TestNAT64, cls).setUpClass()
7624 cls.tcp_port_in = 6303
7625 cls.tcp_port_out = 6303
7626 cls.udp_port_in = 6304
7627 cls.udp_port_out = 6304
7628 cls.icmp_id_in = 6305
7629 cls.icmp_id_out = 6305
7630 cls.tcp_external_port = 80
7631 cls.nat_addr = '10.0.0.3'
7632 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7634 cls.vrf1_nat_addr = '10.0.10.3'
7635 cls.ipfix_src_port = 4739
7636 cls.ipfix_domain_id = 1
7638 cls.create_pg_interfaces(range(6))
7639 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7640 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7641 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7643 cls.vapi.ip_table_add_del(is_add=1,
7644 table={'table_id': cls.vrf1_id,
7647 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7649 cls.pg0.generate_remote_hosts(2)
7651 for i in cls.ip6_interfaces:
7654 i.configure_ipv6_neighbors()
7656 for i in cls.ip4_interfaces:
7662 cls.pg3.config_ip4()
7663 cls.pg3.resolve_arp()
7664 cls.pg3.config_ip6()
7665 cls.pg3.configure_ipv6_neighbors()
7668 cls.pg5.config_ip6()
7671 def tearDownClass(cls):
7672 super(TestNAT64, cls).tearDownClass()
7674 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7675 """ NAT64 inside interface handles Neighbor Advertisement """
7677 flags = self.config_flags.NAT_IS_INSIDE
7678 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7679 sw_if_index=self.pg5.sw_if_index)
7682 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7683 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7684 ICMPv6EchoRequest())
7686 self.pg5.add_stream(pkts)
7687 self.pg_enable_capture(self.pg_interfaces)
7690 # Wait for Neighbor Solicitation
7691 capture = self.pg5.get_capture(len(pkts))
7694 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7695 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7696 tgt = packet[ICMPv6ND_NS].tgt
7698 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7701 # Send Neighbor Advertisement
7702 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7703 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7704 ICMPv6ND_NA(tgt=tgt) /
7705 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7707 self.pg5.add_stream(pkts)
7708 self.pg_enable_capture(self.pg_interfaces)
7711 # Try to send ping again
7713 self.pg5.add_stream(pkts)
7714 self.pg_enable_capture(self.pg_interfaces)
7717 # Wait for ping reply
7718 capture = self.pg5.get_capture(len(pkts))
7721 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7722 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7723 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7725 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7728 def test_pool(self):
7729 """ Add/delete address to NAT64 pool """
7730 nat_addr = '1.2.3.4'
7732 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7734 vrf_id=0xFFFFFFFF, is_add=1)
7736 addresses = self.vapi.nat64_pool_addr_dump()
7737 self.assertEqual(len(addresses), 1)
7738 self.assertEqual(str(addresses[0].address), nat_addr)
7740 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7742 vrf_id=0xFFFFFFFF, is_add=0)
7744 addresses = self.vapi.nat64_pool_addr_dump()
7745 self.assertEqual(len(addresses), 0)
7747 def test_interface(self):
7748 """ Enable/disable NAT64 feature on the interface """
7749 flags = self.config_flags.NAT_IS_INSIDE
7750 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7751 sw_if_index=self.pg0.sw_if_index)
7752 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7753 sw_if_index=self.pg1.sw_if_index)
7755 interfaces = self.vapi.nat64_interface_dump()
7756 self.assertEqual(len(interfaces), 2)
7759 for intf in interfaces:
7760 if intf.sw_if_index == self.pg0.sw_if_index:
7761 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7763 elif intf.sw_if_index == self.pg1.sw_if_index:
7764 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7766 self.assertTrue(pg0_found)
7767 self.assertTrue(pg1_found)
7769 features = self.vapi.cli("show interface features pg0")
7770 self.assertIn('nat64-in2out', features)
7771 features = self.vapi.cli("show interface features pg1")
7772 self.assertIn('nat64-out2in', features)
7774 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7775 sw_if_index=self.pg0.sw_if_index)
7776 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7777 sw_if_index=self.pg1.sw_if_index)
7779 interfaces = self.vapi.nat64_interface_dump()
7780 self.assertEqual(len(interfaces), 0)
7782 def test_static_bib(self):
7783 """ Add/delete static BIB entry """
7784 in_addr = '2001:db8:85a3::8a2e:370:7334'
7785 out_addr = '10.1.1.3'
7788 proto = IP_PROTOS.tcp
7790 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7791 i_port=in_port, o_port=out_port,
7792 proto=proto, vrf_id=0, is_add=1)
7793 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7796 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7798 self.assertEqual(str(bibe.i_addr), in_addr)
7799 self.assertEqual(str(bibe.o_addr), out_addr)
7800 self.assertEqual(bibe.i_port, in_port)
7801 self.assertEqual(bibe.o_port, out_port)
7802 self.assertEqual(static_bib_num, 1)
7803 bibs = self.statistics.get_counter('/nat64/total-bibs')
7804 self.assertEqual(bibs[0][0], 1)
7806 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7807 i_port=in_port, o_port=out_port,
7808 proto=proto, vrf_id=0, is_add=0)
7809 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7812 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7814 self.assertEqual(static_bib_num, 0)
7815 bibs = self.statistics.get_counter('/nat64/total-bibs')
7816 self.assertEqual(bibs[0][0], 0)
7818 def test_set_timeouts(self):
7819 """ Set NAT64 timeouts """
7820 # verify default values
7821 timeouts = self.vapi.nat_get_timeouts()
7822 self.assertEqual(timeouts.udp, 300)
7823 self.assertEqual(timeouts.icmp, 60)
7824 self.assertEqual(timeouts.tcp_transitory, 240)
7825 self.assertEqual(timeouts.tcp_established, 7440)
7827 # set and verify custom values
7828 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7829 tcp_transitory=250, icmp=30)
7830 timeouts = self.vapi.nat_get_timeouts()
7831 self.assertEqual(timeouts.udp, 200)
7832 self.assertEqual(timeouts.icmp, 30)
7833 self.assertEqual(timeouts.tcp_transitory, 250)
7834 self.assertEqual(timeouts.tcp_established, 7450)
7836 def test_dynamic(self):
7837 """ NAT64 dynamic translation test """
7838 self.tcp_port_in = 6303
7839 self.udp_port_in = 6304
7840 self.icmp_id_in = 6305
7842 ses_num_start = self.nat64_get_ses_num()
7844 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7845 end_addr=self.nat_addr,
7848 flags = self.config_flags.NAT_IS_INSIDE
7849 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7850 sw_if_index=self.pg0.sw_if_index)
7851 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7852 sw_if_index=self.pg1.sw_if_index)
7855 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7856 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7857 icmpn = self.statistics.get_err_counter(
7858 '/err/nat64-in2out/ICMP packets')
7859 totaln = self.statistics.get_err_counter(
7860 '/err/nat64-in2out/good in2out packets processed')
7862 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7863 self.pg0.add_stream(pkts)
7864 self.pg_enable_capture(self.pg_interfaces)
7866 capture = self.pg1.get_capture(len(pkts))
7867 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7868 dst_ip=self.pg1.remote_ip4)
7870 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7871 self.assertEqual(err - tcpn, 1)
7872 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7873 self.assertEqual(err - udpn, 1)
7874 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7875 self.assertEqual(err - icmpn, 1)
7876 err = self.statistics.get_err_counter(
7877 '/err/nat64-in2out/good in2out packets processed')
7878 self.assertEqual(err - totaln, 3)
7881 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7882 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7883 icmpn = self.statistics.get_err_counter(
7884 '/err/nat64-out2in/ICMP packets')
7885 totaln = self.statistics.get_err_counter(
7886 '/err/nat64-out2in/good out2in packets processed')
7888 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7889 self.pg1.add_stream(pkts)
7890 self.pg_enable_capture(self.pg_interfaces)
7892 capture = self.pg0.get_capture(len(pkts))
7893 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7894 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7896 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7897 self.assertEqual(err - tcpn, 2)
7898 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7899 self.assertEqual(err - udpn, 1)
7900 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7901 self.assertEqual(err - icmpn, 1)
7902 err = self.statistics.get_err_counter(
7903 '/err/nat64-out2in/good out2in packets processed')
7904 self.assertEqual(err - totaln, 4)
7906 bibs = self.statistics.get_counter('/nat64/total-bibs')
7907 self.assertEqual(bibs[0][0], 3)
7908 sessions = self.statistics.get_counter('/nat64/total-sessions')
7909 self.assertEqual(sessions[0][0], 3)
7912 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7913 self.pg0.add_stream(pkts)
7914 self.pg_enable_capture(self.pg_interfaces)
7916 capture = self.pg1.get_capture(len(pkts))
7917 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7918 dst_ip=self.pg1.remote_ip4)
7921 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7922 self.pg1.add_stream(pkts)
7923 self.pg_enable_capture(self.pg_interfaces)
7925 capture = self.pg0.get_capture(len(pkts))
7926 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7928 ses_num_end = self.nat64_get_ses_num()
7930 self.assertEqual(ses_num_end - ses_num_start, 3)
7932 # tenant with specific VRF
7933 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7934 end_addr=self.vrf1_nat_addr,
7935 vrf_id=self.vrf1_id, is_add=1)
7936 flags = self.config_flags.NAT_IS_INSIDE
7937 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7938 sw_if_index=self.pg2.sw_if_index)
7940 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7941 self.pg2.add_stream(pkts)
7942 self.pg_enable_capture(self.pg_interfaces)
7944 capture = self.pg1.get_capture(len(pkts))
7945 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7946 dst_ip=self.pg1.remote_ip4)
7948 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7949 self.pg1.add_stream(pkts)
7950 self.pg_enable_capture(self.pg_interfaces)
7952 capture = self.pg2.get_capture(len(pkts))
7953 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7955 def test_static(self):
7956 """ NAT64 static translation test """
7957 self.tcp_port_in = 60303
7958 self.udp_port_in = 60304
7959 self.icmp_id_in = 60305
7960 self.tcp_port_out = 60303
7961 self.udp_port_out = 60304
7962 self.icmp_id_out = 60305
7964 ses_num_start = self.nat64_get_ses_num()
7966 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7967 end_addr=self.nat_addr,
7970 flags = self.config_flags.NAT_IS_INSIDE
7971 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7972 sw_if_index=self.pg0.sw_if_index)
7973 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7974 sw_if_index=self.pg1.sw_if_index)
7976 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7977 o_addr=self.nat_addr,
7978 i_port=self.tcp_port_in,
7979 o_port=self.tcp_port_out,
7980 proto=IP_PROTOS.tcp, vrf_id=0,
7982 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7983 o_addr=self.nat_addr,
7984 i_port=self.udp_port_in,
7985 o_port=self.udp_port_out,
7986 proto=IP_PROTOS.udp, vrf_id=0,
7988 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7989 o_addr=self.nat_addr,
7990 i_port=self.icmp_id_in,
7991 o_port=self.icmp_id_out,
7992 proto=IP_PROTOS.icmp, vrf_id=0,
7996 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7997 self.pg0.add_stream(pkts)
7998 self.pg_enable_capture(self.pg_interfaces)
8000 capture = self.pg1.get_capture(len(pkts))
8001 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8002 dst_ip=self.pg1.remote_ip4, same_port=True)
8005 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8006 self.pg1.add_stream(pkts)
8007 self.pg_enable_capture(self.pg_interfaces)
8009 capture = self.pg0.get_capture(len(pkts))
8010 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8011 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8013 ses_num_end = self.nat64_get_ses_num()
8015 self.assertEqual(ses_num_end - ses_num_start, 3)
8017 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8018 def test_session_timeout(self):
8019 """ NAT64 session timeout """
8020 self.icmp_id_in = 1234
8021 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8022 end_addr=self.nat_addr,
8025 flags = self.config_flags.NAT_IS_INSIDE
8026 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8027 sw_if_index=self.pg0.sw_if_index)
8028 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8029 sw_if_index=self.pg1.sw_if_index)
8030 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8034 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8035 self.pg0.add_stream(pkts)
8036 self.pg_enable_capture(self.pg_interfaces)
8038 capture = self.pg1.get_capture(len(pkts))
8040 ses_num_before_timeout = self.nat64_get_ses_num()
8044 # ICMP and TCP session after timeout
8045 ses_num_after_timeout = self.nat64_get_ses_num()
8046 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8048 def test_icmp_error(self):
8049 """ NAT64 ICMP Error message translation """
8050 self.tcp_port_in = 6303
8051 self.udp_port_in = 6304
8052 self.icmp_id_in = 6305
8054 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8055 end_addr=self.nat_addr,
8058 flags = self.config_flags.NAT_IS_INSIDE
8059 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8060 sw_if_index=self.pg0.sw_if_index)
8061 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8062 sw_if_index=self.pg1.sw_if_index)
8064 # send some packets to create sessions
8065 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8066 self.pg0.add_stream(pkts)
8067 self.pg_enable_capture(self.pg_interfaces)
8069 capture_ip4 = self.pg1.get_capture(len(pkts))
8070 self.verify_capture_out(capture_ip4,
8071 nat_ip=self.nat_addr,
8072 dst_ip=self.pg1.remote_ip4)
8074 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8075 self.pg1.add_stream(pkts)
8076 self.pg_enable_capture(self.pg_interfaces)
8078 capture_ip6 = self.pg0.get_capture(len(pkts))
8079 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8080 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8081 self.pg0.remote_ip6)
8084 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8085 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8086 ICMPv6DestUnreach(code=1) /
8087 packet[IPv6] for packet in capture_ip6]
8088 self.pg0.add_stream(pkts)
8089 self.pg_enable_capture(self.pg_interfaces)
8091 capture = self.pg1.get_capture(len(pkts))
8092 for packet in capture:
8094 self.assertEqual(packet[IP].src, self.nat_addr)
8095 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8096 self.assertEqual(packet[ICMP].type, 3)
8097 self.assertEqual(packet[ICMP].code, 13)
8098 inner = packet[IPerror]
8099 self.assertEqual(inner.src, self.pg1.remote_ip4)
8100 self.assertEqual(inner.dst, self.nat_addr)
8101 self.assert_packet_checksums_valid(packet)
8102 if inner.haslayer(TCPerror):
8103 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8104 elif inner.haslayer(UDPerror):
8105 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8107 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8109 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8113 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8114 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8115 ICMP(type=3, code=13) /
8116 packet[IP] for packet in capture_ip4]
8117 self.pg1.add_stream(pkts)
8118 self.pg_enable_capture(self.pg_interfaces)
8120 capture = self.pg0.get_capture(len(pkts))
8121 for packet in capture:
8123 self.assertEqual(packet[IPv6].src, ip.src)
8124 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8125 icmp = packet[ICMPv6DestUnreach]
8126 self.assertEqual(icmp.code, 1)
8127 inner = icmp[IPerror6]
8128 self.assertEqual(inner.src, self.pg0.remote_ip6)
8129 self.assertEqual(inner.dst, ip.src)
8130 self.assert_icmpv6_checksum_valid(packet)
8131 if inner.haslayer(TCPerror):
8132 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8133 elif inner.haslayer(UDPerror):
8134 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8136 self.assertEqual(inner[ICMPv6EchoRequest].id,
8139 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8142 def test_hairpinning(self):
8143 """ NAT64 hairpinning """
8145 client = self.pg0.remote_hosts[0]
8146 server = self.pg0.remote_hosts[1]
8147 server_tcp_in_port = 22
8148 server_tcp_out_port = 4022
8149 server_udp_in_port = 23
8150 server_udp_out_port = 4023
8151 client_tcp_in_port = 1234
8152 client_udp_in_port = 1235
8153 client_tcp_out_port = 0
8154 client_udp_out_port = 0
8155 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8156 nat_addr_ip6 = ip.src
8158 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8159 end_addr=self.nat_addr,
8162 flags = self.config_flags.NAT_IS_INSIDE
8163 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8164 sw_if_index=self.pg0.sw_if_index)
8165 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8166 sw_if_index=self.pg1.sw_if_index)
8168 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8169 o_addr=self.nat_addr,
8170 i_port=server_tcp_in_port,
8171 o_port=server_tcp_out_port,
8172 proto=IP_PROTOS.tcp, vrf_id=0,
8174 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8175 o_addr=self.nat_addr,
8176 i_port=server_udp_in_port,
8177 o_port=server_udp_out_port,
8178 proto=IP_PROTOS.udp, vrf_id=0,
8183 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8184 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8185 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8187 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8188 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8189 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8191 self.pg0.add_stream(pkts)
8192 self.pg_enable_capture(self.pg_interfaces)
8194 capture = self.pg0.get_capture(len(pkts))
8195 for packet in capture:
8197 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8198 self.assertEqual(packet[IPv6].dst, server.ip6)
8199 self.assert_packet_checksums_valid(packet)
8200 if packet.haslayer(TCP):
8201 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8202 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8203 client_tcp_out_port = packet[TCP].sport
8205 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8206 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8207 client_udp_out_port = packet[UDP].sport
8209 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8214 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8215 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8216 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8218 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8219 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8220 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8222 self.pg0.add_stream(pkts)
8223 self.pg_enable_capture(self.pg_interfaces)
8225 capture = self.pg0.get_capture(len(pkts))
8226 for packet in capture:
8228 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8229 self.assertEqual(packet[IPv6].dst, client.ip6)
8230 self.assert_packet_checksums_valid(packet)
8231 if packet.haslayer(TCP):
8232 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8233 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8235 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8236 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8238 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8243 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8244 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8245 ICMPv6DestUnreach(code=1) /
8246 packet[IPv6] for packet in capture]
8247 self.pg0.add_stream(pkts)
8248 self.pg_enable_capture(self.pg_interfaces)
8250 capture = self.pg0.get_capture(len(pkts))
8251 for packet in capture:
8253 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8254 self.assertEqual(packet[IPv6].dst, server.ip6)
8255 icmp = packet[ICMPv6DestUnreach]
8256 self.assertEqual(icmp.code, 1)
8257 inner = icmp[IPerror6]
8258 self.assertEqual(inner.src, server.ip6)
8259 self.assertEqual(inner.dst, nat_addr_ip6)
8260 self.assert_packet_checksums_valid(packet)
8261 if inner.haslayer(TCPerror):
8262 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8263 self.assertEqual(inner[TCPerror].dport,
8264 client_tcp_out_port)
8266 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8267 self.assertEqual(inner[UDPerror].dport,
8268 client_udp_out_port)
8270 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8273 def test_prefix(self):
8274 """ NAT64 Network-Specific Prefix """
8276 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8277 end_addr=self.nat_addr,
8280 flags = self.config_flags.NAT_IS_INSIDE
8281 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8282 sw_if_index=self.pg0.sw_if_index)
8283 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8284 sw_if_index=self.pg1.sw_if_index)
8285 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8286 end_addr=self.vrf1_nat_addr,
8287 vrf_id=self.vrf1_id, is_add=1)
8288 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8289 sw_if_index=self.pg2.sw_if_index)
8292 global_pref64 = "2001:db8::"
8293 global_pref64_len = 32
8294 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8295 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8298 prefix = self.vapi.nat64_prefix_dump()
8299 self.assertEqual(len(prefix), 1)
8300 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8301 self.assertEqual(prefix[0].vrf_id, 0)
8303 # Add tenant specific prefix
8304 vrf1_pref64 = "2001:db8:122:300::"
8305 vrf1_pref64_len = 56
8306 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8307 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8308 vrf_id=self.vrf1_id, is_add=1)
8310 prefix = self.vapi.nat64_prefix_dump()
8311 self.assertEqual(len(prefix), 2)
8314 pkts = self.create_stream_in_ip6(self.pg0,
8317 plen=global_pref64_len)
8318 self.pg0.add_stream(pkts)
8319 self.pg_enable_capture(self.pg_interfaces)
8321 capture = self.pg1.get_capture(len(pkts))
8322 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8323 dst_ip=self.pg1.remote_ip4)
8325 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8326 self.pg1.add_stream(pkts)
8327 self.pg_enable_capture(self.pg_interfaces)
8329 capture = self.pg0.get_capture(len(pkts))
8330 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8333 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8335 # Tenant specific prefix
8336 pkts = self.create_stream_in_ip6(self.pg2,
8339 plen=vrf1_pref64_len)
8340 self.pg2.add_stream(pkts)
8341 self.pg_enable_capture(self.pg_interfaces)
8343 capture = self.pg1.get_capture(len(pkts))
8344 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8345 dst_ip=self.pg1.remote_ip4)
8347 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8348 self.pg1.add_stream(pkts)
8349 self.pg_enable_capture(self.pg_interfaces)
8351 capture = self.pg2.get_capture(len(pkts))
8352 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8355 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8357 def test_unknown_proto(self):
8358 """ NAT64 translate packet with unknown protocol """
8360 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8361 end_addr=self.nat_addr,
8364 flags = self.config_flags.NAT_IS_INSIDE
8365 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8366 sw_if_index=self.pg0.sw_if_index)
8367 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8368 sw_if_index=self.pg1.sw_if_index)
8369 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8372 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8373 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8374 TCP(sport=self.tcp_port_in, dport=20))
8375 self.pg0.add_stream(p)
8376 self.pg_enable_capture(self.pg_interfaces)
8378 p = self.pg1.get_capture(1)
8380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8381 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8383 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8384 TCP(sport=1234, dport=1234))
8385 self.pg0.add_stream(p)
8386 self.pg_enable_capture(self.pg_interfaces)
8388 p = self.pg1.get_capture(1)
8391 self.assertEqual(packet[IP].src, self.nat_addr)
8392 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8393 self.assertEqual(packet.haslayer(GRE), 1)
8394 self.assert_packet_checksums_valid(packet)
8396 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8400 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8401 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8403 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8404 TCP(sport=1234, dport=1234))
8405 self.pg1.add_stream(p)
8406 self.pg_enable_capture(self.pg_interfaces)
8408 p = self.pg0.get_capture(1)
8411 self.assertEqual(packet[IPv6].src, remote_ip6)
8412 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8413 self.assertEqual(packet[IPv6].nh, 47)
8415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8418 def test_hairpinning_unknown_proto(self):
8419 """ NAT64 translate packet with unknown protocol - hairpinning """
8421 client = self.pg0.remote_hosts[0]
8422 server = self.pg0.remote_hosts[1]
8423 server_tcp_in_port = 22
8424 server_tcp_out_port = 4022
8425 client_tcp_in_port = 1234
8426 client_tcp_out_port = 1235
8427 server_nat_ip = "10.0.0.100"
8428 client_nat_ip = "10.0.0.110"
8429 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8430 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8432 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8433 end_addr=client_nat_ip,
8436 flags = self.config_flags.NAT_IS_INSIDE
8437 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8438 sw_if_index=self.pg0.sw_if_index)
8439 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8440 sw_if_index=self.pg1.sw_if_index)
8442 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8443 o_addr=server_nat_ip,
8444 i_port=server_tcp_in_port,
8445 o_port=server_tcp_out_port,
8446 proto=IP_PROTOS.tcp, vrf_id=0,
8449 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8450 o_addr=server_nat_ip, i_port=0,
8452 proto=IP_PROTOS.gre, vrf_id=0,
8455 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8456 o_addr=client_nat_ip,
8457 i_port=client_tcp_in_port,
8458 o_port=client_tcp_out_port,
8459 proto=IP_PROTOS.tcp, vrf_id=0,
8463 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8464 IPv6(src=client.ip6, dst=server_nat_ip6) /
8465 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8466 self.pg0.add_stream(p)
8467 self.pg_enable_capture(self.pg_interfaces)
8469 p = self.pg0.get_capture(1)
8471 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8472 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8474 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8475 TCP(sport=1234, dport=1234))
8476 self.pg0.add_stream(p)
8477 self.pg_enable_capture(self.pg_interfaces)
8479 p = self.pg0.get_capture(1)
8482 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8483 self.assertEqual(packet[IPv6].dst, server.ip6)
8484 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8486 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8491 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8493 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8494 TCP(sport=1234, dport=1234))
8495 self.pg0.add_stream(p)
8496 self.pg_enable_capture(self.pg_interfaces)
8498 p = self.pg0.get_capture(1)
8501 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8502 self.assertEqual(packet[IPv6].dst, client.ip6)
8503 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8505 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8508 def test_one_armed_nat64(self):
8509 """ One armed NAT64 """
8511 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8515 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8516 end_addr=self.nat_addr,
8519 flags = self.config_flags.NAT_IS_INSIDE
8520 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8521 sw_if_index=self.pg3.sw_if_index)
8522 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8523 sw_if_index=self.pg3.sw_if_index)
8526 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8527 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8528 TCP(sport=12345, dport=80))
8529 self.pg3.add_stream(p)
8530 self.pg_enable_capture(self.pg_interfaces)
8532 capture = self.pg3.get_capture(1)
8537 self.assertEqual(ip.src, self.nat_addr)
8538 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8539 self.assertNotEqual(tcp.sport, 12345)
8540 external_port = tcp.sport
8541 self.assertEqual(tcp.dport, 80)
8542 self.assert_packet_checksums_valid(p)
8544 self.logger.error(ppp("Unexpected or invalid packet:", p))
8548 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8549 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8550 TCP(sport=80, dport=external_port))
8551 self.pg3.add_stream(p)
8552 self.pg_enable_capture(self.pg_interfaces)
8554 capture = self.pg3.get_capture(1)
8559 self.assertEqual(ip.src, remote_host_ip6)
8560 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8561 self.assertEqual(tcp.sport, 80)
8562 self.assertEqual(tcp.dport, 12345)
8563 self.assert_packet_checksums_valid(p)
8565 self.logger.error(ppp("Unexpected or invalid packet:", p))
8568 def test_frag_in_order(self):
8569 """ NAT64 translate fragments arriving in order """
8570 self.tcp_port_in = random.randint(1025, 65535)
8572 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8573 end_addr=self.nat_addr,
8576 flags = self.config_flags.NAT_IS_INSIDE
8577 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8578 sw_if_index=self.pg0.sw_if_index)
8579 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8580 sw_if_index=self.pg1.sw_if_index)
8584 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8585 self.tcp_port_in, 20, data)
8586 self.pg0.add_stream(pkts)
8587 self.pg_enable_capture(self.pg_interfaces)
8589 frags = self.pg1.get_capture(len(pkts))
8590 p = self.reass_frags_and_verify(frags,
8592 self.pg1.remote_ip4)
8593 self.assertEqual(p[TCP].dport, 20)
8594 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8595 self.tcp_port_out = p[TCP].sport
8596 self.assertEqual(data, p[Raw].load)
8599 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8600 pkts = self.create_stream_frag(self.pg1,
8605 self.pg1.add_stream(pkts)
8606 self.pg_enable_capture(self.pg_interfaces)
8608 frags = self.pg0.get_capture(len(pkts))
8609 self.logger.debug(ppc("Captured:", frags))
8610 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8611 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8612 self.assertEqual(p[TCP].sport, 20)
8613 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8614 self.assertEqual(data, p[Raw].load)
8616 def test_reass_hairpinning(self):
8617 """ NAT64 fragments hairpinning """
8619 server = self.pg0.remote_hosts[1]
8620 server_in_port = random.randint(1025, 65535)
8621 server_out_port = random.randint(1025, 65535)
8622 client_in_port = random.randint(1025, 65535)
8623 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8624 nat_addr_ip6 = ip.src
8626 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8627 end_addr=self.nat_addr,
8630 flags = self.config_flags.NAT_IS_INSIDE
8631 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8632 sw_if_index=self.pg0.sw_if_index)
8633 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8634 sw_if_index=self.pg1.sw_if_index)
8636 # add static BIB entry for server
8637 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8638 o_addr=self.nat_addr,
8639 i_port=server_in_port,
8640 o_port=server_out_port,
8641 proto=IP_PROTOS.tcp, vrf_id=0,
8644 # send packet from host to server
8645 pkts = self.create_stream_frag_ip6(self.pg0,
8650 self.pg0.add_stream(pkts)
8651 self.pg_enable_capture(self.pg_interfaces)
8653 frags = self.pg0.get_capture(len(pkts))
8654 self.logger.debug(ppc("Captured:", frags))
8655 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8656 self.assertNotEqual(p[TCP].sport, client_in_port)
8657 self.assertEqual(p[TCP].dport, server_in_port)
8658 self.assertEqual(data, p[Raw].load)
8660 def test_frag_out_of_order(self):
8661 """ NAT64 translate fragments arriving out of order """
8662 self.tcp_port_in = random.randint(1025, 65535)
8664 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8665 end_addr=self.nat_addr,
8668 flags = self.config_flags.NAT_IS_INSIDE
8669 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8670 sw_if_index=self.pg0.sw_if_index)
8671 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8672 sw_if_index=self.pg1.sw_if_index)
8676 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8677 self.tcp_port_in, 20, data)
8679 self.pg0.add_stream(pkts)
8680 self.pg_enable_capture(self.pg_interfaces)
8682 frags = self.pg1.get_capture(len(pkts))
8683 p = self.reass_frags_and_verify(frags,
8685 self.pg1.remote_ip4)
8686 self.assertEqual(p[TCP].dport, 20)
8687 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8688 self.tcp_port_out = p[TCP].sport
8689 self.assertEqual(data, p[Raw].load)
8692 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8693 pkts = self.create_stream_frag(self.pg1,
8699 self.pg1.add_stream(pkts)
8700 self.pg_enable_capture(self.pg_interfaces)
8702 frags = self.pg0.get_capture(len(pkts))
8703 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8704 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8705 self.assertEqual(p[TCP].sport, 20)
8706 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8707 self.assertEqual(data, p[Raw].load)
8709 def test_interface_addr(self):
8710 """ Acquire NAT64 pool addresses from interface """
8711 self.vapi.nat64_add_del_interface_addr(
8713 sw_if_index=self.pg4.sw_if_index)
8715 # no address in NAT64 pool
8716 addresses = self.vapi.nat44_address_dump()
8717 self.assertEqual(0, len(addresses))
8719 # configure interface address and check NAT64 address pool
8720 self.pg4.config_ip4()
8721 addresses = self.vapi.nat64_pool_addr_dump()
8722 self.assertEqual(len(addresses), 1)
8724 self.assertEqual(str(addresses[0].address),
8727 # remove interface address and check NAT64 address pool
8728 self.pg4.unconfig_ip4()
8729 addresses = self.vapi.nat64_pool_addr_dump()
8730 self.assertEqual(0, len(addresses))
8732 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8733 def test_ipfix_max_bibs_sessions(self):
8734 """ IPFIX logging maximum session and BIB entries exceeded """
8737 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8741 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8742 end_addr=self.nat_addr,
8745 flags = self.config_flags.NAT_IS_INSIDE
8746 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8747 sw_if_index=self.pg0.sw_if_index)
8748 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8749 sw_if_index=self.pg1.sw_if_index)
8753 for i in range(0, max_bibs):
8754 src = "fd01:aa::%x" % (i)
8755 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8756 IPv6(src=src, dst=remote_host_ip6) /
8757 TCP(sport=12345, dport=80))
8759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8760 IPv6(src=src, dst=remote_host_ip6) /
8761 TCP(sport=12345, dport=22))
8763 self.pg0.add_stream(pkts)
8764 self.pg_enable_capture(self.pg_interfaces)
8766 self.pg1.get_capture(max_sessions)
8768 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8769 src_address=self.pg3.local_ip4,
8771 template_interval=10)
8772 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8773 src_port=self.ipfix_src_port,
8776 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8777 IPv6(src=src, dst=remote_host_ip6) /
8778 TCP(sport=12345, dport=25))
8779 self.pg0.add_stream(p)
8780 self.pg_enable_capture(self.pg_interfaces)
8782 self.pg1.assert_nothing_captured()
8784 self.vapi.ipfix_flush()
8785 capture = self.pg3.get_capture(7)
8786 ipfix = IPFIXDecoder()
8787 # first load template
8789 self.assertTrue(p.haslayer(IPFIX))
8790 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8791 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8792 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8793 self.assertEqual(p[UDP].dport, 4739)
8794 self.assertEqual(p[IPFIX].observationDomainID,
8795 self.ipfix_domain_id)
8796 if p.haslayer(Template):
8797 ipfix.add_template(p.getlayer(Template))
8798 # verify events in data set
8800 if p.haslayer(Data):
8801 data = ipfix.decode_data_set(p.getlayer(Set))
8802 self.verify_ipfix_max_sessions(data, max_sessions)
8804 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8805 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8806 TCP(sport=12345, dport=80))
8807 self.pg0.add_stream(p)
8808 self.pg_enable_capture(self.pg_interfaces)
8810 self.pg1.assert_nothing_captured()
8812 self.vapi.ipfix_flush()
8813 capture = self.pg3.get_capture(1)
8814 # verify events in data set
8816 self.assertTrue(p.haslayer(IPFIX))
8817 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8818 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8819 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8820 self.assertEqual(p[UDP].dport, 4739)
8821 self.assertEqual(p[IPFIX].observationDomainID,
8822 self.ipfix_domain_id)
8823 if p.haslayer(Data):
8824 data = ipfix.decode_data_set(p.getlayer(Set))
8825 self.verify_ipfix_max_bibs(data, max_bibs)
8827 def test_ipfix_bib_ses(self):
8828 """ IPFIX logging NAT64 BIB/session create and delete events """
8829 self.tcp_port_in = random.randint(1025, 65535)
8830 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8834 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8835 end_addr=self.nat_addr,
8838 flags = self.config_flags.NAT_IS_INSIDE
8839 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8840 sw_if_index=self.pg0.sw_if_index)
8841 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8842 sw_if_index=self.pg1.sw_if_index)
8843 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8844 src_address=self.pg3.local_ip4,
8846 template_interval=10)
8847 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8848 src_port=self.ipfix_src_port,
8852 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8853 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8854 TCP(sport=self.tcp_port_in, dport=25))
8855 self.pg0.add_stream(p)
8856 self.pg_enable_capture(self.pg_interfaces)
8858 p = self.pg1.get_capture(1)
8859 self.tcp_port_out = p[0][TCP].sport
8860 self.vapi.ipfix_flush()
8861 capture = self.pg3.get_capture(8)
8862 ipfix = IPFIXDecoder()
8863 # first load template
8865 self.assertTrue(p.haslayer(IPFIX))
8866 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8867 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8868 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8869 self.assertEqual(p[UDP].dport, 4739)
8870 self.assertEqual(p[IPFIX].observationDomainID,
8871 self.ipfix_domain_id)
8872 if p.haslayer(Template):
8873 ipfix.add_template(p.getlayer(Template))
8874 # verify events in data set
8876 if p.haslayer(Data):
8877 data = ipfix.decode_data_set(p.getlayer(Set))
8878 if scapy.compat.orb(data[0][230]) == 10:
8879 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8880 elif scapy.compat.orb(data[0][230]) == 6:
8881 self.verify_ipfix_nat64_ses(data,
8883 self.pg0.remote_ip6n,
8884 self.pg1.remote_ip4,
8887 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8890 self.pg_enable_capture(self.pg_interfaces)
8891 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8892 end_addr=self.nat_addr,
8895 self.vapi.ipfix_flush()
8896 capture = self.pg3.get_capture(2)
8897 # verify events in data set
8899 self.assertTrue(p.haslayer(IPFIX))
8900 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8901 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8902 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8903 self.assertEqual(p[UDP].dport, 4739)
8904 self.assertEqual(p[IPFIX].observationDomainID,
8905 self.ipfix_domain_id)
8906 if p.haslayer(Data):
8907 data = ipfix.decode_data_set(p.getlayer(Set))
8908 if scapy.compat.orb(data[0][230]) == 11:
8909 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8910 elif scapy.compat.orb(data[0][230]) == 7:
8911 self.verify_ipfix_nat64_ses(data,
8913 self.pg0.remote_ip6n,
8914 self.pg1.remote_ip4,
8917 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8919 def test_syslog_sess(self):
8920 """ Test syslog session creation and deletion """
8921 self.tcp_port_in = random.randint(1025, 65535)
8922 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8926 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8927 end_addr=self.nat_addr,
8930 flags = self.config_flags.NAT_IS_INSIDE
8931 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8932 sw_if_index=self.pg0.sw_if_index)
8933 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8934 sw_if_index=self.pg1.sw_if_index)
8935 self.vapi.syslog_set_filter(
8936 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8937 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
8939 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8940 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8941 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8942 self.pg0.add_stream(p)
8943 self.pg_enable_capture(self.pg_interfaces)
8945 p = self.pg1.get_capture(1)
8946 self.tcp_port_out = p[0][TCP].sport
8947 capture = self.pg3.get_capture(1)
8948 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8950 self.pg_enable_capture(self.pg_interfaces)
8952 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8953 end_addr=self.nat_addr,
8956 capture = self.pg3.get_capture(1)
8957 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8959 def nat64_get_ses_num(self):
8961 Return number of active NAT64 sessions.
8963 st = self.vapi.nat64_st_dump(proto=255)
8966 def clear_nat64(self):
8968 Clear NAT64 configuration.
8970 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8971 src_port=self.ipfix_src_port,
8973 self.ipfix_src_port = 4739
8974 self.ipfix_domain_id = 1
8976 self.vapi.syslog_set_filter(
8977 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
8979 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8980 tcp_transitory=240, icmp=60)
8982 interfaces = self.vapi.nat64_interface_dump()
8983 for intf in interfaces:
8984 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
8985 sw_if_index=intf.sw_if_index)
8987 bib = self.vapi.nat64_bib_dump(proto=255)
8989 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8990 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
8998 adresses = self.vapi.nat64_pool_addr_dump()
8999 for addr in adresses:
9000 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9001 end_addr=addr.address,
9005 prefixes = self.vapi.nat64_prefix_dump()
9006 for prefix in prefixes:
9007 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9008 vrf_id=prefix.vrf_id, is_add=0)
9010 bibs = self.statistics.get_counter('/nat64/total-bibs')
9011 self.assertEqual(bibs[0][0], 0)
9012 sessions = self.statistics.get_counter('/nat64/total-sessions')
9013 self.assertEqual(sessions[0][0], 0)
9016 super(TestNAT64, self).tearDown()
9017 if not self.vpp_dead:
9020 def show_commands_at_teardown(self):
9021 self.logger.info(self.vapi.cli("show nat64 pool"))
9022 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9023 self.logger.info(self.vapi.cli("show nat64 prefix"))
9024 self.logger.info(self.vapi.cli("show nat64 bib all"))
9025 self.logger.info(self.vapi.cli("show nat64 session table all"))
9028 class TestNAT66(MethodHolder):
9029 """ NAT66 Test Cases """
9032 def setUpClass(cls):
9033 super(TestNAT66, cls).setUpClass()
9035 cls.nat_addr = 'fd01:ff::2'
9037 cls.create_pg_interfaces(range(2))
9038 cls.interfaces = list(cls.pg_interfaces)
9040 for i in cls.interfaces:
9043 i.configure_ipv6_neighbors()
9046 def tearDownClass(cls):
9047 super(TestNAT66, cls).tearDownClass()
9049 def test_static(self):
9050 """ 1:1 NAT66 test """
9051 flags = self.config_flags.NAT_IS_INSIDE
9052 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9053 sw_if_index=self.pg0.sw_if_index)
9054 self.vapi.nat66_add_del_interface(is_add=1,
9055 sw_if_index=self.pg1.sw_if_index)
9056 self.vapi.nat66_add_del_static_mapping(
9057 local_ip_address=self.pg0.remote_ip6n,
9058 external_ip_address=self.nat_addr,
9063 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9064 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9067 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9068 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9071 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9072 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9073 ICMPv6EchoRequest())
9075 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9076 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9077 GRE() / IP() / TCP())
9079 self.pg0.add_stream(pkts)
9080 self.pg_enable_capture(self.pg_interfaces)
9082 capture = self.pg1.get_capture(len(pkts))
9084 for packet in capture:
9086 self.assertEqual(packet[IPv6].src, self.nat_addr)
9087 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9088 self.assert_packet_checksums_valid(packet)
9090 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9095 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9096 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9099 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9100 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9103 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9104 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9107 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9108 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9109 GRE() / IP() / TCP())
9111 self.pg1.add_stream(pkts)
9112 self.pg_enable_capture(self.pg_interfaces)
9114 capture = self.pg0.get_capture(len(pkts))
9115 for packet in capture:
9117 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9118 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9119 self.assert_packet_checksums_valid(packet)
9121 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9124 sm = self.vapi.nat66_static_mapping_dump()
9125 self.assertEqual(len(sm), 1)
9126 self.assertEqual(sm[0].total_pkts, 8)
9128 def test_check_no_translate(self):
9129 """ NAT66 translate only when egress interface is outside interface """
9130 flags = self.config_flags.NAT_IS_INSIDE
9131 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9132 sw_if_index=self.pg0.sw_if_index)
9133 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9134 sw_if_index=self.pg1.sw_if_index)
9135 self.vapi.nat66_add_del_static_mapping(
9136 local_ip_address=self.pg0.remote_ip6n,
9137 external_ip_address=self.nat_addr,
9141 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9142 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9144 self.pg0.add_stream([p])
9145 self.pg_enable_capture(self.pg_interfaces)
9147 capture = self.pg1.get_capture(1)
9150 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9151 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9153 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9156 def clear_nat66(self):
9158 Clear NAT66 configuration.
9160 interfaces = self.vapi.nat66_interface_dump()
9161 for intf in interfaces:
9162 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9163 sw_if_index=intf.sw_if_index)
9165 static_mappings = self.vapi.nat66_static_mapping_dump()
9166 for sm in static_mappings:
9167 self.vapi.nat66_add_del_static_mapping(
9168 local_ip_address=sm.local_ip_address,
9169 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9173 super(TestNAT66, self).tearDown()
9176 def show_commands_at_teardown(self):
9177 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9178 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9181 if __name__ == '__main__':
9182 unittest.main(testRunner=VppTestRunner)