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 users = self.statistics.get_counter('/nat44/total-users')
4514 self.assertEqual(users[0][0], 1)
4515 sessions = self.statistics.get_counter('/nat44/total-sessions')
4516 self.assertEqual(sessions[0][0], 3)
4518 def test_dynamic_output_feature_vrf(self):
4519 """ NAT44 dynamic translation test: output-feature, VRF"""
4521 # other then default (0)
4524 self.nat44_add_address(self.nat_addr)
4525 flags = self.config_flags.NAT_IS_INSIDE
4526 self.vapi.nat44_interface_add_del_output_feature(
4527 sw_if_index=self.pg7.sw_if_index,
4528 flags=flags, is_add=1)
4529 self.vapi.nat44_interface_add_del_output_feature(
4530 sw_if_index=self.pg8.sw_if_index,
4534 self.vapi.ip_table_add_del(is_add=1,
4535 table={'table_id': new_vrf_id})
4537 self.pg7.unconfig_ip4()
4538 self.pg7.set_table_ip4(new_vrf_id)
4539 self.pg7.config_ip4()
4540 self.pg7.resolve_arp()
4542 self.pg8.unconfig_ip4()
4543 self.pg8.set_table_ip4(new_vrf_id)
4544 self.pg8.config_ip4()
4545 self.pg8.resolve_arp()
4547 nat_config = self.vapi.nat_show_config()
4548 self.assertEqual(1, nat_config.endpoint_dependent)
4551 tcpn = self.statistics.get_err_counter(
4552 '/err/nat44-ed-in2out-slowpath/TCP packets')
4553 udpn = self.statistics.get_err_counter(
4554 '/err/nat44-ed-in2out-slowpath/UDP packets')
4555 icmpn = self.statistics.get_err_counter(
4556 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4557 totaln = self.statistics.get_err_counter(
4558 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4560 pkts = self.create_stream_in(self.pg7, self.pg8)
4561 self.pg7.add_stream(pkts)
4562 self.pg_enable_capture(self.pg_interfaces)
4564 capture = self.pg8.get_capture(len(pkts))
4565 self.verify_capture_out(capture)
4567 err = self.statistics.get_err_counter(
4568 '/err/nat44-ed-in2out-slowpath/TCP packets')
4569 self.assertEqual(err - tcpn, 2)
4570 err = self.statistics.get_err_counter(
4571 '/err/nat44-ed-in2out-slowpath/UDP packets')
4572 self.assertEqual(err - udpn, 1)
4573 err = self.statistics.get_err_counter(
4574 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4575 self.assertEqual(err - icmpn, 1)
4576 err = self.statistics.get_err_counter(
4577 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4578 self.assertEqual(err - totaln, 4)
4581 tcpn = self.statistics.get_err_counter(
4582 '/err/nat44-ed-out2in/TCP packets')
4583 udpn = self.statistics.get_err_counter(
4584 '/err/nat44-ed-out2in/UDP packets')
4585 icmpn = self.statistics.get_err_counter(
4586 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4587 totaln = self.statistics.get_err_counter(
4588 '/err/nat44-ed-out2in/good out2in packets processed')
4590 pkts = self.create_stream_out(self.pg8)
4591 self.pg8.add_stream(pkts)
4592 self.pg_enable_capture(self.pg_interfaces)
4594 capture = self.pg7.get_capture(len(pkts))
4595 self.verify_capture_in(capture, self.pg7)
4597 err = self.statistics.get_err_counter(
4598 '/err/nat44-ed-out2in/TCP packets')
4599 self.assertEqual(err - tcpn, 2)
4600 err = self.statistics.get_err_counter(
4601 '/err/nat44-ed-out2in/UDP packets')
4602 self.assertEqual(err - udpn, 1)
4603 err = self.statistics.get_err_counter(
4604 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4605 self.assertEqual(err - icmpn, 1)
4606 err = self.statistics.get_err_counter(
4607 '/err/nat44-ed-out2in/good out2in packets processed')
4608 self.assertEqual(err - totaln, 3)
4610 users = self.statistics.get_counter('/nat44/total-users')
4611 self.assertEqual(users[0][0], 1)
4612 sessions = self.statistics.get_counter('/nat44/total-sessions')
4613 self.assertEqual(sessions[0][0], 3)
4616 self.pg7.unconfig_ip4()
4617 self.pg7.set_table_ip4(1)
4618 self.pg7.config_ip4()
4619 self.pg7.resolve_arp()
4621 self.pg8.unconfig_ip4()
4622 self.pg8.set_table_ip4(1)
4623 self.pg8.config_ip4()
4624 self.pg8.resolve_arp()
4626 self.vapi.ip_table_add_del(is_add=0,
4627 table={'table_id': new_vrf_id})
4629 def test_forwarding(self):
4630 """ NAT44 forwarding test """
4632 flags = self.config_flags.NAT_IS_INSIDE
4633 self.vapi.nat44_interface_add_del_feature(
4634 sw_if_index=self.pg0.sw_if_index,
4635 flags=flags, is_add=1)
4636 self.vapi.nat44_interface_add_del_feature(
4637 sw_if_index=self.pg1.sw_if_index,
4639 self.vapi.nat44_forwarding_enable_disable(enable=1)
4641 real_ip = self.pg0.remote_ip4
4642 alias_ip = self.nat_addr
4643 flags = self.config_flags.NAT_IS_ADDR_ONLY
4644 self.vapi.nat44_add_del_static_mapping(is_add=1,
4645 local_ip_address=real_ip,
4646 external_ip_address=alias_ip,
4647 external_sw_if_index=0xFFFFFFFF,
4651 # in2out - static mapping match
4653 pkts = self.create_stream_out(self.pg1)
4654 self.pg1.add_stream(pkts)
4655 self.pg_enable_capture(self.pg_interfaces)
4657 capture = self.pg0.get_capture(len(pkts))
4658 self.verify_capture_in(capture, self.pg0)
4660 pkts = self.create_stream_in(self.pg0, self.pg1)
4661 self.pg0.add_stream(pkts)
4662 self.pg_enable_capture(self.pg_interfaces)
4664 capture = self.pg1.get_capture(len(pkts))
4665 self.verify_capture_out(capture, same_port=True)
4667 # in2out - no static mapping match
4669 host0 = self.pg0.remote_hosts[0]
4670 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4672 pkts = self.create_stream_out(self.pg1,
4673 dst_ip=self.pg0.remote_ip4,
4674 use_inside_ports=True)
4675 self.pg1.add_stream(pkts)
4676 self.pg_enable_capture(self.pg_interfaces)
4678 capture = self.pg0.get_capture(len(pkts))
4679 self.verify_capture_in(capture, self.pg0)
4681 pkts = self.create_stream_in(self.pg0, self.pg1)
4682 self.pg0.add_stream(pkts)
4683 self.pg_enable_capture(self.pg_interfaces)
4685 capture = self.pg1.get_capture(len(pkts))
4686 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4689 self.pg0.remote_hosts[0] = host0
4691 user = self.pg0.remote_hosts[1]
4692 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4693 self.assertEqual(len(sessions), 3)
4694 self.assertTrue(sessions[0].flags &
4695 self.config_flags.NAT_IS_EXT_HOST_VALID)
4696 self.vapi.nat44_del_session(
4697 address=sessions[0].inside_ip_address,
4698 port=sessions[0].inside_port,
4699 protocol=sessions[0].protocol,
4700 flags=(self.config_flags.NAT_IS_INSIDE |
4701 self.config_flags.NAT_IS_EXT_HOST_VALID),
4702 ext_host_address=sessions[0].ext_host_address,
4703 ext_host_port=sessions[0].ext_host_port)
4704 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4705 self.assertEqual(len(sessions), 2)
4708 self.vapi.nat44_forwarding_enable_disable(enable=0)
4709 flags = self.config_flags.NAT_IS_ADDR_ONLY
4710 self.vapi.nat44_add_del_static_mapping(
4712 local_ip_address=real_ip,
4713 external_ip_address=alias_ip,
4714 external_sw_if_index=0xFFFFFFFF,
4717 def test_static_lb(self):
4718 """ NAT44 local service load balancing """
4719 external_addr_n = self.nat_addr
4722 server1 = self.pg0.remote_hosts[0]
4723 server2 = self.pg0.remote_hosts[1]
4725 locals = [{'addr': server1.ip4,
4729 {'addr': server2.ip4,
4734 self.nat44_add_address(self.nat_addr)
4735 self.vapi.nat44_add_del_lb_static_mapping(
4737 external_addr=external_addr_n,
4738 external_port=external_port,
4739 protocol=IP_PROTOS.tcp,
4740 local_num=len(locals),
4742 flags = self.config_flags.NAT_IS_INSIDE
4743 self.vapi.nat44_interface_add_del_feature(
4744 sw_if_index=self.pg0.sw_if_index,
4745 flags=flags, is_add=1)
4746 self.vapi.nat44_interface_add_del_feature(
4747 sw_if_index=self.pg1.sw_if_index,
4750 # from client to service
4751 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4752 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4753 TCP(sport=12345, dport=external_port))
4754 self.pg1.add_stream(p)
4755 self.pg_enable_capture(self.pg_interfaces)
4757 capture = self.pg0.get_capture(1)
4763 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4764 if ip.dst == server1.ip4:
4768 self.assertEqual(tcp.dport, local_port)
4769 self.assert_packet_checksums_valid(p)
4771 self.logger.error(ppp("Unexpected or invalid packet:", p))
4774 # from service back to client
4775 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4776 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4777 TCP(sport=local_port, dport=12345))
4778 self.pg0.add_stream(p)
4779 self.pg_enable_capture(self.pg_interfaces)
4781 capture = self.pg1.get_capture(1)
4786 self.assertEqual(ip.src, self.nat_addr)
4787 self.assertEqual(tcp.sport, external_port)
4788 self.assert_packet_checksums_valid(p)
4790 self.logger.error(ppp("Unexpected or invalid packet:", p))
4793 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4794 self.assertEqual(len(sessions), 1)
4795 self.assertTrue(sessions[0].flags &
4796 self.config_flags.NAT_IS_EXT_HOST_VALID)
4797 self.vapi.nat44_del_session(
4798 address=sessions[0].inside_ip_address,
4799 port=sessions[0].inside_port,
4800 protocol=sessions[0].protocol,
4801 flags=(self.config_flags.NAT_IS_INSIDE |
4802 self.config_flags.NAT_IS_EXT_HOST_VALID),
4803 ext_host_address=sessions[0].ext_host_address,
4804 ext_host_port=sessions[0].ext_host_port)
4805 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4806 self.assertEqual(len(sessions), 0)
4808 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4809 def test_static_lb_multi_clients(self):
4810 """ NAT44 local service load balancing - multiple clients"""
4812 external_addr = self.nat_addr
4815 server1 = self.pg0.remote_hosts[0]
4816 server2 = self.pg0.remote_hosts[1]
4817 server3 = self.pg0.remote_hosts[2]
4819 locals = [{'addr': server1.ip4,
4823 {'addr': server2.ip4,
4828 self.nat44_add_address(self.nat_addr)
4829 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4830 external_addr=external_addr,
4831 external_port=external_port,
4832 protocol=IP_PROTOS.tcp,
4833 local_num=len(locals),
4835 flags = self.config_flags.NAT_IS_INSIDE
4836 self.vapi.nat44_interface_add_del_feature(
4837 sw_if_index=self.pg0.sw_if_index,
4838 flags=flags, is_add=1)
4839 self.vapi.nat44_interface_add_del_feature(
4840 sw_if_index=self.pg1.sw_if_index,
4845 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4847 for client in clients:
4848 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4849 IP(src=client, dst=self.nat_addr) /
4850 TCP(sport=12345, dport=external_port))
4852 self.pg1.add_stream(pkts)
4853 self.pg_enable_capture(self.pg_interfaces)
4855 capture = self.pg0.get_capture(len(pkts))
4857 if p[IP].dst == server1.ip4:
4861 self.assertGreater(server1_n, server2_n)
4864 'addr': server3.ip4,
4871 self.vapi.nat44_lb_static_mapping_add_del_local(
4873 external_addr=external_addr,
4874 external_port=external_port,
4876 protocol=IP_PROTOS.tcp)
4880 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4882 for client in clients:
4883 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4884 IP(src=client, dst=self.nat_addr) /
4885 TCP(sport=12346, dport=external_port))
4887 self.assertGreater(len(pkts), 0)
4888 self.pg1.add_stream(pkts)
4889 self.pg_enable_capture(self.pg_interfaces)
4891 capture = self.pg0.get_capture(len(pkts))
4893 if p[IP].dst == server1.ip4:
4895 elif p[IP].dst == server2.ip4:
4899 self.assertGreater(server1_n, 0)
4900 self.assertGreater(server2_n, 0)
4901 self.assertGreater(server3_n, 0)
4904 'addr': server2.ip4,
4910 # remove one back-end
4911 self.vapi.nat44_lb_static_mapping_add_del_local(
4913 external_addr=external_addr,
4914 external_port=external_port,
4916 protocol=IP_PROTOS.tcp)
4920 self.pg1.add_stream(pkts)
4921 self.pg_enable_capture(self.pg_interfaces)
4923 capture = self.pg0.get_capture(len(pkts))
4925 if p[IP].dst == server1.ip4:
4927 elif p[IP].dst == server2.ip4:
4931 self.assertGreater(server1_n, 0)
4932 self.assertEqual(server2_n, 0)
4933 self.assertGreater(server3_n, 0)
4935 def test_static_lb_2(self):
4936 """ NAT44 local service load balancing (asymmetrical rule) """
4937 external_addr = self.nat_addr
4940 server1 = self.pg0.remote_hosts[0]
4941 server2 = self.pg0.remote_hosts[1]
4943 locals = [{'addr': server1.ip4,
4947 {'addr': server2.ip4,
4952 self.vapi.nat44_forwarding_enable_disable(enable=1)
4953 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
4954 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
4955 external_addr=external_addr,
4956 external_port=external_port,
4957 protocol=IP_PROTOS.tcp,
4958 local_num=len(locals),
4960 flags = self.config_flags.NAT_IS_INSIDE
4961 self.vapi.nat44_interface_add_del_feature(
4962 sw_if_index=self.pg0.sw_if_index,
4963 flags=flags, is_add=1)
4964 self.vapi.nat44_interface_add_del_feature(
4965 sw_if_index=self.pg1.sw_if_index,
4968 # from client to service
4969 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4970 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4971 TCP(sport=12345, dport=external_port))
4972 self.pg1.add_stream(p)
4973 self.pg_enable_capture(self.pg_interfaces)
4975 capture = self.pg0.get_capture(1)
4981 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4982 if ip.dst == server1.ip4:
4986 self.assertEqual(tcp.dport, local_port)
4987 self.assert_packet_checksums_valid(p)
4989 self.logger.error(ppp("Unexpected or invalid packet:", p))
4992 # from service back to client
4993 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4994 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4995 TCP(sport=local_port, dport=12345))
4996 self.pg0.add_stream(p)
4997 self.pg_enable_capture(self.pg_interfaces)
4999 capture = self.pg1.get_capture(1)
5004 self.assertEqual(ip.src, self.nat_addr)
5005 self.assertEqual(tcp.sport, external_port)
5006 self.assert_packet_checksums_valid(p)
5008 self.logger.error(ppp("Unexpected or invalid packet:", p))
5011 # from client to server (no translation)
5012 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5013 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5014 TCP(sport=12346, dport=local_port))
5015 self.pg1.add_stream(p)
5016 self.pg_enable_capture(self.pg_interfaces)
5018 capture = self.pg0.get_capture(1)
5024 self.assertEqual(ip.dst, server1.ip4)
5025 self.assertEqual(tcp.dport, local_port)
5026 self.assert_packet_checksums_valid(p)
5028 self.logger.error(ppp("Unexpected or invalid packet:", p))
5031 # from service back to client (no translation)
5032 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5033 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5034 TCP(sport=local_port, dport=12346))
5035 self.pg0.add_stream(p)
5036 self.pg_enable_capture(self.pg_interfaces)
5038 capture = self.pg1.get_capture(1)
5043 self.assertEqual(ip.src, server1.ip4)
5044 self.assertEqual(tcp.sport, local_port)
5045 self.assert_packet_checksums_valid(p)
5047 self.logger.error(ppp("Unexpected or invalid packet:", p))
5050 def test_lb_affinity(self):
5051 """ NAT44 local service load balancing affinity """
5052 external_addr = self.nat_addr
5055 server1 = self.pg0.remote_hosts[0]
5056 server2 = self.pg0.remote_hosts[1]
5058 locals = [{'addr': server1.ip4,
5062 {'addr': server2.ip4,
5067 self.nat44_add_address(self.nat_addr)
5068 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5069 external_addr=external_addr,
5070 external_port=external_port,
5071 protocol=IP_PROTOS.tcp,
5073 local_num=len(locals),
5075 flags = self.config_flags.NAT_IS_INSIDE
5076 self.vapi.nat44_interface_add_del_feature(
5077 sw_if_index=self.pg0.sw_if_index,
5078 flags=flags, is_add=1)
5079 self.vapi.nat44_interface_add_del_feature(
5080 sw_if_index=self.pg1.sw_if_index,
5083 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5084 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5085 TCP(sport=1025, dport=external_port))
5086 self.pg1.add_stream(p)
5087 self.pg_enable_capture(self.pg_interfaces)
5089 capture = self.pg0.get_capture(1)
5090 backend = capture[0][IP].dst
5092 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5093 self.assertEqual(len(sessions), 1)
5094 self.assertTrue(sessions[0].flags &
5095 self.config_flags.NAT_IS_EXT_HOST_VALID)
5096 self.vapi.nat44_del_session(
5097 address=sessions[0].inside_ip_address,
5098 port=sessions[0].inside_port,
5099 protocol=sessions[0].protocol,
5100 flags=(self.config_flags.NAT_IS_INSIDE |
5101 self.config_flags.NAT_IS_EXT_HOST_VALID),
5102 ext_host_address=sessions[0].ext_host_address,
5103 ext_host_port=sessions[0].ext_host_port)
5106 for port in range(1030, 1100):
5107 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5108 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5109 TCP(sport=port, dport=external_port))
5111 self.pg1.add_stream(pkts)
5112 self.pg_enable_capture(self.pg_interfaces)
5114 capture = self.pg0.get_capture(len(pkts))
5116 self.assertEqual(p[IP].dst, backend)
5118 def test_unknown_proto(self):
5119 """ NAT44 translate packet with unknown protocol """
5120 self.nat44_add_address(self.nat_addr)
5121 flags = self.config_flags.NAT_IS_INSIDE
5122 self.vapi.nat44_interface_add_del_feature(
5123 sw_if_index=self.pg0.sw_if_index,
5124 flags=flags, is_add=1)
5125 self.vapi.nat44_interface_add_del_feature(
5126 sw_if_index=self.pg1.sw_if_index,
5130 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5131 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5132 TCP(sport=self.tcp_port_in, dport=20))
5133 self.pg0.add_stream(p)
5134 self.pg_enable_capture(self.pg_interfaces)
5136 p = self.pg1.get_capture(1)
5138 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5139 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5141 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5142 TCP(sport=1234, dport=1234))
5143 self.pg0.add_stream(p)
5144 self.pg_enable_capture(self.pg_interfaces)
5146 p = self.pg1.get_capture(1)
5149 self.assertEqual(packet[IP].src, self.nat_addr)
5150 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5151 self.assertEqual(packet.haslayer(GRE), 1)
5152 self.assert_packet_checksums_valid(packet)
5154 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5158 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5159 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5161 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5162 TCP(sport=1234, dport=1234))
5163 self.pg1.add_stream(p)
5164 self.pg_enable_capture(self.pg_interfaces)
5166 p = self.pg0.get_capture(1)
5169 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5170 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5171 self.assertEqual(packet.haslayer(GRE), 1)
5172 self.assert_packet_checksums_valid(packet)
5174 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5177 def test_hairpinning_unknown_proto(self):
5178 """ NAT44 translate packet with unknown protocol - hairpinning """
5179 host = self.pg0.remote_hosts[0]
5180 server = self.pg0.remote_hosts[1]
5182 server_out_port = 8765
5183 server_nat_ip = "10.0.0.11"
5185 self.nat44_add_address(self.nat_addr)
5186 flags = self.config_flags.NAT_IS_INSIDE
5187 self.vapi.nat44_interface_add_del_feature(
5188 sw_if_index=self.pg0.sw_if_index,
5189 flags=flags, is_add=1)
5190 self.vapi.nat44_interface_add_del_feature(
5191 sw_if_index=self.pg1.sw_if_index,
5194 # add static mapping for server
5195 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5198 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5199 IP(src=host.ip4, dst=server_nat_ip) /
5200 TCP(sport=host_in_port, dport=server_out_port))
5201 self.pg0.add_stream(p)
5202 self.pg_enable_capture(self.pg_interfaces)
5204 self.pg0.get_capture(1)
5206 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5207 IP(src=host.ip4, dst=server_nat_ip) /
5209 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5210 TCP(sport=1234, dport=1234))
5211 self.pg0.add_stream(p)
5212 self.pg_enable_capture(self.pg_interfaces)
5214 p = self.pg0.get_capture(1)
5217 self.assertEqual(packet[IP].src, self.nat_addr)
5218 self.assertEqual(packet[IP].dst, server.ip4)
5219 self.assertEqual(packet.haslayer(GRE), 1)
5220 self.assert_packet_checksums_valid(packet)
5222 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5226 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5227 IP(src=server.ip4, dst=self.nat_addr) /
5229 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5230 TCP(sport=1234, dport=1234))
5231 self.pg0.add_stream(p)
5232 self.pg_enable_capture(self.pg_interfaces)
5234 p = self.pg0.get_capture(1)
5237 self.assertEqual(packet[IP].src, server_nat_ip)
5238 self.assertEqual(packet[IP].dst, host.ip4)
5239 self.assertEqual(packet.haslayer(GRE), 1)
5240 self.assert_packet_checksums_valid(packet)
5242 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5245 def test_output_feature_and_service(self):
5246 """ NAT44 interface output feature and services """
5247 external_addr = '1.2.3.4'
5251 self.vapi.nat44_forwarding_enable_disable(enable=1)
5252 self.nat44_add_address(self.nat_addr)
5253 flags = self.config_flags.NAT_IS_ADDR_ONLY
5254 self.vapi.nat44_add_del_identity_mapping(
5255 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5256 flags=flags, is_add=1)
5257 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5258 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5259 local_port, external_port,
5260 proto=IP_PROTOS.tcp, flags=flags)
5261 flags = self.config_flags.NAT_IS_INSIDE
5262 self.vapi.nat44_interface_add_del_feature(
5263 sw_if_index=self.pg0.sw_if_index,
5265 self.vapi.nat44_interface_add_del_feature(
5266 sw_if_index=self.pg0.sw_if_index,
5267 flags=flags, is_add=1)
5268 self.vapi.nat44_interface_add_del_output_feature(
5270 sw_if_index=self.pg1.sw_if_index)
5272 # from client to service
5273 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5274 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5275 TCP(sport=12345, dport=external_port))
5276 self.pg1.add_stream(p)
5277 self.pg_enable_capture(self.pg_interfaces)
5279 capture = self.pg0.get_capture(1)
5284 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5285 self.assertEqual(tcp.dport, local_port)
5286 self.assert_packet_checksums_valid(p)
5288 self.logger.error(ppp("Unexpected or invalid packet:", p))
5291 # from service back to client
5292 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5293 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5294 TCP(sport=local_port, dport=12345))
5295 self.pg0.add_stream(p)
5296 self.pg_enable_capture(self.pg_interfaces)
5298 capture = self.pg1.get_capture(1)
5303 self.assertEqual(ip.src, external_addr)
5304 self.assertEqual(tcp.sport, external_port)
5305 self.assert_packet_checksums_valid(p)
5307 self.logger.error(ppp("Unexpected or invalid packet:", p))
5310 # from local network host to external network
5311 pkts = self.create_stream_in(self.pg0, self.pg1)
5312 self.pg0.add_stream(pkts)
5313 self.pg_enable_capture(self.pg_interfaces)
5315 capture = self.pg1.get_capture(len(pkts))
5316 self.verify_capture_out(capture)
5317 pkts = self.create_stream_in(self.pg0, self.pg1)
5318 self.pg0.add_stream(pkts)
5319 self.pg_enable_capture(self.pg_interfaces)
5321 capture = self.pg1.get_capture(len(pkts))
5322 self.verify_capture_out(capture)
5324 # from external network back to local network host
5325 pkts = self.create_stream_out(self.pg1)
5326 self.pg1.add_stream(pkts)
5327 self.pg_enable_capture(self.pg_interfaces)
5329 capture = self.pg0.get_capture(len(pkts))
5330 self.verify_capture_in(capture, self.pg0)
5332 def test_output_feature_and_service2(self):
5333 """ NAT44 interface output feature and service host direct access """
5334 self.vapi.nat44_forwarding_enable_disable(enable=1)
5335 self.nat44_add_address(self.nat_addr)
5336 self.vapi.nat44_interface_add_del_output_feature(
5338 sw_if_index=self.pg1.sw_if_index)
5340 # session initiated from service host - translate
5341 pkts = self.create_stream_in(self.pg0, self.pg1)
5342 self.pg0.add_stream(pkts)
5343 self.pg_enable_capture(self.pg_interfaces)
5345 capture = self.pg1.get_capture(len(pkts))
5346 self.verify_capture_out(capture)
5348 pkts = self.create_stream_out(self.pg1)
5349 self.pg1.add_stream(pkts)
5350 self.pg_enable_capture(self.pg_interfaces)
5352 capture = self.pg0.get_capture(len(pkts))
5353 self.verify_capture_in(capture, self.pg0)
5355 # session initiated from remote host - do not translate
5356 self.tcp_port_in = 60303
5357 self.udp_port_in = 60304
5358 self.icmp_id_in = 60305
5359 pkts = self.create_stream_out(self.pg1,
5360 self.pg0.remote_ip4,
5361 use_inside_ports=True)
5362 self.pg1.add_stream(pkts)
5363 self.pg_enable_capture(self.pg_interfaces)
5365 capture = self.pg0.get_capture(len(pkts))
5366 self.verify_capture_in(capture, self.pg0)
5368 pkts = self.create_stream_in(self.pg0, self.pg1)
5369 self.pg0.add_stream(pkts)
5370 self.pg_enable_capture(self.pg_interfaces)
5372 capture = self.pg1.get_capture(len(pkts))
5373 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5376 def test_output_feature_and_service3(self):
5377 """ NAT44 interface output feature and DST NAT """
5378 external_addr = '1.2.3.4'
5382 self.vapi.nat44_forwarding_enable_disable(enable=1)
5383 self.nat44_add_address(self.nat_addr)
5384 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5385 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5386 local_port, external_port,
5387 proto=IP_PROTOS.tcp, flags=flags)
5388 flags = self.config_flags.NAT_IS_INSIDE
5389 self.vapi.nat44_interface_add_del_feature(
5390 sw_if_index=self.pg0.sw_if_index,
5392 self.vapi.nat44_interface_add_del_feature(
5393 sw_if_index=self.pg0.sw_if_index,
5394 flags=flags, is_add=1)
5395 self.vapi.nat44_interface_add_del_output_feature(
5397 sw_if_index=self.pg1.sw_if_index)
5399 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5400 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5401 TCP(sport=12345, dport=external_port))
5402 self.pg0.add_stream(p)
5403 self.pg_enable_capture(self.pg_interfaces)
5405 capture = self.pg1.get_capture(1)
5410 self.assertEqual(ip.src, self.pg0.remote_ip4)
5411 self.assertEqual(tcp.sport, 12345)
5412 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5413 self.assertEqual(tcp.dport, local_port)
5414 self.assert_packet_checksums_valid(p)
5416 self.logger.error(ppp("Unexpected or invalid packet:", p))
5419 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5420 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5421 TCP(sport=local_port, dport=12345))
5422 self.pg1.add_stream(p)
5423 self.pg_enable_capture(self.pg_interfaces)
5425 capture = self.pg0.get_capture(1)
5430 self.assertEqual(ip.src, external_addr)
5431 self.assertEqual(tcp.sport, external_port)
5432 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5433 self.assertEqual(tcp.dport, 12345)
5434 self.assert_packet_checksums_valid(p)
5436 self.logger.error(ppp("Unexpected or invalid packet:", p))
5439 def test_next_src_nat(self):
5440 """ On way back forward packet to nat44-in2out node. """
5441 twice_nat_addr = '10.0.1.3'
5444 post_twice_nat_port = 0
5446 self.vapi.nat44_forwarding_enable_disable(enable=1)
5447 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5448 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5449 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5450 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5451 local_port, external_port,
5452 proto=IP_PROTOS.tcp, vrf_id=1,
5454 self.vapi.nat44_interface_add_del_feature(
5455 sw_if_index=self.pg6.sw_if_index,
5458 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5459 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5460 TCP(sport=12345, dport=external_port))
5461 self.pg6.add_stream(p)
5462 self.pg_enable_capture(self.pg_interfaces)
5464 capture = self.pg6.get_capture(1)
5469 self.assertEqual(ip.src, twice_nat_addr)
5470 self.assertNotEqual(tcp.sport, 12345)
5471 post_twice_nat_port = tcp.sport
5472 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5473 self.assertEqual(tcp.dport, local_port)
5474 self.assert_packet_checksums_valid(p)
5476 self.logger.error(ppp("Unexpected or invalid packet:", p))
5479 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5480 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5481 TCP(sport=local_port, dport=post_twice_nat_port))
5482 self.pg6.add_stream(p)
5483 self.pg_enable_capture(self.pg_interfaces)
5485 capture = self.pg6.get_capture(1)
5490 self.assertEqual(ip.src, self.pg1.remote_ip4)
5491 self.assertEqual(tcp.sport, external_port)
5492 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5493 self.assertEqual(tcp.dport, 12345)
5494 self.assert_packet_checksums_valid(p)
5496 self.logger.error(ppp("Unexpected or invalid packet:", p))
5499 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5501 twice_nat_addr = '10.0.1.3'
5509 port_in1 = port_in + 1
5510 port_in2 = port_in + 2
5515 server1 = self.pg0.remote_hosts[0]
5516 server2 = self.pg0.remote_hosts[1]
5528 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5531 self.nat44_add_address(self.nat_addr)
5532 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5536 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5538 flags |= self.config_flags.NAT_IS_TWICE_NAT
5541 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5543 proto=IP_PROTOS.tcp,
5546 locals = [{'addr': server1.ip4,
5550 {'addr': server2.ip4,
5554 out_addr = self.nat_addr
5556 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5557 external_addr=out_addr,
5558 external_port=port_out,
5559 protocol=IP_PROTOS.tcp,
5560 local_num=len(locals),
5562 flags = self.config_flags.NAT_IS_INSIDE
5563 self.vapi.nat44_interface_add_del_feature(
5564 sw_if_index=pg0.sw_if_index,
5565 flags=flags, is_add=1)
5566 self.vapi.nat44_interface_add_del_feature(
5567 sw_if_index=pg1.sw_if_index,
5574 assert client_id is not None
5576 client = self.pg0.remote_hosts[0]
5577 elif client_id == 2:
5578 client = self.pg0.remote_hosts[1]
5580 client = pg1.remote_hosts[0]
5581 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5582 IP(src=client.ip4, dst=self.nat_addr) /
5583 TCP(sport=eh_port_out, dport=port_out))
5585 self.pg_enable_capture(self.pg_interfaces)
5587 capture = pg0.get_capture(1)
5593 if ip.dst == server1.ip4:
5599 self.assertEqual(ip.dst, server.ip4)
5601 self.assertIn(tcp.dport, [port_in1, port_in2])
5603 self.assertEqual(tcp.dport, port_in)
5605 self.assertEqual(ip.src, twice_nat_addr)
5606 self.assertNotEqual(tcp.sport, eh_port_out)
5608 self.assertEqual(ip.src, client.ip4)
5609 self.assertEqual(tcp.sport, eh_port_out)
5611 eh_port_in = tcp.sport
5612 saved_port_in = tcp.dport
5613 self.assert_packet_checksums_valid(p)
5615 self.logger.error(ppp("Unexpected or invalid packet:", p))
5618 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5619 IP(src=server.ip4, dst=eh_addr_in) /
5620 TCP(sport=saved_port_in, dport=eh_port_in))
5622 self.pg_enable_capture(self.pg_interfaces)
5624 capture = pg1.get_capture(1)
5629 self.assertEqual(ip.dst, client.ip4)
5630 self.assertEqual(ip.src, self.nat_addr)
5631 self.assertEqual(tcp.dport, eh_port_out)
5632 self.assertEqual(tcp.sport, port_out)
5633 self.assert_packet_checksums_valid(p)
5635 self.logger.error(ppp("Unexpected or invalid packet:", p))
5639 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5640 self.assertEqual(len(sessions), 1)
5641 self.assertTrue(sessions[0].flags &
5642 self.config_flags.NAT_IS_EXT_HOST_VALID)
5643 self.assertTrue(sessions[0].flags &
5644 self.config_flags.NAT_IS_TWICE_NAT)
5645 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5646 self.vapi.nat44_del_session(
5647 address=sessions[0].inside_ip_address,
5648 port=sessions[0].inside_port,
5649 protocol=sessions[0].protocol,
5650 flags=(self.config_flags.NAT_IS_INSIDE |
5651 self.config_flags.NAT_IS_EXT_HOST_VALID),
5652 ext_host_address=sessions[0].ext_host_nat_address,
5653 ext_host_port=sessions[0].ext_host_nat_port)
5654 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5655 self.assertEqual(len(sessions), 0)
5657 def test_twice_nat(self):
5659 self.twice_nat_common()
5661 def test_self_twice_nat_positive(self):
5662 """ Self Twice NAT44 (positive test) """
5663 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5665 def test_self_twice_nat_negative(self):
5666 """ Self Twice NAT44 (negative test) """
5667 self.twice_nat_common(self_twice_nat=True)
5669 def test_twice_nat_lb(self):
5670 """ Twice NAT44 local service load balancing """
5671 self.twice_nat_common(lb=True)
5673 def test_self_twice_nat_lb_positive(self):
5674 """ Self Twice NAT44 local service load balancing (positive test) """
5675 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5678 def test_self_twice_nat_lb_negative(self):
5679 """ Self Twice NAT44 local service load balancing (negative test) """
5680 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5683 def test_twice_nat_interface_addr(self):
5684 """ Acquire twice NAT44 addresses from interface """
5685 flags = self.config_flags.NAT_IS_TWICE_NAT
5686 self.vapi.nat44_add_del_interface_addr(
5688 sw_if_index=self.pg3.sw_if_index,
5691 # no address in NAT pool
5692 adresses = self.vapi.nat44_address_dump()
5693 self.assertEqual(0, len(adresses))
5695 # configure interface address and check NAT address pool
5696 self.pg3.config_ip4()
5697 adresses = self.vapi.nat44_address_dump()
5698 self.assertEqual(1, len(adresses))
5699 self.assertEqual(str(adresses[0].ip_address),
5701 self.assertEqual(adresses[0].flags, flags)
5703 # remove interface address and check NAT address pool
5704 self.pg3.unconfig_ip4()
5705 adresses = self.vapi.nat44_address_dump()
5706 self.assertEqual(0, len(adresses))
5708 def test_tcp_close(self):
5709 """ Close TCP session from inside network - output feature """
5710 self.vapi.nat44_forwarding_enable_disable(enable=1)
5711 self.nat44_add_address(self.pg1.local_ip4)
5712 twice_nat_addr = '10.0.1.3'
5713 service_ip = '192.168.16.150'
5714 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5715 flags = self.config_flags.NAT_IS_INSIDE
5716 self.vapi.nat44_interface_add_del_feature(
5717 sw_if_index=self.pg0.sw_if_index,
5719 self.vapi.nat44_interface_add_del_feature(
5720 sw_if_index=self.pg0.sw_if_index,
5721 flags=flags, is_add=1)
5722 self.vapi.nat44_interface_add_del_output_feature(
5724 sw_if_index=self.pg1.sw_if_index)
5725 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5726 self.config_flags.NAT_IS_TWICE_NAT)
5727 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5731 proto=IP_PROTOS.tcp,
5733 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5734 start_sessnum = len(sessions)
5736 # SYN packet out->in
5737 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5738 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5739 TCP(sport=33898, dport=80, flags="S"))
5740 self.pg1.add_stream(p)
5741 self.pg_enable_capture(self.pg_interfaces)
5743 capture = self.pg0.get_capture(1)
5745 tcp_port = p[TCP].sport
5747 # SYN + ACK packet in->out
5748 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5749 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5750 TCP(sport=80, dport=tcp_port, flags="SA"))
5751 self.pg0.add_stream(p)
5752 self.pg_enable_capture(self.pg_interfaces)
5754 self.pg1.get_capture(1)
5756 # ACK packet out->in
5757 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5758 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5759 TCP(sport=33898, dport=80, flags="A"))
5760 self.pg1.add_stream(p)
5761 self.pg_enable_capture(self.pg_interfaces)
5763 self.pg0.get_capture(1)
5765 # FIN packet in -> out
5766 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5767 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5768 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5769 self.pg0.add_stream(p)
5770 self.pg_enable_capture(self.pg_interfaces)
5772 self.pg1.get_capture(1)
5774 # FIN+ACK packet out -> in
5775 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5776 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5777 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5778 self.pg1.add_stream(p)
5779 self.pg_enable_capture(self.pg_interfaces)
5781 self.pg0.get_capture(1)
5783 # ACK packet in -> out
5784 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5785 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5786 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5787 self.pg0.add_stream(p)
5788 self.pg_enable_capture(self.pg_interfaces)
5790 self.pg1.get_capture(1)
5792 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5794 self.assertEqual(len(sessions) - start_sessnum, 0)
5796 def test_tcp_session_close_in(self):
5797 """ Close TCP session from inside network """
5798 self.tcp_port_out = 10505
5799 self.nat44_add_address(self.nat_addr)
5800 flags = self.config_flags.NAT_IS_TWICE_NAT
5801 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5805 proto=IP_PROTOS.tcp,
5807 flags = self.config_flags.NAT_IS_INSIDE
5808 self.vapi.nat44_interface_add_del_feature(
5809 sw_if_index=self.pg0.sw_if_index,
5810 flags=flags, is_add=1)
5811 self.vapi.nat44_interface_add_del_feature(
5812 sw_if_index=self.pg1.sw_if_index,
5815 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5816 start_sessnum = len(sessions)
5818 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5819 tcp_transitory=2, icmp=5)
5821 self.initiate_tcp_session(self.pg0, self.pg1)
5823 # FIN packet in -> out
5824 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5825 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5826 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5827 flags="FA", seq=100, ack=300))
5828 self.pg0.add_stream(p)
5829 self.pg_enable_capture(self.pg_interfaces)
5831 self.pg1.get_capture(1)
5835 # ACK packet out -> in
5836 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5837 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5838 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5839 flags="A", seq=300, ack=101))
5842 # FIN packet out -> in
5843 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5844 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5845 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5846 flags="FA", seq=300, ack=101))
5849 self.pg1.add_stream(pkts)
5850 self.pg_enable_capture(self.pg_interfaces)
5852 self.pg0.get_capture(2)
5854 # ACK packet in -> out
5855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5856 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5857 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5858 flags="A", seq=101, ack=301))
5859 self.pg0.add_stream(p)
5860 self.pg_enable_capture(self.pg_interfaces)
5862 self.pg1.get_capture(1)
5864 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5865 self.assertEqual(len(sessions) - start_sessnum, 1)
5867 stats = self.statistics.get_counter(
5868 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5869 out2in_drops = stats[0]
5870 stats = self.statistics.get_counter(
5871 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5872 in2out_drops = stats[0]
5874 # extra FIN packet out -> in - this should be dropped
5875 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5876 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5877 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5878 flags="FA", seq=300, ack=101))
5880 self.pg1.add_stream(p)
5881 self.pg_enable_capture(self.pg_interfaces)
5883 self.pg0.assert_nothing_captured()
5885 # extra ACK packet in -> out - this should be dropped
5886 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5887 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5888 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5889 flags="A", seq=101, ack=301))
5890 self.pg0.add_stream(p)
5891 self.pg_enable_capture(self.pg_interfaces)
5893 self.pg1.assert_nothing_captured()
5895 stats = self.statistics.get_counter(
5896 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5897 self.assertEqual(stats[0] - out2in_drops, 1)
5898 stats = self.statistics.get_counter(
5899 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5900 self.assertEqual(stats[0] - in2out_drops, 1)
5903 # extra ACK packet in -> out - this will cause session to be wiped
5904 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5905 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5906 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5907 flags="A", seq=101, ack=301))
5908 self.pg0.add_stream(p)
5909 self.pg_enable_capture(self.pg_interfaces)
5911 self.pg1.assert_nothing_captured()
5912 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5913 self.assertEqual(len(sessions) - start_sessnum, 0)
5915 def test_tcp_session_close_out(self):
5916 """ Close TCP session from outside network """
5917 self.tcp_port_out = 10505
5918 self.nat44_add_address(self.nat_addr)
5919 flags = self.config_flags.NAT_IS_TWICE_NAT
5920 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5924 proto=IP_PROTOS.tcp,
5926 flags = self.config_flags.NAT_IS_INSIDE
5927 self.vapi.nat44_interface_add_del_feature(
5928 sw_if_index=self.pg0.sw_if_index,
5929 flags=flags, is_add=1)
5930 self.vapi.nat44_interface_add_del_feature(
5931 sw_if_index=self.pg1.sw_if_index,
5934 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5935 start_sessnum = len(sessions)
5937 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
5938 tcp_transitory=2, icmp=5)
5940 self.initiate_tcp_session(self.pg0, self.pg1)
5942 # FIN packet out -> in
5943 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5944 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5945 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5946 flags="FA", seq=100, ack=300))
5947 self.pg1.add_stream(p)
5948 self.pg_enable_capture(self.pg_interfaces)
5950 self.pg0.get_capture(1)
5952 # FIN+ACK packet in -> out
5953 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5954 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5955 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5956 flags="FA", seq=300, ack=101))
5958 self.pg0.add_stream(p)
5959 self.pg_enable_capture(self.pg_interfaces)
5961 self.pg1.get_capture(1)
5963 # ACK packet out -> in
5964 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5965 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5966 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5967 flags="A", seq=101, ack=301))
5968 self.pg1.add_stream(p)
5969 self.pg_enable_capture(self.pg_interfaces)
5971 self.pg0.get_capture(1)
5973 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5974 self.assertEqual(len(sessions) - start_sessnum, 1)
5976 stats = self.statistics.get_counter(
5977 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
5978 out2in_drops = stats[0]
5979 stats = self.statistics.get_counter(
5980 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
5981 in2out_drops = stats[0]
5983 # extra FIN packet out -> in - this should be dropped
5984 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5985 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5986 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5987 flags="FA", seq=300, ack=101))
5989 self.pg1.add_stream(p)
5990 self.pg_enable_capture(self.pg_interfaces)
5992 self.pg0.assert_nothing_captured()
5994 # extra ACK packet in -> out - this should be dropped
5995 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5996 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5997 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5998 flags="A", seq=101, ack=301))
5999 self.pg0.add_stream(p)
6000 self.pg_enable_capture(self.pg_interfaces)
6002 self.pg1.assert_nothing_captured()
6004 stats = self.statistics.get_counter(
6005 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6006 self.assertEqual(stats[0] - out2in_drops, 1)
6007 stats = self.statistics.get_counter(
6008 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6009 self.assertEqual(stats[0] - in2out_drops, 1)
6012 # extra ACK packet in -> out - this will cause session to be wiped
6013 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6014 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6015 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6016 flags="A", seq=101, ack=301))
6017 self.pg0.add_stream(p)
6018 self.pg_enable_capture(self.pg_interfaces)
6020 self.pg1.assert_nothing_captured()
6021 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6022 self.assertEqual(len(sessions) - start_sessnum, 0)
6024 def test_tcp_session_close_simultaneous(self):
6025 """ Close TCP session from inside network """
6026 self.tcp_port_out = 10505
6027 self.nat44_add_address(self.nat_addr)
6028 flags = self.config_flags.NAT_IS_TWICE_NAT
6029 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6033 proto=IP_PROTOS.tcp,
6035 flags = self.config_flags.NAT_IS_INSIDE
6036 self.vapi.nat44_interface_add_del_feature(
6037 sw_if_index=self.pg0.sw_if_index,
6038 flags=flags, is_add=1)
6039 self.vapi.nat44_interface_add_del_feature(
6040 sw_if_index=self.pg1.sw_if_index,
6043 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6044 start_sessnum = len(sessions)
6046 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6047 tcp_transitory=2, icmp=5)
6049 self.initiate_tcp_session(self.pg0, self.pg1)
6051 # FIN packet in -> out
6052 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6053 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6054 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6055 flags="FA", seq=100, ack=300))
6056 self.pg0.add_stream(p)
6057 self.pg_enable_capture(self.pg_interfaces)
6059 self.pg1.get_capture(1)
6061 # FIN packet out -> in
6062 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6063 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6064 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6065 flags="FA", seq=300, ack=100))
6066 self.pg1.add_stream(p)
6067 self.pg_enable_capture(self.pg_interfaces)
6069 self.pg0.get_capture(1)
6071 # ACK packet in -> out
6072 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6073 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6074 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6075 flags="A", seq=101, ack=301))
6076 self.pg0.add_stream(p)
6077 self.pg_enable_capture(self.pg_interfaces)
6079 self.pg1.get_capture(1)
6081 # ACK packet out -> in
6082 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6083 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6084 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6085 flags="A", seq=301, ack=101))
6086 self.pg1.add_stream(p)
6087 self.pg_enable_capture(self.pg_interfaces)
6089 self.pg0.get_capture(1)
6091 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6092 self.assertEqual(len(sessions) - start_sessnum, 1)
6094 stats = self.statistics.get_counter(
6095 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6096 out2in_drops = stats[0]
6097 stats = self.statistics.get_counter(
6098 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6099 in2out_drops = stats[0]
6101 # extra FIN packet out -> in - this should be dropped
6102 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6103 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6104 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6105 flags="FA", seq=300, ack=101))
6107 self.pg1.add_stream(p)
6108 self.pg_enable_capture(self.pg_interfaces)
6110 self.pg0.assert_nothing_captured()
6112 # extra ACK packet in -> out - this should be dropped
6113 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6114 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6115 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6116 flags="A", seq=101, ack=301))
6117 self.pg0.add_stream(p)
6118 self.pg_enable_capture(self.pg_interfaces)
6120 self.pg1.assert_nothing_captured()
6122 stats = self.statistics.get_counter(
6123 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6124 self.assertEqual(stats[0] - out2in_drops, 1)
6125 stats = self.statistics.get_counter(
6126 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6127 self.assertEqual(stats[0] - in2out_drops, 1)
6130 # extra ACK packet in -> out - this will cause session to be wiped
6131 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6132 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6133 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6134 flags="A", seq=101, ack=301))
6135 self.pg0.add_stream(p)
6136 self.pg_enable_capture(self.pg_interfaces)
6138 self.pg1.assert_nothing_captured()
6139 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6140 self.assertEqual(len(sessions) - start_sessnum, 0)
6142 def test_one_armed_nat44_static(self):
6143 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6144 remote_host = self.pg4.remote_hosts[0]
6145 local_host = self.pg4.remote_hosts[1]
6150 self.vapi.nat44_forwarding_enable_disable(enable=1)
6151 self.nat44_add_address(self.nat_addr, twice_nat=1)
6152 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6153 self.config_flags.NAT_IS_TWICE_NAT)
6154 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6155 local_port, external_port,
6156 proto=IP_PROTOS.tcp, flags=flags)
6157 flags = self.config_flags.NAT_IS_INSIDE
6158 self.vapi.nat44_interface_add_del_feature(
6159 sw_if_index=self.pg4.sw_if_index,
6161 self.vapi.nat44_interface_add_del_feature(
6162 sw_if_index=self.pg4.sw_if_index,
6163 flags=flags, is_add=1)
6165 # from client to service
6166 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6167 IP(src=remote_host.ip4, dst=self.nat_addr) /
6168 TCP(sport=12345, dport=external_port))
6169 self.pg4.add_stream(p)
6170 self.pg_enable_capture(self.pg_interfaces)
6172 capture = self.pg4.get_capture(1)
6177 self.assertEqual(ip.dst, local_host.ip4)
6178 self.assertEqual(ip.src, self.nat_addr)
6179 self.assertEqual(tcp.dport, local_port)
6180 self.assertNotEqual(tcp.sport, 12345)
6181 eh_port_in = tcp.sport
6182 self.assert_packet_checksums_valid(p)
6184 self.logger.error(ppp("Unexpected or invalid packet:", p))
6187 # from service back to client
6188 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6189 IP(src=local_host.ip4, dst=self.nat_addr) /
6190 TCP(sport=local_port, dport=eh_port_in))
6191 self.pg4.add_stream(p)
6192 self.pg_enable_capture(self.pg_interfaces)
6194 capture = self.pg4.get_capture(1)
6199 self.assertEqual(ip.src, self.nat_addr)
6200 self.assertEqual(ip.dst, remote_host.ip4)
6201 self.assertEqual(tcp.sport, external_port)
6202 self.assertEqual(tcp.dport, 12345)
6203 self.assert_packet_checksums_valid(p)
6205 self.logger.error(ppp("Unexpected or invalid packet:", p))
6208 def test_static_with_port_out2(self):
6209 """ 1:1 NAPT asymmetrical rule """
6214 self.vapi.nat44_forwarding_enable_disable(enable=1)
6215 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6216 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6217 local_port, external_port,
6218 proto=IP_PROTOS.tcp, flags=flags)
6219 flags = self.config_flags.NAT_IS_INSIDE
6220 self.vapi.nat44_interface_add_del_feature(
6221 sw_if_index=self.pg0.sw_if_index,
6222 flags=flags, is_add=1)
6223 self.vapi.nat44_interface_add_del_feature(
6224 sw_if_index=self.pg1.sw_if_index,
6227 # from client to service
6228 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6229 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6230 TCP(sport=12345, dport=external_port))
6231 self.pg1.add_stream(p)
6232 self.pg_enable_capture(self.pg_interfaces)
6234 capture = self.pg0.get_capture(1)
6239 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6240 self.assertEqual(tcp.dport, local_port)
6241 self.assert_packet_checksums_valid(p)
6243 self.logger.error(ppp("Unexpected or invalid packet:", p))
6247 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6248 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6249 ICMP(type=11) / capture[0][IP])
6250 self.pg0.add_stream(p)
6251 self.pg_enable_capture(self.pg_interfaces)
6253 capture = self.pg1.get_capture(1)
6256 self.assertEqual(p[IP].src, self.nat_addr)
6258 self.assertEqual(inner.dst, self.nat_addr)
6259 self.assertEqual(inner[TCPerror].dport, external_port)
6261 self.logger.error(ppp("Unexpected or invalid packet:", p))
6264 # from service back to client
6265 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6266 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6267 TCP(sport=local_port, dport=12345))
6268 self.pg0.add_stream(p)
6269 self.pg_enable_capture(self.pg_interfaces)
6271 capture = self.pg1.get_capture(1)
6276 self.assertEqual(ip.src, self.nat_addr)
6277 self.assertEqual(tcp.sport, external_port)
6278 self.assert_packet_checksums_valid(p)
6280 self.logger.error(ppp("Unexpected or invalid packet:", p))
6284 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6285 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6286 ICMP(type=11) / capture[0][IP])
6287 self.pg1.add_stream(p)
6288 self.pg_enable_capture(self.pg_interfaces)
6290 capture = self.pg0.get_capture(1)
6293 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6295 self.assertEqual(inner.src, self.pg0.remote_ip4)
6296 self.assertEqual(inner[TCPerror].sport, local_port)
6298 self.logger.error(ppp("Unexpected or invalid packet:", p))
6301 # from client to server (no translation)
6302 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6303 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6304 TCP(sport=12346, dport=local_port))
6305 self.pg1.add_stream(p)
6306 self.pg_enable_capture(self.pg_interfaces)
6308 capture = self.pg0.get_capture(1)
6313 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6314 self.assertEqual(tcp.dport, local_port)
6315 self.assert_packet_checksums_valid(p)
6317 self.logger.error(ppp("Unexpected or invalid packet:", p))
6320 # from service back to client (no translation)
6321 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6322 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6323 TCP(sport=local_port, dport=12346))
6324 self.pg0.add_stream(p)
6325 self.pg_enable_capture(self.pg_interfaces)
6327 capture = self.pg1.get_capture(1)
6332 self.assertEqual(ip.src, self.pg0.remote_ip4)
6333 self.assertEqual(tcp.sport, local_port)
6334 self.assert_packet_checksums_valid(p)
6336 self.logger.error(ppp("Unexpected or invalid packet:", p))
6339 def test_output_feature(self):
6340 """ NAT44 interface output feature (in2out postrouting) """
6341 self.vapi.nat44_forwarding_enable_disable(enable=1)
6342 self.nat44_add_address(self.nat_addr)
6343 self.vapi.nat44_interface_add_del_feature(
6344 sw_if_index=self.pg0.sw_if_index,
6346 self.vapi.nat44_interface_add_del_output_feature(
6348 sw_if_index=self.pg1.sw_if_index)
6351 pkts = self.create_stream_in(self.pg0, self.pg1)
6352 self.pg0.add_stream(pkts)
6353 self.pg_enable_capture(self.pg_interfaces)
6355 capture = self.pg1.get_capture(len(pkts))
6356 self.verify_capture_out(capture)
6359 pkts = self.create_stream_out(self.pg1)
6360 self.pg1.add_stream(pkts)
6361 self.pg_enable_capture(self.pg_interfaces)
6363 capture = self.pg0.get_capture(len(pkts))
6364 self.verify_capture_in(capture, self.pg0)
6366 def test_output_feature_stateful_acl(self):
6367 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6368 self.nat44_add_address(self.nat_addr)
6369 self.vapi.nat44_interface_add_del_output_feature(
6370 sw_if_index=self.pg0.sw_if_index,
6371 flags=self.config_flags.NAT_IS_INSIDE,
6373 self.vapi.nat44_interface_add_del_output_feature(
6374 sw_if_index=self.pg1.sw_if_index,
6375 flags=self.config_flags.NAT_IS_OUTSIDE,
6378 # First ensure that the NAT is working sans ACL
6380 # send packets out2in, no sessions yet so packets should drop
6381 pkts_out2in = self.create_stream_out(self.pg1)
6382 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6384 # send packets into inside intf, ensure received via outside intf
6385 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6386 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6388 self.verify_capture_out(capture)
6390 # send out2in again, with sessions created it should work now
6391 pkts_out2in = self.create_stream_out(self.pg1)
6392 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6394 self.verify_capture_in(capture, self.pg0)
6396 # Create an ACL blocking everything
6397 out2in_deny_rule = AclRule(is_permit=0)
6398 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6399 out2in_acl.add_vpp_config()
6401 # create an ACL to permit/reflect everything
6402 in2out_reflect_rule = AclRule(is_permit=2)
6403 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6404 in2out_acl.add_vpp_config()
6406 # apply as input acl on interface and confirm it blocks everything
6407 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6408 n_input=1, acls=[out2in_acl])
6409 acl_if.add_vpp_config()
6410 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6413 acl_if.acls = [out2in_acl, in2out_acl]
6414 acl_if.add_vpp_config()
6415 # send in2out to generate ACL state (NAT state was created earlier)
6416 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6418 self.verify_capture_out(capture)
6420 # send out2in again. ACL state exists so it should work now.
6421 # TCP packets with the syn flag set also need the ack flag
6422 for p in pkts_out2in:
6423 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6424 p[TCP].flags |= 0x10
6425 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6427 self.verify_capture_in(capture, self.pg0)
6428 self.logger.info(self.vapi.cli("show trace"))
6430 def test_multiple_vrf(self):
6431 """ Multiple VRF setup """
6432 external_addr = '1.2.3.4'
6437 self.vapi.nat44_forwarding_enable_disable(enable=1)
6438 self.nat44_add_address(self.nat_addr)
6439 flags = self.config_flags.NAT_IS_INSIDE
6440 self.vapi.nat44_interface_add_del_feature(
6441 sw_if_index=self.pg0.sw_if_index,
6443 self.vapi.nat44_interface_add_del_feature(
6444 sw_if_index=self.pg0.sw_if_index,
6445 flags=flags, is_add=1)
6446 self.vapi.nat44_interface_add_del_output_feature(
6448 sw_if_index=self.pg1.sw_if_index)
6449 self.vapi.nat44_interface_add_del_feature(
6450 sw_if_index=self.pg5.sw_if_index,
6452 self.vapi.nat44_interface_add_del_feature(
6453 sw_if_index=self.pg5.sw_if_index,
6454 flags=flags, is_add=1)
6455 self.vapi.nat44_interface_add_del_feature(
6456 sw_if_index=self.pg6.sw_if_index,
6458 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6459 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6460 local_port, external_port, vrf_id=1,
6461 proto=IP_PROTOS.tcp, flags=flags)
6462 self.nat44_add_static_mapping(
6463 self.pg0.remote_ip4,
6464 external_sw_if_index=self.pg0.sw_if_index,
6465 local_port=local_port,
6467 external_port=external_port,
6468 proto=IP_PROTOS.tcp,
6472 # from client to service (both VRF1)
6473 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6474 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6475 TCP(sport=12345, dport=external_port))
6476 self.pg6.add_stream(p)
6477 self.pg_enable_capture(self.pg_interfaces)
6479 capture = self.pg5.get_capture(1)
6484 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6485 self.assertEqual(tcp.dport, local_port)
6486 self.assert_packet_checksums_valid(p)
6488 self.logger.error(ppp("Unexpected or invalid packet:", p))
6491 # from service back to client (both VRF1)
6492 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6493 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6494 TCP(sport=local_port, dport=12345))
6495 self.pg5.add_stream(p)
6496 self.pg_enable_capture(self.pg_interfaces)
6498 capture = self.pg6.get_capture(1)
6503 self.assertEqual(ip.src, external_addr)
6504 self.assertEqual(tcp.sport, external_port)
6505 self.assert_packet_checksums_valid(p)
6507 self.logger.error(ppp("Unexpected or invalid packet:", p))
6510 # dynamic NAT from VRF1 to VRF0 (output-feature)
6511 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6512 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6513 TCP(sport=2345, dport=22))
6514 self.pg5.add_stream(p)
6515 self.pg_enable_capture(self.pg_interfaces)
6517 capture = self.pg1.get_capture(1)
6522 self.assertEqual(ip.src, self.nat_addr)
6523 self.assertNotEqual(tcp.sport, 2345)
6524 self.assert_packet_checksums_valid(p)
6527 self.logger.error(ppp("Unexpected or invalid packet:", p))
6530 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6531 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6532 TCP(sport=22, dport=port))
6533 self.pg1.add_stream(p)
6534 self.pg_enable_capture(self.pg_interfaces)
6536 capture = self.pg5.get_capture(1)
6541 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6542 self.assertEqual(tcp.dport, 2345)
6543 self.assert_packet_checksums_valid(p)
6545 self.logger.error(ppp("Unexpected or invalid packet:", p))
6548 # from client VRF1 to service VRF0
6549 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6550 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6551 TCP(sport=12346, dport=external_port))
6552 self.pg6.add_stream(p)
6553 self.pg_enable_capture(self.pg_interfaces)
6555 capture = self.pg0.get_capture(1)
6560 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6561 self.assertEqual(tcp.dport, local_port)
6562 self.assert_packet_checksums_valid(p)
6564 self.logger.error(ppp("Unexpected or invalid packet:", p))
6567 # from service VRF0 back to client VRF1
6568 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6569 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6570 TCP(sport=local_port, dport=12346))
6571 self.pg0.add_stream(p)
6572 self.pg_enable_capture(self.pg_interfaces)
6574 capture = self.pg6.get_capture(1)
6579 self.assertEqual(ip.src, self.pg0.local_ip4)
6580 self.assertEqual(tcp.sport, external_port)
6581 self.assert_packet_checksums_valid(p)
6583 self.logger.error(ppp("Unexpected or invalid packet:", p))
6586 # from client VRF0 to service VRF1
6587 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6588 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6589 TCP(sport=12347, dport=external_port))
6590 self.pg0.add_stream(p)
6591 self.pg_enable_capture(self.pg_interfaces)
6593 capture = self.pg5.get_capture(1)
6598 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6599 self.assertEqual(tcp.dport, local_port)
6600 self.assert_packet_checksums_valid(p)
6602 self.logger.error(ppp("Unexpected or invalid packet:", p))
6605 # from service VRF1 back to client VRF0
6606 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6607 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6608 TCP(sport=local_port, dport=12347))
6609 self.pg5.add_stream(p)
6610 self.pg_enable_capture(self.pg_interfaces)
6612 capture = self.pg0.get_capture(1)
6617 self.assertEqual(ip.src, external_addr)
6618 self.assertEqual(tcp.sport, external_port)
6619 self.assert_packet_checksums_valid(p)
6621 self.logger.error(ppp("Unexpected or invalid packet:", p))
6624 # from client to server (both VRF1, no translation)
6625 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6626 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6627 TCP(sport=12348, dport=local_port))
6628 self.pg6.add_stream(p)
6629 self.pg_enable_capture(self.pg_interfaces)
6631 capture = self.pg5.get_capture(1)
6636 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6637 self.assertEqual(tcp.dport, local_port)
6638 self.assert_packet_checksums_valid(p)
6640 self.logger.error(ppp("Unexpected or invalid packet:", p))
6643 # from server back to client (both VRF1, no translation)
6644 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6645 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6646 TCP(sport=local_port, dport=12348))
6647 self.pg5.add_stream(p)
6648 self.pg_enable_capture(self.pg_interfaces)
6650 capture = self.pg6.get_capture(1)
6655 self.assertEqual(ip.src, self.pg5.remote_ip4)
6656 self.assertEqual(tcp.sport, local_port)
6657 self.assert_packet_checksums_valid(p)
6659 self.logger.error(ppp("Unexpected or invalid packet:", p))
6662 # from client VRF1 to server VRF0 (no translation)
6663 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6664 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6665 TCP(sport=local_port, dport=12349))
6666 self.pg0.add_stream(p)
6667 self.pg_enable_capture(self.pg_interfaces)
6669 capture = self.pg6.get_capture(1)
6674 self.assertEqual(ip.src, self.pg0.remote_ip4)
6675 self.assertEqual(tcp.sport, local_port)
6676 self.assert_packet_checksums_valid(p)
6678 self.logger.error(ppp("Unexpected or invalid packet:", p))
6681 # from server VRF0 back to client VRF1 (no translation)
6682 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6683 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6684 TCP(sport=local_port, dport=12349))
6685 self.pg0.add_stream(p)
6686 self.pg_enable_capture(self.pg_interfaces)
6688 capture = self.pg6.get_capture(1)
6693 self.assertEqual(ip.src, self.pg0.remote_ip4)
6694 self.assertEqual(tcp.sport, local_port)
6695 self.assert_packet_checksums_valid(p)
6697 self.logger.error(ppp("Unexpected or invalid packet:", p))
6700 # from client VRF0 to server VRF1 (no translation)
6701 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6702 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6703 TCP(sport=12344, dport=local_port))
6704 self.pg0.add_stream(p)
6705 self.pg_enable_capture(self.pg_interfaces)
6707 capture = self.pg5.get_capture(1)
6712 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6713 self.assertEqual(tcp.dport, local_port)
6714 self.assert_packet_checksums_valid(p)
6716 self.logger.error(ppp("Unexpected or invalid packet:", p))
6719 # from server VRF1 back to client VRF0 (no translation)
6720 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6721 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6722 TCP(sport=local_port, dport=12344))
6723 self.pg5.add_stream(p)
6724 self.pg_enable_capture(self.pg_interfaces)
6726 capture = self.pg0.get_capture(1)
6731 self.assertEqual(ip.src, self.pg5.remote_ip4)
6732 self.assertEqual(tcp.sport, local_port)
6733 self.assert_packet_checksums_valid(p)
6735 self.logger.error(ppp("Unexpected or invalid packet:", p))
6738 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6739 def test_session_timeout(self):
6740 """ NAT44 session timeouts """
6741 self.nat44_add_address(self.nat_addr)
6742 flags = self.config_flags.NAT_IS_INSIDE
6743 self.vapi.nat44_interface_add_del_feature(
6744 sw_if_index=self.pg0.sw_if_index,
6745 flags=flags, is_add=1)
6746 self.vapi.nat44_interface_add_del_feature(
6747 sw_if_index=self.pg1.sw_if_index,
6749 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6750 tcp_transitory=240, icmp=5)
6754 for i in range(0, max_sessions):
6755 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6756 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6757 IP(src=src, dst=self.pg1.remote_ip4) /
6758 ICMP(id=1025, type='echo-request'))
6760 self.pg0.add_stream(pkts)
6761 self.pg_enable_capture(self.pg_interfaces)
6763 self.pg1.get_capture(max_sessions)
6768 for i in range(0, max_sessions):
6769 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6770 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6771 IP(src=src, dst=self.pg1.remote_ip4) /
6772 ICMP(id=1026, type='echo-request'))
6774 self.pg0.add_stream(pkts)
6775 self.pg_enable_capture(self.pg_interfaces)
6777 self.pg1.get_capture(max_sessions)
6780 users = self.vapi.nat44_user_dump()
6782 nsessions = nsessions + user.nsessions
6783 self.assertLess(nsessions, 2 * max_sessions)
6785 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6786 def test_session_rst_timeout(self):
6787 """ NAT44 session RST timeouts """
6788 self.nat44_add_address(self.nat_addr)
6789 flags = self.config_flags.NAT_IS_INSIDE
6790 self.vapi.nat44_interface_add_del_feature(
6791 sw_if_index=self.pg0.sw_if_index,
6792 flags=flags, is_add=1)
6793 self.vapi.nat44_interface_add_del_feature(
6794 sw_if_index=self.pg1.sw_if_index,
6796 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6797 tcp_transitory=5, icmp=60)
6799 self.initiate_tcp_session(self.pg0, self.pg1)
6800 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6801 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6802 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6804 self.pg0.add_stream(p)
6805 self.pg_enable_capture(self.pg_interfaces)
6807 self.pg1.get_capture(1)
6811 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6812 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6813 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6815 self.pg0.add_stream(p)
6816 self.pg_enable_capture(self.pg_interfaces)
6818 self.pg1.get_capture(1)
6821 users = self.vapi.nat44_user_dump()
6822 self.assertEqual(len(users), 1)
6823 self.assertEqual(str(users[0].ip_address),
6824 self.pg0.remote_ip4)
6825 self.assertEqual(users[0].nsessions, 1)
6827 def test_syslog_sess(self):
6828 """ Test syslog session creation and deletion """
6829 self.vapi.syslog_set_filter(
6830 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6831 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6832 self.nat44_add_address(self.nat_addr)
6833 flags = self.config_flags.NAT_IS_INSIDE
6834 self.vapi.nat44_interface_add_del_feature(
6835 sw_if_index=self.pg0.sw_if_index,
6836 flags=flags, is_add=1)
6837 self.vapi.nat44_interface_add_del_feature(
6838 sw_if_index=self.pg1.sw_if_index,
6841 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6842 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6843 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6844 self.pg0.add_stream(p)
6845 self.pg_enable_capture(self.pg_interfaces)
6847 capture = self.pg1.get_capture(1)
6848 self.tcp_port_out = capture[0][TCP].sport
6849 capture = self.pg2.get_capture(1)
6850 self.verify_syslog_sess(capture[0][Raw].load)
6852 self.pg_enable_capture(self.pg_interfaces)
6854 self.nat44_add_address(self.nat_addr, is_add=0)
6855 capture = self.pg2.get_capture(1)
6856 self.verify_syslog_sess(capture[0][Raw].load, False)
6859 super(TestNAT44EndpointDependent, self).tearDown()
6860 if not self.vpp_dead:
6862 self.vapi.cli("clear logging")
6864 def show_commands_at_teardown(self):
6865 self.logger.info(self.vapi.cli("show nat44 addresses"))
6866 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6867 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6868 self.logger.info(self.vapi.cli("show nat44 interface address"))
6869 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6870 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6871 self.logger.info(self.vapi.cli("show nat timeouts"))
6874 class TestNAT44Out2InDPO(MethodHolder):
6875 """ NAT44 Test Cases using out2in DPO """
6878 def setUpConstants(cls):
6879 super(TestNAT44Out2InDPO, cls).setUpConstants()
6880 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6883 def setUpClass(cls):
6884 super(TestNAT44Out2InDPO, cls).setUpClass()
6885 cls.vapi.cli("set log class nat level debug")
6887 cls.tcp_port_in = 6303
6888 cls.tcp_port_out = 6303
6889 cls.udp_port_in = 6304
6890 cls.udp_port_out = 6304
6891 cls.icmp_id_in = 6305
6892 cls.icmp_id_out = 6305
6893 cls.nat_addr = '10.0.0.3'
6894 cls.dst_ip4 = '192.168.70.1'
6896 cls.create_pg_interfaces(range(2))
6899 cls.pg0.config_ip4()
6900 cls.pg0.resolve_arp()
6903 cls.pg1.config_ip6()
6904 cls.pg1.resolve_ndp()
6906 r1 = VppIpRoute(cls, "::", 0,
6907 [VppRoutePath(cls.pg1.remote_ip6,
6908 cls.pg1.sw_if_index)],
6913 def tearDownClass(cls):
6914 super(TestNAT44Out2InDPO, cls).tearDownClass()
6916 def configure_xlat(self):
6917 self.dst_ip6_pfx = '1:2:3::'
6918 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6920 self.dst_ip6_pfx_len = 96
6921 self.src_ip6_pfx = '4:5:6::'
6922 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6924 self.src_ip6_pfx_len = 96
6925 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6926 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6927 '\x00\x00\x00\x00', 0)
6929 @unittest.skip('Temporary disabled')
6930 def test_464xlat_ce(self):
6931 """ Test 464XLAT CE with NAT44 """
6933 nat_config = self.vapi.nat_show_config()
6934 self.assertEqual(1, nat_config.out2in_dpo)
6936 self.configure_xlat()
6938 flags = self.config_flags.NAT_IS_INSIDE
6939 self.vapi.nat44_interface_add_del_feature(
6940 sw_if_index=self.pg0.sw_if_index,
6941 flags=flags, is_add=1)
6942 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6943 last_ip_address=self.nat_addr_n,
6944 vrf_id=0xFFFFFFFF, is_add=1)
6946 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6947 self.dst_ip6_pfx_len)
6948 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6949 self.src_ip6_pfx_len)
6952 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6953 self.pg0.add_stream(pkts)
6954 self.pg_enable_capture(self.pg_interfaces)
6956 capture = self.pg1.get_capture(len(pkts))
6957 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6960 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6962 self.pg1.add_stream(pkts)
6963 self.pg_enable_capture(self.pg_interfaces)
6965 capture = self.pg0.get_capture(len(pkts))
6966 self.verify_capture_in(capture, self.pg0)
6968 self.vapi.nat44_interface_add_del_feature(
6969 sw_if_index=self.pg0.sw_if_index,
6971 self.vapi.nat44_add_del_address_range(
6972 first_ip_address=self.nat_addr_n,
6973 last_ip_address=self.nat_addr_n,
6976 @unittest.skip('Temporary disabled')
6977 def test_464xlat_ce_no_nat(self):
6978 """ Test 464XLAT CE without NAT44 """
6980 self.configure_xlat()
6982 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6983 self.dst_ip6_pfx_len)
6984 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6985 self.src_ip6_pfx_len)
6987 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6988 self.pg0.add_stream(pkts)
6989 self.pg_enable_capture(self.pg_interfaces)
6991 capture = self.pg1.get_capture(len(pkts))
6992 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6993 nat_ip=out_dst_ip6, same_port=True)
6995 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6996 self.pg1.add_stream(pkts)
6997 self.pg_enable_capture(self.pg_interfaces)
6999 capture = self.pg0.get_capture(len(pkts))
7000 self.verify_capture_in(capture, self.pg0)
7003 class TestDeterministicNAT(MethodHolder):
7004 """ Deterministic NAT Test Cases """
7007 def setUpConstants(cls):
7008 super(TestDeterministicNAT, cls).setUpConstants()
7009 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7012 def setUpClass(cls):
7013 super(TestDeterministicNAT, cls).setUpClass()
7014 cls.vapi.cli("set log class nat level debug")
7016 cls.tcp_port_in = 6303
7017 cls.tcp_external_port = 6303
7018 cls.udp_port_in = 6304
7019 cls.udp_external_port = 6304
7020 cls.icmp_id_in = 6305
7021 cls.nat_addr = '10.0.0.3'
7023 cls.create_pg_interfaces(range(3))
7024 cls.interfaces = list(cls.pg_interfaces)
7026 for i in cls.interfaces:
7031 cls.pg0.generate_remote_hosts(2)
7032 cls.pg0.configure_ipv4_neighbors()
7035 def tearDownClass(cls):
7036 super(TestDeterministicNAT, cls).tearDownClass()
7038 def create_stream_in(self, in_if, out_if, ttl=64):
7040 Create packet stream for inside network
7042 :param in_if: Inside interface
7043 :param out_if: Outside interface
7044 :param ttl: TTL of generated packets
7048 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7049 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7050 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7054 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7055 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7056 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7060 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7061 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7062 ICMP(id=self.icmp_id_in, type='echo-request'))
7067 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7069 Create packet stream for outside network
7071 :param out_if: Outside interface
7072 :param dst_ip: Destination IP address (Default use global NAT address)
7073 :param ttl: TTL of generated packets
7076 dst_ip = self.nat_addr
7079 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7080 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7081 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7085 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7086 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7087 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7091 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7092 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7093 ICMP(id=self.icmp_external_id, type='echo-reply'))
7098 def verify_capture_out(self, capture, nat_ip=None):
7100 Verify captured packets on outside network
7102 :param capture: Captured packets
7103 :param nat_ip: Translated IP address (Default use global NAT address)
7104 :param same_port: Source port number is not translated (Default False)
7107 nat_ip = self.nat_addr
7108 for packet in capture:
7110 self.assertEqual(packet[IP].src, nat_ip)
7111 if packet.haslayer(TCP):
7112 self.tcp_port_out = packet[TCP].sport
7113 elif packet.haslayer(UDP):
7114 self.udp_port_out = packet[UDP].sport
7116 self.icmp_external_id = packet[ICMP].id
7118 self.logger.error(ppp("Unexpected or invalid packet "
7119 "(outside network):", packet))
7122 def test_deterministic_mode(self):
7123 """ NAT plugin run deterministic mode """
7124 in_addr = '172.16.255.0'
7125 out_addr = '172.17.255.50'
7126 in_addr_t = '172.16.255.20'
7130 nat_config = self.vapi.nat_show_config()
7131 self.assertEqual(1, nat_config.deterministic)
7133 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7134 in_plen=in_plen, out_addr=out_addr,
7137 rep1 = self.vapi.nat_det_forward(in_addr_t)
7138 self.assertEqual(str(rep1.out_addr), out_addr)
7139 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7141 self.assertEqual(str(rep2.in_addr), in_addr_t)
7143 deterministic_mappings = self.vapi.nat_det_map_dump()
7144 self.assertEqual(len(deterministic_mappings), 1)
7145 dsm = deterministic_mappings[0]
7146 self.assertEqual(in_addr, str(dsm.in_addr))
7147 self.assertEqual(in_plen, dsm.in_plen)
7148 self.assertEqual(out_addr, str(dsm.out_addr))
7149 self.assertEqual(out_plen, dsm.out_plen)
7151 self.clear_nat_det()
7152 deterministic_mappings = self.vapi.nat_det_map_dump()
7153 self.assertEqual(len(deterministic_mappings), 0)
7155 def test_set_timeouts(self):
7156 """ Set deterministic NAT timeouts """
7157 timeouts_before = self.vapi.nat_get_timeouts()
7159 self.vapi.nat_set_timeouts(
7160 udp=timeouts_before.udp + 10,
7161 tcp_established=timeouts_before.tcp_established + 10,
7162 tcp_transitory=timeouts_before.tcp_transitory + 10,
7163 icmp=timeouts_before.icmp + 10)
7165 timeouts_after = self.vapi.nat_get_timeouts()
7167 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7168 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7169 self.assertNotEqual(timeouts_before.tcp_established,
7170 timeouts_after.tcp_established)
7171 self.assertNotEqual(timeouts_before.tcp_transitory,
7172 timeouts_after.tcp_transitory)
7174 def test_det_in(self):
7175 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7177 nat_ip = "10.0.0.10"
7179 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7181 out_addr=socket.inet_aton(nat_ip),
7184 flags = self.config_flags.NAT_IS_INSIDE
7185 self.vapi.nat44_interface_add_del_feature(
7186 sw_if_index=self.pg0.sw_if_index,
7187 flags=flags, is_add=1)
7188 self.vapi.nat44_interface_add_del_feature(
7189 sw_if_index=self.pg1.sw_if_index,
7193 pkts = self.create_stream_in(self.pg0, self.pg1)
7194 self.pg0.add_stream(pkts)
7195 self.pg_enable_capture(self.pg_interfaces)
7197 capture = self.pg1.get_capture(len(pkts))
7198 self.verify_capture_out(capture, nat_ip)
7201 pkts = self.create_stream_out(self.pg1, nat_ip)
7202 self.pg1.add_stream(pkts)
7203 self.pg_enable_capture(self.pg_interfaces)
7205 capture = self.pg0.get_capture(len(pkts))
7206 self.verify_capture_in(capture, self.pg0)
7209 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7210 self.assertEqual(len(sessions), 3)
7214 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7215 self.assertEqual(s.in_port, self.tcp_port_in)
7216 self.assertEqual(s.out_port, self.tcp_port_out)
7217 self.assertEqual(s.ext_port, self.tcp_external_port)
7221 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7222 self.assertEqual(s.in_port, self.udp_port_in)
7223 self.assertEqual(s.out_port, self.udp_port_out)
7224 self.assertEqual(s.ext_port, self.udp_external_port)
7228 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7229 self.assertEqual(s.in_port, self.icmp_id_in)
7230 self.assertEqual(s.out_port, self.icmp_external_id)
7232 def test_multiple_users(self):
7233 """ Deterministic NAT multiple users """
7235 nat_ip = "10.0.0.10"
7237 external_port = 6303
7239 host0 = self.pg0.remote_hosts[0]
7240 host1 = self.pg0.remote_hosts[1]
7242 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7243 out_addr=socket.inet_aton(nat_ip),
7245 flags = self.config_flags.NAT_IS_INSIDE
7246 self.vapi.nat44_interface_add_del_feature(
7247 sw_if_index=self.pg0.sw_if_index,
7248 flags=flags, is_add=1)
7249 self.vapi.nat44_interface_add_del_feature(
7250 sw_if_index=self.pg1.sw_if_index,
7254 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7255 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7256 TCP(sport=port_in, dport=external_port))
7257 self.pg0.add_stream(p)
7258 self.pg_enable_capture(self.pg_interfaces)
7260 capture = self.pg1.get_capture(1)
7265 self.assertEqual(ip.src, nat_ip)
7266 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7267 self.assertEqual(tcp.dport, external_port)
7268 port_out0 = tcp.sport
7270 self.logger.error(ppp("Unexpected or invalid packet:", p))
7274 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7275 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7276 TCP(sport=port_in, dport=external_port))
7277 self.pg0.add_stream(p)
7278 self.pg_enable_capture(self.pg_interfaces)
7280 capture = self.pg1.get_capture(1)
7285 self.assertEqual(ip.src, nat_ip)
7286 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7287 self.assertEqual(tcp.dport, external_port)
7288 port_out1 = tcp.sport
7290 self.logger.error(ppp("Unexpected or invalid packet:", p))
7293 dms = self.vapi.nat_det_map_dump()
7294 self.assertEqual(1, len(dms))
7295 self.assertEqual(2, dms[0].ses_num)
7298 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7299 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7300 TCP(sport=external_port, dport=port_out0))
7301 self.pg1.add_stream(p)
7302 self.pg_enable_capture(self.pg_interfaces)
7304 capture = self.pg0.get_capture(1)
7309 self.assertEqual(ip.src, self.pg1.remote_ip4)
7310 self.assertEqual(ip.dst, host0.ip4)
7311 self.assertEqual(tcp.dport, port_in)
7312 self.assertEqual(tcp.sport, external_port)
7314 self.logger.error(ppp("Unexpected or invalid packet:", p))
7318 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7319 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7320 TCP(sport=external_port, dport=port_out1))
7321 self.pg1.add_stream(p)
7322 self.pg_enable_capture(self.pg_interfaces)
7324 capture = self.pg0.get_capture(1)
7329 self.assertEqual(ip.src, self.pg1.remote_ip4)
7330 self.assertEqual(ip.dst, host1.ip4)
7331 self.assertEqual(tcp.dport, port_in)
7332 self.assertEqual(tcp.sport, external_port)
7334 self.logger.error(ppp("Unexpected or invalid packet", p))
7337 # session close api test
7338 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7340 self.pg1.remote_ip4,
7342 dms = self.vapi.nat_det_map_dump()
7343 self.assertEqual(dms[0].ses_num, 1)
7345 self.vapi.nat_det_close_session_in(host0.ip4,
7347 self.pg1.remote_ip4,
7349 dms = self.vapi.nat_det_map_dump()
7350 self.assertEqual(dms[0].ses_num, 0)
7352 def test_tcp_session_close_detection_in(self):
7353 """ Deterministic NAT TCP session close from inside network """
7354 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7356 out_addr=socket.inet_aton(self.nat_addr),
7358 flags = self.config_flags.NAT_IS_INSIDE
7359 self.vapi.nat44_interface_add_del_feature(
7360 sw_if_index=self.pg0.sw_if_index,
7361 flags=flags, is_add=1)
7362 self.vapi.nat44_interface_add_del_feature(
7363 sw_if_index=self.pg1.sw_if_index,
7366 self.initiate_tcp_session(self.pg0, self.pg1)
7368 # close the session from inside
7370 # FIN packet in -> out
7371 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7372 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7373 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7375 self.pg0.add_stream(p)
7376 self.pg_enable_capture(self.pg_interfaces)
7378 self.pg1.get_capture(1)
7382 # ACK packet out -> in
7383 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7384 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7385 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7389 # FIN packet out -> in
7390 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7391 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7392 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7396 self.pg1.add_stream(pkts)
7397 self.pg_enable_capture(self.pg_interfaces)
7399 self.pg0.get_capture(2)
7401 # ACK packet in -> out
7402 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7403 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7404 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7406 self.pg0.add_stream(p)
7407 self.pg_enable_capture(self.pg_interfaces)
7409 self.pg1.get_capture(1)
7411 # Check if deterministic NAT44 closed the session
7412 dms = self.vapi.nat_det_map_dump()
7413 self.assertEqual(0, dms[0].ses_num)
7415 self.logger.error("TCP session termination failed")
7418 def test_tcp_session_close_detection_out(self):
7419 """ Deterministic NAT TCP session close from outside network """
7420 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7422 out_addr=socket.inet_aton(self.nat_addr),
7424 flags = self.config_flags.NAT_IS_INSIDE
7425 self.vapi.nat44_interface_add_del_feature(
7426 sw_if_index=self.pg0.sw_if_index,
7427 flags=flags, is_add=1)
7428 self.vapi.nat44_interface_add_del_feature(
7429 sw_if_index=self.pg1.sw_if_index,
7432 self.initiate_tcp_session(self.pg0, self.pg1)
7434 # close the session from outside
7436 # FIN packet out -> in
7437 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7438 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7439 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7441 self.pg1.add_stream(p)
7442 self.pg_enable_capture(self.pg_interfaces)
7444 self.pg0.get_capture(1)
7448 # ACK packet in -> out
7449 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7450 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7451 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7455 # ACK packet in -> out
7456 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7457 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7458 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7462 self.pg0.add_stream(pkts)
7463 self.pg_enable_capture(self.pg_interfaces)
7465 self.pg1.get_capture(2)
7467 # ACK packet out -> in
7468 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7469 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7470 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7472 self.pg1.add_stream(p)
7473 self.pg_enable_capture(self.pg_interfaces)
7475 self.pg0.get_capture(1)
7477 # Check if deterministic NAT44 closed the session
7478 dms = self.vapi.nat_det_map_dump()
7479 self.assertEqual(0, dms[0].ses_num)
7481 self.logger.error("TCP session termination failed")
7484 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7485 def test_session_timeout(self):
7486 """ Deterministic NAT session timeouts """
7487 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7489 out_addr=socket.inet_aton(self.nat_addr),
7491 flags = self.config_flags.NAT_IS_INSIDE
7492 self.vapi.nat44_interface_add_del_feature(
7493 sw_if_index=self.pg0.sw_if_index,
7494 flags=flags, is_add=1)
7495 self.vapi.nat44_interface_add_del_feature(
7496 sw_if_index=self.pg1.sw_if_index,
7499 self.initiate_tcp_session(self.pg0, self.pg1)
7500 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7502 pkts = self.create_stream_in(self.pg0, self.pg1)
7503 self.pg0.add_stream(pkts)
7504 self.pg_enable_capture(self.pg_interfaces)
7506 capture = self.pg1.get_capture(len(pkts))
7509 dms = self.vapi.nat_det_map_dump()
7510 self.assertEqual(0, dms[0].ses_num)
7512 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7513 def test_session_limit_per_user(self):
7514 """ Deterministic NAT maximum sessions per user limit """
7515 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7517 out_addr=socket.inet_aton(self.nat_addr),
7519 flags = self.config_flags.NAT_IS_INSIDE
7520 self.vapi.nat44_interface_add_del_feature(
7521 sw_if_index=self.pg0.sw_if_index,
7522 flags=flags, is_add=1)
7523 self.vapi.nat44_interface_add_del_feature(
7524 sw_if_index=self.pg1.sw_if_index,
7526 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7527 src_address=self.pg2.local_ip4,
7529 template_interval=10)
7530 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7534 for port in range(1025, 2025):
7535 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7536 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7537 UDP(sport=port, dport=port))
7540 self.pg0.add_stream(pkts)
7541 self.pg_enable_capture(self.pg_interfaces)
7543 capture = self.pg1.get_capture(len(pkts))
7545 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7546 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7547 UDP(sport=3001, dport=3002))
7548 self.pg0.add_stream(p)
7549 self.pg_enable_capture(self.pg_interfaces)
7551 capture = self.pg1.assert_nothing_captured()
7553 # verify ICMP error packet
7554 capture = self.pg0.get_capture(1)
7556 self.assertTrue(p.haslayer(ICMP))
7558 self.assertEqual(icmp.type, 3)
7559 self.assertEqual(icmp.code, 1)
7560 self.assertTrue(icmp.haslayer(IPerror))
7561 inner_ip = icmp[IPerror]
7562 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7563 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7565 dms = self.vapi.nat_det_map_dump()
7567 self.assertEqual(1000, dms[0].ses_num)
7569 # verify IPFIX logging
7570 self.vapi.ipfix_flush()
7572 capture = self.pg2.get_capture(2)
7573 ipfix = IPFIXDecoder()
7574 # first load template
7576 self.assertTrue(p.haslayer(IPFIX))
7577 if p.haslayer(Template):
7578 ipfix.add_template(p.getlayer(Template))
7579 # verify events in data set
7581 if p.haslayer(Data):
7582 data = ipfix.decode_data_set(p.getlayer(Set))
7583 self.verify_ipfix_max_entries_per_user(data,
7585 self.pg0.remote_ip4)
7587 def clear_nat_det(self):
7589 Clear deterministic NAT configuration.
7591 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7593 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7594 tcp_transitory=240, icmp=60)
7595 deterministic_mappings = self.vapi.nat_det_map_dump()
7596 for dsm in deterministic_mappings:
7597 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7598 in_plen=dsm.in_plen,
7599 out_addr=dsm.out_addr,
7600 out_plen=dsm.out_plen)
7602 interfaces = self.vapi.nat44_interface_dump()
7603 for intf in interfaces:
7604 self.vapi.nat44_interface_add_del_feature(
7605 sw_if_index=intf.sw_if_index,
7609 super(TestDeterministicNAT, self).tearDown()
7610 if not self.vpp_dead:
7611 self.clear_nat_det()
7613 def show_commands_at_teardown(self):
7614 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7615 self.logger.info(self.vapi.cli("show nat timeouts"))
7617 self.vapi.cli("show nat44 deterministic mappings"))
7619 self.vapi.cli("show nat44 deterministic sessions"))
7622 class TestNAT64(MethodHolder):
7623 """ NAT64 Test Cases """
7626 def setUpConstants(cls):
7627 super(TestNAT64, cls).setUpConstants()
7628 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7629 "nat64 st hash buckets 256", "}"])
7632 def setUpClass(cls):
7633 super(TestNAT64, cls).setUpClass()
7635 cls.tcp_port_in = 6303
7636 cls.tcp_port_out = 6303
7637 cls.udp_port_in = 6304
7638 cls.udp_port_out = 6304
7639 cls.icmp_id_in = 6305
7640 cls.icmp_id_out = 6305
7641 cls.tcp_external_port = 80
7642 cls.nat_addr = '10.0.0.3'
7643 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7645 cls.vrf1_nat_addr = '10.0.10.3'
7646 cls.ipfix_src_port = 4739
7647 cls.ipfix_domain_id = 1
7649 cls.create_pg_interfaces(range(6))
7650 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7651 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7652 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7654 cls.vapi.ip_table_add_del(is_add=1,
7655 table={'table_id': cls.vrf1_id,
7658 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7660 cls.pg0.generate_remote_hosts(2)
7662 for i in cls.ip6_interfaces:
7665 i.configure_ipv6_neighbors()
7667 for i in cls.ip4_interfaces:
7673 cls.pg3.config_ip4()
7674 cls.pg3.resolve_arp()
7675 cls.pg3.config_ip6()
7676 cls.pg3.configure_ipv6_neighbors()
7679 cls.pg5.config_ip6()
7682 def tearDownClass(cls):
7683 super(TestNAT64, cls).tearDownClass()
7685 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7686 """ NAT64 inside interface handles Neighbor Advertisement """
7688 flags = self.config_flags.NAT_IS_INSIDE
7689 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7690 sw_if_index=self.pg5.sw_if_index)
7693 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7694 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7695 ICMPv6EchoRequest())
7697 self.pg5.add_stream(pkts)
7698 self.pg_enable_capture(self.pg_interfaces)
7701 # Wait for Neighbor Solicitation
7702 capture = self.pg5.get_capture(len(pkts))
7705 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7706 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7707 tgt = packet[ICMPv6ND_NS].tgt
7709 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7712 # Send Neighbor Advertisement
7713 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7714 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7715 ICMPv6ND_NA(tgt=tgt) /
7716 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7718 self.pg5.add_stream(pkts)
7719 self.pg_enable_capture(self.pg_interfaces)
7722 # Try to send ping again
7724 self.pg5.add_stream(pkts)
7725 self.pg_enable_capture(self.pg_interfaces)
7728 # Wait for ping reply
7729 capture = self.pg5.get_capture(len(pkts))
7732 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7733 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7734 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7736 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7739 def test_pool(self):
7740 """ Add/delete address to NAT64 pool """
7741 nat_addr = '1.2.3.4'
7743 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7745 vrf_id=0xFFFFFFFF, is_add=1)
7747 addresses = self.vapi.nat64_pool_addr_dump()
7748 self.assertEqual(len(addresses), 1)
7749 self.assertEqual(str(addresses[0].address), nat_addr)
7751 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7753 vrf_id=0xFFFFFFFF, is_add=0)
7755 addresses = self.vapi.nat64_pool_addr_dump()
7756 self.assertEqual(len(addresses), 0)
7758 def test_interface(self):
7759 """ Enable/disable NAT64 feature on the interface """
7760 flags = self.config_flags.NAT_IS_INSIDE
7761 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7762 sw_if_index=self.pg0.sw_if_index)
7763 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7764 sw_if_index=self.pg1.sw_if_index)
7766 interfaces = self.vapi.nat64_interface_dump()
7767 self.assertEqual(len(interfaces), 2)
7770 for intf in interfaces:
7771 if intf.sw_if_index == self.pg0.sw_if_index:
7772 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7774 elif intf.sw_if_index == self.pg1.sw_if_index:
7775 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7777 self.assertTrue(pg0_found)
7778 self.assertTrue(pg1_found)
7780 features = self.vapi.cli("show interface features pg0")
7781 self.assertIn('nat64-in2out', features)
7782 features = self.vapi.cli("show interface features pg1")
7783 self.assertIn('nat64-out2in', features)
7785 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7786 sw_if_index=self.pg0.sw_if_index)
7787 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7788 sw_if_index=self.pg1.sw_if_index)
7790 interfaces = self.vapi.nat64_interface_dump()
7791 self.assertEqual(len(interfaces), 0)
7793 def test_static_bib(self):
7794 """ Add/delete static BIB entry """
7795 in_addr = '2001:db8:85a3::8a2e:370:7334'
7796 out_addr = '10.1.1.3'
7799 proto = IP_PROTOS.tcp
7801 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7802 i_port=in_port, o_port=out_port,
7803 proto=proto, vrf_id=0, is_add=1)
7804 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7807 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7809 self.assertEqual(str(bibe.i_addr), in_addr)
7810 self.assertEqual(str(bibe.o_addr), out_addr)
7811 self.assertEqual(bibe.i_port, in_port)
7812 self.assertEqual(bibe.o_port, out_port)
7813 self.assertEqual(static_bib_num, 1)
7814 bibs = self.statistics.get_counter('/nat64/total-bibs')
7815 self.assertEqual(bibs[0][0], 1)
7817 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7818 i_port=in_port, o_port=out_port,
7819 proto=proto, vrf_id=0, is_add=0)
7820 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7823 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7825 self.assertEqual(static_bib_num, 0)
7826 bibs = self.statistics.get_counter('/nat64/total-bibs')
7827 self.assertEqual(bibs[0][0], 0)
7829 def test_set_timeouts(self):
7830 """ Set NAT64 timeouts """
7831 # verify default values
7832 timeouts = self.vapi.nat_get_timeouts()
7833 self.assertEqual(timeouts.udp, 300)
7834 self.assertEqual(timeouts.icmp, 60)
7835 self.assertEqual(timeouts.tcp_transitory, 240)
7836 self.assertEqual(timeouts.tcp_established, 7440)
7838 # set and verify custom values
7839 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7840 tcp_transitory=250, icmp=30)
7841 timeouts = self.vapi.nat_get_timeouts()
7842 self.assertEqual(timeouts.udp, 200)
7843 self.assertEqual(timeouts.icmp, 30)
7844 self.assertEqual(timeouts.tcp_transitory, 250)
7845 self.assertEqual(timeouts.tcp_established, 7450)
7847 def test_dynamic(self):
7848 """ NAT64 dynamic translation test """
7849 self.tcp_port_in = 6303
7850 self.udp_port_in = 6304
7851 self.icmp_id_in = 6305
7853 ses_num_start = self.nat64_get_ses_num()
7855 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7856 end_addr=self.nat_addr,
7859 flags = self.config_flags.NAT_IS_INSIDE
7860 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7861 sw_if_index=self.pg0.sw_if_index)
7862 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7863 sw_if_index=self.pg1.sw_if_index)
7866 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7867 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7868 icmpn = self.statistics.get_err_counter(
7869 '/err/nat64-in2out/ICMP packets')
7870 totaln = self.statistics.get_err_counter(
7871 '/err/nat64-in2out/good in2out packets processed')
7873 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7874 self.pg0.add_stream(pkts)
7875 self.pg_enable_capture(self.pg_interfaces)
7877 capture = self.pg1.get_capture(len(pkts))
7878 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7879 dst_ip=self.pg1.remote_ip4)
7881 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7882 self.assertEqual(err - tcpn, 1)
7883 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7884 self.assertEqual(err - udpn, 1)
7885 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7886 self.assertEqual(err - icmpn, 1)
7887 err = self.statistics.get_err_counter(
7888 '/err/nat64-in2out/good in2out packets processed')
7889 self.assertEqual(err - totaln, 3)
7892 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7893 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7894 icmpn = self.statistics.get_err_counter(
7895 '/err/nat64-out2in/ICMP packets')
7896 totaln = self.statistics.get_err_counter(
7897 '/err/nat64-out2in/good out2in packets processed')
7899 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7900 self.pg1.add_stream(pkts)
7901 self.pg_enable_capture(self.pg_interfaces)
7903 capture = self.pg0.get_capture(len(pkts))
7904 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7905 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7907 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7908 self.assertEqual(err - tcpn, 2)
7909 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7910 self.assertEqual(err - udpn, 1)
7911 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7912 self.assertEqual(err - icmpn, 1)
7913 err = self.statistics.get_err_counter(
7914 '/err/nat64-out2in/good out2in packets processed')
7915 self.assertEqual(err - totaln, 4)
7917 bibs = self.statistics.get_counter('/nat64/total-bibs')
7918 self.assertEqual(bibs[0][0], 3)
7919 sessions = self.statistics.get_counter('/nat64/total-sessions')
7920 self.assertEqual(sessions[0][0], 3)
7923 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7924 self.pg0.add_stream(pkts)
7925 self.pg_enable_capture(self.pg_interfaces)
7927 capture = self.pg1.get_capture(len(pkts))
7928 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7929 dst_ip=self.pg1.remote_ip4)
7932 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7933 self.pg1.add_stream(pkts)
7934 self.pg_enable_capture(self.pg_interfaces)
7936 capture = self.pg0.get_capture(len(pkts))
7937 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7939 ses_num_end = self.nat64_get_ses_num()
7941 self.assertEqual(ses_num_end - ses_num_start, 3)
7943 # tenant with specific VRF
7944 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7945 end_addr=self.vrf1_nat_addr,
7946 vrf_id=self.vrf1_id, is_add=1)
7947 flags = self.config_flags.NAT_IS_INSIDE
7948 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7949 sw_if_index=self.pg2.sw_if_index)
7951 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7952 self.pg2.add_stream(pkts)
7953 self.pg_enable_capture(self.pg_interfaces)
7955 capture = self.pg1.get_capture(len(pkts))
7956 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7957 dst_ip=self.pg1.remote_ip4)
7959 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7960 self.pg1.add_stream(pkts)
7961 self.pg_enable_capture(self.pg_interfaces)
7963 capture = self.pg2.get_capture(len(pkts))
7964 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7966 def test_static(self):
7967 """ NAT64 static translation test """
7968 self.tcp_port_in = 60303
7969 self.udp_port_in = 60304
7970 self.icmp_id_in = 60305
7971 self.tcp_port_out = 60303
7972 self.udp_port_out = 60304
7973 self.icmp_id_out = 60305
7975 ses_num_start = self.nat64_get_ses_num()
7977 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7978 end_addr=self.nat_addr,
7981 flags = self.config_flags.NAT_IS_INSIDE
7982 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7983 sw_if_index=self.pg0.sw_if_index)
7984 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7985 sw_if_index=self.pg1.sw_if_index)
7987 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7988 o_addr=self.nat_addr,
7989 i_port=self.tcp_port_in,
7990 o_port=self.tcp_port_out,
7991 proto=IP_PROTOS.tcp, vrf_id=0,
7993 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
7994 o_addr=self.nat_addr,
7995 i_port=self.udp_port_in,
7996 o_port=self.udp_port_out,
7997 proto=IP_PROTOS.udp, vrf_id=0,
7999 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8000 o_addr=self.nat_addr,
8001 i_port=self.icmp_id_in,
8002 o_port=self.icmp_id_out,
8003 proto=IP_PROTOS.icmp, vrf_id=0,
8007 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8008 self.pg0.add_stream(pkts)
8009 self.pg_enable_capture(self.pg_interfaces)
8011 capture = self.pg1.get_capture(len(pkts))
8012 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8013 dst_ip=self.pg1.remote_ip4, same_port=True)
8016 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8017 self.pg1.add_stream(pkts)
8018 self.pg_enable_capture(self.pg_interfaces)
8020 capture = self.pg0.get_capture(len(pkts))
8021 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8022 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8024 ses_num_end = self.nat64_get_ses_num()
8026 self.assertEqual(ses_num_end - ses_num_start, 3)
8028 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8029 def test_session_timeout(self):
8030 """ NAT64 session timeout """
8031 self.icmp_id_in = 1234
8032 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8033 end_addr=self.nat_addr,
8036 flags = self.config_flags.NAT_IS_INSIDE
8037 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8038 sw_if_index=self.pg0.sw_if_index)
8039 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8040 sw_if_index=self.pg1.sw_if_index)
8041 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8045 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8046 self.pg0.add_stream(pkts)
8047 self.pg_enable_capture(self.pg_interfaces)
8049 capture = self.pg1.get_capture(len(pkts))
8051 ses_num_before_timeout = self.nat64_get_ses_num()
8055 # ICMP and TCP session after timeout
8056 ses_num_after_timeout = self.nat64_get_ses_num()
8057 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8059 def test_icmp_error(self):
8060 """ NAT64 ICMP Error message translation """
8061 self.tcp_port_in = 6303
8062 self.udp_port_in = 6304
8063 self.icmp_id_in = 6305
8065 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8066 end_addr=self.nat_addr,
8069 flags = self.config_flags.NAT_IS_INSIDE
8070 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8071 sw_if_index=self.pg0.sw_if_index)
8072 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8073 sw_if_index=self.pg1.sw_if_index)
8075 # send some packets to create sessions
8076 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8077 self.pg0.add_stream(pkts)
8078 self.pg_enable_capture(self.pg_interfaces)
8080 capture_ip4 = self.pg1.get_capture(len(pkts))
8081 self.verify_capture_out(capture_ip4,
8082 nat_ip=self.nat_addr,
8083 dst_ip=self.pg1.remote_ip4)
8085 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8086 self.pg1.add_stream(pkts)
8087 self.pg_enable_capture(self.pg_interfaces)
8089 capture_ip6 = self.pg0.get_capture(len(pkts))
8090 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8091 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8092 self.pg0.remote_ip6)
8095 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8096 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8097 ICMPv6DestUnreach(code=1) /
8098 packet[IPv6] for packet in capture_ip6]
8099 self.pg0.add_stream(pkts)
8100 self.pg_enable_capture(self.pg_interfaces)
8102 capture = self.pg1.get_capture(len(pkts))
8103 for packet in capture:
8105 self.assertEqual(packet[IP].src, self.nat_addr)
8106 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8107 self.assertEqual(packet[ICMP].type, 3)
8108 self.assertEqual(packet[ICMP].code, 13)
8109 inner = packet[IPerror]
8110 self.assertEqual(inner.src, self.pg1.remote_ip4)
8111 self.assertEqual(inner.dst, self.nat_addr)
8112 self.assert_packet_checksums_valid(packet)
8113 if inner.haslayer(TCPerror):
8114 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8115 elif inner.haslayer(UDPerror):
8116 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8118 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8120 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8124 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8125 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8126 ICMP(type=3, code=13) /
8127 packet[IP] for packet in capture_ip4]
8128 self.pg1.add_stream(pkts)
8129 self.pg_enable_capture(self.pg_interfaces)
8131 capture = self.pg0.get_capture(len(pkts))
8132 for packet in capture:
8134 self.assertEqual(packet[IPv6].src, ip.src)
8135 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8136 icmp = packet[ICMPv6DestUnreach]
8137 self.assertEqual(icmp.code, 1)
8138 inner = icmp[IPerror6]
8139 self.assertEqual(inner.src, self.pg0.remote_ip6)
8140 self.assertEqual(inner.dst, ip.src)
8141 self.assert_icmpv6_checksum_valid(packet)
8142 if inner.haslayer(TCPerror):
8143 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8144 elif inner.haslayer(UDPerror):
8145 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8147 self.assertEqual(inner[ICMPv6EchoRequest].id,
8150 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8153 def test_hairpinning(self):
8154 """ NAT64 hairpinning """
8156 client = self.pg0.remote_hosts[0]
8157 server = self.pg0.remote_hosts[1]
8158 server_tcp_in_port = 22
8159 server_tcp_out_port = 4022
8160 server_udp_in_port = 23
8161 server_udp_out_port = 4023
8162 client_tcp_in_port = 1234
8163 client_udp_in_port = 1235
8164 client_tcp_out_port = 0
8165 client_udp_out_port = 0
8166 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8167 nat_addr_ip6 = ip.src
8169 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8170 end_addr=self.nat_addr,
8173 flags = self.config_flags.NAT_IS_INSIDE
8174 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8175 sw_if_index=self.pg0.sw_if_index)
8176 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8177 sw_if_index=self.pg1.sw_if_index)
8179 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8180 o_addr=self.nat_addr,
8181 i_port=server_tcp_in_port,
8182 o_port=server_tcp_out_port,
8183 proto=IP_PROTOS.tcp, vrf_id=0,
8185 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8186 o_addr=self.nat_addr,
8187 i_port=server_udp_in_port,
8188 o_port=server_udp_out_port,
8189 proto=IP_PROTOS.udp, vrf_id=0,
8194 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8195 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8196 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8198 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8199 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8200 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8202 self.pg0.add_stream(pkts)
8203 self.pg_enable_capture(self.pg_interfaces)
8205 capture = self.pg0.get_capture(len(pkts))
8206 for packet in capture:
8208 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8209 self.assertEqual(packet[IPv6].dst, server.ip6)
8210 self.assert_packet_checksums_valid(packet)
8211 if packet.haslayer(TCP):
8212 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8213 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8214 client_tcp_out_port = packet[TCP].sport
8216 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8217 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8218 client_udp_out_port = packet[UDP].sport
8220 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8225 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8226 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8227 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8229 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8230 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8231 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8233 self.pg0.add_stream(pkts)
8234 self.pg_enable_capture(self.pg_interfaces)
8236 capture = self.pg0.get_capture(len(pkts))
8237 for packet in capture:
8239 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8240 self.assertEqual(packet[IPv6].dst, client.ip6)
8241 self.assert_packet_checksums_valid(packet)
8242 if packet.haslayer(TCP):
8243 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8244 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8246 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8247 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8249 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8254 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8255 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8256 ICMPv6DestUnreach(code=1) /
8257 packet[IPv6] for packet in capture]
8258 self.pg0.add_stream(pkts)
8259 self.pg_enable_capture(self.pg_interfaces)
8261 capture = self.pg0.get_capture(len(pkts))
8262 for packet in capture:
8264 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8265 self.assertEqual(packet[IPv6].dst, server.ip6)
8266 icmp = packet[ICMPv6DestUnreach]
8267 self.assertEqual(icmp.code, 1)
8268 inner = icmp[IPerror6]
8269 self.assertEqual(inner.src, server.ip6)
8270 self.assertEqual(inner.dst, nat_addr_ip6)
8271 self.assert_packet_checksums_valid(packet)
8272 if inner.haslayer(TCPerror):
8273 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8274 self.assertEqual(inner[TCPerror].dport,
8275 client_tcp_out_port)
8277 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8278 self.assertEqual(inner[UDPerror].dport,
8279 client_udp_out_port)
8281 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8284 def test_prefix(self):
8285 """ NAT64 Network-Specific Prefix """
8287 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8288 end_addr=self.nat_addr,
8291 flags = self.config_flags.NAT_IS_INSIDE
8292 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8293 sw_if_index=self.pg0.sw_if_index)
8294 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8295 sw_if_index=self.pg1.sw_if_index)
8296 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8297 end_addr=self.vrf1_nat_addr,
8298 vrf_id=self.vrf1_id, is_add=1)
8299 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8300 sw_if_index=self.pg2.sw_if_index)
8303 global_pref64 = "2001:db8::"
8304 global_pref64_len = 32
8305 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8306 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8309 prefix = self.vapi.nat64_prefix_dump()
8310 self.assertEqual(len(prefix), 1)
8311 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8312 self.assertEqual(prefix[0].vrf_id, 0)
8314 # Add tenant specific prefix
8315 vrf1_pref64 = "2001:db8:122:300::"
8316 vrf1_pref64_len = 56
8317 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8318 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8319 vrf_id=self.vrf1_id, is_add=1)
8321 prefix = self.vapi.nat64_prefix_dump()
8322 self.assertEqual(len(prefix), 2)
8325 pkts = self.create_stream_in_ip6(self.pg0,
8328 plen=global_pref64_len)
8329 self.pg0.add_stream(pkts)
8330 self.pg_enable_capture(self.pg_interfaces)
8332 capture = self.pg1.get_capture(len(pkts))
8333 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8334 dst_ip=self.pg1.remote_ip4)
8336 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8337 self.pg1.add_stream(pkts)
8338 self.pg_enable_capture(self.pg_interfaces)
8340 capture = self.pg0.get_capture(len(pkts))
8341 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8344 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8346 # Tenant specific prefix
8347 pkts = self.create_stream_in_ip6(self.pg2,
8350 plen=vrf1_pref64_len)
8351 self.pg2.add_stream(pkts)
8352 self.pg_enable_capture(self.pg_interfaces)
8354 capture = self.pg1.get_capture(len(pkts))
8355 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8356 dst_ip=self.pg1.remote_ip4)
8358 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8359 self.pg1.add_stream(pkts)
8360 self.pg_enable_capture(self.pg_interfaces)
8362 capture = self.pg2.get_capture(len(pkts))
8363 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8366 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8368 def test_unknown_proto(self):
8369 """ NAT64 translate packet with unknown protocol """
8371 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8372 end_addr=self.nat_addr,
8375 flags = self.config_flags.NAT_IS_INSIDE
8376 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8377 sw_if_index=self.pg0.sw_if_index)
8378 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8379 sw_if_index=self.pg1.sw_if_index)
8380 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8383 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8384 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8385 TCP(sport=self.tcp_port_in, dport=20))
8386 self.pg0.add_stream(p)
8387 self.pg_enable_capture(self.pg_interfaces)
8389 p = self.pg1.get_capture(1)
8391 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8392 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8394 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8395 TCP(sport=1234, dport=1234))
8396 self.pg0.add_stream(p)
8397 self.pg_enable_capture(self.pg_interfaces)
8399 p = self.pg1.get_capture(1)
8402 self.assertEqual(packet[IP].src, self.nat_addr)
8403 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8404 self.assertEqual(packet.haslayer(GRE), 1)
8405 self.assert_packet_checksums_valid(packet)
8407 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8411 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8412 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8414 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8415 TCP(sport=1234, dport=1234))
8416 self.pg1.add_stream(p)
8417 self.pg_enable_capture(self.pg_interfaces)
8419 p = self.pg0.get_capture(1)
8422 self.assertEqual(packet[IPv6].src, remote_ip6)
8423 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8424 self.assertEqual(packet[IPv6].nh, 47)
8426 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8429 def test_hairpinning_unknown_proto(self):
8430 """ NAT64 translate packet with unknown protocol - hairpinning """
8432 client = self.pg0.remote_hosts[0]
8433 server = self.pg0.remote_hosts[1]
8434 server_tcp_in_port = 22
8435 server_tcp_out_port = 4022
8436 client_tcp_in_port = 1234
8437 client_tcp_out_port = 1235
8438 server_nat_ip = "10.0.0.100"
8439 client_nat_ip = "10.0.0.110"
8440 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8441 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8443 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8444 end_addr=client_nat_ip,
8447 flags = self.config_flags.NAT_IS_INSIDE
8448 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8449 sw_if_index=self.pg0.sw_if_index)
8450 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8451 sw_if_index=self.pg1.sw_if_index)
8453 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8454 o_addr=server_nat_ip,
8455 i_port=server_tcp_in_port,
8456 o_port=server_tcp_out_port,
8457 proto=IP_PROTOS.tcp, vrf_id=0,
8460 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8461 o_addr=server_nat_ip, i_port=0,
8463 proto=IP_PROTOS.gre, vrf_id=0,
8466 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8467 o_addr=client_nat_ip,
8468 i_port=client_tcp_in_port,
8469 o_port=client_tcp_out_port,
8470 proto=IP_PROTOS.tcp, vrf_id=0,
8474 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8475 IPv6(src=client.ip6, dst=server_nat_ip6) /
8476 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8477 self.pg0.add_stream(p)
8478 self.pg_enable_capture(self.pg_interfaces)
8480 p = self.pg0.get_capture(1)
8482 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8483 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8485 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8486 TCP(sport=1234, dport=1234))
8487 self.pg0.add_stream(p)
8488 self.pg_enable_capture(self.pg_interfaces)
8490 p = self.pg0.get_capture(1)
8493 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8494 self.assertEqual(packet[IPv6].dst, server.ip6)
8495 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8497 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8501 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8502 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8504 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8505 TCP(sport=1234, dport=1234))
8506 self.pg0.add_stream(p)
8507 self.pg_enable_capture(self.pg_interfaces)
8509 p = self.pg0.get_capture(1)
8512 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8513 self.assertEqual(packet[IPv6].dst, client.ip6)
8514 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8516 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8519 def test_one_armed_nat64(self):
8520 """ One armed NAT64 """
8522 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8526 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8527 end_addr=self.nat_addr,
8530 flags = self.config_flags.NAT_IS_INSIDE
8531 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8532 sw_if_index=self.pg3.sw_if_index)
8533 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8534 sw_if_index=self.pg3.sw_if_index)
8537 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8538 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8539 TCP(sport=12345, dport=80))
8540 self.pg3.add_stream(p)
8541 self.pg_enable_capture(self.pg_interfaces)
8543 capture = self.pg3.get_capture(1)
8548 self.assertEqual(ip.src, self.nat_addr)
8549 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8550 self.assertNotEqual(tcp.sport, 12345)
8551 external_port = tcp.sport
8552 self.assertEqual(tcp.dport, 80)
8553 self.assert_packet_checksums_valid(p)
8555 self.logger.error(ppp("Unexpected or invalid packet:", p))
8559 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8560 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8561 TCP(sport=80, dport=external_port))
8562 self.pg3.add_stream(p)
8563 self.pg_enable_capture(self.pg_interfaces)
8565 capture = self.pg3.get_capture(1)
8570 self.assertEqual(ip.src, remote_host_ip6)
8571 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8572 self.assertEqual(tcp.sport, 80)
8573 self.assertEqual(tcp.dport, 12345)
8574 self.assert_packet_checksums_valid(p)
8576 self.logger.error(ppp("Unexpected or invalid packet:", p))
8579 def test_frag_in_order(self):
8580 """ NAT64 translate fragments arriving in order """
8581 self.tcp_port_in = random.randint(1025, 65535)
8583 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8584 end_addr=self.nat_addr,
8587 flags = self.config_flags.NAT_IS_INSIDE
8588 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8589 sw_if_index=self.pg0.sw_if_index)
8590 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8591 sw_if_index=self.pg1.sw_if_index)
8595 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8596 self.tcp_port_in, 20, data)
8597 self.pg0.add_stream(pkts)
8598 self.pg_enable_capture(self.pg_interfaces)
8600 frags = self.pg1.get_capture(len(pkts))
8601 p = self.reass_frags_and_verify(frags,
8603 self.pg1.remote_ip4)
8604 self.assertEqual(p[TCP].dport, 20)
8605 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8606 self.tcp_port_out = p[TCP].sport
8607 self.assertEqual(data, p[Raw].load)
8610 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8611 pkts = self.create_stream_frag(self.pg1,
8616 self.pg1.add_stream(pkts)
8617 self.pg_enable_capture(self.pg_interfaces)
8619 frags = self.pg0.get_capture(len(pkts))
8620 self.logger.debug(ppc("Captured:", frags))
8621 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8622 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8623 self.assertEqual(p[TCP].sport, 20)
8624 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8625 self.assertEqual(data, p[Raw].load)
8627 def test_reass_hairpinning(self):
8628 """ NAT64 fragments hairpinning """
8630 server = self.pg0.remote_hosts[1]
8631 server_in_port = random.randint(1025, 65535)
8632 server_out_port = random.randint(1025, 65535)
8633 client_in_port = random.randint(1025, 65535)
8634 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8635 nat_addr_ip6 = ip.src
8637 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8638 end_addr=self.nat_addr,
8641 flags = self.config_flags.NAT_IS_INSIDE
8642 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8643 sw_if_index=self.pg0.sw_if_index)
8644 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8645 sw_if_index=self.pg1.sw_if_index)
8647 # add static BIB entry for server
8648 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8649 o_addr=self.nat_addr,
8650 i_port=server_in_port,
8651 o_port=server_out_port,
8652 proto=IP_PROTOS.tcp, vrf_id=0,
8655 # send packet from host to server
8656 pkts = self.create_stream_frag_ip6(self.pg0,
8661 self.pg0.add_stream(pkts)
8662 self.pg_enable_capture(self.pg_interfaces)
8664 frags = self.pg0.get_capture(len(pkts))
8665 self.logger.debug(ppc("Captured:", frags))
8666 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8667 self.assertNotEqual(p[TCP].sport, client_in_port)
8668 self.assertEqual(p[TCP].dport, server_in_port)
8669 self.assertEqual(data, p[Raw].load)
8671 def test_frag_out_of_order(self):
8672 """ NAT64 translate fragments arriving out of order """
8673 self.tcp_port_in = random.randint(1025, 65535)
8675 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8676 end_addr=self.nat_addr,
8679 flags = self.config_flags.NAT_IS_INSIDE
8680 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8681 sw_if_index=self.pg0.sw_if_index)
8682 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8683 sw_if_index=self.pg1.sw_if_index)
8687 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8688 self.tcp_port_in, 20, data)
8690 self.pg0.add_stream(pkts)
8691 self.pg_enable_capture(self.pg_interfaces)
8693 frags = self.pg1.get_capture(len(pkts))
8694 p = self.reass_frags_and_verify(frags,
8696 self.pg1.remote_ip4)
8697 self.assertEqual(p[TCP].dport, 20)
8698 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8699 self.tcp_port_out = p[TCP].sport
8700 self.assertEqual(data, p[Raw].load)
8703 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8704 pkts = self.create_stream_frag(self.pg1,
8710 self.pg1.add_stream(pkts)
8711 self.pg_enable_capture(self.pg_interfaces)
8713 frags = self.pg0.get_capture(len(pkts))
8714 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8715 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8716 self.assertEqual(p[TCP].sport, 20)
8717 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8718 self.assertEqual(data, p[Raw].load)
8720 def test_interface_addr(self):
8721 """ Acquire NAT64 pool addresses from interface """
8722 self.vapi.nat64_add_del_interface_addr(
8724 sw_if_index=self.pg4.sw_if_index)
8726 # no address in NAT64 pool
8727 addresses = self.vapi.nat44_address_dump()
8728 self.assertEqual(0, len(addresses))
8730 # configure interface address and check NAT64 address pool
8731 self.pg4.config_ip4()
8732 addresses = self.vapi.nat64_pool_addr_dump()
8733 self.assertEqual(len(addresses), 1)
8735 self.assertEqual(str(addresses[0].address),
8738 # remove interface address and check NAT64 address pool
8739 self.pg4.unconfig_ip4()
8740 addresses = self.vapi.nat64_pool_addr_dump()
8741 self.assertEqual(0, len(addresses))
8743 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8744 def test_ipfix_max_bibs_sessions(self):
8745 """ IPFIX logging maximum session and BIB entries exceeded """
8748 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8752 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8753 end_addr=self.nat_addr,
8756 flags = self.config_flags.NAT_IS_INSIDE
8757 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8758 sw_if_index=self.pg0.sw_if_index)
8759 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8760 sw_if_index=self.pg1.sw_if_index)
8764 for i in range(0, max_bibs):
8765 src = "fd01:aa::%x" % (i)
8766 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8767 IPv6(src=src, dst=remote_host_ip6) /
8768 TCP(sport=12345, dport=80))
8770 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8771 IPv6(src=src, dst=remote_host_ip6) /
8772 TCP(sport=12345, dport=22))
8774 self.pg0.add_stream(pkts)
8775 self.pg_enable_capture(self.pg_interfaces)
8777 self.pg1.get_capture(max_sessions)
8779 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8780 src_address=self.pg3.local_ip4,
8782 template_interval=10)
8783 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8784 src_port=self.ipfix_src_port,
8787 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8788 IPv6(src=src, dst=remote_host_ip6) /
8789 TCP(sport=12345, dport=25))
8790 self.pg0.add_stream(p)
8791 self.pg_enable_capture(self.pg_interfaces)
8793 self.pg1.assert_nothing_captured()
8795 self.vapi.ipfix_flush()
8796 capture = self.pg3.get_capture(7)
8797 ipfix = IPFIXDecoder()
8798 # first load template
8800 self.assertTrue(p.haslayer(IPFIX))
8801 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8802 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8803 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8804 self.assertEqual(p[UDP].dport, 4739)
8805 self.assertEqual(p[IPFIX].observationDomainID,
8806 self.ipfix_domain_id)
8807 if p.haslayer(Template):
8808 ipfix.add_template(p.getlayer(Template))
8809 # verify events in data set
8811 if p.haslayer(Data):
8812 data = ipfix.decode_data_set(p.getlayer(Set))
8813 self.verify_ipfix_max_sessions(data, max_sessions)
8815 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8816 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8817 TCP(sport=12345, dport=80))
8818 self.pg0.add_stream(p)
8819 self.pg_enable_capture(self.pg_interfaces)
8821 self.pg1.assert_nothing_captured()
8823 self.vapi.ipfix_flush()
8824 capture = self.pg3.get_capture(1)
8825 # verify events in data set
8827 self.assertTrue(p.haslayer(IPFIX))
8828 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8829 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8830 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8831 self.assertEqual(p[UDP].dport, 4739)
8832 self.assertEqual(p[IPFIX].observationDomainID,
8833 self.ipfix_domain_id)
8834 if p.haslayer(Data):
8835 data = ipfix.decode_data_set(p.getlayer(Set))
8836 self.verify_ipfix_max_bibs(data, max_bibs)
8838 def test_ipfix_bib_ses(self):
8839 """ IPFIX logging NAT64 BIB/session create and delete events """
8840 self.tcp_port_in = random.randint(1025, 65535)
8841 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8845 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8846 end_addr=self.nat_addr,
8849 flags = self.config_flags.NAT_IS_INSIDE
8850 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8851 sw_if_index=self.pg0.sw_if_index)
8852 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8853 sw_if_index=self.pg1.sw_if_index)
8854 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8855 src_address=self.pg3.local_ip4,
8857 template_interval=10)
8858 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8859 src_port=self.ipfix_src_port,
8863 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8864 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8865 TCP(sport=self.tcp_port_in, dport=25))
8866 self.pg0.add_stream(p)
8867 self.pg_enable_capture(self.pg_interfaces)
8869 p = self.pg1.get_capture(1)
8870 self.tcp_port_out = p[0][TCP].sport
8871 self.vapi.ipfix_flush()
8872 capture = self.pg3.get_capture(8)
8873 ipfix = IPFIXDecoder()
8874 # first load template
8876 self.assertTrue(p.haslayer(IPFIX))
8877 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8878 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8879 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8880 self.assertEqual(p[UDP].dport, 4739)
8881 self.assertEqual(p[IPFIX].observationDomainID,
8882 self.ipfix_domain_id)
8883 if p.haslayer(Template):
8884 ipfix.add_template(p.getlayer(Template))
8885 # verify events in data set
8887 if p.haslayer(Data):
8888 data = ipfix.decode_data_set(p.getlayer(Set))
8889 if scapy.compat.orb(data[0][230]) == 10:
8890 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8891 elif scapy.compat.orb(data[0][230]) == 6:
8892 self.verify_ipfix_nat64_ses(data,
8894 self.pg0.remote_ip6n,
8895 self.pg1.remote_ip4,
8898 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8901 self.pg_enable_capture(self.pg_interfaces)
8902 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8903 end_addr=self.nat_addr,
8906 self.vapi.ipfix_flush()
8907 capture = self.pg3.get_capture(2)
8908 # verify events in data set
8910 self.assertTrue(p.haslayer(IPFIX))
8911 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8912 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8913 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8914 self.assertEqual(p[UDP].dport, 4739)
8915 self.assertEqual(p[IPFIX].observationDomainID,
8916 self.ipfix_domain_id)
8917 if p.haslayer(Data):
8918 data = ipfix.decode_data_set(p.getlayer(Set))
8919 if scapy.compat.orb(data[0][230]) == 11:
8920 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8921 elif scapy.compat.orb(data[0][230]) == 7:
8922 self.verify_ipfix_nat64_ses(data,
8924 self.pg0.remote_ip6n,
8925 self.pg1.remote_ip4,
8928 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8930 def test_syslog_sess(self):
8931 """ Test syslog session creation and deletion """
8932 self.tcp_port_in = random.randint(1025, 65535)
8933 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8937 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8938 end_addr=self.nat_addr,
8941 flags = self.config_flags.NAT_IS_INSIDE
8942 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8943 sw_if_index=self.pg0.sw_if_index)
8944 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8945 sw_if_index=self.pg1.sw_if_index)
8946 self.vapi.syslog_set_filter(
8947 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8948 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
8950 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8951 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8952 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8953 self.pg0.add_stream(p)
8954 self.pg_enable_capture(self.pg_interfaces)
8956 p = self.pg1.get_capture(1)
8957 self.tcp_port_out = p[0][TCP].sport
8958 capture = self.pg3.get_capture(1)
8959 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8961 self.pg_enable_capture(self.pg_interfaces)
8963 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8964 end_addr=self.nat_addr,
8967 capture = self.pg3.get_capture(1)
8968 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8970 def nat64_get_ses_num(self):
8972 Return number of active NAT64 sessions.
8974 st = self.vapi.nat64_st_dump(proto=255)
8977 def clear_nat64(self):
8979 Clear NAT64 configuration.
8981 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8982 src_port=self.ipfix_src_port,
8984 self.ipfix_src_port = 4739
8985 self.ipfix_domain_id = 1
8987 self.vapi.syslog_set_filter(
8988 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
8990 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8991 tcp_transitory=240, icmp=60)
8993 interfaces = self.vapi.nat64_interface_dump()
8994 for intf in interfaces:
8995 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
8996 sw_if_index=intf.sw_if_index)
8998 bib = self.vapi.nat64_bib_dump(proto=255)
9000 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9001 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9009 adresses = self.vapi.nat64_pool_addr_dump()
9010 for addr in adresses:
9011 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9012 end_addr=addr.address,
9016 prefixes = self.vapi.nat64_prefix_dump()
9017 for prefix in prefixes:
9018 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9019 vrf_id=prefix.vrf_id, is_add=0)
9021 bibs = self.statistics.get_counter('/nat64/total-bibs')
9022 self.assertEqual(bibs[0][0], 0)
9023 sessions = self.statistics.get_counter('/nat64/total-sessions')
9024 self.assertEqual(sessions[0][0], 0)
9027 super(TestNAT64, self).tearDown()
9028 if not self.vpp_dead:
9031 def show_commands_at_teardown(self):
9032 self.logger.info(self.vapi.cli("show nat64 pool"))
9033 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9034 self.logger.info(self.vapi.cli("show nat64 prefix"))
9035 self.logger.info(self.vapi.cli("show nat64 bib all"))
9036 self.logger.info(self.vapi.cli("show nat64 session table all"))
9039 class TestNAT66(MethodHolder):
9040 """ NAT66 Test Cases """
9043 def setUpClass(cls):
9044 super(TestNAT66, cls).setUpClass()
9046 cls.nat_addr = 'fd01:ff::2'
9048 cls.create_pg_interfaces(range(2))
9049 cls.interfaces = list(cls.pg_interfaces)
9051 for i in cls.interfaces:
9054 i.configure_ipv6_neighbors()
9057 def tearDownClass(cls):
9058 super(TestNAT66, cls).tearDownClass()
9060 def test_static(self):
9061 """ 1:1 NAT66 test """
9062 flags = self.config_flags.NAT_IS_INSIDE
9063 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9064 sw_if_index=self.pg0.sw_if_index)
9065 self.vapi.nat66_add_del_interface(is_add=1,
9066 sw_if_index=self.pg1.sw_if_index)
9067 self.vapi.nat66_add_del_static_mapping(
9068 local_ip_address=self.pg0.remote_ip6n,
9069 external_ip_address=self.nat_addr,
9074 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9075 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9078 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9079 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9082 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9083 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9084 ICMPv6EchoRequest())
9086 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9087 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9088 GRE() / IP() / TCP())
9090 self.pg0.add_stream(pkts)
9091 self.pg_enable_capture(self.pg_interfaces)
9093 capture = self.pg1.get_capture(len(pkts))
9095 for packet in capture:
9097 self.assertEqual(packet[IPv6].src, self.nat_addr)
9098 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9099 self.assert_packet_checksums_valid(packet)
9101 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9106 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9107 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9110 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9111 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9114 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9115 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9118 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9119 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9120 GRE() / IP() / TCP())
9122 self.pg1.add_stream(pkts)
9123 self.pg_enable_capture(self.pg_interfaces)
9125 capture = self.pg0.get_capture(len(pkts))
9126 for packet in capture:
9128 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9129 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9130 self.assert_packet_checksums_valid(packet)
9132 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9135 sm = self.vapi.nat66_static_mapping_dump()
9136 self.assertEqual(len(sm), 1)
9137 self.assertEqual(sm[0].total_pkts, 8)
9139 def test_check_no_translate(self):
9140 """ NAT66 translate only when egress interface is outside interface """
9141 flags = self.config_flags.NAT_IS_INSIDE
9142 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9143 sw_if_index=self.pg0.sw_if_index)
9144 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9145 sw_if_index=self.pg1.sw_if_index)
9146 self.vapi.nat66_add_del_static_mapping(
9147 local_ip_address=self.pg0.remote_ip6n,
9148 external_ip_address=self.nat_addr,
9152 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9153 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9155 self.pg0.add_stream([p])
9156 self.pg_enable_capture(self.pg_interfaces)
9158 capture = self.pg1.get_capture(1)
9161 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9162 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9164 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9167 def clear_nat66(self):
9169 Clear NAT66 configuration.
9171 interfaces = self.vapi.nat66_interface_dump()
9172 for intf in interfaces:
9173 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9174 sw_if_index=intf.sw_if_index)
9176 static_mappings = self.vapi.nat66_static_mapping_dump()
9177 for sm in static_mappings:
9178 self.vapi.nat66_add_del_static_mapping(
9179 local_ip_address=sm.local_ip_address,
9180 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9184 super(TestNAT66, self).tearDown()
9187 def show_commands_at_teardown(self):
9188 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9189 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9192 if __name__ == '__main__':
9193 unittest.main(testRunner=VppTestRunner)