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
38 # NAT HA protocol event data
41 fields_desc = [ByteEnumField("event_type", None,
42 {1: "add", 2: "del", 3: "refresh"}),
43 ByteEnumField("protocol", None,
44 {0: "udp", 1: "tcp", 2: "icmp"}),
45 ShortField("flags", 0),
46 IPField("in_addr", None),
47 IPField("out_addr", None),
48 ShortField("in_port", None),
49 ShortField("out_port", None),
50 IPField("eh_addr", None),
51 IPField("ehn_addr", None),
52 ShortField("eh_port", None),
53 ShortField("ehn_port", None),
54 IntField("fib_index", None),
55 IntField("total_pkts", 0),
56 LongField("total_bytes", 0)]
58 def extract_padding(self, s):
62 # NAT HA protocol header
63 class HANATStateSync(Packet):
64 name = "HA NAT state sync"
65 fields_desc = [XByteField("version", 1),
66 FlagsField("flags", 0, 8, ['ACK']),
67 FieldLenField("count", None, count_of="events"),
68 IntField("sequence_number", 1),
69 IntField("thread_index", 0),
70 PacketListField("events", [], Event,
71 count_from=lambda pkt: pkt.count)]
74 class MethodHolder(VppTestCase):
75 """ NAT create capture and verify method holder """
78 def config_flags(self):
79 return VppEnum.vl_api_nat_config_flags_t
82 def SYSLOG_SEVERITY(self):
83 return VppEnum.vl_api_syslog_severity_t
85 def clear_nat44(self):
87 Clear NAT44 configuration.
89 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
90 if self.pg7.has_ip4_config:
91 self.pg7.unconfig_ip4()
93 self.vapi.nat44_forwarding_enable_disable(enable=0)
95 interfaces = self.vapi.nat44_interface_addr_dump()
96 for intf in interfaces:
97 self.vapi.nat44_add_del_interface_addr(
99 sw_if_index=intf.sw_if_index,
102 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
103 src_port=self.ipfix_src_port,
105 self.ipfix_src_port = 4739
106 self.ipfix_domain_id = 1
108 self.vapi.syslog_set_filter(
109 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
111 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
113 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
114 session_refresh_interval=10)
116 interfaces = self.vapi.nat44_interface_dump()
117 for intf in interfaces:
118 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
119 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
120 self.vapi.nat44_interface_add_del_feature(
121 sw_if_index=intf.sw_if_index)
122 self.vapi.nat44_interface_add_del_feature(
123 sw_if_index=intf.sw_if_index,
126 interfaces = self.vapi.nat44_interface_output_feature_dump()
127 for intf in interfaces:
128 self.vapi.nat44_interface_add_del_output_feature(
131 sw_if_index=intf.sw_if_index)
132 static_mappings = self.vapi.nat44_static_mapping_dump()
133 for sm in static_mappings:
134 self.vapi.nat44_add_del_static_mapping(
136 local_ip_address=sm.local_ip_address,
137 external_ip_address=sm.external_ip_address,
138 external_sw_if_index=sm.external_sw_if_index,
139 local_port=sm.local_port,
140 external_port=sm.external_port,
142 protocol=sm.protocol,
143 flags=sm.flags, tag=sm.tag)
145 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
146 for lb_sm in lb_static_mappings:
147 self.vapi.nat44_add_del_lb_static_mapping(
150 external_addr=lb_sm.external_addr,
151 external_port=lb_sm.external_port,
152 protocol=lb_sm.protocol,
153 local_num=0, locals=[],
156 identity_mappings = self.vapi.nat44_identity_mapping_dump()
157 for id_m in identity_mappings:
158 self.vapi.nat44_add_del_identity_mapping(
159 ip_address=id_m.ip_address,
160 sw_if_index=id_m.sw_if_index,
164 protocol=id_m.protocol)
166 addresses = self.vapi.nat44_address_dump()
167 for addr in addresses:
168 self.vapi.nat44_add_del_address_range(
169 first_ip_address=addr.ip_address,
170 last_ip_address=addr.ip_address,
171 vrf_id=0xFFFFFFFF, flags=addr.flags)
173 self.verify_no_nat44_user()
174 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
175 tcp_transitory=240, icmp=60)
176 self.vapi.nat_set_addr_and_port_alloc_alg()
177 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
179 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
180 local_port=0, external_port=0, vrf_id=0,
181 is_add=1, external_sw_if_index=0xFFFFFFFF,
182 proto=0, tag="", flags=0):
184 Add/delete NAT44 static mapping
186 :param local_ip: Local IP address
187 :param external_ip: External IP address
188 :param local_port: Local port number (Optional)
189 :param external_port: External port number (Optional)
190 :param vrf_id: VRF ID (Default 0)
191 :param is_add: 1 if add, 0 if delete (Default add)
192 :param external_sw_if_index: External interface instead of IP address
193 :param proto: IP protocol (Mandatory if port specified)
194 :param tag: Opaque string tag
195 :param flags: NAT configuration flags
198 if not (local_port and external_port):
199 flags |= self.config_flags.NAT_IS_ADDR_ONLY
201 self.vapi.nat44_add_del_static_mapping(
203 local_ip_address=local_ip,
204 external_ip_address=external_ip,
205 external_sw_if_index=external_sw_if_index,
206 local_port=local_port,
207 external_port=external_port,
208 vrf_id=vrf_id, protocol=proto,
212 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
214 Add/delete NAT44 address
216 :param ip: IP address
217 :param is_add: 1 if add, 0 if delete (Default add)
218 :param twice_nat: twice NAT address for external hosts
220 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
221 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
227 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
229 Create packet stream for inside network
231 :param in_if: Inside interface
232 :param out_if: Outside interface
233 :param dst_ip: Destination address
234 :param ttl: TTL of generated packets
237 dst_ip = out_if.remote_ip4
241 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
242 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
243 TCP(sport=self.tcp_port_in, dport=20))
247 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
248 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
249 UDP(sport=self.udp_port_in, dport=20))
253 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
254 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
255 ICMP(id=self.icmp_id_in, type='echo-request'))
260 def compose_ip6(self, ip4, pref, plen):
262 Compose IPv4-embedded IPv6 addresses
264 :param ip4: IPv4 address
265 :param pref: IPv6 prefix
266 :param plen: IPv6 prefix length
267 :returns: IPv4-embedded IPv6 addresses
269 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
270 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
285 pref_n[10] = ip4_n[3]
289 pref_n[10] = ip4_n[2]
290 pref_n[11] = ip4_n[3]
293 pref_n[10] = ip4_n[1]
294 pref_n[11] = ip4_n[2]
295 pref_n[12] = ip4_n[3]
297 pref_n[12] = ip4_n[0]
298 pref_n[13] = ip4_n[1]
299 pref_n[14] = ip4_n[2]
300 pref_n[15] = ip4_n[3]
301 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
302 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
304 def extract_ip4(self, ip6, plen):
306 Extract IPv4 address embedded in IPv6 addresses
308 :param ip6: IPv6 address
309 :param plen: IPv6 prefix length
310 :returns: extracted IPv4 address
312 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
344 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
346 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
348 Create IPv6 packet stream for inside network
350 :param in_if: Inside interface
351 :param out_if: Outside interface
352 :param ttl: Hop Limit of generated packets
353 :param pref: NAT64 prefix
354 :param plen: NAT64 prefix length
358 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
360 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
363 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
364 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
365 TCP(sport=self.tcp_port_in, dport=20))
369 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
370 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
371 UDP(sport=self.udp_port_in, dport=20))
375 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
376 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
377 ICMPv6EchoRequest(id=self.icmp_id_in))
382 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
383 use_inside_ports=False):
385 Create packet stream for outside network
387 :param out_if: Outside interface
388 :param dst_ip: Destination IP address (Default use global NAT address)
389 :param ttl: TTL of generated packets
390 :param use_inside_ports: Use inside NAT ports as destination ports
391 instead of outside ports
394 dst_ip = self.nat_addr
395 if not use_inside_ports:
396 tcp_port = self.tcp_port_out
397 udp_port = self.udp_port_out
398 icmp_id = self.icmp_id_out
400 tcp_port = self.tcp_port_in
401 udp_port = self.udp_port_in
402 icmp_id = self.icmp_id_in
405 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
406 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
407 TCP(dport=tcp_port, sport=20))
411 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
412 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
413 UDP(dport=udp_port, sport=20))
417 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
418 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
419 ICMP(id=icmp_id, type='echo-reply'))
424 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
426 Create packet stream for outside network
428 :param out_if: Outside interface
429 :param dst_ip: Destination IP address (Default use global NAT address)
430 :param hl: HL of generated packets
434 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
435 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
436 TCP(dport=self.tcp_port_out, sport=20))
440 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
441 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
442 UDP(dport=self.udp_port_out, sport=20))
446 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
447 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
448 ICMPv6EchoReply(id=self.icmp_id_out))
453 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
454 dst_ip=None, is_ip6=False):
456 Verify captured packets on outside network
458 :param capture: Captured packets
459 :param nat_ip: Translated IP address (Default use global NAT address)
460 :param same_port: Source port number is not translated (Default False)
461 :param dst_ip: Destination IP address (Default do not verify)
462 :param is_ip6: If L3 protocol is IPv6 (Default False)
466 ICMP46 = ICMPv6EchoRequest
471 nat_ip = self.nat_addr
472 for packet in capture:
475 self.assert_packet_checksums_valid(packet)
476 self.assertEqual(packet[IP46].src, nat_ip)
477 if dst_ip is not None:
478 self.assertEqual(packet[IP46].dst, dst_ip)
479 if packet.haslayer(TCP):
481 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
484 packet[TCP].sport, self.tcp_port_in)
485 self.tcp_port_out = packet[TCP].sport
486 self.assert_packet_checksums_valid(packet)
487 elif packet.haslayer(UDP):
489 self.assertEqual(packet[UDP].sport, self.udp_port_in)
492 packet[UDP].sport, self.udp_port_in)
493 self.udp_port_out = packet[UDP].sport
496 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
498 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
499 self.icmp_id_out = packet[ICMP46].id
500 self.assert_packet_checksums_valid(packet)
502 self.logger.error(ppp("Unexpected or invalid packet "
503 "(outside network):", packet))
506 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
509 Verify captured packets on outside network
511 :param capture: Captured packets
512 :param nat_ip: Translated IP address
513 :param same_port: Source port number is not translated (Default False)
514 :param dst_ip: Destination IP address (Default do not verify)
516 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
519 def verify_capture_in(self, capture, in_if):
521 Verify captured packets on inside network
523 :param capture: Captured packets
524 :param in_if: Inside interface
526 for packet in capture:
528 self.assert_packet_checksums_valid(packet)
529 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
530 if packet.haslayer(TCP):
531 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
532 elif packet.haslayer(UDP):
533 self.assertEqual(packet[UDP].dport, self.udp_port_in)
535 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
537 self.logger.error(ppp("Unexpected or invalid packet "
538 "(inside network):", packet))
541 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
543 Verify captured IPv6 packets on inside network
545 :param capture: Captured packets
546 :param src_ip: Source IP
547 :param dst_ip: Destination IP address
549 for packet in capture:
551 self.assertEqual(packet[IPv6].src, src_ip)
552 self.assertEqual(packet[IPv6].dst, dst_ip)
553 self.assert_packet_checksums_valid(packet)
554 if packet.haslayer(TCP):
555 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
556 elif packet.haslayer(UDP):
557 self.assertEqual(packet[UDP].dport, self.udp_port_in)
559 self.assertEqual(packet[ICMPv6EchoReply].id,
562 self.logger.error(ppp("Unexpected or invalid packet "
563 "(inside network):", packet))
566 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
568 Verify captured packet that don't have to be translated
570 :param capture: Captured packets
571 :param ingress_if: Ingress interface
572 :param egress_if: Egress interface
574 for packet in capture:
576 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
577 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
578 if packet.haslayer(TCP):
579 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
580 elif packet.haslayer(UDP):
581 self.assertEqual(packet[UDP].sport, self.udp_port_in)
583 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
585 self.logger.error(ppp("Unexpected or invalid packet "
586 "(inside network):", packet))
589 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
592 Verify captured packets with ICMP errors on outside network
594 :param capture: Captured packets
595 :param src_ip: Translated IP address or IP address of VPP
596 (Default use global NAT address)
597 :param icmp_type: Type of error ICMP packet
598 we are expecting (Default 11)
601 src_ip = self.nat_addr
602 for packet in capture:
604 self.assertEqual(packet[IP].src, src_ip)
605 self.assertEqual(packet.haslayer(ICMP), 1)
607 self.assertEqual(icmp.type, icmp_type)
608 self.assertTrue(icmp.haslayer(IPerror))
609 inner_ip = icmp[IPerror]
610 if inner_ip.haslayer(TCPerror):
611 self.assertEqual(inner_ip[TCPerror].dport,
613 elif inner_ip.haslayer(UDPerror):
614 self.assertEqual(inner_ip[UDPerror].dport,
617 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
619 self.logger.error(ppp("Unexpected or invalid packet "
620 "(outside network):", packet))
623 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
625 Verify captured packets with ICMP errors on inside network
627 :param capture: Captured packets
628 :param in_if: Inside interface
629 :param icmp_type: Type of error ICMP packet
630 we are expecting (Default 11)
632 for packet in capture:
634 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
635 self.assertEqual(packet.haslayer(ICMP), 1)
637 self.assertEqual(icmp.type, icmp_type)
638 self.assertTrue(icmp.haslayer(IPerror))
639 inner_ip = icmp[IPerror]
640 if inner_ip.haslayer(TCPerror):
641 self.assertEqual(inner_ip[TCPerror].sport,
643 elif inner_ip.haslayer(UDPerror):
644 self.assertEqual(inner_ip[UDPerror].sport,
647 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
649 self.logger.error(ppp("Unexpected or invalid packet "
650 "(inside network):", packet))
653 def create_stream_frag(self, src_if, dst, sport, dport, data,
654 proto=IP_PROTOS.tcp, echo_reply=False):
656 Create fragmented packet stream
658 :param src_if: Source interface
659 :param dst: Destination IPv4 address
660 :param sport: Source port
661 :param dport: Destination port
662 :param data: Payload data
663 :param proto: protocol (TCP, UDP, ICMP)
664 :param echo_reply: use echo_reply if protocol is ICMP
667 if proto == IP_PROTOS.tcp:
668 p = (IP(src=src_if.remote_ip4, dst=dst) /
669 TCP(sport=sport, dport=dport) /
671 p = p.__class__(scapy.compat.raw(p))
672 chksum = p[TCP].chksum
673 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
674 elif proto == IP_PROTOS.udp:
675 proto_header = UDP(sport=sport, dport=dport)
676 elif proto == IP_PROTOS.icmp:
678 proto_header = ICMP(id=sport, type='echo-request')
680 proto_header = ICMP(id=sport, type='echo-reply')
682 raise Exception("Unsupported protocol")
683 id = random.randint(0, 65535)
685 if proto == IP_PROTOS.tcp:
688 raw = Raw(data[0:16])
689 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
690 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
694 if proto == IP_PROTOS.tcp:
695 raw = Raw(data[4:20])
697 raw = Raw(data[16:32])
698 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
699 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
703 if proto == IP_PROTOS.tcp:
707 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
708 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
714 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
715 pref=None, plen=0, frag_size=128):
717 Create fragmented packet stream
719 :param src_if: Source interface
720 :param dst: Destination IPv4 address
721 :param sport: Source TCP port
722 :param dport: Destination TCP port
723 :param data: Payload data
724 :param pref: NAT64 prefix
725 :param plen: NAT64 prefix length
726 :param fragsize: size of fragments
730 dst_ip6 = ''.join(['64:ff9b::', dst])
732 dst_ip6 = self.compose_ip6(dst, pref, plen)
734 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
735 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
736 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
737 TCP(sport=sport, dport=dport) /
740 return fragment6(p, frag_size)
742 def reass_frags_and_verify(self, frags, src, dst):
744 Reassemble and verify fragmented packet
746 :param frags: Captured fragments
747 :param src: Source IPv4 address to verify
748 :param dst: Destination IPv4 address to verify
750 :returns: Reassembled IPv4 packet
754 self.assertEqual(p[IP].src, src)
755 self.assertEqual(p[IP].dst, dst)
756 self.assert_ip_checksum_valid(p)
757 buffer.seek(p[IP].frag * 8)
758 buffer.write(bytes(p[IP].payload))
759 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
760 proto=frags[0][IP].proto)
761 if ip.proto == IP_PROTOS.tcp:
762 p = (ip / TCP(buffer.getvalue()))
763 self.logger.debug(ppp("Reassembled:", p))
764 self.assert_tcp_checksum_valid(p)
765 elif ip.proto == IP_PROTOS.udp:
766 p = (ip / UDP(buffer.getvalue()[:8]) /
767 Raw(buffer.getvalue()[8:]))
768 elif ip.proto == IP_PROTOS.icmp:
769 p = (ip / ICMP(buffer.getvalue()))
772 def reass_frags_and_verify_ip6(self, frags, src, dst):
774 Reassemble and verify fragmented packet
776 :param frags: Captured fragments
777 :param src: Source IPv6 address to verify
778 :param dst: Destination IPv6 address to verify
780 :returns: Reassembled IPv6 packet
784 self.assertEqual(p[IPv6].src, src)
785 self.assertEqual(p[IPv6].dst, dst)
786 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
787 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
788 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
789 nh=frags[0][IPv6ExtHdrFragment].nh)
790 if ip.nh == IP_PROTOS.tcp:
791 p = (ip / TCP(buffer.getvalue()))
792 elif ip.nh == IP_PROTOS.udp:
793 p = (ip / UDP(buffer.getvalue()))
794 self.logger.debug(ppp("Reassembled:", p))
795 self.assert_packet_checksums_valid(p)
798 def initiate_tcp_session(self, in_if, out_if):
800 Initiates TCP session
802 :param in_if: Inside interface
803 :param out_if: Outside interface
807 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
808 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
809 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
812 self.pg_enable_capture(self.pg_interfaces)
814 capture = out_if.get_capture(1)
816 self.tcp_port_out = p[TCP].sport
818 # SYN + ACK packet out->in
819 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
820 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
821 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
824 self.pg_enable_capture(self.pg_interfaces)
829 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
830 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
834 self.pg_enable_capture(self.pg_interfaces)
836 out_if.get_capture(1)
839 self.logger.error("TCP 3 way handshake failed")
842 def verify_ipfix_nat44_ses(self, data):
844 Verify IPFIX NAT44 session create/delete event
846 :param data: Decoded IPFIX data records
848 nat44_ses_create_num = 0
849 nat44_ses_delete_num = 0
850 self.assertEqual(6, len(data))
853 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
854 if scapy.compat.orb(record[230]) == 4:
855 nat44_ses_create_num += 1
857 nat44_ses_delete_num += 1
859 self.assertEqual(self.pg0.remote_ip4n, record[8])
860 # postNATSourceIPv4Address
861 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
864 self.assertEqual(struct.pack("!I", 0), record[234])
865 # protocolIdentifier/sourceTransportPort
866 # /postNAPTSourceTransportPort
867 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
868 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
869 self.assertEqual(struct.pack("!H", self.icmp_id_out),
871 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
872 self.assertEqual(struct.pack("!H", self.tcp_port_in),
874 self.assertEqual(struct.pack("!H", self.tcp_port_out),
876 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.udp_port_in),
879 self.assertEqual(struct.pack("!H", self.udp_port_out),
882 self.fail("Invalid protocol")
883 self.assertEqual(3, nat44_ses_create_num)
884 self.assertEqual(3, nat44_ses_delete_num)
886 def verify_ipfix_addr_exhausted(self, data):
888 Verify IPFIX NAT addresses event
890 :param data: Decoded IPFIX data records
892 self.assertEqual(1, len(data))
895 self.assertEqual(scapy.compat.orb(record[230]), 3)
897 self.assertEqual(struct.pack("!I", 0), record[283])
899 def verify_ipfix_max_sessions(self, data, limit):
901 Verify IPFIX maximum session entries exceeded event
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum session entries that can be created.
906 self.assertEqual(1, len(data))
909 self.assertEqual(scapy.compat.orb(record[230]), 13)
910 # natQuotaExceededEvent
911 self.assertEqual(struct.pack("I", 1), record[466])
913 self.assertEqual(struct.pack("I", limit), record[471])
915 def verify_ipfix_max_bibs(self, data, limit):
917 Verify IPFIX maximum BIB entries exceeded event
919 :param data: Decoded IPFIX data records
920 :param limit: Number of maximum BIB entries that can be created.
922 self.assertEqual(1, len(data))
925 self.assertEqual(scapy.compat.orb(record[230]), 13)
926 # natQuotaExceededEvent
927 self.assertEqual(struct.pack("I", 2), record[466])
929 self.assertEqual(struct.pack("I", limit), record[472])
931 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
933 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
935 :param data: Decoded IPFIX data records
936 :param limit: Number of maximum fragments pending reassembly
937 :param src_addr: IPv6 source address
939 self.assertEqual(1, len(data))
942 self.assertEqual(scapy.compat.orb(record[230]), 13)
943 # natQuotaExceededEvent
944 self.assertEqual(struct.pack("I", 5), record[466])
945 # maxFragmentsPendingReassembly
946 self.assertEqual(struct.pack("I", limit), record[475])
948 self.assertEqual(src_addr, record[27])
950 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
952 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
954 :param data: Decoded IPFIX data records
955 :param limit: Number of maximum fragments pending reassembly
956 :param src_addr: IPv4 source address
958 self.assertEqual(1, len(data))
961 self.assertEqual(scapy.compat.orb(record[230]), 13)
962 # natQuotaExceededEvent
963 self.assertEqual(struct.pack("I", 5), record[466])
964 # maxFragmentsPendingReassembly
965 self.assertEqual(struct.pack("I", limit), record[475])
967 self.assertEqual(src_addr, record[8])
969 def verify_ipfix_bib(self, data, is_create, src_addr):
971 Verify IPFIX NAT64 BIB create and delete events
973 :param data: Decoded IPFIX data records
974 :param is_create: Create event if nonzero value otherwise delete event
975 :param src_addr: IPv6 source address
977 self.assertEqual(1, len(data))
981 self.assertEqual(scapy.compat.orb(record[230]), 10)
983 self.assertEqual(scapy.compat.orb(record[230]), 11)
985 self.assertEqual(src_addr, record[27])
986 # postNATSourceIPv4Address
987 self.assertEqual(self.nat_addr_n, record[225])
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
997 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
1000 Verify IPFIX NAT64 session create and delete events
1002 :param data: Decoded IPFIX data records
1003 :param is_create: Create event if nonzero value otherwise delete event
1004 :param src_addr: IPv6 source address
1005 :param dst_addr: IPv4 destination address
1006 :param dst_port: destination TCP port
1008 self.assertEqual(1, len(data))
1012 self.assertEqual(scapy.compat.orb(record[230]), 6)
1014 self.assertEqual(scapy.compat.orb(record[230]), 7)
1016 self.assertEqual(src_addr, record[27])
1017 # destinationIPv6Address
1018 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1019 self.compose_ip6(dst_addr,
1023 # postNATSourceIPv4Address
1024 self.assertEqual(self.nat_addr_n, record[225])
1025 # postNATDestinationIPv4Address
1026 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1028 # protocolIdentifier
1029 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1031 self.assertEqual(struct.pack("!I", 0), record[234])
1032 # sourceTransportPort
1033 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1034 # postNAPTSourceTransportPort
1035 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1036 # destinationTransportPort
1037 self.assertEqual(struct.pack("!H", dst_port), record[11])
1038 # postNAPTDestinationTransportPort
1039 self.assertEqual(struct.pack("!H", dst_port), record[228])
1041 def verify_no_nat44_user(self):
1042 """ Verify that there is no NAT44 user """
1043 users = self.vapi.nat44_user_dump()
1044 self.assertEqual(len(users), 0)
1045 users = self.statistics.get_counter('/nat44/total-users')
1046 self.assertEqual(users[0][0], 0)
1047 sessions = self.statistics.get_counter('/nat44/total-sessions')
1048 self.assertEqual(sessions[0][0], 0)
1050 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1052 Verify IPFIX maximum entries per user exceeded event
1054 :param data: Decoded IPFIX data records
1055 :param limit: Number of maximum entries per user
1056 :param src_addr: IPv4 source address
1058 self.assertEqual(1, len(data))
1061 self.assertEqual(scapy.compat.orb(record[230]), 13)
1062 # natQuotaExceededEvent
1063 self.assertEqual(struct.pack("I", 3), record[466])
1065 self.assertEqual(struct.pack("I", limit), record[473])
1067 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1069 def verify_syslog_apmap(self, data, is_add=True):
1070 message = data.decode('utf-8')
1072 message = SyslogMessage.parse(message)
1073 except ParseError as e:
1074 self.logger.error(e)
1077 self.assertEqual(message.severity, SyslogSeverity.info)
1078 self.assertEqual(message.appname, 'NAT')
1079 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1080 sd_params = message.sd.get('napmap')
1081 self.assertTrue(sd_params is not None)
1082 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1083 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1084 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1085 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1086 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1087 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1088 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1089 self.assertTrue(sd_params.get('SSUBIX') is not None)
1090 self.assertEqual(sd_params.get('SVLAN'), '0')
1092 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1093 message = data.decode('utf-8')
1095 message = SyslogMessage.parse(message)
1096 except ParseError as e:
1097 self.logger.error(e)
1100 self.assertEqual(message.severity, SyslogSeverity.info)
1101 self.assertEqual(message.appname, 'NAT')
1102 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1103 sd_params = message.sd.get('nsess')
1104 self.assertTrue(sd_params is not None)
1106 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1107 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1109 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1110 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1111 self.assertTrue(sd_params.get('SSUBIX') is not None)
1112 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1113 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1114 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1115 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1116 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1117 self.assertEqual(sd_params.get('SVLAN'), '0')
1118 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1119 self.assertEqual(sd_params.get('XDPORT'),
1120 "%d" % self.tcp_external_port)
1122 def verify_mss_value(self, pkt, mss):
1124 Verify TCP MSS value
1129 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1130 raise TypeError("Not a TCP/IP packet")
1132 for option in pkt[TCP].options:
1133 if option[0] == 'MSS':
1134 self.assertEqual(option[1], mss)
1135 self.assert_tcp_checksum_valid(pkt)
1138 def proto2layer(proto):
1139 if proto == IP_PROTOS.tcp:
1141 elif proto == IP_PROTOS.udp:
1143 elif proto == IP_PROTOS.icmp:
1146 raise Exception("Unsupported protocol")
1148 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1149 layer = self.proto2layer(proto)
1151 if proto == IP_PROTOS.tcp:
1152 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1154 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1155 self.port_in = random.randint(1025, 65535)
1158 pkts = self.create_stream_frag(self.pg0,
1159 self.pg1.remote_ip4,
1164 self.pg0.add_stream(pkts)
1165 self.pg_enable_capture(self.pg_interfaces)
1167 frags = self.pg1.get_capture(len(pkts))
1168 if not dont_translate:
1169 p = self.reass_frags_and_verify(frags,
1171 self.pg1.remote_ip4)
1173 p = self.reass_frags_and_verify(frags,
1174 self.pg0.remote_ip4,
1175 self.pg1.remote_ip4)
1176 if proto != IP_PROTOS.icmp:
1177 if not dont_translate:
1178 self.assertEqual(p[layer].dport, 20)
1179 self.assertNotEqual(p[layer].sport, self.port_in)
1181 self.assertEqual(p[layer].sport, self.port_in)
1183 if not dont_translate:
1184 self.assertNotEqual(p[layer].id, self.port_in)
1186 self.assertEqual(p[layer].id, self.port_in)
1187 self.assertEqual(data, p[Raw].load)
1190 if not dont_translate:
1191 dst_addr = self.nat_addr
1193 dst_addr = self.pg0.remote_ip4
1194 if proto != IP_PROTOS.icmp:
1196 dport = p[layer].sport
1200 pkts = self.create_stream_frag(self.pg1,
1207 self.pg1.add_stream(pkts)
1208 self.pg_enable_capture(self.pg_interfaces)
1210 frags = self.pg0.get_capture(len(pkts))
1211 p = self.reass_frags_and_verify(frags,
1212 self.pg1.remote_ip4,
1213 self.pg0.remote_ip4)
1214 if proto != IP_PROTOS.icmp:
1215 self.assertEqual(p[layer].sport, 20)
1216 self.assertEqual(p[layer].dport, self.port_in)
1218 self.assertEqual(p[layer].id, self.port_in)
1219 self.assertEqual(data, p[Raw].load)
1221 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1222 layer = self.proto2layer(proto)
1224 if proto == IP_PROTOS.tcp:
1225 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1227 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1228 self.port_in = random.randint(1025, 65535)
1232 pkts = self.create_stream_frag(self.pg0,
1233 self.server_out_addr,
1235 self.server_out_port,
1238 self.pg0.add_stream(pkts)
1239 self.pg_enable_capture(self.pg_interfaces)
1241 frags = self.pg1.get_capture(len(pkts))
1242 p = self.reass_frags_and_verify(frags,
1243 self.pg0.remote_ip4,
1244 self.server_in_addr)
1245 if proto != IP_PROTOS.icmp:
1246 self.assertEqual(p[layer].sport, self.port_in)
1247 self.assertEqual(p[layer].dport, self.server_in_port)
1249 self.assertEqual(p[layer].id, self.port_in)
1250 self.assertEqual(data, p[Raw].load)
1253 if proto != IP_PROTOS.icmp:
1254 pkts = self.create_stream_frag(self.pg1,
1255 self.pg0.remote_ip4,
1256 self.server_in_port,
1261 pkts = self.create_stream_frag(self.pg1,
1262 self.pg0.remote_ip4,
1268 self.pg1.add_stream(pkts)
1269 self.pg_enable_capture(self.pg_interfaces)
1271 frags = self.pg0.get_capture(len(pkts))
1272 p = self.reass_frags_and_verify(frags,
1273 self.server_out_addr,
1274 self.pg0.remote_ip4)
1275 if proto != IP_PROTOS.icmp:
1276 self.assertEqual(p[layer].sport, self.server_out_port)
1277 self.assertEqual(p[layer].dport, self.port_in)
1279 self.assertEqual(p[layer].id, self.port_in)
1280 self.assertEqual(data, p[Raw].load)
1282 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1283 layer = self.proto2layer(proto)
1285 if proto == IP_PROTOS.tcp:
1286 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1288 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1290 # send packet from host to server
1291 pkts = self.create_stream_frag(self.pg0,
1294 self.server_out_port,
1297 self.pg0.add_stream(pkts)
1298 self.pg_enable_capture(self.pg_interfaces)
1300 frags = self.pg0.get_capture(len(pkts))
1301 p = self.reass_frags_and_verify(frags,
1304 if proto != IP_PROTOS.icmp:
1305 self.assertNotEqual(p[layer].sport, self.host_in_port)
1306 self.assertEqual(p[layer].dport, self.server_in_port)
1308 self.assertNotEqual(p[layer].id, self.host_in_port)
1309 self.assertEqual(data, p[Raw].load)
1311 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1312 layer = self.proto2layer(proto)
1314 if proto == IP_PROTOS.tcp:
1315 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1317 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1318 self.port_in = random.randint(1025, 65535)
1322 pkts = self.create_stream_frag(self.pg0,
1323 self.pg1.remote_ip4,
1329 self.pg0.add_stream(pkts)
1330 self.pg_enable_capture(self.pg_interfaces)
1332 frags = self.pg1.get_capture(len(pkts))
1333 if not dont_translate:
1334 p = self.reass_frags_and_verify(frags,
1336 self.pg1.remote_ip4)
1338 p = self.reass_frags_and_verify(frags,
1339 self.pg0.remote_ip4,
1340 self.pg1.remote_ip4)
1341 if proto != IP_PROTOS.icmp:
1342 if not dont_translate:
1343 self.assertEqual(p[layer].dport, 20)
1344 self.assertNotEqual(p[layer].sport, self.port_in)
1346 self.assertEqual(p[layer].sport, self.port_in)
1348 if not dont_translate:
1349 self.assertNotEqual(p[layer].id, self.port_in)
1351 self.assertEqual(p[layer].id, self.port_in)
1352 self.assertEqual(data, p[Raw].load)
1355 if not dont_translate:
1356 dst_addr = self.nat_addr
1358 dst_addr = self.pg0.remote_ip4
1359 if proto != IP_PROTOS.icmp:
1361 dport = p[layer].sport
1365 pkts = self.create_stream_frag(self.pg1,
1373 self.pg1.add_stream(pkts)
1374 self.pg_enable_capture(self.pg_interfaces)
1376 frags = self.pg0.get_capture(len(pkts))
1377 p = self.reass_frags_and_verify(frags,
1378 self.pg1.remote_ip4,
1379 self.pg0.remote_ip4)
1380 if proto != IP_PROTOS.icmp:
1381 self.assertEqual(p[layer].sport, 20)
1382 self.assertEqual(p[layer].dport, self.port_in)
1384 self.assertEqual(p[layer].id, self.port_in)
1385 self.assertEqual(data, p[Raw].load)
1387 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1388 layer = self.proto2layer(proto)
1390 if proto == IP_PROTOS.tcp:
1391 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1393 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1394 self.port_in = random.randint(1025, 65535)
1398 pkts = self.create_stream_frag(self.pg0,
1399 self.server_out_addr,
1401 self.server_out_port,
1405 self.pg0.add_stream(pkts)
1406 self.pg_enable_capture(self.pg_interfaces)
1408 frags = self.pg1.get_capture(len(pkts))
1409 p = self.reass_frags_and_verify(frags,
1410 self.pg0.remote_ip4,
1411 self.server_in_addr)
1412 if proto != IP_PROTOS.icmp:
1413 self.assertEqual(p[layer].dport, self.server_in_port)
1414 self.assertEqual(p[layer].sport, self.port_in)
1415 self.assertEqual(p[layer].dport, self.server_in_port)
1417 self.assertEqual(p[layer].id, self.port_in)
1418 self.assertEqual(data, p[Raw].load)
1421 if proto != IP_PROTOS.icmp:
1422 pkts = self.create_stream_frag(self.pg1,
1423 self.pg0.remote_ip4,
1424 self.server_in_port,
1429 pkts = self.create_stream_frag(self.pg1,
1430 self.pg0.remote_ip4,
1437 self.pg1.add_stream(pkts)
1438 self.pg_enable_capture(self.pg_interfaces)
1440 frags = self.pg0.get_capture(len(pkts))
1441 p = self.reass_frags_and_verify(frags,
1442 self.server_out_addr,
1443 self.pg0.remote_ip4)
1444 if proto != IP_PROTOS.icmp:
1445 self.assertEqual(p[layer].sport, self.server_out_port)
1446 self.assertEqual(p[layer].dport, self.port_in)
1448 self.assertEqual(p[layer].id, self.port_in)
1449 self.assertEqual(data, p[Raw].load)
1452 class TestNAT44(MethodHolder):
1453 """ NAT44 Test Cases """
1456 def setUpClass(cls):
1457 super(TestNAT44, cls).setUpClass()
1458 cls.vapi.cli("set log class nat level debug")
1460 cls.tcp_port_in = 6303
1461 cls.tcp_port_out = 6303
1462 cls.udp_port_in = 6304
1463 cls.udp_port_out = 6304
1464 cls.icmp_id_in = 6305
1465 cls.icmp_id_out = 6305
1466 cls.nat_addr = '10.0.0.3'
1467 cls.ipfix_src_port = 4739
1468 cls.ipfix_domain_id = 1
1469 cls.tcp_external_port = 80
1470 cls.udp_external_port = 69
1472 cls.create_pg_interfaces(range(10))
1473 cls.interfaces = list(cls.pg_interfaces[0:4])
1475 for i in cls.interfaces:
1480 cls.pg0.generate_remote_hosts(3)
1481 cls.pg0.configure_ipv4_neighbors()
1483 cls.pg1.generate_remote_hosts(1)
1484 cls.pg1.configure_ipv4_neighbors()
1486 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1487 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1488 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1490 cls.pg4._local_ip4 = "172.16.255.1"
1491 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1492 cls.pg4.set_table_ip4(10)
1493 cls.pg5._local_ip4 = "172.17.255.3"
1494 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1495 cls.pg5.set_table_ip4(10)
1496 cls.pg6._local_ip4 = "172.16.255.1"
1497 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1498 cls.pg6.set_table_ip4(20)
1499 for i in cls.overlapping_interfaces:
1507 cls.pg9.generate_remote_hosts(2)
1508 cls.pg9.config_ip4()
1509 cls.vapi.sw_interface_add_del_address(
1510 sw_if_index=cls.pg9.sw_if_index,
1511 prefix="10.0.0.1/24")
1514 cls.pg9.resolve_arp()
1515 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1516 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1517 cls.pg9.resolve_arp()
1520 def tearDownClass(cls):
1521 super(TestNAT44, cls).tearDownClass()
1523 def test_dynamic(self):
1524 """ NAT44 dynamic translation test """
1525 self.nat44_add_address(self.nat_addr)
1526 flags = self.config_flags.NAT_IS_INSIDE
1527 self.vapi.nat44_interface_add_del_feature(
1528 sw_if_index=self.pg0.sw_if_index,
1529 flags=flags, is_add=1)
1530 self.vapi.nat44_interface_add_del_feature(
1531 sw_if_index=self.pg1.sw_if_index,
1535 tcpn = self.statistics.get_err_counter(
1536 '/err/nat44-in2out-slowpath/TCP packets')
1537 udpn = self.statistics.get_err_counter(
1538 '/err/nat44-in2out-slowpath/UDP packets')
1539 icmpn = self.statistics.get_err_counter(
1540 '/err/nat44-in2out-slowpath/ICMP packets')
1541 totaln = self.statistics.get_err_counter(
1542 '/err/nat44-in2out-slowpath/good in2out packets processed')
1544 pkts = self.create_stream_in(self.pg0, self.pg1)
1545 self.pg0.add_stream(pkts)
1546 self.pg_enable_capture(self.pg_interfaces)
1548 capture = self.pg1.get_capture(len(pkts))
1549 self.verify_capture_out(capture)
1551 err = self.statistics.get_err_counter(
1552 '/err/nat44-in2out-slowpath/TCP packets')
1553 self.assertEqual(err - tcpn, 2)
1554 err = self.statistics.get_err_counter(
1555 '/err/nat44-in2out-slowpath/UDP packets')
1556 self.assertEqual(err - udpn, 1)
1557 err = self.statistics.get_err_counter(
1558 '/err/nat44-in2out-slowpath/ICMP packets')
1559 self.assertEqual(err - icmpn, 1)
1560 err = self.statistics.get_err_counter(
1561 '/err/nat44-in2out-slowpath/good in2out packets processed')
1562 self.assertEqual(err - totaln, 4)
1565 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1566 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1567 icmpn = self.statistics.get_err_counter(
1568 '/err/nat44-out2in/ICMP packets')
1569 totaln = self.statistics.get_err_counter(
1570 '/err/nat44-out2in/good out2in packets processed')
1572 pkts = self.create_stream_out(self.pg1)
1573 self.pg1.add_stream(pkts)
1574 self.pg_enable_capture(self.pg_interfaces)
1576 capture = self.pg0.get_capture(len(pkts))
1577 self.verify_capture_in(capture, self.pg0)
1579 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1580 self.assertEqual(err - tcpn, 2)
1581 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1582 self.assertEqual(err - udpn, 1)
1583 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1584 self.assertEqual(err - icmpn, 1)
1585 err = self.statistics.get_err_counter(
1586 '/err/nat44-out2in/good out2in packets processed')
1587 self.assertEqual(err - totaln, 4)
1589 users = self.statistics.get_counter('/nat44/total-users')
1590 self.assertEqual(users[0][0], 1)
1591 sessions = self.statistics.get_counter('/nat44/total-sessions')
1592 self.assertEqual(sessions[0][0], 3)
1594 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1595 """ NAT44 handling of client packets with TTL=1 """
1597 self.nat44_add_address(self.nat_addr)
1598 flags = self.config_flags.NAT_IS_INSIDE
1599 self.vapi.nat44_interface_add_del_feature(
1600 sw_if_index=self.pg0.sw_if_index,
1601 flags=flags, is_add=1)
1602 self.vapi.nat44_interface_add_del_feature(
1603 sw_if_index=self.pg1.sw_if_index,
1606 # Client side - generate traffic
1607 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1608 self.pg0.add_stream(pkts)
1609 self.pg_enable_capture(self.pg_interfaces)
1612 # Client side - verify ICMP type 11 packets
1613 capture = self.pg0.get_capture(len(pkts))
1614 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1616 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1617 """ NAT44 handling of server packets with TTL=1 """
1619 self.nat44_add_address(self.nat_addr)
1620 flags = self.config_flags.NAT_IS_INSIDE
1621 self.vapi.nat44_interface_add_del_feature(
1622 sw_if_index=self.pg0.sw_if_index,
1623 flags=flags, is_add=1)
1624 self.vapi.nat44_interface_add_del_feature(
1625 sw_if_index=self.pg1.sw_if_index,
1628 # Client side - create sessions
1629 pkts = self.create_stream_in(self.pg0, self.pg1)
1630 self.pg0.add_stream(pkts)
1631 self.pg_enable_capture(self.pg_interfaces)
1634 # Server side - generate traffic
1635 capture = self.pg1.get_capture(len(pkts))
1636 self.verify_capture_out(capture)
1637 pkts = self.create_stream_out(self.pg1, ttl=1)
1638 self.pg1.add_stream(pkts)
1639 self.pg_enable_capture(self.pg_interfaces)
1642 # Server side - verify ICMP type 11 packets
1643 capture = self.pg1.get_capture(len(pkts))
1644 self.verify_capture_out_with_icmp_errors(capture,
1645 src_ip=self.pg1.local_ip4)
1647 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1648 """ NAT44 handling of error responses to client packets with TTL=2 """
1650 self.nat44_add_address(self.nat_addr)
1651 flags = self.config_flags.NAT_IS_INSIDE
1652 self.vapi.nat44_interface_add_del_feature(
1653 sw_if_index=self.pg0.sw_if_index,
1654 flags=flags, is_add=1)
1655 self.vapi.nat44_interface_add_del_feature(
1656 sw_if_index=self.pg1.sw_if_index,
1659 # Client side - generate traffic
1660 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1661 self.pg0.add_stream(pkts)
1662 self.pg_enable_capture(self.pg_interfaces)
1665 # Server side - simulate ICMP type 11 response
1666 capture = self.pg1.get_capture(len(pkts))
1667 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1668 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1669 ICMP(type=11) / packet[IP] for packet in capture]
1670 self.pg1.add_stream(pkts)
1671 self.pg_enable_capture(self.pg_interfaces)
1674 # Client side - verify ICMP type 11 packets
1675 capture = self.pg0.get_capture(len(pkts))
1676 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1678 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1679 """ NAT44 handling of error responses to server packets with TTL=2 """
1681 self.nat44_add_address(self.nat_addr)
1682 flags = self.config_flags.NAT_IS_INSIDE
1683 self.vapi.nat44_interface_add_del_feature(
1684 sw_if_index=self.pg0.sw_if_index,
1685 flags=flags, is_add=1)
1686 self.vapi.nat44_interface_add_del_feature(
1687 sw_if_index=self.pg1.sw_if_index,
1690 # Client side - create sessions
1691 pkts = self.create_stream_in(self.pg0, self.pg1)
1692 self.pg0.add_stream(pkts)
1693 self.pg_enable_capture(self.pg_interfaces)
1696 # Server side - generate traffic
1697 capture = self.pg1.get_capture(len(pkts))
1698 self.verify_capture_out(capture)
1699 pkts = self.create_stream_out(self.pg1, ttl=2)
1700 self.pg1.add_stream(pkts)
1701 self.pg_enable_capture(self.pg_interfaces)
1704 # Client side - simulate ICMP type 11 response
1705 capture = self.pg0.get_capture(len(pkts))
1706 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1707 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1708 ICMP(type=11) / packet[IP] for packet in capture]
1709 self.pg0.add_stream(pkts)
1710 self.pg_enable_capture(self.pg_interfaces)
1713 # Server side - verify ICMP type 11 packets
1714 capture = self.pg1.get_capture(len(pkts))
1715 self.verify_capture_out_with_icmp_errors(capture)
1717 def test_ping_out_interface_from_outside(self):
1718 """ Ping NAT44 out interface from outside network """
1720 self.nat44_add_address(self.nat_addr)
1721 flags = self.config_flags.NAT_IS_INSIDE
1722 self.vapi.nat44_interface_add_del_feature(
1723 sw_if_index=self.pg0.sw_if_index,
1724 flags=flags, is_add=1)
1725 self.vapi.nat44_interface_add_del_feature(
1726 sw_if_index=self.pg1.sw_if_index,
1729 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1730 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1731 ICMP(id=self.icmp_id_out, type='echo-request'))
1733 self.pg1.add_stream(pkts)
1734 self.pg_enable_capture(self.pg_interfaces)
1736 capture = self.pg1.get_capture(len(pkts))
1739 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1740 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1741 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1742 self.assertEqual(packet[ICMP].type, 0) # echo reply
1744 self.logger.error(ppp("Unexpected or invalid packet "
1745 "(outside network):", packet))
1748 def test_ping_internal_host_from_outside(self):
1749 """ Ping internal host from outside network """
1751 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1752 flags = self.config_flags.NAT_IS_INSIDE
1753 self.vapi.nat44_interface_add_del_feature(
1754 sw_if_index=self.pg0.sw_if_index,
1755 flags=flags, is_add=1)
1756 self.vapi.nat44_interface_add_del_feature(
1757 sw_if_index=self.pg1.sw_if_index,
1761 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1762 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1763 ICMP(id=self.icmp_id_out, type='echo-request'))
1764 self.pg1.add_stream(pkt)
1765 self.pg_enable_capture(self.pg_interfaces)
1767 capture = self.pg0.get_capture(1)
1768 self.verify_capture_in(capture, self.pg0)
1769 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1772 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1773 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1774 ICMP(id=self.icmp_id_in, type='echo-reply'))
1775 self.pg0.add_stream(pkt)
1776 self.pg_enable_capture(self.pg_interfaces)
1778 capture = self.pg1.get_capture(1)
1779 self.verify_capture_out(capture, same_port=True)
1780 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1782 def test_forwarding(self):
1783 """ NAT44 forwarding test """
1785 flags = self.config_flags.NAT_IS_INSIDE
1786 self.vapi.nat44_interface_add_del_feature(
1787 sw_if_index=self.pg0.sw_if_index,
1788 flags=flags, is_add=1)
1789 self.vapi.nat44_interface_add_del_feature(
1790 sw_if_index=self.pg1.sw_if_index,
1792 self.vapi.nat44_forwarding_enable_disable(enable=1)
1794 real_ip = self.pg0.remote_ip4
1795 alias_ip = self.nat_addr
1796 flags = self.config_flags.NAT_IS_ADDR_ONLY
1797 self.vapi.nat44_add_del_static_mapping(is_add=1,
1798 local_ip_address=real_ip,
1799 external_ip_address=alias_ip,
1800 external_sw_if_index=0xFFFFFFFF,
1804 # static mapping match
1806 pkts = self.create_stream_out(self.pg1)
1807 self.pg1.add_stream(pkts)
1808 self.pg_enable_capture(self.pg_interfaces)
1810 capture = self.pg0.get_capture(len(pkts))
1811 self.verify_capture_in(capture, self.pg0)
1813 pkts = self.create_stream_in(self.pg0, self.pg1)
1814 self.pg0.add_stream(pkts)
1815 self.pg_enable_capture(self.pg_interfaces)
1817 capture = self.pg1.get_capture(len(pkts))
1818 self.verify_capture_out(capture, same_port=True)
1820 # no static mapping match
1822 host0 = self.pg0.remote_hosts[0]
1823 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1825 pkts = self.create_stream_out(self.pg1,
1826 dst_ip=self.pg0.remote_ip4,
1827 use_inside_ports=True)
1828 self.pg1.add_stream(pkts)
1829 self.pg_enable_capture(self.pg_interfaces)
1831 capture = self.pg0.get_capture(len(pkts))
1832 self.verify_capture_in(capture, self.pg0)
1834 pkts = self.create_stream_in(self.pg0, self.pg1)
1835 self.pg0.add_stream(pkts)
1836 self.pg_enable_capture(self.pg_interfaces)
1838 capture = self.pg1.get_capture(len(pkts))
1839 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1842 self.pg0.remote_hosts[0] = host0
1845 self.vapi.nat44_forwarding_enable_disable(enable=0)
1846 flags = self.config_flags.NAT_IS_ADDR_ONLY
1847 self.vapi.nat44_add_del_static_mapping(
1849 local_ip_address=real_ip,
1850 external_ip_address=alias_ip,
1851 external_sw_if_index=0xFFFFFFFF,
1854 def test_static_in(self):
1855 """ 1:1 NAT initialized from inside network """
1857 nat_ip = "10.0.0.10"
1858 self.tcp_port_out = 6303
1859 self.udp_port_out = 6304
1860 self.icmp_id_out = 6305
1862 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1863 flags = self.config_flags.NAT_IS_INSIDE
1864 self.vapi.nat44_interface_add_del_feature(
1865 sw_if_index=self.pg0.sw_if_index,
1866 flags=flags, is_add=1)
1867 self.vapi.nat44_interface_add_del_feature(
1868 sw_if_index=self.pg1.sw_if_index,
1870 sm = self.vapi.nat44_static_mapping_dump()
1871 self.assertEqual(len(sm), 1)
1872 self.assertEqual(sm[0].tag, '')
1873 self.assertEqual(sm[0].protocol, 0)
1874 self.assertEqual(sm[0].local_port, 0)
1875 self.assertEqual(sm[0].external_port, 0)
1878 pkts = self.create_stream_in(self.pg0, self.pg1)
1879 self.pg0.add_stream(pkts)
1880 self.pg_enable_capture(self.pg_interfaces)
1882 capture = self.pg1.get_capture(len(pkts))
1883 self.verify_capture_out(capture, nat_ip, True)
1886 pkts = self.create_stream_out(self.pg1, nat_ip)
1887 self.pg1.add_stream(pkts)
1888 self.pg_enable_capture(self.pg_interfaces)
1890 capture = self.pg0.get_capture(len(pkts))
1891 self.verify_capture_in(capture, self.pg0)
1893 def test_static_out(self):
1894 """ 1:1 NAT initialized from outside network """
1896 nat_ip = "10.0.0.20"
1897 self.tcp_port_out = 6303
1898 self.udp_port_out = 6304
1899 self.icmp_id_out = 6305
1902 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1903 flags = self.config_flags.NAT_IS_INSIDE
1904 self.vapi.nat44_interface_add_del_feature(
1905 sw_if_index=self.pg0.sw_if_index,
1906 flags=flags, is_add=1)
1907 self.vapi.nat44_interface_add_del_feature(
1908 sw_if_index=self.pg1.sw_if_index,
1910 sm = self.vapi.nat44_static_mapping_dump()
1911 self.assertEqual(len(sm), 1)
1912 self.assertEqual(sm[0].tag, tag)
1915 pkts = self.create_stream_out(self.pg1, nat_ip)
1916 self.pg1.add_stream(pkts)
1917 self.pg_enable_capture(self.pg_interfaces)
1919 capture = self.pg0.get_capture(len(pkts))
1920 self.verify_capture_in(capture, self.pg0)
1923 pkts = self.create_stream_in(self.pg0, self.pg1)
1924 self.pg0.add_stream(pkts)
1925 self.pg_enable_capture(self.pg_interfaces)
1927 capture = self.pg1.get_capture(len(pkts))
1928 self.verify_capture_out(capture, nat_ip, True)
1930 def test_static_with_port_in(self):
1931 """ 1:1 NAPT initialized from inside network """
1933 self.tcp_port_out = 3606
1934 self.udp_port_out = 3607
1935 self.icmp_id_out = 3608
1937 self.nat44_add_address(self.nat_addr)
1938 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1939 self.tcp_port_in, self.tcp_port_out,
1940 proto=IP_PROTOS.tcp)
1941 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1942 self.udp_port_in, self.udp_port_out,
1943 proto=IP_PROTOS.udp)
1944 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1945 self.icmp_id_in, self.icmp_id_out,
1946 proto=IP_PROTOS.icmp)
1947 flags = self.config_flags.NAT_IS_INSIDE
1948 self.vapi.nat44_interface_add_del_feature(
1949 sw_if_index=self.pg0.sw_if_index,
1950 flags=flags, is_add=1)
1951 self.vapi.nat44_interface_add_del_feature(
1952 sw_if_index=self.pg1.sw_if_index,
1956 pkts = self.create_stream_in(self.pg0, self.pg1)
1957 self.pg0.add_stream(pkts)
1958 self.pg_enable_capture(self.pg_interfaces)
1960 capture = self.pg1.get_capture(len(pkts))
1961 self.verify_capture_out(capture)
1964 pkts = self.create_stream_out(self.pg1)
1965 self.pg1.add_stream(pkts)
1966 self.pg_enable_capture(self.pg_interfaces)
1968 capture = self.pg0.get_capture(len(pkts))
1969 self.verify_capture_in(capture, self.pg0)
1971 def test_static_with_port_out(self):
1972 """ 1:1 NAPT initialized from outside network """
1974 self.tcp_port_out = 30606
1975 self.udp_port_out = 30607
1976 self.icmp_id_out = 30608
1978 self.nat44_add_address(self.nat_addr)
1979 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1980 self.tcp_port_in, self.tcp_port_out,
1981 proto=IP_PROTOS.tcp)
1982 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1983 self.udp_port_in, self.udp_port_out,
1984 proto=IP_PROTOS.udp)
1985 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1986 self.icmp_id_in, self.icmp_id_out,
1987 proto=IP_PROTOS.icmp)
1988 flags = self.config_flags.NAT_IS_INSIDE
1989 self.vapi.nat44_interface_add_del_feature(
1990 sw_if_index=self.pg0.sw_if_index,
1991 flags=flags, is_add=1)
1992 self.vapi.nat44_interface_add_del_feature(
1993 sw_if_index=self.pg1.sw_if_index,
1997 pkts = self.create_stream_out(self.pg1)
1998 self.pg1.add_stream(pkts)
1999 self.pg_enable_capture(self.pg_interfaces)
2001 capture = self.pg0.get_capture(len(pkts))
2002 self.verify_capture_in(capture, self.pg0)
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)
2012 def test_static_vrf_aware(self):
2013 """ 1:1 NAT VRF awareness """
2015 nat_ip1 = "10.0.0.30"
2016 nat_ip2 = "10.0.0.40"
2017 self.tcp_port_out = 6303
2018 self.udp_port_out = 6304
2019 self.icmp_id_out = 6305
2021 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2023 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2025 flags = self.config_flags.NAT_IS_INSIDE
2026 self.vapi.nat44_interface_add_del_feature(
2027 sw_if_index=self.pg3.sw_if_index,
2029 self.vapi.nat44_interface_add_del_feature(
2030 sw_if_index=self.pg0.sw_if_index,
2031 flags=flags, is_add=1)
2032 self.vapi.nat44_interface_add_del_feature(
2033 sw_if_index=self.pg4.sw_if_index,
2034 flags=flags, is_add=1)
2036 # inside interface VRF match NAT44 static mapping VRF
2037 pkts = self.create_stream_in(self.pg4, self.pg3)
2038 self.pg4.add_stream(pkts)
2039 self.pg_enable_capture(self.pg_interfaces)
2041 capture = self.pg3.get_capture(len(pkts))
2042 self.verify_capture_out(capture, nat_ip1, True)
2044 # inside interface VRF don't match NAT44 static mapping VRF (packets
2046 pkts = self.create_stream_in(self.pg0, self.pg3)
2047 self.pg0.add_stream(pkts)
2048 self.pg_enable_capture(self.pg_interfaces)
2050 self.pg3.assert_nothing_captured()
2052 def test_dynamic_to_static(self):
2053 """ Switch from dynamic translation to 1:1NAT """
2054 nat_ip = "10.0.0.10"
2055 self.tcp_port_out = 6303
2056 self.udp_port_out = 6304
2057 self.icmp_id_out = 6305
2059 self.nat44_add_address(self.nat_addr)
2060 flags = self.config_flags.NAT_IS_INSIDE
2061 self.vapi.nat44_interface_add_del_feature(
2062 sw_if_index=self.pg0.sw_if_index,
2063 flags=flags, is_add=1)
2064 self.vapi.nat44_interface_add_del_feature(
2065 sw_if_index=self.pg1.sw_if_index,
2069 pkts = self.create_stream_in(self.pg0, self.pg1)
2070 self.pg0.add_stream(pkts)
2071 self.pg_enable_capture(self.pg_interfaces)
2073 capture = self.pg1.get_capture(len(pkts))
2074 self.verify_capture_out(capture)
2077 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2078 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2079 self.assertEqual(len(sessions), 0)
2080 pkts = self.create_stream_in(self.pg0, self.pg1)
2081 self.pg0.add_stream(pkts)
2082 self.pg_enable_capture(self.pg_interfaces)
2084 capture = self.pg1.get_capture(len(pkts))
2085 self.verify_capture_out(capture, nat_ip, True)
2087 def test_identity_nat(self):
2088 """ Identity NAT """
2089 flags = self.config_flags.NAT_IS_ADDR_ONLY
2090 self.vapi.nat44_add_del_identity_mapping(
2091 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2092 flags=flags, is_add=1)
2093 flags = self.config_flags.NAT_IS_INSIDE
2094 self.vapi.nat44_interface_add_del_feature(
2095 sw_if_index=self.pg0.sw_if_index,
2096 flags=flags, is_add=1)
2097 self.vapi.nat44_interface_add_del_feature(
2098 sw_if_index=self.pg1.sw_if_index,
2101 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2102 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2103 TCP(sport=12345, dport=56789))
2104 self.pg1.add_stream(p)
2105 self.pg_enable_capture(self.pg_interfaces)
2107 capture = self.pg0.get_capture(1)
2112 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2113 self.assertEqual(ip.src, self.pg1.remote_ip4)
2114 self.assertEqual(tcp.dport, 56789)
2115 self.assertEqual(tcp.sport, 12345)
2116 self.assert_packet_checksums_valid(p)
2118 self.logger.error(ppp("Unexpected or invalid packet:", p))
2121 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2122 self.assertEqual(len(sessions), 0)
2123 flags = self.config_flags.NAT_IS_ADDR_ONLY
2124 self.vapi.nat44_add_del_identity_mapping(
2125 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2126 flags=flags, vrf_id=1, is_add=1)
2127 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2128 self.assertEqual(len(identity_mappings), 2)
2130 def test_multiple_inside_interfaces(self):
2131 """ NAT44 multiple non-overlapping address space inside interfaces """
2133 self.nat44_add_address(self.nat_addr)
2134 flags = self.config_flags.NAT_IS_INSIDE
2135 self.vapi.nat44_interface_add_del_feature(
2136 sw_if_index=self.pg0.sw_if_index,
2137 flags=flags, is_add=1)
2138 self.vapi.nat44_interface_add_del_feature(
2139 sw_if_index=self.pg1.sw_if_index,
2140 flags=flags, is_add=1)
2141 self.vapi.nat44_interface_add_del_feature(
2142 sw_if_index=self.pg3.sw_if_index,
2145 # between two NAT44 inside interfaces (no translation)
2146 pkts = self.create_stream_in(self.pg0, self.pg1)
2147 self.pg0.add_stream(pkts)
2148 self.pg_enable_capture(self.pg_interfaces)
2150 capture = self.pg1.get_capture(len(pkts))
2151 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2153 # from NAT44 inside to interface without NAT44 feature (no translation)
2154 pkts = self.create_stream_in(self.pg0, self.pg2)
2155 self.pg0.add_stream(pkts)
2156 self.pg_enable_capture(self.pg_interfaces)
2158 capture = self.pg2.get_capture(len(pkts))
2159 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2161 # in2out 1st interface
2162 pkts = self.create_stream_in(self.pg0, self.pg3)
2163 self.pg0.add_stream(pkts)
2164 self.pg_enable_capture(self.pg_interfaces)
2166 capture = self.pg3.get_capture(len(pkts))
2167 self.verify_capture_out(capture)
2169 # out2in 1st interface
2170 pkts = self.create_stream_out(self.pg3)
2171 self.pg3.add_stream(pkts)
2172 self.pg_enable_capture(self.pg_interfaces)
2174 capture = self.pg0.get_capture(len(pkts))
2175 self.verify_capture_in(capture, self.pg0)
2177 # in2out 2nd interface
2178 pkts = self.create_stream_in(self.pg1, self.pg3)
2179 self.pg1.add_stream(pkts)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg3.get_capture(len(pkts))
2183 self.verify_capture_out(capture)
2185 # out2in 2nd interface
2186 pkts = self.create_stream_out(self.pg3)
2187 self.pg3.add_stream(pkts)
2188 self.pg_enable_capture(self.pg_interfaces)
2190 capture = self.pg1.get_capture(len(pkts))
2191 self.verify_capture_in(capture, self.pg1)
2193 def test_inside_overlapping_interfaces(self):
2194 """ NAT44 multiple inside interfaces with overlapping address space """
2196 static_nat_ip = "10.0.0.10"
2197 self.nat44_add_address(self.nat_addr)
2198 flags = self.config_flags.NAT_IS_INSIDE
2199 self.vapi.nat44_interface_add_del_feature(
2200 sw_if_index=self.pg3.sw_if_index,
2202 self.vapi.nat44_interface_add_del_feature(
2203 sw_if_index=self.pg4.sw_if_index,
2204 flags=flags, is_add=1)
2205 self.vapi.nat44_interface_add_del_feature(
2206 sw_if_index=self.pg5.sw_if_index,
2207 flags=flags, is_add=1)
2208 self.vapi.nat44_interface_add_del_feature(
2209 sw_if_index=self.pg6.sw_if_index,
2210 flags=flags, is_add=1)
2211 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2214 # between NAT44 inside interfaces with same VRF (no translation)
2215 pkts = self.create_stream_in(self.pg4, self.pg5)
2216 self.pg4.add_stream(pkts)
2217 self.pg_enable_capture(self.pg_interfaces)
2219 capture = self.pg5.get_capture(len(pkts))
2220 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2222 # between NAT44 inside interfaces with different VRF (hairpinning)
2223 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2224 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2225 TCP(sport=1234, dport=5678))
2226 self.pg4.add_stream(p)
2227 self.pg_enable_capture(self.pg_interfaces)
2229 capture = self.pg6.get_capture(1)
2234 self.assertEqual(ip.src, self.nat_addr)
2235 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2236 self.assertNotEqual(tcp.sport, 1234)
2237 self.assertEqual(tcp.dport, 5678)
2239 self.logger.error(ppp("Unexpected or invalid packet:", p))
2242 # in2out 1st interface
2243 pkts = self.create_stream_in(self.pg4, self.pg3)
2244 self.pg4.add_stream(pkts)
2245 self.pg_enable_capture(self.pg_interfaces)
2247 capture = self.pg3.get_capture(len(pkts))
2248 self.verify_capture_out(capture)
2250 # out2in 1st interface
2251 pkts = self.create_stream_out(self.pg3)
2252 self.pg3.add_stream(pkts)
2253 self.pg_enable_capture(self.pg_interfaces)
2255 capture = self.pg4.get_capture(len(pkts))
2256 self.verify_capture_in(capture, self.pg4)
2258 # in2out 2nd interface
2259 pkts = self.create_stream_in(self.pg5, self.pg3)
2260 self.pg5.add_stream(pkts)
2261 self.pg_enable_capture(self.pg_interfaces)
2263 capture = self.pg3.get_capture(len(pkts))
2264 self.verify_capture_out(capture)
2266 # out2in 2nd interface
2267 pkts = self.create_stream_out(self.pg3)
2268 self.pg3.add_stream(pkts)
2269 self.pg_enable_capture(self.pg_interfaces)
2271 capture = self.pg5.get_capture(len(pkts))
2272 self.verify_capture_in(capture, self.pg5)
2275 addresses = self.vapi.nat44_address_dump()
2276 self.assertEqual(len(addresses), 1)
2277 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2278 self.assertEqual(len(sessions), 3)
2279 for session in sessions:
2280 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2281 self.assertEqual(str(session.inside_ip_address),
2282 self.pg5.remote_ip4)
2283 self.assertEqual(session.outside_ip_address,
2284 addresses[0].ip_address)
2285 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2286 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2287 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2288 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2289 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2290 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2291 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2292 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2293 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2295 # in2out 3rd interface
2296 pkts = self.create_stream_in(self.pg6, self.pg3)
2297 self.pg6.add_stream(pkts)
2298 self.pg_enable_capture(self.pg_interfaces)
2300 capture = self.pg3.get_capture(len(pkts))
2301 self.verify_capture_out(capture, static_nat_ip, True)
2303 # out2in 3rd interface
2304 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2305 self.pg3.add_stream(pkts)
2306 self.pg_enable_capture(self.pg_interfaces)
2308 capture = self.pg6.get_capture(len(pkts))
2309 self.verify_capture_in(capture, self.pg6)
2311 # general user and session dump verifications
2312 users = self.vapi.nat44_user_dump()
2313 self.assertGreaterEqual(len(users), 3)
2314 addresses = self.vapi.nat44_address_dump()
2315 self.assertEqual(len(addresses), 1)
2317 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2319 for session in sessions:
2320 self.assertEqual(user.ip_address, session.inside_ip_address)
2321 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2322 self.assertTrue(session.protocol in
2323 [IP_PROTOS.tcp, IP_PROTOS.udp,
2325 self.assertFalse(session.flags &
2326 self.config_flags.NAT_IS_EXT_HOST_VALID)
2329 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2330 self.assertGreaterEqual(len(sessions), 4)
2331 for session in sessions:
2332 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2333 self.assertEqual(str(session.inside_ip_address),
2334 self.pg4.remote_ip4)
2335 self.assertEqual(session.outside_ip_address,
2336 addresses[0].ip_address)
2339 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2340 self.assertGreaterEqual(len(sessions), 3)
2341 for session in sessions:
2342 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2343 self.assertEqual(str(session.inside_ip_address),
2344 self.pg6.remote_ip4)
2345 self.assertEqual(str(session.outside_ip_address),
2347 self.assertTrue(session.inside_port in
2348 [self.tcp_port_in, self.udp_port_in,
2351 def test_hairpinning(self):
2352 """ NAT44 hairpinning - 1:1 NAPT """
2354 host = self.pg0.remote_hosts[0]
2355 server = self.pg0.remote_hosts[1]
2358 server_in_port = 5678
2359 server_out_port = 8765
2361 self.nat44_add_address(self.nat_addr)
2362 flags = self.config_flags.NAT_IS_INSIDE
2363 self.vapi.nat44_interface_add_del_feature(
2364 sw_if_index=self.pg0.sw_if_index,
2365 flags=flags, is_add=1)
2366 self.vapi.nat44_interface_add_del_feature(
2367 sw_if_index=self.pg1.sw_if_index,
2370 # add static mapping for server
2371 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2372 server_in_port, server_out_port,
2373 proto=IP_PROTOS.tcp)
2375 # send packet from host to server
2376 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2377 IP(src=host.ip4, dst=self.nat_addr) /
2378 TCP(sport=host_in_port, dport=server_out_port))
2379 self.pg0.add_stream(p)
2380 self.pg_enable_capture(self.pg_interfaces)
2382 capture = self.pg0.get_capture(1)
2387 self.assertEqual(ip.src, self.nat_addr)
2388 self.assertEqual(ip.dst, server.ip4)
2389 self.assertNotEqual(tcp.sport, host_in_port)
2390 self.assertEqual(tcp.dport, server_in_port)
2391 self.assert_packet_checksums_valid(p)
2392 host_out_port = tcp.sport
2394 self.logger.error(ppp("Unexpected or invalid packet:", p))
2397 # send reply from server to host
2398 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2399 IP(src=server.ip4, dst=self.nat_addr) /
2400 TCP(sport=server_in_port, dport=host_out_port))
2401 self.pg0.add_stream(p)
2402 self.pg_enable_capture(self.pg_interfaces)
2404 capture = self.pg0.get_capture(1)
2409 self.assertEqual(ip.src, self.nat_addr)
2410 self.assertEqual(ip.dst, host.ip4)
2411 self.assertEqual(tcp.sport, server_out_port)
2412 self.assertEqual(tcp.dport, host_in_port)
2413 self.assert_packet_checksums_valid(p)
2415 self.logger.error(ppp("Unexpected or invalid packet:", p))
2418 def test_hairpinning2(self):
2419 """ NAT44 hairpinning - 1:1 NAT"""
2421 server1_nat_ip = "10.0.0.10"
2422 server2_nat_ip = "10.0.0.11"
2423 host = self.pg0.remote_hosts[0]
2424 server1 = self.pg0.remote_hosts[1]
2425 server2 = self.pg0.remote_hosts[2]
2426 server_tcp_port = 22
2427 server_udp_port = 20
2429 self.nat44_add_address(self.nat_addr)
2430 flags = self.config_flags.NAT_IS_INSIDE
2431 self.vapi.nat44_interface_add_del_feature(
2432 sw_if_index=self.pg0.sw_if_index,
2433 flags=flags, is_add=1)
2434 self.vapi.nat44_interface_add_del_feature(
2435 sw_if_index=self.pg1.sw_if_index,
2438 # add static mapping for servers
2439 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2440 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2445 IP(src=host.ip4, dst=server1_nat_ip) /
2446 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2449 IP(src=host.ip4, dst=server1_nat_ip) /
2450 UDP(sport=self.udp_port_in, dport=server_udp_port))
2452 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2453 IP(src=host.ip4, dst=server1_nat_ip) /
2454 ICMP(id=self.icmp_id_in, type='echo-request'))
2456 self.pg0.add_stream(pkts)
2457 self.pg_enable_capture(self.pg_interfaces)
2459 capture = self.pg0.get_capture(len(pkts))
2460 for packet in capture:
2462 self.assertEqual(packet[IP].src, self.nat_addr)
2463 self.assertEqual(packet[IP].dst, server1.ip4)
2464 if packet.haslayer(TCP):
2465 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2466 self.assertEqual(packet[TCP].dport, server_tcp_port)
2467 self.tcp_port_out = packet[TCP].sport
2468 self.assert_packet_checksums_valid(packet)
2469 elif packet.haslayer(UDP):
2470 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2471 self.assertEqual(packet[UDP].dport, server_udp_port)
2472 self.udp_port_out = packet[UDP].sport
2474 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2475 self.icmp_id_out = packet[ICMP].id
2477 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2482 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2483 IP(src=server1.ip4, dst=self.nat_addr) /
2484 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2486 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2487 IP(src=server1.ip4, dst=self.nat_addr) /
2488 UDP(sport=server_udp_port, dport=self.udp_port_out))
2490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2491 IP(src=server1.ip4, dst=self.nat_addr) /
2492 ICMP(id=self.icmp_id_out, type='echo-reply'))
2494 self.pg0.add_stream(pkts)
2495 self.pg_enable_capture(self.pg_interfaces)
2497 capture = self.pg0.get_capture(len(pkts))
2498 for packet in capture:
2500 self.assertEqual(packet[IP].src, server1_nat_ip)
2501 self.assertEqual(packet[IP].dst, host.ip4)
2502 if packet.haslayer(TCP):
2503 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2504 self.assertEqual(packet[TCP].sport, server_tcp_port)
2505 self.assert_packet_checksums_valid(packet)
2506 elif packet.haslayer(UDP):
2507 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2508 self.assertEqual(packet[UDP].sport, server_udp_port)
2510 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2512 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2515 # server2 to server1
2517 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2518 IP(src=server2.ip4, dst=server1_nat_ip) /
2519 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2521 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2522 IP(src=server2.ip4, dst=server1_nat_ip) /
2523 UDP(sport=self.udp_port_in, dport=server_udp_port))
2525 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2526 IP(src=server2.ip4, dst=server1_nat_ip) /
2527 ICMP(id=self.icmp_id_in, type='echo-request'))
2529 self.pg0.add_stream(pkts)
2530 self.pg_enable_capture(self.pg_interfaces)
2532 capture = self.pg0.get_capture(len(pkts))
2533 for packet in capture:
2535 self.assertEqual(packet[IP].src, server2_nat_ip)
2536 self.assertEqual(packet[IP].dst, server1.ip4)
2537 if packet.haslayer(TCP):
2538 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2539 self.assertEqual(packet[TCP].dport, server_tcp_port)
2540 self.tcp_port_out = packet[TCP].sport
2541 self.assert_packet_checksums_valid(packet)
2542 elif packet.haslayer(UDP):
2543 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2544 self.assertEqual(packet[UDP].dport, server_udp_port)
2545 self.udp_port_out = packet[UDP].sport
2547 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2548 self.icmp_id_out = packet[ICMP].id
2550 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2553 # server1 to server2
2555 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2556 IP(src=server1.ip4, dst=server2_nat_ip) /
2557 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2559 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2560 IP(src=server1.ip4, dst=server2_nat_ip) /
2561 UDP(sport=server_udp_port, dport=self.udp_port_out))
2563 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2564 IP(src=server1.ip4, dst=server2_nat_ip) /
2565 ICMP(id=self.icmp_id_out, type='echo-reply'))
2567 self.pg0.add_stream(pkts)
2568 self.pg_enable_capture(self.pg_interfaces)
2570 capture = self.pg0.get_capture(len(pkts))
2571 for packet in capture:
2573 self.assertEqual(packet[IP].src, server1_nat_ip)
2574 self.assertEqual(packet[IP].dst, server2.ip4)
2575 if packet.haslayer(TCP):
2576 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2577 self.assertEqual(packet[TCP].sport, server_tcp_port)
2578 self.assert_packet_checksums_valid(packet)
2579 elif packet.haslayer(UDP):
2580 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2581 self.assertEqual(packet[UDP].sport, server_udp_port)
2583 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2585 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2588 def test_interface_addr(self):
2589 """ Acquire NAT44 addresses from interface """
2590 self.vapi.nat44_add_del_interface_addr(
2592 sw_if_index=self.pg7.sw_if_index)
2594 # no address in NAT pool
2595 addresses = self.vapi.nat44_address_dump()
2596 self.assertEqual(0, len(addresses))
2598 # configure interface address and check NAT address pool
2599 self.pg7.config_ip4()
2600 addresses = self.vapi.nat44_address_dump()
2601 self.assertEqual(1, len(addresses))
2602 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2604 # remove interface address and check NAT address pool
2605 self.pg7.unconfig_ip4()
2606 addresses = self.vapi.nat44_address_dump()
2607 self.assertEqual(0, len(addresses))
2609 def test_interface_addr_static_mapping(self):
2610 """ Static mapping with addresses from interface """
2613 self.vapi.nat44_add_del_interface_addr(
2615 sw_if_index=self.pg7.sw_if_index)
2616 self.nat44_add_static_mapping(
2618 external_sw_if_index=self.pg7.sw_if_index,
2621 # static mappings with external interface
2622 static_mappings = self.vapi.nat44_static_mapping_dump()
2623 self.assertEqual(1, len(static_mappings))
2624 self.assertEqual(self.pg7.sw_if_index,
2625 static_mappings[0].external_sw_if_index)
2626 self.assertEqual(static_mappings[0].tag, tag)
2628 # configure interface address and check static mappings
2629 self.pg7.config_ip4()
2630 static_mappings = self.vapi.nat44_static_mapping_dump()
2631 self.assertEqual(2, len(static_mappings))
2633 for sm in static_mappings:
2634 if sm.external_sw_if_index == 0xFFFFFFFF:
2635 self.assertEqual(str(sm.external_ip_address),
2637 self.assertEqual(sm.tag, tag)
2639 self.assertTrue(resolved)
2641 # remove interface address and check static mappings
2642 self.pg7.unconfig_ip4()
2643 static_mappings = self.vapi.nat44_static_mapping_dump()
2644 self.assertEqual(1, len(static_mappings))
2645 self.assertEqual(self.pg7.sw_if_index,
2646 static_mappings[0].external_sw_if_index)
2647 self.assertEqual(static_mappings[0].tag, tag)
2649 # configure interface address again and check static mappings
2650 self.pg7.config_ip4()
2651 static_mappings = self.vapi.nat44_static_mapping_dump()
2652 self.assertEqual(2, len(static_mappings))
2654 for sm in static_mappings:
2655 if sm.external_sw_if_index == 0xFFFFFFFF:
2656 self.assertEqual(str(sm.external_ip_address),
2658 self.assertEqual(sm.tag, tag)
2660 self.assertTrue(resolved)
2662 # remove static mapping
2663 self.nat44_add_static_mapping(
2665 external_sw_if_index=self.pg7.sw_if_index,
2668 static_mappings = self.vapi.nat44_static_mapping_dump()
2669 self.assertEqual(0, len(static_mappings))
2671 def test_interface_addr_identity_nat(self):
2672 """ Identity NAT with addresses from interface """
2675 self.vapi.nat44_add_del_interface_addr(
2677 sw_if_index=self.pg7.sw_if_index)
2678 self.vapi.nat44_add_del_identity_mapping(
2680 sw_if_index=self.pg7.sw_if_index,
2682 protocol=IP_PROTOS.tcp,
2685 # identity mappings with external interface
2686 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2687 self.assertEqual(1, len(identity_mappings))
2688 self.assertEqual(self.pg7.sw_if_index,
2689 identity_mappings[0].sw_if_index)
2691 # configure interface address and check identity mappings
2692 self.pg7.config_ip4()
2693 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2695 self.assertEqual(2, len(identity_mappings))
2696 for sm in identity_mappings:
2697 if sm.sw_if_index == 0xFFFFFFFF:
2698 self.assertEqual(str(identity_mappings[0].ip_address),
2700 self.assertEqual(port, identity_mappings[0].port)
2701 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2703 self.assertTrue(resolved)
2705 # remove interface address and check identity mappings
2706 self.pg7.unconfig_ip4()
2707 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2708 self.assertEqual(1, len(identity_mappings))
2709 self.assertEqual(self.pg7.sw_if_index,
2710 identity_mappings[0].sw_if_index)
2712 def test_ipfix_nat44_sess(self):
2713 """ IPFIX logging NAT44 session created/deleted """
2714 self.ipfix_domain_id = 10
2715 self.ipfix_src_port = 20202
2716 collector_port = 30303
2717 bind_layers(UDP, IPFIX, dport=30303)
2718 self.nat44_add_address(self.nat_addr)
2719 flags = self.config_flags.NAT_IS_INSIDE
2720 self.vapi.nat44_interface_add_del_feature(
2721 sw_if_index=self.pg0.sw_if_index,
2722 flags=flags, is_add=1)
2723 self.vapi.nat44_interface_add_del_feature(
2724 sw_if_index=self.pg1.sw_if_index,
2726 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2727 src_address=self.pg3.local_ip4,
2729 template_interval=10,
2730 collector_port=collector_port)
2731 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2732 src_port=self.ipfix_src_port,
2735 pkts = self.create_stream_in(self.pg0, self.pg1)
2736 self.pg0.add_stream(pkts)
2737 self.pg_enable_capture(self.pg_interfaces)
2739 capture = self.pg1.get_capture(len(pkts))
2740 self.verify_capture_out(capture)
2741 self.nat44_add_address(self.nat_addr, is_add=0)
2742 self.vapi.ipfix_flush()
2743 capture = self.pg3.get_capture(9)
2744 ipfix = IPFIXDecoder()
2745 # first load template
2747 self.assertTrue(p.haslayer(IPFIX))
2748 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2749 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2750 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2751 self.assertEqual(p[UDP].dport, collector_port)
2752 self.assertEqual(p[IPFIX].observationDomainID,
2753 self.ipfix_domain_id)
2754 if p.haslayer(Template):
2755 ipfix.add_template(p.getlayer(Template))
2756 # verify events in data set
2758 if p.haslayer(Data):
2759 data = ipfix.decode_data_set(p.getlayer(Set))
2760 self.verify_ipfix_nat44_ses(data)
2762 def test_ipfix_addr_exhausted(self):
2763 """ IPFIX logging NAT addresses exhausted """
2764 flags = self.config_flags.NAT_IS_INSIDE
2765 self.vapi.nat44_interface_add_del_feature(
2766 sw_if_index=self.pg0.sw_if_index,
2767 flags=flags, is_add=1)
2768 self.vapi.nat44_interface_add_del_feature(
2769 sw_if_index=self.pg1.sw_if_index,
2771 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2772 src_address=self.pg3.local_ip4,
2774 template_interval=10)
2775 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2776 src_port=self.ipfix_src_port,
2779 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2780 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2782 self.pg0.add_stream(p)
2783 self.pg_enable_capture(self.pg_interfaces)
2785 self.pg1.assert_nothing_captured()
2787 self.vapi.ipfix_flush()
2788 capture = self.pg3.get_capture(9)
2789 ipfix = IPFIXDecoder()
2790 # first load template
2792 self.assertTrue(p.haslayer(IPFIX))
2793 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2794 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2795 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2796 self.assertEqual(p[UDP].dport, 4739)
2797 self.assertEqual(p[IPFIX].observationDomainID,
2798 self.ipfix_domain_id)
2799 if p.haslayer(Template):
2800 ipfix.add_template(p.getlayer(Template))
2801 # verify events in data set
2803 if p.haslayer(Data):
2804 data = ipfix.decode_data_set(p.getlayer(Set))
2805 self.verify_ipfix_addr_exhausted(data)
2807 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2808 def test_ipfix_max_sessions(self):
2809 """ IPFIX logging maximum session entries exceeded """
2810 self.nat44_add_address(self.nat_addr)
2811 flags = self.config_flags.NAT_IS_INSIDE
2812 self.vapi.nat44_interface_add_del_feature(
2813 sw_if_index=self.pg0.sw_if_index,
2814 flags=flags, is_add=1)
2815 self.vapi.nat44_interface_add_del_feature(
2816 sw_if_index=self.pg1.sw_if_index,
2819 nat44_config = self.vapi.nat_show_config()
2820 max_sessions = 10 * nat44_config.translation_buckets
2823 for i in range(0, max_sessions):
2824 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2825 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2826 IP(src=src, dst=self.pg1.remote_ip4) /
2829 self.pg0.add_stream(pkts)
2830 self.pg_enable_capture(self.pg_interfaces)
2833 self.pg1.get_capture(max_sessions)
2834 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2835 src_address=self.pg3.local_ip4,
2837 template_interval=10)
2838 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2839 src_port=self.ipfix_src_port,
2842 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2843 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2845 self.pg0.add_stream(p)
2846 self.pg_enable_capture(self.pg_interfaces)
2848 self.pg1.assert_nothing_captured()
2850 self.vapi.ipfix_flush()
2851 capture = self.pg3.get_capture(9)
2852 ipfix = IPFIXDecoder()
2853 # first load template
2855 self.assertTrue(p.haslayer(IPFIX))
2856 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2857 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2858 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2859 self.assertEqual(p[UDP].dport, 4739)
2860 self.assertEqual(p[IPFIX].observationDomainID,
2861 self.ipfix_domain_id)
2862 if p.haslayer(Template):
2863 ipfix.add_template(p.getlayer(Template))
2864 # verify events in data set
2866 if p.haslayer(Data):
2867 data = ipfix.decode_data_set(p.getlayer(Set))
2868 self.verify_ipfix_max_sessions(data, max_sessions)
2870 def test_syslog_apmap(self):
2871 """ Test syslog address and port mapping creation and deletion """
2872 self.vapi.syslog_set_filter(
2873 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2874 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2875 self.nat44_add_address(self.nat_addr)
2876 flags = self.config_flags.NAT_IS_INSIDE
2877 self.vapi.nat44_interface_add_del_feature(
2878 sw_if_index=self.pg0.sw_if_index,
2879 flags=flags, is_add=1)
2880 self.vapi.nat44_interface_add_del_feature(
2881 sw_if_index=self.pg1.sw_if_index,
2884 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2885 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2886 TCP(sport=self.tcp_port_in, dport=20))
2887 self.pg0.add_stream(p)
2888 self.pg_enable_capture(self.pg_interfaces)
2890 capture = self.pg1.get_capture(1)
2891 self.tcp_port_out = capture[0][TCP].sport
2892 capture = self.pg3.get_capture(1)
2893 self.verify_syslog_apmap(capture[0][Raw].load)
2895 self.pg_enable_capture(self.pg_interfaces)
2897 self.nat44_add_address(self.nat_addr, is_add=0)
2898 capture = self.pg3.get_capture(1)
2899 self.verify_syslog_apmap(capture[0][Raw].load, False)
2901 def test_pool_addr_fib(self):
2902 """ NAT44 add pool addresses to FIB """
2903 static_addr = '10.0.0.10'
2904 self.nat44_add_address(self.nat_addr)
2905 flags = self.config_flags.NAT_IS_INSIDE
2906 self.vapi.nat44_interface_add_del_feature(
2907 sw_if_index=self.pg0.sw_if_index,
2908 flags=flags, is_add=1)
2909 self.vapi.nat44_interface_add_del_feature(
2910 sw_if_index=self.pg1.sw_if_index,
2912 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2915 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2916 ARP(op=ARP.who_has, pdst=self.nat_addr,
2917 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2918 self.pg1.add_stream(p)
2919 self.pg_enable_capture(self.pg_interfaces)
2921 capture = self.pg1.get_capture(1)
2922 self.assertTrue(capture[0].haslayer(ARP))
2923 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2926 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2927 ARP(op=ARP.who_has, pdst=static_addr,
2928 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2929 self.pg1.add_stream(p)
2930 self.pg_enable_capture(self.pg_interfaces)
2932 capture = self.pg1.get_capture(1)
2933 self.assertTrue(capture[0].haslayer(ARP))
2934 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2936 # send ARP to non-NAT44 interface
2937 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2938 ARP(op=ARP.who_has, pdst=self.nat_addr,
2939 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2940 self.pg2.add_stream(p)
2941 self.pg_enable_capture(self.pg_interfaces)
2943 self.pg1.assert_nothing_captured()
2945 # remove addresses and verify
2946 self.nat44_add_address(self.nat_addr, is_add=0)
2947 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2950 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2951 ARP(op=ARP.who_has, pdst=self.nat_addr,
2952 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2953 self.pg1.add_stream(p)
2954 self.pg_enable_capture(self.pg_interfaces)
2956 self.pg1.assert_nothing_captured()
2958 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2959 ARP(op=ARP.who_has, pdst=static_addr,
2960 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2961 self.pg1.add_stream(p)
2962 self.pg_enable_capture(self.pg_interfaces)
2964 self.pg1.assert_nothing_captured()
2966 def test_vrf_mode(self):
2967 """ NAT44 tenant VRF aware address pool mode """
2971 nat_ip1 = "10.0.0.10"
2972 nat_ip2 = "10.0.0.11"
2974 self.pg0.unconfig_ip4()
2975 self.pg1.unconfig_ip4()
2976 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2977 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2978 self.pg0.set_table_ip4(vrf_id1)
2979 self.pg1.set_table_ip4(vrf_id2)
2980 self.pg0.config_ip4()
2981 self.pg1.config_ip4()
2982 self.pg0.resolve_arp()
2983 self.pg1.resolve_arp()
2985 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2986 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2987 flags = self.config_flags.NAT_IS_INSIDE
2988 self.vapi.nat44_interface_add_del_feature(
2989 sw_if_index=self.pg0.sw_if_index,
2990 flags=flags, is_add=1)
2991 self.vapi.nat44_interface_add_del_feature(
2992 sw_if_index=self.pg1.sw_if_index,
2993 flags=flags, is_add=1)
2994 self.vapi.nat44_interface_add_del_feature(
2995 sw_if_index=self.pg2.sw_if_index,
3000 pkts = self.create_stream_in(self.pg0, self.pg2)
3001 self.pg0.add_stream(pkts)
3002 self.pg_enable_capture(self.pg_interfaces)
3004 capture = self.pg2.get_capture(len(pkts))
3005 self.verify_capture_out(capture, nat_ip1)
3008 pkts = self.create_stream_in(self.pg1, self.pg2)
3009 self.pg1.add_stream(pkts)
3010 self.pg_enable_capture(self.pg_interfaces)
3012 capture = self.pg2.get_capture(len(pkts))
3013 self.verify_capture_out(capture, nat_ip2)
3016 self.pg0.unconfig_ip4()
3017 self.pg1.unconfig_ip4()
3018 self.pg0.set_table_ip4(0)
3019 self.pg1.set_table_ip4(0)
3020 self.pg0.config_ip4()
3021 self.pg1.config_ip4()
3022 self.pg0.resolve_arp()
3023 self.pg1.resolve_arp()
3024 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3025 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3027 def test_vrf_feature_independent(self):
3028 """ NAT44 tenant VRF independent address pool mode """
3030 nat_ip1 = "10.0.0.10"
3031 nat_ip2 = "10.0.0.11"
3033 self.nat44_add_address(nat_ip1)
3034 self.nat44_add_address(nat_ip2, vrf_id=99)
3035 flags = self.config_flags.NAT_IS_INSIDE
3036 self.vapi.nat44_interface_add_del_feature(
3037 sw_if_index=self.pg0.sw_if_index,
3038 flags=flags, is_add=1)
3039 self.vapi.nat44_interface_add_del_feature(
3040 sw_if_index=self.pg1.sw_if_index,
3041 flags=flags, is_add=1)
3042 self.vapi.nat44_interface_add_del_feature(
3043 sw_if_index=self.pg2.sw_if_index,
3047 pkts = self.create_stream_in(self.pg0, self.pg2)
3048 self.pg0.add_stream(pkts)
3049 self.pg_enable_capture(self.pg_interfaces)
3051 capture = self.pg2.get_capture(len(pkts))
3052 self.verify_capture_out(capture, nat_ip1)
3055 pkts = self.create_stream_in(self.pg1, self.pg2)
3056 self.pg1.add_stream(pkts)
3057 self.pg_enable_capture(self.pg_interfaces)
3059 capture = self.pg2.get_capture(len(pkts))
3060 self.verify_capture_out(capture, nat_ip1)
3062 def create_routes_and_neigbors(self):
3063 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3064 [VppRoutePath(self.pg7.remote_ip4,
3065 self.pg7.sw_if_index)])
3066 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3067 [VppRoutePath(self.pg8.remote_ip4,
3068 self.pg8.sw_if_index)])
3072 n1 = VppNeighbor(self,
3073 self.pg7.sw_if_index,
3074 self.pg7.remote_mac,
3075 self.pg7.remote_ip4,
3077 n2 = VppNeighbor(self,
3078 self.pg8.sw_if_index,
3079 self.pg8.remote_mac,
3080 self.pg8.remote_ip4,
3085 def test_dynamic_ipless_interfaces(self):
3086 """ NAT44 interfaces without configured IP address """
3087 self.create_routes_and_neigbors()
3088 self.nat44_add_address(self.nat_addr)
3089 flags = self.config_flags.NAT_IS_INSIDE
3090 self.vapi.nat44_interface_add_del_feature(
3091 sw_if_index=self.pg7.sw_if_index,
3092 flags=flags, is_add=1)
3093 self.vapi.nat44_interface_add_del_feature(
3094 sw_if_index=self.pg8.sw_if_index,
3098 pkts = self.create_stream_in(self.pg7, self.pg8)
3099 self.pg7.add_stream(pkts)
3100 self.pg_enable_capture(self.pg_interfaces)
3102 capture = self.pg8.get_capture(len(pkts))
3103 self.verify_capture_out(capture)
3106 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3107 self.pg8.add_stream(pkts)
3108 self.pg_enable_capture(self.pg_interfaces)
3110 capture = self.pg7.get_capture(len(pkts))
3111 self.verify_capture_in(capture, self.pg7)
3113 def test_static_ipless_interfaces(self):
3114 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3116 self.create_routes_and_neigbors()
3117 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3118 flags = self.config_flags.NAT_IS_INSIDE
3119 self.vapi.nat44_interface_add_del_feature(
3120 sw_if_index=self.pg7.sw_if_index,
3121 flags=flags, is_add=1)
3122 self.vapi.nat44_interface_add_del_feature(
3123 sw_if_index=self.pg8.sw_if_index,
3127 pkts = self.create_stream_out(self.pg8)
3128 self.pg8.add_stream(pkts)
3129 self.pg_enable_capture(self.pg_interfaces)
3131 capture = self.pg7.get_capture(len(pkts))
3132 self.verify_capture_in(capture, self.pg7)
3135 pkts = self.create_stream_in(self.pg7, self.pg8)
3136 self.pg7.add_stream(pkts)
3137 self.pg_enable_capture(self.pg_interfaces)
3139 capture = self.pg8.get_capture(len(pkts))
3140 self.verify_capture_out(capture, self.nat_addr, True)
3142 def test_static_with_port_ipless_interfaces(self):
3143 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3145 self.tcp_port_out = 30606
3146 self.udp_port_out = 30607
3147 self.icmp_id_out = 30608
3149 self.create_routes_and_neigbors()
3150 self.nat44_add_address(self.nat_addr)
3151 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3152 self.tcp_port_in, self.tcp_port_out,
3153 proto=IP_PROTOS.tcp)
3154 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3155 self.udp_port_in, self.udp_port_out,
3156 proto=IP_PROTOS.udp)
3157 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3158 self.icmp_id_in, self.icmp_id_out,
3159 proto=IP_PROTOS.icmp)
3160 flags = self.config_flags.NAT_IS_INSIDE
3161 self.vapi.nat44_interface_add_del_feature(
3162 sw_if_index=self.pg7.sw_if_index,
3163 flags=flags, is_add=1)
3164 self.vapi.nat44_interface_add_del_feature(
3165 sw_if_index=self.pg8.sw_if_index,
3169 pkts = self.create_stream_out(self.pg8)
3170 self.pg8.add_stream(pkts)
3171 self.pg_enable_capture(self.pg_interfaces)
3173 capture = self.pg7.get_capture(len(pkts))
3174 self.verify_capture_in(capture, self.pg7)
3177 pkts = self.create_stream_in(self.pg7, self.pg8)
3178 self.pg7.add_stream(pkts)
3179 self.pg_enable_capture(self.pg_interfaces)
3181 capture = self.pg8.get_capture(len(pkts))
3182 self.verify_capture_out(capture)
3184 def test_static_unknown_proto(self):
3185 """ 1:1 NAT translate packet with unknown protocol """
3186 nat_ip = "10.0.0.10"
3187 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3188 flags = self.config_flags.NAT_IS_INSIDE
3189 self.vapi.nat44_interface_add_del_feature(
3190 sw_if_index=self.pg0.sw_if_index,
3191 flags=flags, is_add=1)
3192 self.vapi.nat44_interface_add_del_feature(
3193 sw_if_index=self.pg1.sw_if_index,
3197 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3198 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3200 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3201 TCP(sport=1234, dport=1234))
3202 self.pg0.add_stream(p)
3203 self.pg_enable_capture(self.pg_interfaces)
3205 p = self.pg1.get_capture(1)
3208 self.assertEqual(packet[IP].src, nat_ip)
3209 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3210 self.assertEqual(packet.haslayer(GRE), 1)
3211 self.assert_packet_checksums_valid(packet)
3213 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3217 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3218 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3220 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3221 TCP(sport=1234, dport=1234))
3222 self.pg1.add_stream(p)
3223 self.pg_enable_capture(self.pg_interfaces)
3225 p = self.pg0.get_capture(1)
3228 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3229 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3230 self.assertEqual(packet.haslayer(GRE), 1)
3231 self.assert_packet_checksums_valid(packet)
3233 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3236 def test_hairpinning_static_unknown_proto(self):
3237 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3239 host = self.pg0.remote_hosts[0]
3240 server = self.pg0.remote_hosts[1]
3242 host_nat_ip = "10.0.0.10"
3243 server_nat_ip = "10.0.0.11"
3245 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3246 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3247 flags = self.config_flags.NAT_IS_INSIDE
3248 self.vapi.nat44_interface_add_del_feature(
3249 sw_if_index=self.pg0.sw_if_index,
3250 flags=flags, is_add=1)
3251 self.vapi.nat44_interface_add_del_feature(
3252 sw_if_index=self.pg1.sw_if_index,
3256 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3257 IP(src=host.ip4, dst=server_nat_ip) /
3259 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3260 TCP(sport=1234, dport=1234))
3261 self.pg0.add_stream(p)
3262 self.pg_enable_capture(self.pg_interfaces)
3264 p = self.pg0.get_capture(1)
3267 self.assertEqual(packet[IP].src, host_nat_ip)
3268 self.assertEqual(packet[IP].dst, server.ip4)
3269 self.assertEqual(packet.haslayer(GRE), 1)
3270 self.assert_packet_checksums_valid(packet)
3272 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3276 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3277 IP(src=server.ip4, dst=host_nat_ip) /
3279 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3280 TCP(sport=1234, dport=1234))
3281 self.pg0.add_stream(p)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 p = self.pg0.get_capture(1)
3287 self.assertEqual(packet[IP].src, server_nat_ip)
3288 self.assertEqual(packet[IP].dst, host.ip4)
3289 self.assertEqual(packet.haslayer(GRE), 1)
3290 self.assert_packet_checksums_valid(packet)
3292 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3295 def test_output_feature(self):
3296 """ NAT44 interface output feature (in2out postrouting) """
3297 self.nat44_add_address(self.nat_addr)
3298 flags = self.config_flags.NAT_IS_INSIDE
3299 self.vapi.nat44_interface_add_del_output_feature(
3300 is_add=1, flags=flags,
3301 sw_if_index=self.pg0.sw_if_index)
3302 self.vapi.nat44_interface_add_del_output_feature(
3303 is_add=1, flags=flags,
3304 sw_if_index=self.pg1.sw_if_index)
3305 self.vapi.nat44_interface_add_del_output_feature(
3307 sw_if_index=self.pg3.sw_if_index)
3310 pkts = self.create_stream_in(self.pg0, self.pg3)
3311 self.pg0.add_stream(pkts)
3312 self.pg_enable_capture(self.pg_interfaces)
3314 capture = self.pg3.get_capture(len(pkts))
3315 self.verify_capture_out(capture)
3318 pkts = self.create_stream_out(self.pg3)
3319 self.pg3.add_stream(pkts)
3320 self.pg_enable_capture(self.pg_interfaces)
3322 capture = self.pg0.get_capture(len(pkts))
3323 self.verify_capture_in(capture, self.pg0)
3325 # from non-NAT interface to NAT inside interface
3326 pkts = self.create_stream_in(self.pg2, self.pg0)
3327 self.pg2.add_stream(pkts)
3328 self.pg_enable_capture(self.pg_interfaces)
3330 capture = self.pg0.get_capture(len(pkts))
3331 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3333 def test_output_feature_vrf_aware(self):
3334 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3335 nat_ip_vrf10 = "10.0.0.10"
3336 nat_ip_vrf20 = "10.0.0.20"
3338 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3339 [VppRoutePath(self.pg3.remote_ip4,
3340 self.pg3.sw_if_index)],
3342 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3343 [VppRoutePath(self.pg3.remote_ip4,
3344 self.pg3.sw_if_index)],
3349 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3350 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3351 flags = self.config_flags.NAT_IS_INSIDE
3352 self.vapi.nat44_interface_add_del_output_feature(
3353 is_add=1, flags=flags,
3354 sw_if_index=self.pg4.sw_if_index)
3355 self.vapi.nat44_interface_add_del_output_feature(
3356 is_add=1, flags=flags,
3357 sw_if_index=self.pg6.sw_if_index)
3358 self.vapi.nat44_interface_add_del_output_feature(
3360 sw_if_index=self.pg3.sw_if_index)
3363 pkts = self.create_stream_in(self.pg4, self.pg3)
3364 self.pg4.add_stream(pkts)
3365 self.pg_enable_capture(self.pg_interfaces)
3367 capture = self.pg3.get_capture(len(pkts))
3368 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3371 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3372 self.pg3.add_stream(pkts)
3373 self.pg_enable_capture(self.pg_interfaces)
3375 capture = self.pg4.get_capture(len(pkts))
3376 self.verify_capture_in(capture, self.pg4)
3379 pkts = self.create_stream_in(self.pg6, self.pg3)
3380 self.pg6.add_stream(pkts)
3381 self.pg_enable_capture(self.pg_interfaces)
3383 capture = self.pg3.get_capture(len(pkts))
3384 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3387 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3388 self.pg3.add_stream(pkts)
3389 self.pg_enable_capture(self.pg_interfaces)
3391 capture = self.pg6.get_capture(len(pkts))
3392 self.verify_capture_in(capture, self.pg6)
3394 def test_output_feature_hairpinning(self):
3395 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3396 host = self.pg0.remote_hosts[0]
3397 server = self.pg0.remote_hosts[1]
3400 server_in_port = 5678
3401 server_out_port = 8765
3403 self.nat44_add_address(self.nat_addr)
3404 flags = self.config_flags.NAT_IS_INSIDE
3405 self.vapi.nat44_interface_add_del_output_feature(
3406 is_add=1, flags=flags,
3407 sw_if_index=self.pg0.sw_if_index)
3408 self.vapi.nat44_interface_add_del_output_feature(
3410 sw_if_index=self.pg1.sw_if_index)
3412 # add static mapping for server
3413 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3414 server_in_port, server_out_port,
3415 proto=IP_PROTOS.tcp)
3417 # send packet from host to server
3418 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3419 IP(src=host.ip4, dst=self.nat_addr) /
3420 TCP(sport=host_in_port, dport=server_out_port))
3421 self.pg0.add_stream(p)
3422 self.pg_enable_capture(self.pg_interfaces)
3424 capture = self.pg0.get_capture(1)
3429 self.assertEqual(ip.src, self.nat_addr)
3430 self.assertEqual(ip.dst, server.ip4)
3431 self.assertNotEqual(tcp.sport, host_in_port)
3432 self.assertEqual(tcp.dport, server_in_port)
3433 self.assert_packet_checksums_valid(p)
3434 host_out_port = tcp.sport
3436 self.logger.error(ppp("Unexpected or invalid packet:", p))
3439 # send reply from server to host
3440 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3441 IP(src=server.ip4, dst=self.nat_addr) /
3442 TCP(sport=server_in_port, dport=host_out_port))
3443 self.pg0.add_stream(p)
3444 self.pg_enable_capture(self.pg_interfaces)
3446 capture = self.pg0.get_capture(1)
3451 self.assertEqual(ip.src, self.nat_addr)
3452 self.assertEqual(ip.dst, host.ip4)
3453 self.assertEqual(tcp.sport, server_out_port)
3454 self.assertEqual(tcp.dport, host_in_port)
3455 self.assert_packet_checksums_valid(p)
3457 self.logger.error(ppp("Unexpected or invalid packet:", p))
3460 def test_one_armed_nat44(self):
3461 """ One armed NAT44 """
3462 remote_host = self.pg9.remote_hosts[0]
3463 local_host = self.pg9.remote_hosts[1]
3466 self.nat44_add_address(self.nat_addr)
3467 flags = self.config_flags.NAT_IS_INSIDE
3468 self.vapi.nat44_interface_add_del_feature(
3469 sw_if_index=self.pg9.sw_if_index,
3471 self.vapi.nat44_interface_add_del_feature(
3472 sw_if_index=self.pg9.sw_if_index,
3473 flags=flags, is_add=1)
3476 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3477 IP(src=local_host.ip4, dst=remote_host.ip4) /
3478 TCP(sport=12345, dport=80))
3479 self.pg9.add_stream(p)
3480 self.pg_enable_capture(self.pg_interfaces)
3482 capture = self.pg9.get_capture(1)
3487 self.assertEqual(ip.src, self.nat_addr)
3488 self.assertEqual(ip.dst, remote_host.ip4)
3489 self.assertNotEqual(tcp.sport, 12345)
3490 external_port = tcp.sport
3491 self.assertEqual(tcp.dport, 80)
3492 self.assert_packet_checksums_valid(p)
3494 self.logger.error(ppp("Unexpected or invalid packet:", p))
3498 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3499 IP(src=remote_host.ip4, dst=self.nat_addr) /
3500 TCP(sport=80, dport=external_port))
3501 self.pg9.add_stream(p)
3502 self.pg_enable_capture(self.pg_interfaces)
3504 capture = self.pg9.get_capture(1)
3509 self.assertEqual(ip.src, remote_host.ip4)
3510 self.assertEqual(ip.dst, local_host.ip4)
3511 self.assertEqual(tcp.sport, 80)
3512 self.assertEqual(tcp.dport, 12345)
3513 self.assert_packet_checksums_valid(p)
3515 self.logger.error(ppp("Unexpected or invalid packet:", p))
3518 err = self.statistics.get_err_counter(
3519 '/err/nat44-classify/next in2out')
3520 self.assertEqual(err, 1)
3521 err = self.statistics.get_err_counter(
3522 '/err/nat44-classify/next out2in')
3523 self.assertEqual(err, 1)
3525 def test_del_session(self):
3526 """ Delete NAT44 session """
3527 self.nat44_add_address(self.nat_addr)
3528 flags = self.config_flags.NAT_IS_INSIDE
3529 self.vapi.nat44_interface_add_del_feature(
3530 sw_if_index=self.pg0.sw_if_index,
3531 flags=flags, is_add=1)
3532 self.vapi.nat44_interface_add_del_feature(
3533 sw_if_index=self.pg1.sw_if_index,
3536 pkts = self.create_stream_in(self.pg0, self.pg1)
3537 self.pg0.add_stream(pkts)
3538 self.pg_enable_capture(self.pg_interfaces)
3540 self.pg1.get_capture(len(pkts))
3542 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3543 nsessions = len(sessions)
3545 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3546 port=sessions[0].inside_port,
3547 protocol=sessions[0].protocol,
3548 flags=self.config_flags.NAT_IS_INSIDE)
3549 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3550 port=sessions[1].outside_port,
3551 protocol=sessions[1].protocol)
3553 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3554 self.assertEqual(nsessions - len(sessions), 2)
3556 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3557 port=sessions[0].inside_port,
3558 protocol=sessions[0].protocol,
3559 flags=self.config_flags.NAT_IS_INSIDE)
3561 self.verify_no_nat44_user()
3563 def test_frag_in_order(self):
3564 """ NAT44 translate fragments arriving in order """
3566 self.nat44_add_address(self.nat_addr)
3567 flags = self.config_flags.NAT_IS_INSIDE
3568 self.vapi.nat44_interface_add_del_feature(
3569 sw_if_index=self.pg0.sw_if_index,
3570 flags=flags, is_add=1)
3571 self.vapi.nat44_interface_add_del_feature(
3572 sw_if_index=self.pg1.sw_if_index,
3575 self.frag_in_order(proto=IP_PROTOS.tcp)
3576 self.frag_in_order(proto=IP_PROTOS.udp)
3577 self.frag_in_order(proto=IP_PROTOS.icmp)
3579 def test_frag_forwarding(self):
3580 """ NAT44 forwarding fragment test """
3581 self.vapi.nat44_add_del_interface_addr(
3583 sw_if_index=self.pg1.sw_if_index)
3584 flags = self.config_flags.NAT_IS_INSIDE
3585 self.vapi.nat44_interface_add_del_feature(
3586 sw_if_index=self.pg0.sw_if_index,
3587 flags=flags, is_add=1)
3588 self.vapi.nat44_interface_add_del_feature(
3589 sw_if_index=self.pg1.sw_if_index,
3591 self.vapi.nat44_forwarding_enable_disable(enable=1)
3593 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3594 pkts = self.create_stream_frag(self.pg1,
3595 self.pg0.remote_ip4,
3599 proto=IP_PROTOS.udp)
3600 self.pg1.add_stream(pkts)
3601 self.pg_enable_capture(self.pg_interfaces)
3603 frags = self.pg0.get_capture(len(pkts))
3604 p = self.reass_frags_and_verify(frags,
3605 self.pg1.remote_ip4,
3606 self.pg0.remote_ip4)
3607 self.assertEqual(p[UDP].sport, 4789)
3608 self.assertEqual(p[UDP].dport, 4789)
3609 self.assertEqual(data, p[Raw].load)
3611 def test_reass_hairpinning(self):
3612 """ NAT44 fragments hairpinning """
3614 self.server = self.pg0.remote_hosts[1]
3615 self.host_in_port = random.randint(1025, 65535)
3616 self.server_in_port = random.randint(1025, 65535)
3617 self.server_out_port = random.randint(1025, 65535)
3619 self.nat44_add_address(self.nat_addr)
3620 flags = self.config_flags.NAT_IS_INSIDE
3621 self.vapi.nat44_interface_add_del_feature(
3622 sw_if_index=self.pg0.sw_if_index,
3623 flags=flags, is_add=1)
3624 self.vapi.nat44_interface_add_del_feature(
3625 sw_if_index=self.pg1.sw_if_index,
3627 # add static mapping for server
3628 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3629 self.server_in_port,
3630 self.server_out_port,
3631 proto=IP_PROTOS.tcp)
3632 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3633 self.server_in_port,
3634 self.server_out_port,
3635 proto=IP_PROTOS.udp)
3636 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3638 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3639 self.reass_hairpinning(proto=IP_PROTOS.udp)
3640 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3642 def test_frag_out_of_order(self):
3643 """ NAT44 translate fragments arriving out of order """
3645 self.nat44_add_address(self.nat_addr)
3646 flags = self.config_flags.NAT_IS_INSIDE
3647 self.vapi.nat44_interface_add_del_feature(
3648 sw_if_index=self.pg0.sw_if_index,
3649 flags=flags, is_add=1)
3650 self.vapi.nat44_interface_add_del_feature(
3651 sw_if_index=self.pg1.sw_if_index,
3654 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3655 self.frag_out_of_order(proto=IP_PROTOS.udp)
3656 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3658 def test_port_restricted(self):
3659 """ Port restricted NAT44 (MAP-E CE) """
3660 self.nat44_add_address(self.nat_addr)
3661 flags = self.config_flags.NAT_IS_INSIDE
3662 self.vapi.nat44_interface_add_del_feature(
3663 sw_if_index=self.pg0.sw_if_index,
3664 flags=flags, is_add=1)
3665 self.vapi.nat44_interface_add_del_feature(
3666 sw_if_index=self.pg1.sw_if_index,
3668 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3673 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3674 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3675 TCP(sport=4567, dport=22))
3676 self.pg0.add_stream(p)
3677 self.pg_enable_capture(self.pg_interfaces)
3679 capture = self.pg1.get_capture(1)
3684 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3685 self.assertEqual(ip.src, self.nat_addr)
3686 self.assertEqual(tcp.dport, 22)
3687 self.assertNotEqual(tcp.sport, 4567)
3688 self.assertEqual((tcp.sport >> 6) & 63, 10)
3689 self.assert_packet_checksums_valid(p)
3691 self.logger.error(ppp("Unexpected or invalid packet:", p))
3694 def test_port_range(self):
3695 """ External address port range """
3696 self.nat44_add_address(self.nat_addr)
3697 flags = self.config_flags.NAT_IS_INSIDE
3698 self.vapi.nat44_interface_add_del_feature(
3699 sw_if_index=self.pg0.sw_if_index,
3700 flags=flags, is_add=1)
3701 self.vapi.nat44_interface_add_del_feature(
3702 sw_if_index=self.pg1.sw_if_index,
3704 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3709 for port in range(0, 5):
3710 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3711 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3712 TCP(sport=1125 + port))
3714 self.pg0.add_stream(pkts)
3715 self.pg_enable_capture(self.pg_interfaces)
3717 capture = self.pg1.get_capture(3)
3720 self.assertGreaterEqual(tcp.sport, 1025)
3721 self.assertLessEqual(tcp.sport, 1027)
3723 def test_multiple_outside_vrf(self):
3724 """ Multiple outside VRF """
3728 self.pg1.unconfig_ip4()
3729 self.pg2.unconfig_ip4()
3730 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3731 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3732 self.pg1.set_table_ip4(vrf_id1)
3733 self.pg2.set_table_ip4(vrf_id2)
3734 self.pg1.config_ip4()
3735 self.pg2.config_ip4()
3736 self.pg1.resolve_arp()
3737 self.pg2.resolve_arp()
3739 self.nat44_add_address(self.nat_addr)
3740 flags = self.config_flags.NAT_IS_INSIDE
3741 self.vapi.nat44_interface_add_del_feature(
3742 sw_if_index=self.pg0.sw_if_index,
3743 flags=flags, is_add=1)
3744 self.vapi.nat44_interface_add_del_feature(
3745 sw_if_index=self.pg1.sw_if_index,
3747 self.vapi.nat44_interface_add_del_feature(
3748 sw_if_index=self.pg2.sw_if_index,
3753 pkts = self.create_stream_in(self.pg0, self.pg1)
3754 self.pg0.add_stream(pkts)
3755 self.pg_enable_capture(self.pg_interfaces)
3757 capture = self.pg1.get_capture(len(pkts))
3758 self.verify_capture_out(capture, self.nat_addr)
3760 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3761 self.pg1.add_stream(pkts)
3762 self.pg_enable_capture(self.pg_interfaces)
3764 capture = self.pg0.get_capture(len(pkts))
3765 self.verify_capture_in(capture, self.pg0)
3767 self.tcp_port_in = 60303
3768 self.udp_port_in = 60304
3769 self.icmp_id_in = 60305
3772 pkts = self.create_stream_in(self.pg0, self.pg2)
3773 self.pg0.add_stream(pkts)
3774 self.pg_enable_capture(self.pg_interfaces)
3776 capture = self.pg2.get_capture(len(pkts))
3777 self.verify_capture_out(capture, self.nat_addr)
3779 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3780 self.pg2.add_stream(pkts)
3781 self.pg_enable_capture(self.pg_interfaces)
3783 capture = self.pg0.get_capture(len(pkts))
3784 self.verify_capture_in(capture, self.pg0)
3787 self.nat44_add_address(self.nat_addr, is_add=0)
3788 self.pg1.unconfig_ip4()
3789 self.pg2.unconfig_ip4()
3790 self.pg1.set_table_ip4(0)
3791 self.pg2.set_table_ip4(0)
3792 self.pg1.config_ip4()
3793 self.pg2.config_ip4()
3794 self.pg1.resolve_arp()
3795 self.pg2.resolve_arp()
3797 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3798 def test_session_timeout(self):
3799 """ NAT44 session timeouts """
3800 self.nat44_add_address(self.nat_addr)
3801 flags = self.config_flags.NAT_IS_INSIDE
3802 self.vapi.nat44_interface_add_del_feature(
3803 sw_if_index=self.pg0.sw_if_index,
3804 flags=flags, is_add=1)
3805 self.vapi.nat44_interface_add_del_feature(
3806 sw_if_index=self.pg1.sw_if_index,
3808 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3809 tcp_transitory=240, icmp=60)
3813 for i in range(0, max_sessions):
3814 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3815 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3816 IP(src=src, dst=self.pg1.remote_ip4) /
3817 UDP(sport=1025, dport=53))
3819 self.pg0.add_stream(pkts)
3820 self.pg_enable_capture(self.pg_interfaces)
3822 self.pg1.get_capture(max_sessions)
3827 for i in range(0, max_sessions):
3828 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3829 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3830 IP(src=src, dst=self.pg1.remote_ip4) /
3831 UDP(sport=1026, dport=53))
3833 self.pg0.add_stream(pkts)
3834 self.pg_enable_capture(self.pg_interfaces)
3836 self.pg1.get_capture(max_sessions)
3839 users = self.vapi.nat44_user_dump()
3841 nsessions = nsessions + user.nsessions
3842 self.assertLess(nsessions, 2 * max_sessions)
3844 def test_mss_clamping(self):
3845 """ TCP MSS clamping """
3846 self.nat44_add_address(self.nat_addr)
3847 flags = self.config_flags.NAT_IS_INSIDE
3848 self.vapi.nat44_interface_add_del_feature(
3849 sw_if_index=self.pg0.sw_if_index,
3850 flags=flags, is_add=1)
3851 self.vapi.nat44_interface_add_del_feature(
3852 sw_if_index=self.pg1.sw_if_index,
3855 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3856 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3857 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3858 flags="S", options=[('MSS', 1400)]))
3860 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3861 self.pg0.add_stream(p)
3862 self.pg_enable_capture(self.pg_interfaces)
3864 capture = self.pg1.get_capture(1)
3865 # Negotiated MSS value greater than configured - changed
3866 self.verify_mss_value(capture[0], 1000)
3868 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3869 self.pg0.add_stream(p)
3870 self.pg_enable_capture(self.pg_interfaces)
3872 capture = self.pg1.get_capture(1)
3873 # MSS clamping disabled - negotiated MSS unchanged
3874 self.verify_mss_value(capture[0], 1400)
3876 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3877 self.pg0.add_stream(p)
3878 self.pg_enable_capture(self.pg_interfaces)
3880 capture = self.pg1.get_capture(1)
3881 # Negotiated MSS value smaller than configured - unchanged
3882 self.verify_mss_value(capture[0], 1400)
3884 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3885 def test_ha_send(self):
3886 """ Send HA session synchronization events (active) """
3887 self.nat44_add_address(self.nat_addr)
3888 flags = self.config_flags.NAT_IS_INSIDE
3889 self.vapi.nat44_interface_add_del_feature(
3890 sw_if_index=self.pg0.sw_if_index,
3891 flags=flags, is_add=1)
3892 self.vapi.nat44_interface_add_del_feature(
3893 sw_if_index=self.pg1.sw_if_index,
3895 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3898 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3899 port=12346, session_refresh_interval=10)
3900 bind_layers(UDP, HANATStateSync, sport=12345)
3903 pkts = self.create_stream_in(self.pg0, self.pg1)
3904 self.pg0.add_stream(pkts)
3905 self.pg_enable_capture(self.pg_interfaces)
3907 capture = self.pg1.get_capture(len(pkts))
3908 self.verify_capture_out(capture)
3909 # active send HA events
3910 self.vapi.nat_ha_flush()
3911 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3912 self.assertEqual(stats[0][0], 3)
3913 capture = self.pg3.get_capture(1)
3915 self.assert_packet_checksums_valid(p)
3919 hanat = p[HANATStateSync]
3921 self.logger.error(ppp("Invalid packet:", p))
3924 self.assertEqual(ip.src, self.pg3.local_ip4)
3925 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3926 self.assertEqual(udp.sport, 12345)
3927 self.assertEqual(udp.dport, 12346)
3928 self.assertEqual(hanat.version, 1)
3929 self.assertEqual(hanat.thread_index, 0)
3930 self.assertEqual(hanat.count, 3)
3931 seq = hanat.sequence_number
3932 for event in hanat.events:
3933 self.assertEqual(event.event_type, 1)
3934 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3935 self.assertEqual(event.out_addr, self.nat_addr)
3936 self.assertEqual(event.fib_index, 0)
3938 # ACK received events
3939 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3940 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3941 UDP(sport=12346, dport=12345) /
3942 HANATStateSync(sequence_number=seq, flags='ACK'))
3943 self.pg3.add_stream(ack)
3945 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3946 self.assertEqual(stats[0][0], 1)
3948 # delete one session
3949 self.pg_enable_capture(self.pg_interfaces)
3950 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3951 port=self.tcp_port_in,
3952 protocol=IP_PROTOS.tcp,
3953 flags=self.config_flags.NAT_IS_INSIDE)
3954 self.vapi.nat_ha_flush()
3955 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3956 self.assertEqual(stats[0][0], 1)
3957 capture = self.pg3.get_capture(1)
3960 hanat = p[HANATStateSync]
3962 self.logger.error(ppp("Invalid packet:", p))
3965 self.assertGreater(hanat.sequence_number, seq)
3967 # do not send ACK, active retry send HA event again
3968 self.pg_enable_capture(self.pg_interfaces)
3970 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3971 self.assertEqual(stats[0][0], 3)
3972 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3973 self.assertEqual(stats[0][0], 1)
3974 capture = self.pg3.get_capture(3)
3975 for packet in capture:
3976 self.assertEqual(packet, p)
3978 # session counters refresh
3979 pkts = self.create_stream_out(self.pg1)
3980 self.pg1.add_stream(pkts)
3981 self.pg_enable_capture(self.pg_interfaces)
3983 self.pg0.get_capture(2)
3984 self.vapi.nat_ha_flush()
3985 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3986 self.assertEqual(stats[0][0], 2)
3987 capture = self.pg3.get_capture(1)
3989 self.assert_packet_checksums_valid(p)
3993 hanat = p[HANATStateSync]
3995 self.logger.error(ppp("Invalid packet:", p))
3998 self.assertEqual(ip.src, self.pg3.local_ip4)
3999 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4000 self.assertEqual(udp.sport, 12345)
4001 self.assertEqual(udp.dport, 12346)
4002 self.assertEqual(hanat.version, 1)
4003 self.assertEqual(hanat.count, 2)
4004 seq = hanat.sequence_number
4005 for event in hanat.events:
4006 self.assertEqual(event.event_type, 3)
4007 self.assertEqual(event.out_addr, self.nat_addr)
4008 self.assertEqual(event.fib_index, 0)
4009 self.assertEqual(event.total_pkts, 2)
4010 self.assertGreater(event.total_bytes, 0)
4012 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4013 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4014 UDP(sport=12346, dport=12345) /
4015 HANATStateSync(sequence_number=seq, flags='ACK'))
4016 self.pg3.add_stream(ack)
4018 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4019 self.assertEqual(stats[0][0], 2)
4021 def test_ha_recv(self):
4022 """ Receive HA session synchronization events (passive) """
4023 self.nat44_add_address(self.nat_addr)
4024 flags = self.config_flags.NAT_IS_INSIDE
4025 self.vapi.nat44_interface_add_del_feature(
4026 sw_if_index=self.pg0.sw_if_index,
4027 flags=flags, is_add=1)
4028 self.vapi.nat44_interface_add_del_feature(
4029 sw_if_index=self.pg1.sw_if_index,
4031 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4034 bind_layers(UDP, HANATStateSync, sport=12345)
4036 self.tcp_port_out = random.randint(1025, 65535)
4037 self.udp_port_out = random.randint(1025, 65535)
4039 # send HA session add events to failover/passive
4040 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4041 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4042 UDP(sport=12346, dport=12345) /
4043 HANATStateSync(sequence_number=1, events=[
4044 Event(event_type='add', protocol='tcp',
4045 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4046 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4047 eh_addr=self.pg1.remote_ip4,
4048 ehn_addr=self.pg1.remote_ip4,
4049 eh_port=self.tcp_external_port,
4050 ehn_port=self.tcp_external_port, fib_index=0),
4051 Event(event_type='add', protocol='udp',
4052 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4053 in_port=self.udp_port_in, out_port=self.udp_port_out,
4054 eh_addr=self.pg1.remote_ip4,
4055 ehn_addr=self.pg1.remote_ip4,
4056 eh_port=self.udp_external_port,
4057 ehn_port=self.udp_external_port, fib_index=0)]))
4059 self.pg3.add_stream(p)
4060 self.pg_enable_capture(self.pg_interfaces)
4063 capture = self.pg3.get_capture(1)
4066 hanat = p[HANATStateSync]
4068 self.logger.error(ppp("Invalid packet:", p))
4071 self.assertEqual(hanat.sequence_number, 1)
4072 self.assertEqual(hanat.flags, 'ACK')
4073 self.assertEqual(hanat.version, 1)
4074 self.assertEqual(hanat.thread_index, 0)
4075 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4076 self.assertEqual(stats[0][0], 1)
4077 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4078 self.assertEqual(stats[0][0], 2)
4079 users = self.statistics.get_counter('/nat44/total-users')
4080 self.assertEqual(users[0][0], 1)
4081 sessions = self.statistics.get_counter('/nat44/total-sessions')
4082 self.assertEqual(sessions[0][0], 2)
4083 users = self.vapi.nat44_user_dump()
4084 self.assertEqual(len(users), 1)
4085 self.assertEqual(str(users[0].ip_address),
4086 self.pg0.remote_ip4)
4087 # there should be 2 sessions created by HA
4088 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4090 self.assertEqual(len(sessions), 2)
4091 for session in sessions:
4092 self.assertEqual(str(session.inside_ip_address),
4093 self.pg0.remote_ip4)
4094 self.assertEqual(str(session.outside_ip_address),
4096 self.assertIn(session.inside_port,
4097 [self.tcp_port_in, self.udp_port_in])
4098 self.assertIn(session.outside_port,
4099 [self.tcp_port_out, self.udp_port_out])
4100 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4102 # send HA session delete event to failover/passive
4103 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4104 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4105 UDP(sport=12346, dport=12345) /
4106 HANATStateSync(sequence_number=2, events=[
4107 Event(event_type='del', protocol='udp',
4108 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4109 in_port=self.udp_port_in, out_port=self.udp_port_out,
4110 eh_addr=self.pg1.remote_ip4,
4111 ehn_addr=self.pg1.remote_ip4,
4112 eh_port=self.udp_external_port,
4113 ehn_port=self.udp_external_port, fib_index=0)]))
4115 self.pg3.add_stream(p)
4116 self.pg_enable_capture(self.pg_interfaces)
4119 capture = self.pg3.get_capture(1)
4122 hanat = p[HANATStateSync]
4124 self.logger.error(ppp("Invalid packet:", p))
4127 self.assertEqual(hanat.sequence_number, 2)
4128 self.assertEqual(hanat.flags, 'ACK')
4129 self.assertEqual(hanat.version, 1)
4130 users = self.vapi.nat44_user_dump()
4131 self.assertEqual(len(users), 1)
4132 self.assertEqual(str(users[0].ip_address),
4133 self.pg0.remote_ip4)
4134 # now we should have only 1 session, 1 deleted by HA
4135 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4137 self.assertEqual(len(sessions), 1)
4138 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4139 self.assertEqual(stats[0][0], 1)
4141 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4142 self.assertEqual(stats, 2)
4144 # send HA session refresh event to failover/passive
4145 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4146 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4147 UDP(sport=12346, dport=12345) /
4148 HANATStateSync(sequence_number=3, events=[
4149 Event(event_type='refresh', protocol='tcp',
4150 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4151 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4152 eh_addr=self.pg1.remote_ip4,
4153 ehn_addr=self.pg1.remote_ip4,
4154 eh_port=self.tcp_external_port,
4155 ehn_port=self.tcp_external_port, fib_index=0,
4156 total_bytes=1024, total_pkts=2)]))
4157 self.pg3.add_stream(p)
4158 self.pg_enable_capture(self.pg_interfaces)
4161 capture = self.pg3.get_capture(1)
4164 hanat = p[HANATStateSync]
4166 self.logger.error(ppp("Invalid packet:", p))
4169 self.assertEqual(hanat.sequence_number, 3)
4170 self.assertEqual(hanat.flags, 'ACK')
4171 self.assertEqual(hanat.version, 1)
4172 users = self.vapi.nat44_user_dump()
4173 self.assertEqual(len(users), 1)
4174 self.assertEqual(str(users[0].ip_address),
4175 self.pg0.remote_ip4)
4176 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4178 self.assertEqual(len(sessions), 1)
4179 session = sessions[0]
4180 self.assertEqual(session.total_bytes, 1024)
4181 self.assertEqual(session.total_pkts, 2)
4182 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4183 self.assertEqual(stats[0][0], 1)
4185 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4186 self.assertEqual(stats, 3)
4188 # send packet to test session created by HA
4189 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4190 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4191 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4192 self.pg1.add_stream(p)
4193 self.pg_enable_capture(self.pg_interfaces)
4195 capture = self.pg0.get_capture(1)
4201 self.logger.error(ppp("Invalid packet:", p))
4204 self.assertEqual(ip.src, self.pg1.remote_ip4)
4205 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4206 self.assertEqual(tcp.sport, self.tcp_external_port)
4207 self.assertEqual(tcp.dport, self.tcp_port_in)
4210 super(TestNAT44, self).tearDown()
4212 self.vapi.cli("clear logging")
4214 def show_commands_at_teardown(self):
4215 self.logger.info(self.vapi.cli("show nat44 addresses"))
4216 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4217 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4218 self.logger.info(self.vapi.cli("show nat44 interface address"))
4219 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4220 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4221 self.logger.info(self.vapi.cli("show nat timeouts"))
4223 self.vapi.cli("show nat addr-port-assignment-alg"))
4224 self.logger.info(self.vapi.cli("show nat ha"))
4227 class TestNAT44EndpointDependent2(MethodHolder):
4228 """ Endpoint-Dependent session test cases """
4233 def setUpConstants(cls):
4234 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4235 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent",
4236 "translation", "hash", "buckets", "1",
4237 "icmp", "timeout", str(cls.icmp_timeout), "}"])
4240 def setUpClass(cls):
4241 super(TestNAT44EndpointDependent2, cls).setUpClass()
4242 translation_buckets = 1
4243 cls.max_translations = 10 * translation_buckets
4245 cls.create_pg_interfaces(range(2))
4246 cls.interfaces = list(cls.pg_interfaces[0:2])
4248 for i in cls.interfaces:
4253 cls.pg0.generate_remote_hosts(1)
4254 cls.pg0.configure_ipv4_neighbors()
4256 cls.pg1.generate_remote_hosts(1)
4257 cls.pg1.configure_ipv4_neighbors()
4260 def tearDownClass(cls):
4261 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4263 def create_icmp_stream(self, in_if, out_if, count):
4265 Create ICMP packet stream for inside network
4267 :param in_if: Inside interface
4268 :param out_if: Outside interface
4269 :param count: Number of packets
4272 self.assertTrue(count > 0)
4273 icmp_id = random.randint(0, 65535 - (count - 1))
4276 for i in range(count):
4277 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4278 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4279 ICMP(id=icmp_id + i, type='echo-request'))
4283 def send_pkts(self, pkts, expected=None):
4284 self.pg0.add_stream(pkts)
4285 self.pg_enable_capture(self.pg_interfaces)
4287 return self.pg1.get_capture(
4288 len(pkts) if expected is None else expected)
4290 def test_session_cleanup(self):
4291 """ NAT44 session cleanup test """
4293 self.nat44_add_address(self.pg1.local_ip4)
4294 flags = self.config_flags.NAT_IS_INSIDE
4295 self.vapi.nat44_interface_add_del_feature(
4296 sw_if_index=self.pg0.sw_if_index,
4297 flags=flags, is_add=1)
4298 self.vapi.nat44_interface_add_del_feature(
4299 sw_if_index=self.pg1.sw_if_index,
4302 nat_config = self.vapi.nat_show_config()
4303 self.assertEqual(1, nat_config.endpoint_dependent)
4305 pkts = self.create_icmp_stream(self.pg0, self.pg1,
4306 self.max_translations + 2)
4310 self.send_pkts(pkts[0:self.max_translations])
4312 # false positive test
4313 self.send_pkts(pkts[self.max_translations:sz - 1], 0)
4315 sleep(self.icmp_timeout)
4318 self.send_pkts(pkts[self.max_translations + 1:sz])
4321 class TestNAT44EndpointDependent(MethodHolder):
4322 """ Endpoint-Dependent mapping and filtering test cases """
4325 def setUpConstants(cls):
4326 super(TestNAT44EndpointDependent, cls).setUpConstants()
4327 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4330 def setUpClass(cls):
4331 super(TestNAT44EndpointDependent, cls).setUpClass()
4332 cls.vapi.cli("set log class nat level debug")
4334 cls.tcp_port_in = 6303
4335 cls.tcp_port_out = 6303
4336 cls.udp_port_in = 6304
4337 cls.udp_port_out = 6304
4338 cls.icmp_id_in = 6305
4339 cls.icmp_id_out = 6305
4340 cls.nat_addr = '10.0.0.3'
4341 cls.ipfix_src_port = 4739
4342 cls.ipfix_domain_id = 1
4343 cls.tcp_external_port = 80
4345 cls.create_pg_interfaces(range(9))
4346 cls.interfaces = list(cls.pg_interfaces[0:3])
4348 for i in cls.interfaces:
4353 cls.pg0.generate_remote_hosts(3)
4354 cls.pg0.configure_ipv4_neighbors()
4358 cls.pg4.generate_remote_hosts(2)
4359 cls.pg4.config_ip4()
4360 cls.vapi.sw_interface_add_del_address(
4361 sw_if_index=cls.pg4.sw_if_index,
4362 prefix="10.0.0.1/24")
4365 cls.pg4.resolve_arp()
4366 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4367 cls.pg4.resolve_arp()
4369 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4370 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4372 cls.pg5._local_ip4 = "10.1.1.1"
4373 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4374 cls.pg5.set_table_ip4(1)
4375 cls.pg5.config_ip4()
4377 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4378 [VppRoutePath("0.0.0.0",
4379 cls.pg5.sw_if_index)],
4384 cls.pg6._local_ip4 = "10.1.2.1"
4385 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4386 cls.pg6.set_table_ip4(1)
4387 cls.pg6.config_ip4()
4390 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4391 [VppRoutePath("0.0.0.0",
4392 cls.pg6.sw_if_index)],
4395 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4396 [VppRoutePath("0.0.0.0",
4401 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4402 [VppRoutePath("0.0.0.0", 0xffffffff,
4406 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4407 [VppRoutePath(cls.pg1.local_ip4,
4408 cls.pg1.sw_if_index)],
4415 cls.pg5.resolve_arp()
4416 cls.pg6.resolve_arp()
4419 cls.pg7.config_ip4()
4420 cls.pg7.resolve_arp()
4421 cls.pg7.generate_remote_hosts(3)
4422 cls.pg7.configure_ipv4_neighbors()
4425 cls.pg8.config_ip4()
4426 cls.pg8.resolve_arp()
4429 def tearDownClass(cls):
4430 super(TestNAT44EndpointDependent, cls).tearDownClass()
4432 def test_frag_in_order(self):
4433 """ NAT44 translate fragments arriving in order """
4434 self.nat44_add_address(self.nat_addr)
4435 flags = self.config_flags.NAT_IS_INSIDE
4436 self.vapi.nat44_interface_add_del_feature(
4437 sw_if_index=self.pg0.sw_if_index,
4438 flags=flags, is_add=1)
4439 self.vapi.nat44_interface_add_del_feature(
4440 sw_if_index=self.pg1.sw_if_index,
4442 self.frag_in_order(proto=IP_PROTOS.tcp)
4443 self.frag_in_order(proto=IP_PROTOS.udp)
4444 self.frag_in_order(proto=IP_PROTOS.icmp)
4446 def test_frag_in_order_dont_translate(self):
4447 """ NAT44 don't translate fragments arriving in order """
4448 flags = self.config_flags.NAT_IS_INSIDE
4449 self.vapi.nat44_interface_add_del_feature(
4450 sw_if_index=self.pg0.sw_if_index,
4451 flags=flags, is_add=1)
4452 self.vapi.nat44_interface_add_del_feature(
4453 sw_if_index=self.pg1.sw_if_index,
4455 self.vapi.nat44_forwarding_enable_disable(enable=True)
4456 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4458 def test_frag_out_of_order(self):
4459 """ NAT44 translate fragments arriving out of order """
4460 self.nat44_add_address(self.nat_addr)
4461 flags = self.config_flags.NAT_IS_INSIDE
4462 self.vapi.nat44_interface_add_del_feature(
4463 sw_if_index=self.pg0.sw_if_index,
4464 flags=flags, is_add=1)
4465 self.vapi.nat44_interface_add_del_feature(
4466 sw_if_index=self.pg1.sw_if_index,
4468 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4469 self.frag_out_of_order(proto=IP_PROTOS.udp)
4470 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4472 def test_frag_out_of_order_dont_translate(self):
4473 """ NAT44 don't translate fragments arriving out of order """
4474 flags = self.config_flags.NAT_IS_INSIDE
4475 self.vapi.nat44_interface_add_del_feature(
4476 sw_if_index=self.pg0.sw_if_index,
4477 flags=flags, is_add=1)
4478 self.vapi.nat44_interface_add_del_feature(
4479 sw_if_index=self.pg1.sw_if_index,
4481 self.vapi.nat44_forwarding_enable_disable(enable=True)
4482 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4484 def test_frag_in_order_in_plus_out(self):
4485 """ in+out interface fragments in order """
4486 flags = self.config_flags.NAT_IS_INSIDE
4487 self.vapi.nat44_interface_add_del_feature(
4488 sw_if_index=self.pg0.sw_if_index,
4490 self.vapi.nat44_interface_add_del_feature(
4491 sw_if_index=self.pg0.sw_if_index,
4492 flags=flags, is_add=1)
4493 self.vapi.nat44_interface_add_del_feature(
4494 sw_if_index=self.pg1.sw_if_index,
4496 self.vapi.nat44_interface_add_del_feature(
4497 sw_if_index=self.pg1.sw_if_index,
4498 flags=flags, is_add=1)
4500 self.server = self.pg1.remote_hosts[0]
4502 self.server_in_addr = self.server.ip4
4503 self.server_out_addr = '11.11.11.11'
4504 self.server_in_port = random.randint(1025, 65535)
4505 self.server_out_port = random.randint(1025, 65535)
4507 self.nat44_add_address(self.server_out_addr)
4509 # add static mappings for server
4510 self.nat44_add_static_mapping(self.server_in_addr,
4511 self.server_out_addr,
4512 self.server_in_port,
4513 self.server_out_port,
4514 proto=IP_PROTOS.tcp)
4515 self.nat44_add_static_mapping(self.server_in_addr,
4516 self.server_out_addr,
4517 self.server_in_port,
4518 self.server_out_port,
4519 proto=IP_PROTOS.udp)
4520 self.nat44_add_static_mapping(self.server_in_addr,
4521 self.server_out_addr,
4522 proto=IP_PROTOS.icmp)
4524 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4525 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4526 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4528 def test_frag_out_of_order_in_plus_out(self):
4529 """ in+out interface fragments out of order """
4530 flags = self.config_flags.NAT_IS_INSIDE
4531 self.vapi.nat44_interface_add_del_feature(
4532 sw_if_index=self.pg0.sw_if_index,
4534 self.vapi.nat44_interface_add_del_feature(
4535 sw_if_index=self.pg0.sw_if_index,
4536 flags=flags, is_add=1)
4537 self.vapi.nat44_interface_add_del_feature(
4538 sw_if_index=self.pg1.sw_if_index,
4540 self.vapi.nat44_interface_add_del_feature(
4541 sw_if_index=self.pg1.sw_if_index,
4542 flags=flags, is_add=1)
4544 self.server = self.pg1.remote_hosts[0]
4546 self.server_in_addr = self.server.ip4
4547 self.server_out_addr = '11.11.11.11'
4548 self.server_in_port = random.randint(1025, 65535)
4549 self.server_out_port = random.randint(1025, 65535)
4551 self.nat44_add_address(self.server_out_addr)
4553 # add static mappings for server
4554 self.nat44_add_static_mapping(self.server_in_addr,
4555 self.server_out_addr,
4556 self.server_in_port,
4557 self.server_out_port,
4558 proto=IP_PROTOS.tcp)
4559 self.nat44_add_static_mapping(self.server_in_addr,
4560 self.server_out_addr,
4561 self.server_in_port,
4562 self.server_out_port,
4563 proto=IP_PROTOS.udp)
4564 self.nat44_add_static_mapping(self.server_in_addr,
4565 self.server_out_addr,
4566 proto=IP_PROTOS.icmp)
4568 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4569 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4570 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4572 def test_reass_hairpinning(self):
4573 """ NAT44 fragments hairpinning """
4574 self.server = self.pg0.remote_hosts[1]
4575 self.host_in_port = random.randint(1025, 65535)
4576 self.server_in_port = random.randint(1025, 65535)
4577 self.server_out_port = random.randint(1025, 65535)
4579 self.nat44_add_address(self.nat_addr)
4580 flags = self.config_flags.NAT_IS_INSIDE
4581 self.vapi.nat44_interface_add_del_feature(
4582 sw_if_index=self.pg0.sw_if_index,
4583 flags=flags, is_add=1)
4584 self.vapi.nat44_interface_add_del_feature(
4585 sw_if_index=self.pg1.sw_if_index,
4587 # add static mapping for server
4588 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4589 self.server_in_port,
4590 self.server_out_port,
4591 proto=IP_PROTOS.tcp)
4592 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4593 self.server_in_port,
4594 self.server_out_port,
4595 proto=IP_PROTOS.udp)
4596 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4598 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4599 self.reass_hairpinning(proto=IP_PROTOS.udp)
4600 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4602 def test_dynamic(self):
4603 """ NAT44 dynamic translation test """
4605 self.nat44_add_address(self.nat_addr)
4606 flags = self.config_flags.NAT_IS_INSIDE
4607 self.vapi.nat44_interface_add_del_feature(
4608 sw_if_index=self.pg0.sw_if_index,
4609 flags=flags, is_add=1)
4610 self.vapi.nat44_interface_add_del_feature(
4611 sw_if_index=self.pg1.sw_if_index,
4614 nat_config = self.vapi.nat_show_config()
4615 self.assertEqual(1, nat_config.endpoint_dependent)
4618 tcpn = self.statistics.get_err_counter(
4619 '/err/nat44-ed-in2out-slowpath/TCP packets')
4620 udpn = self.statistics.get_err_counter(
4621 '/err/nat44-ed-in2out-slowpath/UDP packets')
4622 icmpn = self.statistics.get_err_counter(
4623 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4624 totaln = self.statistics.get_err_counter(
4625 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4627 pkts = self.create_stream_in(self.pg0, self.pg1)
4628 self.pg0.add_stream(pkts)
4629 self.pg_enable_capture(self.pg_interfaces)
4631 capture = self.pg1.get_capture(len(pkts))
4632 self.verify_capture_out(capture)
4634 err = self.statistics.get_err_counter(
4635 '/err/nat44-ed-in2out-slowpath/TCP packets')
4636 self.assertEqual(err - tcpn, 2)
4637 err = self.statistics.get_err_counter(
4638 '/err/nat44-ed-in2out-slowpath/UDP packets')
4639 self.assertEqual(err - udpn, 1)
4640 err = self.statistics.get_err_counter(
4641 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4642 self.assertEqual(err - icmpn, 1)
4643 err = self.statistics.get_err_counter(
4644 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4645 self.assertEqual(err - totaln, 4)
4648 tcpn = self.statistics.get_err_counter(
4649 '/err/nat44-ed-out2in/TCP packets')
4650 udpn = self.statistics.get_err_counter(
4651 '/err/nat44-ed-out2in/UDP packets')
4652 icmpn = self.statistics.get_err_counter(
4653 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4654 totaln = self.statistics.get_err_counter(
4655 '/err/nat44-ed-out2in/good out2in packets processed')
4657 pkts = self.create_stream_out(self.pg1)
4658 self.pg1.add_stream(pkts)
4659 self.pg_enable_capture(self.pg_interfaces)
4661 capture = self.pg0.get_capture(len(pkts))
4662 self.verify_capture_in(capture, self.pg0)
4664 err = self.statistics.get_err_counter(
4665 '/err/nat44-ed-out2in/TCP packets')
4666 self.assertEqual(err - tcpn, 2)
4667 err = self.statistics.get_err_counter(
4668 '/err/nat44-ed-out2in/UDP packets')
4669 self.assertEqual(err - udpn, 1)
4670 err = self.statistics.get_err_counter(
4671 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4672 self.assertEqual(err - icmpn, 1)
4673 err = self.statistics.get_err_counter(
4674 '/err/nat44-ed-out2in/good out2in packets processed')
4675 self.assertEqual(err - totaln, 3)
4677 users = self.statistics.get_counter('/nat44/total-users')
4678 self.assertEqual(users[0][0], 1)
4679 sessions = self.statistics.get_counter('/nat44/total-sessions')
4680 self.assertEqual(sessions[0][0], 3)
4682 def test_dynamic_output_feature_vrf(self):
4683 """ NAT44 dynamic translation test: output-feature, VRF"""
4685 # other then default (0)
4688 self.nat44_add_address(self.nat_addr)
4689 flags = self.config_flags.NAT_IS_INSIDE
4690 self.vapi.nat44_interface_add_del_output_feature(
4691 sw_if_index=self.pg7.sw_if_index,
4692 flags=flags, is_add=1)
4693 self.vapi.nat44_interface_add_del_output_feature(
4694 sw_if_index=self.pg8.sw_if_index,
4698 self.vapi.ip_table_add_del(is_add=1,
4699 table={'table_id': new_vrf_id})
4701 self.pg7.unconfig_ip4()
4702 self.pg7.set_table_ip4(new_vrf_id)
4703 self.pg7.config_ip4()
4704 self.pg7.resolve_arp()
4706 self.pg8.unconfig_ip4()
4707 self.pg8.set_table_ip4(new_vrf_id)
4708 self.pg8.config_ip4()
4709 self.pg8.resolve_arp()
4711 nat_config = self.vapi.nat_show_config()
4712 self.assertEqual(1, nat_config.endpoint_dependent)
4715 tcpn = self.statistics.get_err_counter(
4716 '/err/nat44-ed-in2out-slowpath/TCP packets')
4717 udpn = self.statistics.get_err_counter(
4718 '/err/nat44-ed-in2out-slowpath/UDP packets')
4719 icmpn = self.statistics.get_err_counter(
4720 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4721 totaln = self.statistics.get_err_counter(
4722 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4724 pkts = self.create_stream_in(self.pg7, self.pg8)
4725 self.pg7.add_stream(pkts)
4726 self.pg_enable_capture(self.pg_interfaces)
4728 capture = self.pg8.get_capture(len(pkts))
4729 self.verify_capture_out(capture)
4731 err = self.statistics.get_err_counter(
4732 '/err/nat44-ed-in2out-slowpath/TCP packets')
4733 self.assertEqual(err - tcpn, 2)
4734 err = self.statistics.get_err_counter(
4735 '/err/nat44-ed-in2out-slowpath/UDP packets')
4736 self.assertEqual(err - udpn, 1)
4737 err = self.statistics.get_err_counter(
4738 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4739 self.assertEqual(err - icmpn, 1)
4740 err = self.statistics.get_err_counter(
4741 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4742 self.assertEqual(err - totaln, 4)
4745 tcpn = self.statistics.get_err_counter(
4746 '/err/nat44-ed-out2in/TCP packets')
4747 udpn = self.statistics.get_err_counter(
4748 '/err/nat44-ed-out2in/UDP packets')
4749 icmpn = self.statistics.get_err_counter(
4750 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4751 totaln = self.statistics.get_err_counter(
4752 '/err/nat44-ed-out2in/good out2in packets processed')
4754 pkts = self.create_stream_out(self.pg8)
4755 self.pg8.add_stream(pkts)
4756 self.pg_enable_capture(self.pg_interfaces)
4758 capture = self.pg7.get_capture(len(pkts))
4759 self.verify_capture_in(capture, self.pg7)
4761 err = self.statistics.get_err_counter(
4762 '/err/nat44-ed-out2in/TCP packets')
4763 self.assertEqual(err - tcpn, 2)
4764 err = self.statistics.get_err_counter(
4765 '/err/nat44-ed-out2in/UDP packets')
4766 self.assertEqual(err - udpn, 1)
4767 err = self.statistics.get_err_counter(
4768 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4769 self.assertEqual(err - icmpn, 1)
4770 err = self.statistics.get_err_counter(
4771 '/err/nat44-ed-out2in/good out2in packets processed')
4772 self.assertEqual(err - totaln, 3)
4774 users = self.statistics.get_counter('/nat44/total-users')
4775 self.assertEqual(users[0][0], 1)
4776 sessions = self.statistics.get_counter('/nat44/total-sessions')
4777 self.assertEqual(sessions[0][0], 3)
4780 self.pg7.unconfig_ip4()
4781 self.pg7.set_table_ip4(1)
4782 self.pg7.config_ip4()
4783 self.pg7.resolve_arp()
4785 self.pg8.unconfig_ip4()
4786 self.pg8.set_table_ip4(1)
4787 self.pg8.config_ip4()
4788 self.pg8.resolve_arp()
4790 self.vapi.ip_table_add_del(is_add=0,
4791 table={'table_id': new_vrf_id})
4793 def test_forwarding(self):
4794 """ NAT44 forwarding test """
4796 flags = self.config_flags.NAT_IS_INSIDE
4797 self.vapi.nat44_interface_add_del_feature(
4798 sw_if_index=self.pg0.sw_if_index,
4799 flags=flags, is_add=1)
4800 self.vapi.nat44_interface_add_del_feature(
4801 sw_if_index=self.pg1.sw_if_index,
4803 self.vapi.nat44_forwarding_enable_disable(enable=1)
4805 real_ip = self.pg0.remote_ip4
4806 alias_ip = self.nat_addr
4807 flags = self.config_flags.NAT_IS_ADDR_ONLY
4808 self.vapi.nat44_add_del_static_mapping(is_add=1,
4809 local_ip_address=real_ip,
4810 external_ip_address=alias_ip,
4811 external_sw_if_index=0xFFFFFFFF,
4815 # in2out - static mapping match
4817 pkts = self.create_stream_out(self.pg1)
4818 self.pg1.add_stream(pkts)
4819 self.pg_enable_capture(self.pg_interfaces)
4821 capture = self.pg0.get_capture(len(pkts))
4822 self.verify_capture_in(capture, self.pg0)
4824 pkts = self.create_stream_in(self.pg0, self.pg1)
4825 self.pg0.add_stream(pkts)
4826 self.pg_enable_capture(self.pg_interfaces)
4828 capture = self.pg1.get_capture(len(pkts))
4829 self.verify_capture_out(capture, same_port=True)
4831 # in2out - no static mapping match
4833 host0 = self.pg0.remote_hosts[0]
4834 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4836 pkts = self.create_stream_out(self.pg1,
4837 dst_ip=self.pg0.remote_ip4,
4838 use_inside_ports=True)
4839 self.pg1.add_stream(pkts)
4840 self.pg_enable_capture(self.pg_interfaces)
4842 capture = self.pg0.get_capture(len(pkts))
4843 self.verify_capture_in(capture, self.pg0)
4845 pkts = self.create_stream_in(self.pg0, self.pg1)
4846 self.pg0.add_stream(pkts)
4847 self.pg_enable_capture(self.pg_interfaces)
4849 capture = self.pg1.get_capture(len(pkts))
4850 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4853 self.pg0.remote_hosts[0] = host0
4855 user = self.pg0.remote_hosts[1]
4856 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4857 self.assertEqual(len(sessions), 3)
4858 self.assertTrue(sessions[0].flags &
4859 self.config_flags.NAT_IS_EXT_HOST_VALID)
4860 self.vapi.nat44_del_session(
4861 address=sessions[0].inside_ip_address,
4862 port=sessions[0].inside_port,
4863 protocol=sessions[0].protocol,
4864 flags=(self.config_flags.NAT_IS_INSIDE |
4865 self.config_flags.NAT_IS_EXT_HOST_VALID),
4866 ext_host_address=sessions[0].ext_host_address,
4867 ext_host_port=sessions[0].ext_host_port)
4868 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4869 self.assertEqual(len(sessions), 2)
4872 self.vapi.nat44_forwarding_enable_disable(enable=0)
4873 flags = self.config_flags.NAT_IS_ADDR_ONLY
4874 self.vapi.nat44_add_del_static_mapping(
4876 local_ip_address=real_ip,
4877 external_ip_address=alias_ip,
4878 external_sw_if_index=0xFFFFFFFF,
4881 def test_static_lb(self):
4882 """ NAT44 local service load balancing """
4883 external_addr_n = self.nat_addr
4886 server1 = self.pg0.remote_hosts[0]
4887 server2 = self.pg0.remote_hosts[1]
4889 locals = [{'addr': server1.ip4,
4893 {'addr': server2.ip4,
4898 self.nat44_add_address(self.nat_addr)
4899 self.vapi.nat44_add_del_lb_static_mapping(
4901 external_addr=external_addr_n,
4902 external_port=external_port,
4903 protocol=IP_PROTOS.tcp,
4904 local_num=len(locals),
4906 flags = self.config_flags.NAT_IS_INSIDE
4907 self.vapi.nat44_interface_add_del_feature(
4908 sw_if_index=self.pg0.sw_if_index,
4909 flags=flags, is_add=1)
4910 self.vapi.nat44_interface_add_del_feature(
4911 sw_if_index=self.pg1.sw_if_index,
4914 # from client to service
4915 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4916 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4917 TCP(sport=12345, dport=external_port))
4918 self.pg1.add_stream(p)
4919 self.pg_enable_capture(self.pg_interfaces)
4921 capture = self.pg0.get_capture(1)
4927 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4928 if ip.dst == server1.ip4:
4932 self.assertEqual(tcp.dport, local_port)
4933 self.assert_packet_checksums_valid(p)
4935 self.logger.error(ppp("Unexpected or invalid packet:", p))
4938 # from service back to client
4939 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4940 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4941 TCP(sport=local_port, dport=12345))
4942 self.pg0.add_stream(p)
4943 self.pg_enable_capture(self.pg_interfaces)
4945 capture = self.pg1.get_capture(1)
4950 self.assertEqual(ip.src, self.nat_addr)
4951 self.assertEqual(tcp.sport, external_port)
4952 self.assert_packet_checksums_valid(p)
4954 self.logger.error(ppp("Unexpected or invalid packet:", p))
4957 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4958 self.assertEqual(len(sessions), 1)
4959 self.assertTrue(sessions[0].flags &
4960 self.config_flags.NAT_IS_EXT_HOST_VALID)
4961 self.vapi.nat44_del_session(
4962 address=sessions[0].inside_ip_address,
4963 port=sessions[0].inside_port,
4964 protocol=sessions[0].protocol,
4965 flags=(self.config_flags.NAT_IS_INSIDE |
4966 self.config_flags.NAT_IS_EXT_HOST_VALID),
4967 ext_host_address=sessions[0].ext_host_address,
4968 ext_host_port=sessions[0].ext_host_port)
4969 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4970 self.assertEqual(len(sessions), 0)
4972 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4973 def test_static_lb_multi_clients(self):
4974 """ NAT44 local service load balancing - multiple clients"""
4976 external_addr = self.nat_addr
4979 server1 = self.pg0.remote_hosts[0]
4980 server2 = self.pg0.remote_hosts[1]
4981 server3 = self.pg0.remote_hosts[2]
4983 locals = [{'addr': server1.ip4,
4987 {'addr': server2.ip4,
4992 self.nat44_add_address(self.nat_addr)
4993 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
4994 external_addr=external_addr,
4995 external_port=external_port,
4996 protocol=IP_PROTOS.tcp,
4997 local_num=len(locals),
4999 flags = self.config_flags.NAT_IS_INSIDE
5000 self.vapi.nat44_interface_add_del_feature(
5001 sw_if_index=self.pg0.sw_if_index,
5002 flags=flags, is_add=1)
5003 self.vapi.nat44_interface_add_del_feature(
5004 sw_if_index=self.pg1.sw_if_index,
5009 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5011 for client in clients:
5012 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5013 IP(src=client, dst=self.nat_addr) /
5014 TCP(sport=12345, dport=external_port))
5016 self.pg1.add_stream(pkts)
5017 self.pg_enable_capture(self.pg_interfaces)
5019 capture = self.pg0.get_capture(len(pkts))
5021 if p[IP].dst == server1.ip4:
5025 self.assertGreater(server1_n, server2_n)
5028 'addr': server3.ip4,
5035 self.vapi.nat44_lb_static_mapping_add_del_local(
5037 external_addr=external_addr,
5038 external_port=external_port,
5040 protocol=IP_PROTOS.tcp)
5044 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5046 for client in clients:
5047 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5048 IP(src=client, dst=self.nat_addr) /
5049 TCP(sport=12346, dport=external_port))
5051 self.assertGreater(len(pkts), 0)
5052 self.pg1.add_stream(pkts)
5053 self.pg_enable_capture(self.pg_interfaces)
5055 capture = self.pg0.get_capture(len(pkts))
5057 if p[IP].dst == server1.ip4:
5059 elif p[IP].dst == server2.ip4:
5063 self.assertGreater(server1_n, 0)
5064 self.assertGreater(server2_n, 0)
5065 self.assertGreater(server3_n, 0)
5068 'addr': server2.ip4,
5074 # remove one back-end
5075 self.vapi.nat44_lb_static_mapping_add_del_local(
5077 external_addr=external_addr,
5078 external_port=external_port,
5080 protocol=IP_PROTOS.tcp)
5084 self.pg1.add_stream(pkts)
5085 self.pg_enable_capture(self.pg_interfaces)
5087 capture = self.pg0.get_capture(len(pkts))
5089 if p[IP].dst == server1.ip4:
5091 elif p[IP].dst == server2.ip4:
5095 self.assertGreater(server1_n, 0)
5096 self.assertEqual(server2_n, 0)
5097 self.assertGreater(server3_n, 0)
5099 def test_static_lb_2(self):
5100 """ NAT44 local service load balancing (asymmetrical rule) """
5101 external_addr = self.nat_addr
5104 server1 = self.pg0.remote_hosts[0]
5105 server2 = self.pg0.remote_hosts[1]
5107 locals = [{'addr': server1.ip4,
5111 {'addr': server2.ip4,
5116 self.vapi.nat44_forwarding_enable_disable(enable=1)
5117 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5118 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5119 external_addr=external_addr,
5120 external_port=external_port,
5121 protocol=IP_PROTOS.tcp,
5122 local_num=len(locals),
5124 flags = self.config_flags.NAT_IS_INSIDE
5125 self.vapi.nat44_interface_add_del_feature(
5126 sw_if_index=self.pg0.sw_if_index,
5127 flags=flags, is_add=1)
5128 self.vapi.nat44_interface_add_del_feature(
5129 sw_if_index=self.pg1.sw_if_index,
5132 # from client to service
5133 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5134 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5135 TCP(sport=12345, dport=external_port))
5136 self.pg1.add_stream(p)
5137 self.pg_enable_capture(self.pg_interfaces)
5139 capture = self.pg0.get_capture(1)
5145 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5146 if ip.dst == server1.ip4:
5150 self.assertEqual(tcp.dport, local_port)
5151 self.assert_packet_checksums_valid(p)
5153 self.logger.error(ppp("Unexpected or invalid packet:", p))
5156 # from service back to client
5157 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5158 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5159 TCP(sport=local_port, dport=12345))
5160 self.pg0.add_stream(p)
5161 self.pg_enable_capture(self.pg_interfaces)
5163 capture = self.pg1.get_capture(1)
5168 self.assertEqual(ip.src, self.nat_addr)
5169 self.assertEqual(tcp.sport, external_port)
5170 self.assert_packet_checksums_valid(p)
5172 self.logger.error(ppp("Unexpected or invalid packet:", p))
5175 # from client to server (no translation)
5176 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5177 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5178 TCP(sport=12346, dport=local_port))
5179 self.pg1.add_stream(p)
5180 self.pg_enable_capture(self.pg_interfaces)
5182 capture = self.pg0.get_capture(1)
5188 self.assertEqual(ip.dst, server1.ip4)
5189 self.assertEqual(tcp.dport, local_port)
5190 self.assert_packet_checksums_valid(p)
5192 self.logger.error(ppp("Unexpected or invalid packet:", p))
5195 # from service back to client (no translation)
5196 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5197 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5198 TCP(sport=local_port, dport=12346))
5199 self.pg0.add_stream(p)
5200 self.pg_enable_capture(self.pg_interfaces)
5202 capture = self.pg1.get_capture(1)
5207 self.assertEqual(ip.src, server1.ip4)
5208 self.assertEqual(tcp.sport, local_port)
5209 self.assert_packet_checksums_valid(p)
5211 self.logger.error(ppp("Unexpected or invalid packet:", p))
5214 def test_lb_affinity(self):
5215 """ NAT44 local service load balancing affinity """
5216 external_addr = self.nat_addr
5219 server1 = self.pg0.remote_hosts[0]
5220 server2 = self.pg0.remote_hosts[1]
5222 locals = [{'addr': server1.ip4,
5226 {'addr': server2.ip4,
5231 self.nat44_add_address(self.nat_addr)
5232 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5233 external_addr=external_addr,
5234 external_port=external_port,
5235 protocol=IP_PROTOS.tcp,
5237 local_num=len(locals),
5239 flags = self.config_flags.NAT_IS_INSIDE
5240 self.vapi.nat44_interface_add_del_feature(
5241 sw_if_index=self.pg0.sw_if_index,
5242 flags=flags, is_add=1)
5243 self.vapi.nat44_interface_add_del_feature(
5244 sw_if_index=self.pg1.sw_if_index,
5247 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5248 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5249 TCP(sport=1025, dport=external_port))
5250 self.pg1.add_stream(p)
5251 self.pg_enable_capture(self.pg_interfaces)
5253 capture = self.pg0.get_capture(1)
5254 backend = capture[0][IP].dst
5256 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5257 self.assertEqual(len(sessions), 1)
5258 self.assertTrue(sessions[0].flags &
5259 self.config_flags.NAT_IS_EXT_HOST_VALID)
5260 self.vapi.nat44_del_session(
5261 address=sessions[0].inside_ip_address,
5262 port=sessions[0].inside_port,
5263 protocol=sessions[0].protocol,
5264 flags=(self.config_flags.NAT_IS_INSIDE |
5265 self.config_flags.NAT_IS_EXT_HOST_VALID),
5266 ext_host_address=sessions[0].ext_host_address,
5267 ext_host_port=sessions[0].ext_host_port)
5270 for port in range(1030, 1100):
5271 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5272 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5273 TCP(sport=port, dport=external_port))
5275 self.pg1.add_stream(pkts)
5276 self.pg_enable_capture(self.pg_interfaces)
5278 capture = self.pg0.get_capture(len(pkts))
5280 self.assertEqual(p[IP].dst, backend)
5282 def test_unknown_proto(self):
5283 """ NAT44 translate packet with unknown protocol """
5284 self.nat44_add_address(self.nat_addr)
5285 flags = self.config_flags.NAT_IS_INSIDE
5286 self.vapi.nat44_interface_add_del_feature(
5287 sw_if_index=self.pg0.sw_if_index,
5288 flags=flags, is_add=1)
5289 self.vapi.nat44_interface_add_del_feature(
5290 sw_if_index=self.pg1.sw_if_index,
5294 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5295 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5296 TCP(sport=self.tcp_port_in, dport=20))
5297 self.pg0.add_stream(p)
5298 self.pg_enable_capture(self.pg_interfaces)
5300 p = self.pg1.get_capture(1)
5302 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5303 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5305 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5306 TCP(sport=1234, dport=1234))
5307 self.pg0.add_stream(p)
5308 self.pg_enable_capture(self.pg_interfaces)
5310 p = self.pg1.get_capture(1)
5313 self.assertEqual(packet[IP].src, self.nat_addr)
5314 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5315 self.assertEqual(packet.haslayer(GRE), 1)
5316 self.assert_packet_checksums_valid(packet)
5318 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5322 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5323 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5325 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5326 TCP(sport=1234, dport=1234))
5327 self.pg1.add_stream(p)
5328 self.pg_enable_capture(self.pg_interfaces)
5330 p = self.pg0.get_capture(1)
5333 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5334 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5335 self.assertEqual(packet.haslayer(GRE), 1)
5336 self.assert_packet_checksums_valid(packet)
5338 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5341 def test_hairpinning_unknown_proto(self):
5342 """ NAT44 translate packet with unknown protocol - hairpinning """
5343 host = self.pg0.remote_hosts[0]
5344 server = self.pg0.remote_hosts[1]
5346 server_out_port = 8765
5347 server_nat_ip = "10.0.0.11"
5349 self.nat44_add_address(self.nat_addr)
5350 flags = self.config_flags.NAT_IS_INSIDE
5351 self.vapi.nat44_interface_add_del_feature(
5352 sw_if_index=self.pg0.sw_if_index,
5353 flags=flags, is_add=1)
5354 self.vapi.nat44_interface_add_del_feature(
5355 sw_if_index=self.pg1.sw_if_index,
5358 # add static mapping for server
5359 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5362 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5363 IP(src=host.ip4, dst=server_nat_ip) /
5364 TCP(sport=host_in_port, dport=server_out_port))
5365 self.pg0.add_stream(p)
5366 self.pg_enable_capture(self.pg_interfaces)
5368 self.pg0.get_capture(1)
5370 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5371 IP(src=host.ip4, dst=server_nat_ip) /
5373 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5374 TCP(sport=1234, dport=1234))
5375 self.pg0.add_stream(p)
5376 self.pg_enable_capture(self.pg_interfaces)
5378 p = self.pg0.get_capture(1)
5381 self.assertEqual(packet[IP].src, self.nat_addr)
5382 self.assertEqual(packet[IP].dst, server.ip4)
5383 self.assertEqual(packet.haslayer(GRE), 1)
5384 self.assert_packet_checksums_valid(packet)
5386 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5390 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5391 IP(src=server.ip4, dst=self.nat_addr) /
5393 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5394 TCP(sport=1234, dport=1234))
5395 self.pg0.add_stream(p)
5396 self.pg_enable_capture(self.pg_interfaces)
5398 p = self.pg0.get_capture(1)
5401 self.assertEqual(packet[IP].src, server_nat_ip)
5402 self.assertEqual(packet[IP].dst, host.ip4)
5403 self.assertEqual(packet.haslayer(GRE), 1)
5404 self.assert_packet_checksums_valid(packet)
5406 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5409 def test_output_feature_and_service(self):
5410 """ NAT44 interface output feature and services """
5411 external_addr = '1.2.3.4'
5415 self.vapi.nat44_forwarding_enable_disable(enable=1)
5416 self.nat44_add_address(self.nat_addr)
5417 flags = self.config_flags.NAT_IS_ADDR_ONLY
5418 self.vapi.nat44_add_del_identity_mapping(
5419 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5420 flags=flags, is_add=1)
5421 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5422 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5423 local_port, external_port,
5424 proto=IP_PROTOS.tcp, flags=flags)
5425 flags = self.config_flags.NAT_IS_INSIDE
5426 self.vapi.nat44_interface_add_del_feature(
5427 sw_if_index=self.pg0.sw_if_index,
5429 self.vapi.nat44_interface_add_del_feature(
5430 sw_if_index=self.pg0.sw_if_index,
5431 flags=flags, is_add=1)
5432 self.vapi.nat44_interface_add_del_output_feature(
5434 sw_if_index=self.pg1.sw_if_index)
5436 # from client to service
5437 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5438 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5439 TCP(sport=12345, dport=external_port))
5440 self.pg1.add_stream(p)
5441 self.pg_enable_capture(self.pg_interfaces)
5443 capture = self.pg0.get_capture(1)
5448 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5449 self.assertEqual(tcp.dport, local_port)
5450 self.assert_packet_checksums_valid(p)
5452 self.logger.error(ppp("Unexpected or invalid packet:", p))
5455 # from service back to client
5456 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5457 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5458 TCP(sport=local_port, dport=12345))
5459 self.pg0.add_stream(p)
5460 self.pg_enable_capture(self.pg_interfaces)
5462 capture = self.pg1.get_capture(1)
5467 self.assertEqual(ip.src, external_addr)
5468 self.assertEqual(tcp.sport, external_port)
5469 self.assert_packet_checksums_valid(p)
5471 self.logger.error(ppp("Unexpected or invalid packet:", p))
5474 # from local network host to external network
5475 pkts = self.create_stream_in(self.pg0, self.pg1)
5476 self.pg0.add_stream(pkts)
5477 self.pg_enable_capture(self.pg_interfaces)
5479 capture = self.pg1.get_capture(len(pkts))
5480 self.verify_capture_out(capture)
5481 pkts = self.create_stream_in(self.pg0, self.pg1)
5482 self.pg0.add_stream(pkts)
5483 self.pg_enable_capture(self.pg_interfaces)
5485 capture = self.pg1.get_capture(len(pkts))
5486 self.verify_capture_out(capture)
5488 # from external network back to local network host
5489 pkts = self.create_stream_out(self.pg1)
5490 self.pg1.add_stream(pkts)
5491 self.pg_enable_capture(self.pg_interfaces)
5493 capture = self.pg0.get_capture(len(pkts))
5494 self.verify_capture_in(capture, self.pg0)
5496 def test_output_feature_and_service2(self):
5497 """ NAT44 interface output feature and service host direct access """
5498 self.vapi.nat44_forwarding_enable_disable(enable=1)
5499 self.nat44_add_address(self.nat_addr)
5500 self.vapi.nat44_interface_add_del_output_feature(
5502 sw_if_index=self.pg1.sw_if_index)
5504 # session initiated from service host - translate
5505 pkts = self.create_stream_in(self.pg0, self.pg1)
5506 self.pg0.add_stream(pkts)
5507 self.pg_enable_capture(self.pg_interfaces)
5509 capture = self.pg1.get_capture(len(pkts))
5510 self.verify_capture_out(capture)
5512 pkts = self.create_stream_out(self.pg1)
5513 self.pg1.add_stream(pkts)
5514 self.pg_enable_capture(self.pg_interfaces)
5516 capture = self.pg0.get_capture(len(pkts))
5517 self.verify_capture_in(capture, self.pg0)
5519 # session initiated from remote host - do not translate
5520 self.tcp_port_in = 60303
5521 self.udp_port_in = 60304
5522 self.icmp_id_in = 60305
5523 pkts = self.create_stream_out(self.pg1,
5524 self.pg0.remote_ip4,
5525 use_inside_ports=True)
5526 self.pg1.add_stream(pkts)
5527 self.pg_enable_capture(self.pg_interfaces)
5529 capture = self.pg0.get_capture(len(pkts))
5530 self.verify_capture_in(capture, self.pg0)
5532 pkts = self.create_stream_in(self.pg0, self.pg1)
5533 self.pg0.add_stream(pkts)
5534 self.pg_enable_capture(self.pg_interfaces)
5536 capture = self.pg1.get_capture(len(pkts))
5537 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5540 def test_output_feature_and_service3(self):
5541 """ NAT44 interface output feature and DST NAT """
5542 external_addr = '1.2.3.4'
5546 self.vapi.nat44_forwarding_enable_disable(enable=1)
5547 self.nat44_add_address(self.nat_addr)
5548 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5549 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5550 local_port, external_port,
5551 proto=IP_PROTOS.tcp, flags=flags)
5552 flags = self.config_flags.NAT_IS_INSIDE
5553 self.vapi.nat44_interface_add_del_feature(
5554 sw_if_index=self.pg0.sw_if_index,
5556 self.vapi.nat44_interface_add_del_feature(
5557 sw_if_index=self.pg0.sw_if_index,
5558 flags=flags, is_add=1)
5559 self.vapi.nat44_interface_add_del_output_feature(
5561 sw_if_index=self.pg1.sw_if_index)
5563 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5564 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5565 TCP(sport=12345, dport=external_port))
5566 self.pg0.add_stream(p)
5567 self.pg_enable_capture(self.pg_interfaces)
5569 capture = self.pg1.get_capture(1)
5574 self.assertEqual(ip.src, self.pg0.remote_ip4)
5575 self.assertEqual(tcp.sport, 12345)
5576 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5577 self.assertEqual(tcp.dport, local_port)
5578 self.assert_packet_checksums_valid(p)
5580 self.logger.error(ppp("Unexpected or invalid packet:", p))
5583 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5584 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5585 TCP(sport=local_port, dport=12345))
5586 self.pg1.add_stream(p)
5587 self.pg_enable_capture(self.pg_interfaces)
5589 capture = self.pg0.get_capture(1)
5594 self.assertEqual(ip.src, external_addr)
5595 self.assertEqual(tcp.sport, external_port)
5596 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5597 self.assertEqual(tcp.dport, 12345)
5598 self.assert_packet_checksums_valid(p)
5600 self.logger.error(ppp("Unexpected or invalid packet:", p))
5603 def test_next_src_nat(self):
5604 """ On way back forward packet to nat44-in2out node. """
5605 twice_nat_addr = '10.0.1.3'
5608 post_twice_nat_port = 0
5610 self.vapi.nat44_forwarding_enable_disable(enable=1)
5611 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5612 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5613 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5614 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5615 local_port, external_port,
5616 proto=IP_PROTOS.tcp, vrf_id=1,
5618 self.vapi.nat44_interface_add_del_feature(
5619 sw_if_index=self.pg6.sw_if_index,
5622 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5623 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5624 TCP(sport=12345, dport=external_port))
5625 self.pg6.add_stream(p)
5626 self.pg_enable_capture(self.pg_interfaces)
5628 capture = self.pg6.get_capture(1)
5633 self.assertEqual(ip.src, twice_nat_addr)
5634 self.assertNotEqual(tcp.sport, 12345)
5635 post_twice_nat_port = tcp.sport
5636 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5637 self.assertEqual(tcp.dport, local_port)
5638 self.assert_packet_checksums_valid(p)
5640 self.logger.error(ppp("Unexpected or invalid packet:", p))
5643 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5644 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5645 TCP(sport=local_port, dport=post_twice_nat_port))
5646 self.pg6.add_stream(p)
5647 self.pg_enable_capture(self.pg_interfaces)
5649 capture = self.pg6.get_capture(1)
5654 self.assertEqual(ip.src, self.pg1.remote_ip4)
5655 self.assertEqual(tcp.sport, external_port)
5656 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5657 self.assertEqual(tcp.dport, 12345)
5658 self.assert_packet_checksums_valid(p)
5660 self.logger.error(ppp("Unexpected or invalid packet:", p))
5663 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5665 twice_nat_addr = '10.0.1.3'
5673 port_in1 = port_in + 1
5674 port_in2 = port_in + 2
5679 server1 = self.pg0.remote_hosts[0]
5680 server2 = self.pg0.remote_hosts[1]
5692 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5695 self.nat44_add_address(self.nat_addr)
5696 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5700 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5702 flags |= self.config_flags.NAT_IS_TWICE_NAT
5705 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5707 proto=IP_PROTOS.tcp,
5710 locals = [{'addr': server1.ip4,
5714 {'addr': server2.ip4,
5718 out_addr = self.nat_addr
5720 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5721 external_addr=out_addr,
5722 external_port=port_out,
5723 protocol=IP_PROTOS.tcp,
5724 local_num=len(locals),
5726 flags = self.config_flags.NAT_IS_INSIDE
5727 self.vapi.nat44_interface_add_del_feature(
5728 sw_if_index=pg0.sw_if_index,
5729 flags=flags, is_add=1)
5730 self.vapi.nat44_interface_add_del_feature(
5731 sw_if_index=pg1.sw_if_index,
5738 assert client_id is not None
5740 client = self.pg0.remote_hosts[0]
5741 elif client_id == 2:
5742 client = self.pg0.remote_hosts[1]
5744 client = pg1.remote_hosts[0]
5745 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5746 IP(src=client.ip4, dst=self.nat_addr) /
5747 TCP(sport=eh_port_out, dport=port_out))
5749 self.pg_enable_capture(self.pg_interfaces)
5751 capture = pg0.get_capture(1)
5757 if ip.dst == server1.ip4:
5763 self.assertEqual(ip.dst, server.ip4)
5765 self.assertIn(tcp.dport, [port_in1, port_in2])
5767 self.assertEqual(tcp.dport, port_in)
5769 self.assertEqual(ip.src, twice_nat_addr)
5770 self.assertNotEqual(tcp.sport, eh_port_out)
5772 self.assertEqual(ip.src, client.ip4)
5773 self.assertEqual(tcp.sport, eh_port_out)
5775 eh_port_in = tcp.sport
5776 saved_port_in = tcp.dport
5777 self.assert_packet_checksums_valid(p)
5779 self.logger.error(ppp("Unexpected or invalid packet:", p))
5782 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5783 IP(src=server.ip4, dst=eh_addr_in) /
5784 TCP(sport=saved_port_in, dport=eh_port_in))
5786 self.pg_enable_capture(self.pg_interfaces)
5788 capture = pg1.get_capture(1)
5793 self.assertEqual(ip.dst, client.ip4)
5794 self.assertEqual(ip.src, self.nat_addr)
5795 self.assertEqual(tcp.dport, eh_port_out)
5796 self.assertEqual(tcp.sport, port_out)
5797 self.assert_packet_checksums_valid(p)
5799 self.logger.error(ppp("Unexpected or invalid packet:", p))
5803 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5804 self.assertEqual(len(sessions), 1)
5805 self.assertTrue(sessions[0].flags &
5806 self.config_flags.NAT_IS_EXT_HOST_VALID)
5807 self.assertTrue(sessions[0].flags &
5808 self.config_flags.NAT_IS_TWICE_NAT)
5809 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5810 self.vapi.nat44_del_session(
5811 address=sessions[0].inside_ip_address,
5812 port=sessions[0].inside_port,
5813 protocol=sessions[0].protocol,
5814 flags=(self.config_flags.NAT_IS_INSIDE |
5815 self.config_flags.NAT_IS_EXT_HOST_VALID),
5816 ext_host_address=sessions[0].ext_host_nat_address,
5817 ext_host_port=sessions[0].ext_host_nat_port)
5818 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5819 self.assertEqual(len(sessions), 0)
5821 def test_twice_nat(self):
5823 self.twice_nat_common()
5825 def test_self_twice_nat_positive(self):
5826 """ Self Twice NAT44 (positive test) """
5827 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5829 def test_self_twice_nat_negative(self):
5830 """ Self Twice NAT44 (negative test) """
5831 self.twice_nat_common(self_twice_nat=True)
5833 def test_twice_nat_lb(self):
5834 """ Twice NAT44 local service load balancing """
5835 self.twice_nat_common(lb=True)
5837 def test_self_twice_nat_lb_positive(self):
5838 """ Self Twice NAT44 local service load balancing (positive test) """
5839 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5842 def test_self_twice_nat_lb_negative(self):
5843 """ Self Twice NAT44 local service load balancing (negative test) """
5844 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5847 def test_twice_nat_interface_addr(self):
5848 """ Acquire twice NAT44 addresses from interface """
5849 flags = self.config_flags.NAT_IS_TWICE_NAT
5850 self.vapi.nat44_add_del_interface_addr(
5852 sw_if_index=self.pg3.sw_if_index,
5855 # no address in NAT pool
5856 adresses = self.vapi.nat44_address_dump()
5857 self.assertEqual(0, len(adresses))
5859 # configure interface address and check NAT address pool
5860 self.pg3.config_ip4()
5861 adresses = self.vapi.nat44_address_dump()
5862 self.assertEqual(1, len(adresses))
5863 self.assertEqual(str(adresses[0].ip_address),
5865 self.assertEqual(adresses[0].flags, flags)
5867 # remove interface address and check NAT address pool
5868 self.pg3.unconfig_ip4()
5869 adresses = self.vapi.nat44_address_dump()
5870 self.assertEqual(0, len(adresses))
5872 def test_tcp_close(self):
5873 """ Close TCP session from inside network - output feature """
5874 self.vapi.nat44_forwarding_enable_disable(enable=1)
5875 self.nat44_add_address(self.pg1.local_ip4)
5876 twice_nat_addr = '10.0.1.3'
5877 service_ip = '192.168.16.150'
5878 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5879 flags = self.config_flags.NAT_IS_INSIDE
5880 self.vapi.nat44_interface_add_del_feature(
5881 sw_if_index=self.pg0.sw_if_index,
5883 self.vapi.nat44_interface_add_del_feature(
5884 sw_if_index=self.pg0.sw_if_index,
5885 flags=flags, is_add=1)
5886 self.vapi.nat44_interface_add_del_output_feature(
5888 sw_if_index=self.pg1.sw_if_index)
5889 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5890 self.config_flags.NAT_IS_TWICE_NAT)
5891 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5895 proto=IP_PROTOS.tcp,
5897 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5898 start_sessnum = len(sessions)
5900 # SYN packet out->in
5901 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5902 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5903 TCP(sport=33898, dport=80, flags="S"))
5904 self.pg1.add_stream(p)
5905 self.pg_enable_capture(self.pg_interfaces)
5907 capture = self.pg0.get_capture(1)
5909 tcp_port = p[TCP].sport
5911 # SYN + ACK packet in->out
5912 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5913 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5914 TCP(sport=80, dport=tcp_port, flags="SA"))
5915 self.pg0.add_stream(p)
5916 self.pg_enable_capture(self.pg_interfaces)
5918 self.pg1.get_capture(1)
5920 # ACK packet out->in
5921 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5922 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5923 TCP(sport=33898, dport=80, flags="A"))
5924 self.pg1.add_stream(p)
5925 self.pg_enable_capture(self.pg_interfaces)
5927 self.pg0.get_capture(1)
5929 # FIN packet in -> out
5930 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5931 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5932 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5933 self.pg0.add_stream(p)
5934 self.pg_enable_capture(self.pg_interfaces)
5936 self.pg1.get_capture(1)
5938 # FIN+ACK packet out -> in
5939 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5940 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5941 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5942 self.pg1.add_stream(p)
5943 self.pg_enable_capture(self.pg_interfaces)
5945 self.pg0.get_capture(1)
5947 # ACK packet in -> out
5948 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5949 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5950 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5951 self.pg0.add_stream(p)
5952 self.pg_enable_capture(self.pg_interfaces)
5954 self.pg1.get_capture(1)
5956 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5958 self.assertEqual(len(sessions) - start_sessnum, 0)
5960 def test_tcp_session_close_in(self):
5961 """ Close TCP session from inside network """
5962 self.tcp_port_out = 10505
5963 self.nat44_add_address(self.nat_addr)
5964 flags = self.config_flags.NAT_IS_TWICE_NAT
5965 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5969 proto=IP_PROTOS.tcp,
5971 flags = self.config_flags.NAT_IS_INSIDE
5972 self.vapi.nat44_interface_add_del_feature(
5973 sw_if_index=self.pg0.sw_if_index,
5974 flags=flags, is_add=1)
5975 self.vapi.nat44_interface_add_del_feature(
5976 sw_if_index=self.pg1.sw_if_index,
5979 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5980 start_sessnum = len(sessions)
5982 self.initiate_tcp_session(self.pg0, self.pg1)
5984 # FIN packet in -> out
5985 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5986 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5987 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5988 flags="FA", seq=100, ack=300))
5989 self.pg0.add_stream(p)
5990 self.pg_enable_capture(self.pg_interfaces)
5992 self.pg1.get_capture(1)
5996 # ACK packet out -> in
5997 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5998 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5999 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6000 flags="A", seq=300, ack=101))
6003 # FIN packet out -> in
6004 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6005 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6006 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6007 flags="FA", seq=300, ack=101))
6010 self.pg1.add_stream(pkts)
6011 self.pg_enable_capture(self.pg_interfaces)
6013 self.pg0.get_capture(2)
6015 # ACK packet in -> out
6016 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6017 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6018 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6019 flags="A", seq=101, ack=301))
6020 self.pg0.add_stream(p)
6021 self.pg_enable_capture(self.pg_interfaces)
6023 self.pg1.get_capture(1)
6025 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6027 self.assertEqual(len(sessions) - start_sessnum, 0)
6029 def test_tcp_session_close_out(self):
6030 """ Close TCP session from outside network """
6031 self.tcp_port_out = 10505
6032 self.nat44_add_address(self.nat_addr)
6033 flags = self.config_flags.NAT_IS_TWICE_NAT
6034 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6038 proto=IP_PROTOS.tcp,
6040 flags = self.config_flags.NAT_IS_INSIDE
6041 self.vapi.nat44_interface_add_del_feature(
6042 sw_if_index=self.pg0.sw_if_index,
6043 flags=flags, is_add=1)
6044 self.vapi.nat44_interface_add_del_feature(
6045 sw_if_index=self.pg1.sw_if_index,
6048 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6049 start_sessnum = len(sessions)
6051 self.initiate_tcp_session(self.pg0, self.pg1)
6053 # FIN packet out -> in
6054 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6055 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6056 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6057 flags="FA", seq=100, ack=300))
6058 self.pg1.add_stream(p)
6059 self.pg_enable_capture(self.pg_interfaces)
6061 self.pg0.get_capture(1)
6063 # FIN+ACK packet in -> out
6064 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6065 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6066 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6067 flags="FA", seq=300, ack=101))
6069 self.pg0.add_stream(p)
6070 self.pg_enable_capture(self.pg_interfaces)
6072 self.pg1.get_capture(1)
6074 # ACK packet out -> in
6075 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6076 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6077 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6078 flags="A", seq=101, ack=301))
6079 self.pg1.add_stream(p)
6080 self.pg_enable_capture(self.pg_interfaces)
6082 self.pg0.get_capture(1)
6084 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6086 self.assertEqual(len(sessions) - start_sessnum, 0)
6088 def test_tcp_session_close_simultaneous(self):
6089 """ Close TCP session from inside network """
6090 self.tcp_port_out = 10505
6091 self.nat44_add_address(self.nat_addr)
6092 flags = self.config_flags.NAT_IS_TWICE_NAT
6093 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6097 proto=IP_PROTOS.tcp,
6099 flags = self.config_flags.NAT_IS_INSIDE
6100 self.vapi.nat44_interface_add_del_feature(
6101 sw_if_index=self.pg0.sw_if_index,
6102 flags=flags, is_add=1)
6103 self.vapi.nat44_interface_add_del_feature(
6104 sw_if_index=self.pg1.sw_if_index,
6107 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6108 start_sessnum = len(sessions)
6110 self.initiate_tcp_session(self.pg0, self.pg1)
6112 # FIN packet in -> out
6113 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6114 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6115 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6116 flags="FA", seq=100, ack=300))
6117 self.pg0.add_stream(p)
6118 self.pg_enable_capture(self.pg_interfaces)
6120 self.pg1.get_capture(1)
6122 # FIN packet out -> in
6123 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6124 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6125 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6126 flags="FA", seq=300, ack=100))
6127 self.pg1.add_stream(p)
6128 self.pg_enable_capture(self.pg_interfaces)
6130 self.pg0.get_capture(1)
6132 # ACK packet in -> out
6133 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6134 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6135 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6136 flags="A", seq=101, ack=301))
6137 self.pg0.add_stream(p)
6138 self.pg_enable_capture(self.pg_interfaces)
6140 self.pg1.get_capture(1)
6142 # ACK packet out -> in
6143 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6144 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6145 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6146 flags="A", seq=301, ack=101))
6147 self.pg1.add_stream(p)
6148 self.pg_enable_capture(self.pg_interfaces)
6150 self.pg0.get_capture(1)
6152 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6154 self.assertEqual(len(sessions) - start_sessnum, 0)
6156 def test_one_armed_nat44_static(self):
6157 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6158 remote_host = self.pg4.remote_hosts[0]
6159 local_host = self.pg4.remote_hosts[1]
6164 self.vapi.nat44_forwarding_enable_disable(enable=1)
6165 self.nat44_add_address(self.nat_addr, twice_nat=1)
6166 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6167 self.config_flags.NAT_IS_TWICE_NAT)
6168 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6169 local_port, external_port,
6170 proto=IP_PROTOS.tcp, flags=flags)
6171 flags = self.config_flags.NAT_IS_INSIDE
6172 self.vapi.nat44_interface_add_del_feature(
6173 sw_if_index=self.pg4.sw_if_index,
6175 self.vapi.nat44_interface_add_del_feature(
6176 sw_if_index=self.pg4.sw_if_index,
6177 flags=flags, is_add=1)
6179 # from client to service
6180 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6181 IP(src=remote_host.ip4, dst=self.nat_addr) /
6182 TCP(sport=12345, dport=external_port))
6183 self.pg4.add_stream(p)
6184 self.pg_enable_capture(self.pg_interfaces)
6186 capture = self.pg4.get_capture(1)
6191 self.assertEqual(ip.dst, local_host.ip4)
6192 self.assertEqual(ip.src, self.nat_addr)
6193 self.assertEqual(tcp.dport, local_port)
6194 self.assertNotEqual(tcp.sport, 12345)
6195 eh_port_in = tcp.sport
6196 self.assert_packet_checksums_valid(p)
6198 self.logger.error(ppp("Unexpected or invalid packet:", p))
6201 # from service back to client
6202 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6203 IP(src=local_host.ip4, dst=self.nat_addr) /
6204 TCP(sport=local_port, dport=eh_port_in))
6205 self.pg4.add_stream(p)
6206 self.pg_enable_capture(self.pg_interfaces)
6208 capture = self.pg4.get_capture(1)
6213 self.assertEqual(ip.src, self.nat_addr)
6214 self.assertEqual(ip.dst, remote_host.ip4)
6215 self.assertEqual(tcp.sport, external_port)
6216 self.assertEqual(tcp.dport, 12345)
6217 self.assert_packet_checksums_valid(p)
6219 self.logger.error(ppp("Unexpected or invalid packet:", p))
6222 def test_static_with_port_out2(self):
6223 """ 1:1 NAPT asymmetrical rule """
6228 self.vapi.nat44_forwarding_enable_disable(enable=1)
6229 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6230 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6231 local_port, external_port,
6232 proto=IP_PROTOS.tcp, flags=flags)
6233 flags = self.config_flags.NAT_IS_INSIDE
6234 self.vapi.nat44_interface_add_del_feature(
6235 sw_if_index=self.pg0.sw_if_index,
6236 flags=flags, is_add=1)
6237 self.vapi.nat44_interface_add_del_feature(
6238 sw_if_index=self.pg1.sw_if_index,
6241 # from client to service
6242 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6243 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6244 TCP(sport=12345, dport=external_port))
6245 self.pg1.add_stream(p)
6246 self.pg_enable_capture(self.pg_interfaces)
6248 capture = self.pg0.get_capture(1)
6253 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6254 self.assertEqual(tcp.dport, local_port)
6255 self.assert_packet_checksums_valid(p)
6257 self.logger.error(ppp("Unexpected or invalid packet:", p))
6261 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6262 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6263 ICMP(type=11) / capture[0][IP])
6264 self.pg0.add_stream(p)
6265 self.pg_enable_capture(self.pg_interfaces)
6267 capture = self.pg1.get_capture(1)
6270 self.assertEqual(p[IP].src, self.nat_addr)
6272 self.assertEqual(inner.dst, self.nat_addr)
6273 self.assertEqual(inner[TCPerror].dport, external_port)
6275 self.logger.error(ppp("Unexpected or invalid packet:", p))
6278 # from service back to client
6279 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6280 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6281 TCP(sport=local_port, dport=12345))
6282 self.pg0.add_stream(p)
6283 self.pg_enable_capture(self.pg_interfaces)
6285 capture = self.pg1.get_capture(1)
6290 self.assertEqual(ip.src, self.nat_addr)
6291 self.assertEqual(tcp.sport, external_port)
6292 self.assert_packet_checksums_valid(p)
6294 self.logger.error(ppp("Unexpected or invalid packet:", p))
6298 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6299 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6300 ICMP(type=11) / capture[0][IP])
6301 self.pg1.add_stream(p)
6302 self.pg_enable_capture(self.pg_interfaces)
6304 capture = self.pg0.get_capture(1)
6307 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6309 self.assertEqual(inner.src, self.pg0.remote_ip4)
6310 self.assertEqual(inner[TCPerror].sport, local_port)
6312 self.logger.error(ppp("Unexpected or invalid packet:", p))
6315 # from client to server (no translation)
6316 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6317 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6318 TCP(sport=12346, dport=local_port))
6319 self.pg1.add_stream(p)
6320 self.pg_enable_capture(self.pg_interfaces)
6322 capture = self.pg0.get_capture(1)
6327 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6328 self.assertEqual(tcp.dport, local_port)
6329 self.assert_packet_checksums_valid(p)
6331 self.logger.error(ppp("Unexpected or invalid packet:", p))
6334 # from service back to client (no translation)
6335 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6336 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6337 TCP(sport=local_port, dport=12346))
6338 self.pg0.add_stream(p)
6339 self.pg_enable_capture(self.pg_interfaces)
6341 capture = self.pg1.get_capture(1)
6346 self.assertEqual(ip.src, self.pg0.remote_ip4)
6347 self.assertEqual(tcp.sport, local_port)
6348 self.assert_packet_checksums_valid(p)
6350 self.logger.error(ppp("Unexpected or invalid packet:", p))
6353 def test_output_feature(self):
6354 """ NAT44 interface output feature (in2out postrouting) """
6355 self.vapi.nat44_forwarding_enable_disable(enable=1)
6356 self.nat44_add_address(self.nat_addr)
6357 self.vapi.nat44_interface_add_del_feature(
6358 sw_if_index=self.pg0.sw_if_index,
6360 self.vapi.nat44_interface_add_del_output_feature(
6362 sw_if_index=self.pg1.sw_if_index)
6365 pkts = self.create_stream_in(self.pg0, self.pg1)
6366 self.pg0.add_stream(pkts)
6367 self.pg_enable_capture(self.pg_interfaces)
6369 capture = self.pg1.get_capture(len(pkts))
6370 self.verify_capture_out(capture)
6373 pkts = self.create_stream_out(self.pg1)
6374 self.pg1.add_stream(pkts)
6375 self.pg_enable_capture(self.pg_interfaces)
6377 capture = self.pg0.get_capture(len(pkts))
6378 self.verify_capture_in(capture, self.pg0)
6380 def test_output_feature_stateful_acl(self):
6381 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6382 self.nat44_add_address(self.nat_addr)
6383 self.vapi.nat44_interface_add_del_output_feature(
6384 sw_if_index=self.pg0.sw_if_index,
6385 flags=self.config_flags.NAT_IS_INSIDE,
6387 self.vapi.nat44_interface_add_del_output_feature(
6388 sw_if_index=self.pg1.sw_if_index,
6389 flags=self.config_flags.NAT_IS_OUTSIDE,
6392 # First ensure that the NAT is working sans ACL
6394 # send packets out2in, no sessions yet so packets should drop
6395 pkts_out2in = self.create_stream_out(self.pg1)
6396 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6398 # send packets into inside intf, ensure received via outside intf
6399 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6400 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6402 self.verify_capture_out(capture)
6404 # send out2in again, with sessions created it should work now
6405 pkts_out2in = self.create_stream_out(self.pg1)
6406 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6408 self.verify_capture_in(capture, self.pg0)
6410 # Create an ACL blocking everything
6411 out2in_deny_rule = {
6414 'src_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6415 'src_ip_prefix_len': 0,
6416 'dst_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6417 'dst_ip_prefix_len': 0,
6418 'srcport_or_icmptype_first': 0,
6419 'srcport_or_icmptype_last': 65535,
6420 'dstport_or_icmpcode_first': 0,
6421 'dstport_or_icmpcode_last': 65535,
6424 out2in_rules = [out2in_deny_rule]
6425 res = self.vapi.acl_add_replace(0xffffffff, out2in_rules)
6426 self.assertEqual(res.retval, 0, "error adding out2in ACL")
6427 out2in_acl = res.acl_index
6429 # apply as input acl on interface and confirm it blocks everything
6430 self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
6433 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6435 # create an ACL to permit/reflect everything
6436 in2out_reflect_rule = {
6439 'src_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6440 'src_ip_prefix_len': 0,
6441 'dst_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6442 'dst_ip_prefix_len': 0,
6443 'srcport_or_icmptype_first': 0,
6444 'srcport_or_icmptype_last': 65535,
6445 'dstport_or_icmpcode_first': 0,
6446 'dstport_or_icmpcode_last': 65535,
6449 in2out_rules = [in2out_reflect_rule]
6450 res = self.vapi.acl_add_replace(0xffffffff, in2out_rules)
6451 self.assertEqual(res.retval, 0, "error adding in2out ACL")
6452 in2out_acl = res.acl_index
6455 self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
6457 acls=[out2in_acl, in2out_acl])
6458 # send in2out to generate ACL state (NAT state was created earlier)
6459 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6461 self.verify_capture_out(capture)
6463 # send out2in again. ACL state exists so it should work now.
6464 # TCP packets with the syn flag set also need the ack flag
6465 for p in pkts_out2in:
6466 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6467 p[TCP].flags |= 0x10
6468 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6470 self.verify_capture_in(capture, self.pg0)
6471 self.logger.info(self.vapi.cli("show trace"))
6474 # Remove ACLs from interface
6475 self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
6479 self.vapi.acl_del(acl_index=out2in_acl, expected_retval=0)
6480 self.vapi.acl_del(acl_index=in2out_acl, expected_retval=0)
6482 def test_multiple_vrf(self):
6483 """ Multiple VRF setup """
6484 external_addr = '1.2.3.4'
6489 self.vapi.nat44_forwarding_enable_disable(enable=1)
6490 self.nat44_add_address(self.nat_addr)
6491 flags = self.config_flags.NAT_IS_INSIDE
6492 self.vapi.nat44_interface_add_del_feature(
6493 sw_if_index=self.pg0.sw_if_index,
6495 self.vapi.nat44_interface_add_del_feature(
6496 sw_if_index=self.pg0.sw_if_index,
6497 flags=flags, is_add=1)
6498 self.vapi.nat44_interface_add_del_output_feature(
6500 sw_if_index=self.pg1.sw_if_index)
6501 self.vapi.nat44_interface_add_del_feature(
6502 sw_if_index=self.pg5.sw_if_index,
6504 self.vapi.nat44_interface_add_del_feature(
6505 sw_if_index=self.pg5.sw_if_index,
6506 flags=flags, is_add=1)
6507 self.vapi.nat44_interface_add_del_feature(
6508 sw_if_index=self.pg6.sw_if_index,
6510 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6511 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6512 local_port, external_port, vrf_id=1,
6513 proto=IP_PROTOS.tcp, flags=flags)
6514 self.nat44_add_static_mapping(
6515 self.pg0.remote_ip4,
6516 external_sw_if_index=self.pg0.sw_if_index,
6517 local_port=local_port,
6519 external_port=external_port,
6520 proto=IP_PROTOS.tcp,
6524 # from client to service (both VRF1)
6525 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6526 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6527 TCP(sport=12345, dport=external_port))
6528 self.pg6.add_stream(p)
6529 self.pg_enable_capture(self.pg_interfaces)
6531 capture = self.pg5.get_capture(1)
6536 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6537 self.assertEqual(tcp.dport, local_port)
6538 self.assert_packet_checksums_valid(p)
6540 self.logger.error(ppp("Unexpected or invalid packet:", p))
6543 # from service back to client (both VRF1)
6544 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6545 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6546 TCP(sport=local_port, dport=12345))
6547 self.pg5.add_stream(p)
6548 self.pg_enable_capture(self.pg_interfaces)
6550 capture = self.pg6.get_capture(1)
6555 self.assertEqual(ip.src, external_addr)
6556 self.assertEqual(tcp.sport, external_port)
6557 self.assert_packet_checksums_valid(p)
6559 self.logger.error(ppp("Unexpected or invalid packet:", p))
6562 # dynamic NAT from VRF1 to VRF0 (output-feature)
6563 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6564 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6565 TCP(sport=2345, dport=22))
6566 self.pg5.add_stream(p)
6567 self.pg_enable_capture(self.pg_interfaces)
6569 capture = self.pg1.get_capture(1)
6574 self.assertEqual(ip.src, self.nat_addr)
6575 self.assertNotEqual(tcp.sport, 2345)
6576 self.assert_packet_checksums_valid(p)
6579 self.logger.error(ppp("Unexpected or invalid packet:", p))
6582 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6583 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6584 TCP(sport=22, dport=port))
6585 self.pg1.add_stream(p)
6586 self.pg_enable_capture(self.pg_interfaces)
6588 capture = self.pg5.get_capture(1)
6593 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6594 self.assertEqual(tcp.dport, 2345)
6595 self.assert_packet_checksums_valid(p)
6597 self.logger.error(ppp("Unexpected or invalid packet:", p))
6600 # from client VRF1 to service VRF0
6601 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6602 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6603 TCP(sport=12346, dport=external_port))
6604 self.pg6.add_stream(p)
6605 self.pg_enable_capture(self.pg_interfaces)
6607 capture = self.pg0.get_capture(1)
6612 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6613 self.assertEqual(tcp.dport, local_port)
6614 self.assert_packet_checksums_valid(p)
6616 self.logger.error(ppp("Unexpected or invalid packet:", p))
6619 # from service VRF0 back to client VRF1
6620 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6621 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6622 TCP(sport=local_port, dport=12346))
6623 self.pg0.add_stream(p)
6624 self.pg_enable_capture(self.pg_interfaces)
6626 capture = self.pg6.get_capture(1)
6631 self.assertEqual(ip.src, self.pg0.local_ip4)
6632 self.assertEqual(tcp.sport, external_port)
6633 self.assert_packet_checksums_valid(p)
6635 self.logger.error(ppp("Unexpected or invalid packet:", p))
6638 # from client VRF0 to service VRF1
6639 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6640 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6641 TCP(sport=12347, dport=external_port))
6642 self.pg0.add_stream(p)
6643 self.pg_enable_capture(self.pg_interfaces)
6645 capture = self.pg5.get_capture(1)
6650 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6651 self.assertEqual(tcp.dport, local_port)
6652 self.assert_packet_checksums_valid(p)
6654 self.logger.error(ppp("Unexpected or invalid packet:", p))
6657 # from service VRF1 back to client VRF0
6658 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6659 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6660 TCP(sport=local_port, dport=12347))
6661 self.pg5.add_stream(p)
6662 self.pg_enable_capture(self.pg_interfaces)
6664 capture = self.pg0.get_capture(1)
6669 self.assertEqual(ip.src, external_addr)
6670 self.assertEqual(tcp.sport, external_port)
6671 self.assert_packet_checksums_valid(p)
6673 self.logger.error(ppp("Unexpected or invalid packet:", p))
6676 # from client to server (both VRF1, no translation)
6677 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6678 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6679 TCP(sport=12348, dport=local_port))
6680 self.pg6.add_stream(p)
6681 self.pg_enable_capture(self.pg_interfaces)
6683 capture = self.pg5.get_capture(1)
6688 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6689 self.assertEqual(tcp.dport, local_port)
6690 self.assert_packet_checksums_valid(p)
6692 self.logger.error(ppp("Unexpected or invalid packet:", p))
6695 # from server back to client (both VRF1, no translation)
6696 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6697 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6698 TCP(sport=local_port, dport=12348))
6699 self.pg5.add_stream(p)
6700 self.pg_enable_capture(self.pg_interfaces)
6702 capture = self.pg6.get_capture(1)
6707 self.assertEqual(ip.src, self.pg5.remote_ip4)
6708 self.assertEqual(tcp.sport, local_port)
6709 self.assert_packet_checksums_valid(p)
6711 self.logger.error(ppp("Unexpected or invalid packet:", p))
6714 # from client VRF1 to server VRF0 (no translation)
6715 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6716 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6717 TCP(sport=local_port, dport=12349))
6718 self.pg0.add_stream(p)
6719 self.pg_enable_capture(self.pg_interfaces)
6721 capture = self.pg6.get_capture(1)
6726 self.assertEqual(ip.src, self.pg0.remote_ip4)
6727 self.assertEqual(tcp.sport, local_port)
6728 self.assert_packet_checksums_valid(p)
6730 self.logger.error(ppp("Unexpected or invalid packet:", p))
6733 # from server VRF0 back to client VRF1 (no translation)
6734 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6735 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6736 TCP(sport=local_port, dport=12349))
6737 self.pg0.add_stream(p)
6738 self.pg_enable_capture(self.pg_interfaces)
6740 capture = self.pg6.get_capture(1)
6745 self.assertEqual(ip.src, self.pg0.remote_ip4)
6746 self.assertEqual(tcp.sport, local_port)
6747 self.assert_packet_checksums_valid(p)
6749 self.logger.error(ppp("Unexpected or invalid packet:", p))
6752 # from client VRF0 to server VRF1 (no translation)
6753 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6754 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6755 TCP(sport=12344, dport=local_port))
6756 self.pg0.add_stream(p)
6757 self.pg_enable_capture(self.pg_interfaces)
6759 capture = self.pg5.get_capture(1)
6764 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6765 self.assertEqual(tcp.dport, local_port)
6766 self.assert_packet_checksums_valid(p)
6768 self.logger.error(ppp("Unexpected or invalid packet:", p))
6771 # from server VRF1 back to client VRF0 (no translation)
6772 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6773 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6774 TCP(sport=local_port, dport=12344))
6775 self.pg5.add_stream(p)
6776 self.pg_enable_capture(self.pg_interfaces)
6778 capture = self.pg0.get_capture(1)
6783 self.assertEqual(ip.src, self.pg5.remote_ip4)
6784 self.assertEqual(tcp.sport, local_port)
6785 self.assert_packet_checksums_valid(p)
6787 self.logger.error(ppp("Unexpected or invalid packet:", p))
6790 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6791 def test_session_timeout(self):
6792 """ NAT44 session timeouts """
6793 self.nat44_add_address(self.nat_addr)
6794 flags = self.config_flags.NAT_IS_INSIDE
6795 self.vapi.nat44_interface_add_del_feature(
6796 sw_if_index=self.pg0.sw_if_index,
6797 flags=flags, is_add=1)
6798 self.vapi.nat44_interface_add_del_feature(
6799 sw_if_index=self.pg1.sw_if_index,
6801 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6802 tcp_transitory=240, icmp=5)
6806 for i in range(0, max_sessions):
6807 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6808 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6809 IP(src=src, dst=self.pg1.remote_ip4) /
6810 ICMP(id=1025, type='echo-request'))
6812 self.pg0.add_stream(pkts)
6813 self.pg_enable_capture(self.pg_interfaces)
6815 self.pg1.get_capture(max_sessions)
6820 for i in range(0, max_sessions):
6821 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6822 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6823 IP(src=src, dst=self.pg1.remote_ip4) /
6824 ICMP(id=1026, type='echo-request'))
6826 self.pg0.add_stream(pkts)
6827 self.pg_enable_capture(self.pg_interfaces)
6829 self.pg1.get_capture(max_sessions)
6832 users = self.vapi.nat44_user_dump()
6834 nsessions = nsessions + user.nsessions
6835 self.assertLess(nsessions, 2 * max_sessions)
6837 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6838 def test_session_rst_timeout(self):
6839 """ NAT44 session RST timeouts """
6840 self.nat44_add_address(self.nat_addr)
6841 flags = self.config_flags.NAT_IS_INSIDE
6842 self.vapi.nat44_interface_add_del_feature(
6843 sw_if_index=self.pg0.sw_if_index,
6844 flags=flags, is_add=1)
6845 self.vapi.nat44_interface_add_del_feature(
6846 sw_if_index=self.pg1.sw_if_index,
6848 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6849 tcp_transitory=5, icmp=60)
6851 self.initiate_tcp_session(self.pg0, self.pg1)
6852 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6853 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6854 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6856 self.pg0.add_stream(p)
6857 self.pg_enable_capture(self.pg_interfaces)
6859 self.pg1.get_capture(1)
6863 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6864 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6865 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6867 self.pg0.add_stream(p)
6868 self.pg_enable_capture(self.pg_interfaces)
6870 self.pg1.get_capture(1)
6873 users = self.vapi.nat44_user_dump()
6874 self.assertEqual(len(users), 1)
6875 self.assertEqual(str(users[0].ip_address),
6876 self.pg0.remote_ip4)
6877 self.assertEqual(users[0].nsessions, 1)
6879 def test_syslog_sess(self):
6880 """ Test syslog session creation and deletion """
6881 self.vapi.syslog_set_filter(
6882 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6883 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6884 self.nat44_add_address(self.nat_addr)
6885 flags = self.config_flags.NAT_IS_INSIDE
6886 self.vapi.nat44_interface_add_del_feature(
6887 sw_if_index=self.pg0.sw_if_index,
6888 flags=flags, is_add=1)
6889 self.vapi.nat44_interface_add_del_feature(
6890 sw_if_index=self.pg1.sw_if_index,
6893 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6894 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6895 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6896 self.pg0.add_stream(p)
6897 self.pg_enable_capture(self.pg_interfaces)
6899 capture = self.pg1.get_capture(1)
6900 self.tcp_port_out = capture[0][TCP].sport
6901 capture = self.pg2.get_capture(1)
6902 self.verify_syslog_sess(capture[0][Raw].load)
6904 self.pg_enable_capture(self.pg_interfaces)
6906 self.nat44_add_address(self.nat_addr, is_add=0)
6907 capture = self.pg2.get_capture(1)
6908 self.verify_syslog_sess(capture[0][Raw].load, False)
6911 super(TestNAT44EndpointDependent, self).tearDown()
6912 if not self.vpp_dead:
6914 self.vapi.cli("clear logging")
6916 def show_commands_at_teardown(self):
6917 self.logger.info(self.vapi.cli("show nat44 addresses"))
6918 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6919 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6920 self.logger.info(self.vapi.cli("show nat44 interface address"))
6921 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6922 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6923 self.logger.info(self.vapi.cli("show nat timeouts"))
6926 class TestNAT44Out2InDPO(MethodHolder):
6927 """ NAT44 Test Cases using out2in DPO """
6930 def setUpConstants(cls):
6931 super(TestNAT44Out2InDPO, cls).setUpConstants()
6932 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6935 def setUpClass(cls):
6936 super(TestNAT44Out2InDPO, cls).setUpClass()
6937 cls.vapi.cli("set log class nat level debug")
6939 cls.tcp_port_in = 6303
6940 cls.tcp_port_out = 6303
6941 cls.udp_port_in = 6304
6942 cls.udp_port_out = 6304
6943 cls.icmp_id_in = 6305
6944 cls.icmp_id_out = 6305
6945 cls.nat_addr = '10.0.0.3'
6946 cls.dst_ip4 = '192.168.70.1'
6948 cls.create_pg_interfaces(range(2))
6951 cls.pg0.config_ip4()
6952 cls.pg0.resolve_arp()
6955 cls.pg1.config_ip6()
6956 cls.pg1.resolve_ndp()
6958 r1 = VppIpRoute(cls, "::", 0,
6959 [VppRoutePath(cls.pg1.remote_ip6,
6960 cls.pg1.sw_if_index)],
6965 def tearDownClass(cls):
6966 super(TestNAT44Out2InDPO, cls).tearDownClass()
6968 def configure_xlat(self):
6969 self.dst_ip6_pfx = '1:2:3::'
6970 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6972 self.dst_ip6_pfx_len = 96
6973 self.src_ip6_pfx = '4:5:6::'
6974 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6976 self.src_ip6_pfx_len = 96
6977 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6978 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6979 '\x00\x00\x00\x00', 0)
6981 @unittest.skip('Temporary disabled')
6982 def test_464xlat_ce(self):
6983 """ Test 464XLAT CE with NAT44 """
6985 nat_config = self.vapi.nat_show_config()
6986 self.assertEqual(1, nat_config.out2in_dpo)
6988 self.configure_xlat()
6990 flags = self.config_flags.NAT_IS_INSIDE
6991 self.vapi.nat44_interface_add_del_feature(
6992 sw_if_index=self.pg0.sw_if_index,
6993 flags=flags, is_add=1)
6994 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6995 last_ip_address=self.nat_addr_n,
6996 vrf_id=0xFFFFFFFF, is_add=1)
6998 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6999 self.dst_ip6_pfx_len)
7000 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7001 self.src_ip6_pfx_len)
7004 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7005 self.pg0.add_stream(pkts)
7006 self.pg_enable_capture(self.pg_interfaces)
7008 capture = self.pg1.get_capture(len(pkts))
7009 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7012 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7014 self.pg1.add_stream(pkts)
7015 self.pg_enable_capture(self.pg_interfaces)
7017 capture = self.pg0.get_capture(len(pkts))
7018 self.verify_capture_in(capture, self.pg0)
7020 self.vapi.nat44_interface_add_del_feature(
7021 sw_if_index=self.pg0.sw_if_index,
7023 self.vapi.nat44_add_del_address_range(
7024 first_ip_address=self.nat_addr_n,
7025 last_ip_address=self.nat_addr_n,
7028 @unittest.skip('Temporary disabled')
7029 def test_464xlat_ce_no_nat(self):
7030 """ Test 464XLAT CE without NAT44 """
7032 self.configure_xlat()
7034 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7035 self.dst_ip6_pfx_len)
7036 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7037 self.src_ip6_pfx_len)
7039 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7040 self.pg0.add_stream(pkts)
7041 self.pg_enable_capture(self.pg_interfaces)
7043 capture = self.pg1.get_capture(len(pkts))
7044 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7045 nat_ip=out_dst_ip6, same_port=True)
7047 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7048 self.pg1.add_stream(pkts)
7049 self.pg_enable_capture(self.pg_interfaces)
7051 capture = self.pg0.get_capture(len(pkts))
7052 self.verify_capture_in(capture, self.pg0)
7055 class TestDeterministicNAT(MethodHolder):
7056 """ Deterministic NAT Test Cases """
7059 def setUpConstants(cls):
7060 super(TestDeterministicNAT, cls).setUpConstants()
7061 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7064 def setUpClass(cls):
7065 super(TestDeterministicNAT, cls).setUpClass()
7066 cls.vapi.cli("set log class nat level debug")
7068 cls.tcp_port_in = 6303
7069 cls.tcp_external_port = 6303
7070 cls.udp_port_in = 6304
7071 cls.udp_external_port = 6304
7072 cls.icmp_id_in = 6305
7073 cls.nat_addr = '10.0.0.3'
7075 cls.create_pg_interfaces(range(3))
7076 cls.interfaces = list(cls.pg_interfaces)
7078 for i in cls.interfaces:
7083 cls.pg0.generate_remote_hosts(2)
7084 cls.pg0.configure_ipv4_neighbors()
7087 def tearDownClass(cls):
7088 super(TestDeterministicNAT, cls).tearDownClass()
7090 def create_stream_in(self, in_if, out_if, ttl=64):
7092 Create packet stream for inside network
7094 :param in_if: Inside interface
7095 :param out_if: Outside interface
7096 :param ttl: TTL of generated packets
7100 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7101 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7102 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7106 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7107 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7108 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7112 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7113 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7114 ICMP(id=self.icmp_id_in, type='echo-request'))
7119 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7121 Create packet stream for outside network
7123 :param out_if: Outside interface
7124 :param dst_ip: Destination IP address (Default use global NAT address)
7125 :param ttl: TTL of generated packets
7128 dst_ip = self.nat_addr
7131 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7132 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7133 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7137 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7138 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7139 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7143 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7144 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7145 ICMP(id=self.icmp_external_id, type='echo-reply'))
7150 def verify_capture_out(self, capture, nat_ip=None):
7152 Verify captured packets on outside network
7154 :param capture: Captured packets
7155 :param nat_ip: Translated IP address (Default use global NAT address)
7156 :param same_port: Source port number is not translated (Default False)
7159 nat_ip = self.nat_addr
7160 for packet in capture:
7162 self.assertEqual(packet[IP].src, nat_ip)
7163 if packet.haslayer(TCP):
7164 self.tcp_port_out = packet[TCP].sport
7165 elif packet.haslayer(UDP):
7166 self.udp_port_out = packet[UDP].sport
7168 self.icmp_external_id = packet[ICMP].id
7170 self.logger.error(ppp("Unexpected or invalid packet "
7171 "(outside network):", packet))
7174 def test_deterministic_mode(self):
7175 """ NAT plugin run deterministic mode """
7176 in_addr = '172.16.255.0'
7177 out_addr = '172.17.255.50'
7178 in_addr_t = '172.16.255.20'
7182 nat_config = self.vapi.nat_show_config()
7183 self.assertEqual(1, nat_config.deterministic)
7185 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7186 in_plen=in_plen, out_addr=out_addr,
7189 rep1 = self.vapi.nat_det_forward(in_addr_t)
7190 self.assertEqual(str(rep1.out_addr), out_addr)
7191 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7193 self.assertEqual(str(rep2.in_addr), in_addr_t)
7195 deterministic_mappings = self.vapi.nat_det_map_dump()
7196 self.assertEqual(len(deterministic_mappings), 1)
7197 dsm = deterministic_mappings[0]
7198 self.assertEqual(in_addr, str(dsm.in_addr))
7199 self.assertEqual(in_plen, dsm.in_plen)
7200 self.assertEqual(out_addr, str(dsm.out_addr))
7201 self.assertEqual(out_plen, dsm.out_plen)
7203 self.clear_nat_det()
7204 deterministic_mappings = self.vapi.nat_det_map_dump()
7205 self.assertEqual(len(deterministic_mappings), 0)
7207 def test_set_timeouts(self):
7208 """ Set deterministic NAT timeouts """
7209 timeouts_before = self.vapi.nat_get_timeouts()
7211 self.vapi.nat_set_timeouts(
7212 udp=timeouts_before.udp + 10,
7213 tcp_established=timeouts_before.tcp_established + 10,
7214 tcp_transitory=timeouts_before.tcp_transitory + 10,
7215 icmp=timeouts_before.icmp + 10)
7217 timeouts_after = self.vapi.nat_get_timeouts()
7219 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7220 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7221 self.assertNotEqual(timeouts_before.tcp_established,
7222 timeouts_after.tcp_established)
7223 self.assertNotEqual(timeouts_before.tcp_transitory,
7224 timeouts_after.tcp_transitory)
7226 def test_det_in(self):
7227 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7229 nat_ip = "10.0.0.10"
7231 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7233 out_addr=socket.inet_aton(nat_ip),
7236 flags = self.config_flags.NAT_IS_INSIDE
7237 self.vapi.nat44_interface_add_del_feature(
7238 sw_if_index=self.pg0.sw_if_index,
7239 flags=flags, is_add=1)
7240 self.vapi.nat44_interface_add_del_feature(
7241 sw_if_index=self.pg1.sw_if_index,
7245 pkts = self.create_stream_in(self.pg0, self.pg1)
7246 self.pg0.add_stream(pkts)
7247 self.pg_enable_capture(self.pg_interfaces)
7249 capture = self.pg1.get_capture(len(pkts))
7250 self.verify_capture_out(capture, nat_ip)
7253 pkts = self.create_stream_out(self.pg1, nat_ip)
7254 self.pg1.add_stream(pkts)
7255 self.pg_enable_capture(self.pg_interfaces)
7257 capture = self.pg0.get_capture(len(pkts))
7258 self.verify_capture_in(capture, self.pg0)
7261 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7262 self.assertEqual(len(sessions), 3)
7266 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7267 self.assertEqual(s.in_port, self.tcp_port_in)
7268 self.assertEqual(s.out_port, self.tcp_port_out)
7269 self.assertEqual(s.ext_port, self.tcp_external_port)
7273 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7274 self.assertEqual(s.in_port, self.udp_port_in)
7275 self.assertEqual(s.out_port, self.udp_port_out)
7276 self.assertEqual(s.ext_port, self.udp_external_port)
7280 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7281 self.assertEqual(s.in_port, self.icmp_id_in)
7282 self.assertEqual(s.out_port, self.icmp_external_id)
7284 def test_multiple_users(self):
7285 """ Deterministic NAT multiple users """
7287 nat_ip = "10.0.0.10"
7289 external_port = 6303
7291 host0 = self.pg0.remote_hosts[0]
7292 host1 = self.pg0.remote_hosts[1]
7294 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7295 out_addr=socket.inet_aton(nat_ip),
7297 flags = self.config_flags.NAT_IS_INSIDE
7298 self.vapi.nat44_interface_add_del_feature(
7299 sw_if_index=self.pg0.sw_if_index,
7300 flags=flags, is_add=1)
7301 self.vapi.nat44_interface_add_del_feature(
7302 sw_if_index=self.pg1.sw_if_index,
7306 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7307 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7308 TCP(sport=port_in, dport=external_port))
7309 self.pg0.add_stream(p)
7310 self.pg_enable_capture(self.pg_interfaces)
7312 capture = self.pg1.get_capture(1)
7317 self.assertEqual(ip.src, nat_ip)
7318 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7319 self.assertEqual(tcp.dport, external_port)
7320 port_out0 = tcp.sport
7322 self.logger.error(ppp("Unexpected or invalid packet:", p))
7326 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7327 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7328 TCP(sport=port_in, dport=external_port))
7329 self.pg0.add_stream(p)
7330 self.pg_enable_capture(self.pg_interfaces)
7332 capture = self.pg1.get_capture(1)
7337 self.assertEqual(ip.src, nat_ip)
7338 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7339 self.assertEqual(tcp.dport, external_port)
7340 port_out1 = tcp.sport
7342 self.logger.error(ppp("Unexpected or invalid packet:", p))
7345 dms = self.vapi.nat_det_map_dump()
7346 self.assertEqual(1, len(dms))
7347 self.assertEqual(2, dms[0].ses_num)
7350 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7351 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7352 TCP(sport=external_port, dport=port_out0))
7353 self.pg1.add_stream(p)
7354 self.pg_enable_capture(self.pg_interfaces)
7356 capture = self.pg0.get_capture(1)
7361 self.assertEqual(ip.src, self.pg1.remote_ip4)
7362 self.assertEqual(ip.dst, host0.ip4)
7363 self.assertEqual(tcp.dport, port_in)
7364 self.assertEqual(tcp.sport, external_port)
7366 self.logger.error(ppp("Unexpected or invalid packet:", p))
7370 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7371 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7372 TCP(sport=external_port, dport=port_out1))
7373 self.pg1.add_stream(p)
7374 self.pg_enable_capture(self.pg_interfaces)
7376 capture = self.pg0.get_capture(1)
7381 self.assertEqual(ip.src, self.pg1.remote_ip4)
7382 self.assertEqual(ip.dst, host1.ip4)
7383 self.assertEqual(tcp.dport, port_in)
7384 self.assertEqual(tcp.sport, external_port)
7386 self.logger.error(ppp("Unexpected or invalid packet", p))
7389 # session close api test
7390 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7392 self.pg1.remote_ip4,
7394 dms = self.vapi.nat_det_map_dump()
7395 self.assertEqual(dms[0].ses_num, 1)
7397 self.vapi.nat_det_close_session_in(host0.ip4,
7399 self.pg1.remote_ip4,
7401 dms = self.vapi.nat_det_map_dump()
7402 self.assertEqual(dms[0].ses_num, 0)
7404 def test_tcp_session_close_detection_in(self):
7405 """ Deterministic NAT TCP session close from inside network """
7406 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7408 out_addr=socket.inet_aton(self.nat_addr),
7410 flags = self.config_flags.NAT_IS_INSIDE
7411 self.vapi.nat44_interface_add_del_feature(
7412 sw_if_index=self.pg0.sw_if_index,
7413 flags=flags, is_add=1)
7414 self.vapi.nat44_interface_add_del_feature(
7415 sw_if_index=self.pg1.sw_if_index,
7418 self.initiate_tcp_session(self.pg0, self.pg1)
7420 # close the session from inside
7422 # FIN packet in -> out
7423 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7424 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7425 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7427 self.pg0.add_stream(p)
7428 self.pg_enable_capture(self.pg_interfaces)
7430 self.pg1.get_capture(1)
7434 # ACK packet out -> in
7435 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7436 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7437 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7441 # FIN packet out -> in
7442 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7443 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7444 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7448 self.pg1.add_stream(pkts)
7449 self.pg_enable_capture(self.pg_interfaces)
7451 self.pg0.get_capture(2)
7453 # ACK packet in -> out
7454 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7455 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7456 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7458 self.pg0.add_stream(p)
7459 self.pg_enable_capture(self.pg_interfaces)
7461 self.pg1.get_capture(1)
7463 # Check if deterministic NAT44 closed the session
7464 dms = self.vapi.nat_det_map_dump()
7465 self.assertEqual(0, dms[0].ses_num)
7467 self.logger.error("TCP session termination failed")
7470 def test_tcp_session_close_detection_out(self):
7471 """ Deterministic NAT TCP session close from outside network """
7472 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7474 out_addr=socket.inet_aton(self.nat_addr),
7476 flags = self.config_flags.NAT_IS_INSIDE
7477 self.vapi.nat44_interface_add_del_feature(
7478 sw_if_index=self.pg0.sw_if_index,
7479 flags=flags, is_add=1)
7480 self.vapi.nat44_interface_add_del_feature(
7481 sw_if_index=self.pg1.sw_if_index,
7484 self.initiate_tcp_session(self.pg0, self.pg1)
7486 # close the session from outside
7488 # FIN packet out -> in
7489 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7490 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7491 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7493 self.pg1.add_stream(p)
7494 self.pg_enable_capture(self.pg_interfaces)
7496 self.pg0.get_capture(1)
7500 # ACK packet in -> out
7501 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7502 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7503 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7507 # ACK packet in -> out
7508 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7509 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7510 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7514 self.pg0.add_stream(pkts)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 self.pg1.get_capture(2)
7519 # ACK packet out -> in
7520 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7521 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7522 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7524 self.pg1.add_stream(p)
7525 self.pg_enable_capture(self.pg_interfaces)
7527 self.pg0.get_capture(1)
7529 # Check if deterministic NAT44 closed the session
7530 dms = self.vapi.nat_det_map_dump()
7531 self.assertEqual(0, dms[0].ses_num)
7533 self.logger.error("TCP session termination failed")
7536 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7537 def test_session_timeout(self):
7538 """ Deterministic NAT session timeouts """
7539 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7541 out_addr=socket.inet_aton(self.nat_addr),
7543 flags = self.config_flags.NAT_IS_INSIDE
7544 self.vapi.nat44_interface_add_del_feature(
7545 sw_if_index=self.pg0.sw_if_index,
7546 flags=flags, is_add=1)
7547 self.vapi.nat44_interface_add_del_feature(
7548 sw_if_index=self.pg1.sw_if_index,
7551 self.initiate_tcp_session(self.pg0, self.pg1)
7552 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7554 pkts = self.create_stream_in(self.pg0, self.pg1)
7555 self.pg0.add_stream(pkts)
7556 self.pg_enable_capture(self.pg_interfaces)
7558 capture = self.pg1.get_capture(len(pkts))
7561 dms = self.vapi.nat_det_map_dump()
7562 self.assertEqual(0, dms[0].ses_num)
7564 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7565 def test_session_limit_per_user(self):
7566 """ Deterministic NAT maximum sessions per user limit """
7567 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7569 out_addr=socket.inet_aton(self.nat_addr),
7571 flags = self.config_flags.NAT_IS_INSIDE
7572 self.vapi.nat44_interface_add_del_feature(
7573 sw_if_index=self.pg0.sw_if_index,
7574 flags=flags, is_add=1)
7575 self.vapi.nat44_interface_add_del_feature(
7576 sw_if_index=self.pg1.sw_if_index,
7578 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7579 src_address=self.pg2.local_ip4,
7581 template_interval=10)
7582 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7586 for port in range(1025, 2025):
7587 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7588 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7589 UDP(sport=port, dport=port))
7592 self.pg0.add_stream(pkts)
7593 self.pg_enable_capture(self.pg_interfaces)
7595 capture = self.pg1.get_capture(len(pkts))
7597 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7598 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7599 UDP(sport=3001, dport=3002))
7600 self.pg0.add_stream(p)
7601 self.pg_enable_capture(self.pg_interfaces)
7603 capture = self.pg1.assert_nothing_captured()
7605 # verify ICMP error packet
7606 capture = self.pg0.get_capture(1)
7608 self.assertTrue(p.haslayer(ICMP))
7610 self.assertEqual(icmp.type, 3)
7611 self.assertEqual(icmp.code, 1)
7612 self.assertTrue(icmp.haslayer(IPerror))
7613 inner_ip = icmp[IPerror]
7614 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7615 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7617 dms = self.vapi.nat_det_map_dump()
7619 self.assertEqual(1000, dms[0].ses_num)
7621 # verify IPFIX logging
7622 self.vapi.ipfix_flush()
7624 capture = self.pg2.get_capture(2)
7625 ipfix = IPFIXDecoder()
7626 # first load template
7628 self.assertTrue(p.haslayer(IPFIX))
7629 if p.haslayer(Template):
7630 ipfix.add_template(p.getlayer(Template))
7631 # verify events in data set
7633 if p.haslayer(Data):
7634 data = ipfix.decode_data_set(p.getlayer(Set))
7635 self.verify_ipfix_max_entries_per_user(data,
7637 self.pg0.remote_ip4)
7639 def clear_nat_det(self):
7641 Clear deterministic NAT configuration.
7643 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7645 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7646 tcp_transitory=240, icmp=60)
7647 deterministic_mappings = self.vapi.nat_det_map_dump()
7648 for dsm in deterministic_mappings:
7649 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7650 in_plen=dsm.in_plen,
7651 out_addr=dsm.out_addr,
7652 out_plen=dsm.out_plen)
7654 interfaces = self.vapi.nat44_interface_dump()
7655 for intf in interfaces:
7656 self.vapi.nat44_interface_add_del_feature(
7657 sw_if_index=intf.sw_if_index,
7661 super(TestDeterministicNAT, self).tearDown()
7662 if not self.vpp_dead:
7663 self.clear_nat_det()
7665 def show_commands_at_teardown(self):
7666 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7667 self.logger.info(self.vapi.cli("show nat timeouts"))
7669 self.vapi.cli("show nat44 deterministic mappings"))
7671 self.vapi.cli("show nat44 deterministic sessions"))
7674 class TestNAT64(MethodHolder):
7675 """ NAT64 Test Cases """
7678 def setUpConstants(cls):
7679 super(TestNAT64, cls).setUpConstants()
7680 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7681 "nat64 st hash buckets 256", "}"])
7684 def setUpClass(cls):
7685 super(TestNAT64, cls).setUpClass()
7687 cls.tcp_port_in = 6303
7688 cls.tcp_port_out = 6303
7689 cls.udp_port_in = 6304
7690 cls.udp_port_out = 6304
7691 cls.icmp_id_in = 6305
7692 cls.icmp_id_out = 6305
7693 cls.tcp_external_port = 80
7694 cls.nat_addr = '10.0.0.3'
7695 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7697 cls.vrf1_nat_addr = '10.0.10.3'
7698 cls.ipfix_src_port = 4739
7699 cls.ipfix_domain_id = 1
7701 cls.create_pg_interfaces(range(6))
7702 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7703 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7704 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7706 cls.vapi.ip_table_add_del(is_add=1,
7707 table={'table_id': cls.vrf1_id,
7710 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7712 cls.pg0.generate_remote_hosts(2)
7714 for i in cls.ip6_interfaces:
7717 i.configure_ipv6_neighbors()
7719 for i in cls.ip4_interfaces:
7725 cls.pg3.config_ip4()
7726 cls.pg3.resolve_arp()
7727 cls.pg3.config_ip6()
7728 cls.pg3.configure_ipv6_neighbors()
7731 cls.pg5.config_ip6()
7734 def tearDownClass(cls):
7735 super(TestNAT64, cls).tearDownClass()
7737 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7738 """ NAT64 inside interface handles Neighbor Advertisement """
7740 flags = self.config_flags.NAT_IS_INSIDE
7741 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7742 sw_if_index=self.pg5.sw_if_index)
7745 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7746 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7747 ICMPv6EchoRequest())
7749 self.pg5.add_stream(pkts)
7750 self.pg_enable_capture(self.pg_interfaces)
7753 # Wait for Neighbor Solicitation
7754 capture = self.pg5.get_capture(len(pkts))
7757 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7758 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7759 tgt = packet[ICMPv6ND_NS].tgt
7761 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7764 # Send Neighbor Advertisement
7765 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7766 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7767 ICMPv6ND_NA(tgt=tgt) /
7768 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7770 self.pg5.add_stream(pkts)
7771 self.pg_enable_capture(self.pg_interfaces)
7774 # Try to send ping again
7776 self.pg5.add_stream(pkts)
7777 self.pg_enable_capture(self.pg_interfaces)
7780 # Wait for ping reply
7781 capture = self.pg5.get_capture(len(pkts))
7784 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7785 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7786 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7788 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7791 def test_pool(self):
7792 """ Add/delete address to NAT64 pool """
7793 nat_addr = '1.2.3.4'
7795 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7797 vrf_id=0xFFFFFFFF, is_add=1)
7799 addresses = self.vapi.nat64_pool_addr_dump()
7800 self.assertEqual(len(addresses), 1)
7801 self.assertEqual(str(addresses[0].address), nat_addr)
7803 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7805 vrf_id=0xFFFFFFFF, is_add=0)
7807 addresses = self.vapi.nat64_pool_addr_dump()
7808 self.assertEqual(len(addresses), 0)
7810 def test_interface(self):
7811 """ Enable/disable NAT64 feature on the interface """
7812 flags = self.config_flags.NAT_IS_INSIDE
7813 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7814 sw_if_index=self.pg0.sw_if_index)
7815 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7816 sw_if_index=self.pg1.sw_if_index)
7818 interfaces = self.vapi.nat64_interface_dump()
7819 self.assertEqual(len(interfaces), 2)
7822 for intf in interfaces:
7823 if intf.sw_if_index == self.pg0.sw_if_index:
7824 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7826 elif intf.sw_if_index == self.pg1.sw_if_index:
7827 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7829 self.assertTrue(pg0_found)
7830 self.assertTrue(pg1_found)
7832 features = self.vapi.cli("show interface features pg0")
7833 self.assertIn('nat64-in2out', features)
7834 features = self.vapi.cli("show interface features pg1")
7835 self.assertIn('nat64-out2in', features)
7837 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7838 sw_if_index=self.pg0.sw_if_index)
7839 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7840 sw_if_index=self.pg1.sw_if_index)
7842 interfaces = self.vapi.nat64_interface_dump()
7843 self.assertEqual(len(interfaces), 0)
7845 def test_static_bib(self):
7846 """ Add/delete static BIB entry """
7847 in_addr = '2001:db8:85a3::8a2e:370:7334'
7848 out_addr = '10.1.1.3'
7851 proto = IP_PROTOS.tcp
7853 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7854 i_port=in_port, o_port=out_port,
7855 proto=proto, vrf_id=0, is_add=1)
7856 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7859 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7861 self.assertEqual(str(bibe.i_addr), in_addr)
7862 self.assertEqual(str(bibe.o_addr), out_addr)
7863 self.assertEqual(bibe.i_port, in_port)
7864 self.assertEqual(bibe.o_port, out_port)
7865 self.assertEqual(static_bib_num, 1)
7866 bibs = self.statistics.get_counter('/nat64/total-bibs')
7867 self.assertEqual(bibs[0][0], 1)
7869 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7870 i_port=in_port, o_port=out_port,
7871 proto=proto, vrf_id=0, is_add=0)
7872 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7875 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7877 self.assertEqual(static_bib_num, 0)
7878 bibs = self.statistics.get_counter('/nat64/total-bibs')
7879 self.assertEqual(bibs[0][0], 0)
7881 def test_set_timeouts(self):
7882 """ Set NAT64 timeouts """
7883 # verify default values
7884 timeouts = self.vapi.nat_get_timeouts()
7885 self.assertEqual(timeouts.udp, 300)
7886 self.assertEqual(timeouts.icmp, 60)
7887 self.assertEqual(timeouts.tcp_transitory, 240)
7888 self.assertEqual(timeouts.tcp_established, 7440)
7890 # set and verify custom values
7891 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7892 tcp_transitory=250, icmp=30)
7893 timeouts = self.vapi.nat_get_timeouts()
7894 self.assertEqual(timeouts.udp, 200)
7895 self.assertEqual(timeouts.icmp, 30)
7896 self.assertEqual(timeouts.tcp_transitory, 250)
7897 self.assertEqual(timeouts.tcp_established, 7450)
7899 def test_dynamic(self):
7900 """ NAT64 dynamic translation test """
7901 self.tcp_port_in = 6303
7902 self.udp_port_in = 6304
7903 self.icmp_id_in = 6305
7905 ses_num_start = self.nat64_get_ses_num()
7907 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7908 end_addr=self.nat_addr,
7911 flags = self.config_flags.NAT_IS_INSIDE
7912 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7913 sw_if_index=self.pg0.sw_if_index)
7914 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7915 sw_if_index=self.pg1.sw_if_index)
7918 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7919 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7920 icmpn = self.statistics.get_err_counter(
7921 '/err/nat64-in2out/ICMP packets')
7922 totaln = self.statistics.get_err_counter(
7923 '/err/nat64-in2out/good in2out packets processed')
7925 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7926 self.pg0.add_stream(pkts)
7927 self.pg_enable_capture(self.pg_interfaces)
7929 capture = self.pg1.get_capture(len(pkts))
7930 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7931 dst_ip=self.pg1.remote_ip4)
7933 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7934 self.assertEqual(err - tcpn, 1)
7935 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7936 self.assertEqual(err - udpn, 1)
7937 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7938 self.assertEqual(err - icmpn, 1)
7939 err = self.statistics.get_err_counter(
7940 '/err/nat64-in2out/good in2out packets processed')
7941 self.assertEqual(err - totaln, 3)
7944 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7945 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7946 icmpn = self.statistics.get_err_counter(
7947 '/err/nat64-out2in/ICMP packets')
7948 totaln = self.statistics.get_err_counter(
7949 '/err/nat64-out2in/good out2in packets processed')
7951 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7952 self.pg1.add_stream(pkts)
7953 self.pg_enable_capture(self.pg_interfaces)
7955 capture = self.pg0.get_capture(len(pkts))
7956 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7957 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7959 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7960 self.assertEqual(err - tcpn, 2)
7961 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7962 self.assertEqual(err - udpn, 1)
7963 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7964 self.assertEqual(err - icmpn, 1)
7965 err = self.statistics.get_err_counter(
7966 '/err/nat64-out2in/good out2in packets processed')
7967 self.assertEqual(err - totaln, 4)
7969 bibs = self.statistics.get_counter('/nat64/total-bibs')
7970 self.assertEqual(bibs[0][0], 3)
7971 sessions = self.statistics.get_counter('/nat64/total-sessions')
7972 self.assertEqual(sessions[0][0], 3)
7975 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7976 self.pg0.add_stream(pkts)
7977 self.pg_enable_capture(self.pg_interfaces)
7979 capture = self.pg1.get_capture(len(pkts))
7980 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7981 dst_ip=self.pg1.remote_ip4)
7984 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7985 self.pg1.add_stream(pkts)
7986 self.pg_enable_capture(self.pg_interfaces)
7988 capture = self.pg0.get_capture(len(pkts))
7989 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7991 ses_num_end = self.nat64_get_ses_num()
7993 self.assertEqual(ses_num_end - ses_num_start, 3)
7995 # tenant with specific VRF
7996 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7997 end_addr=self.vrf1_nat_addr,
7998 vrf_id=self.vrf1_id, is_add=1)
7999 flags = self.config_flags.NAT_IS_INSIDE
8000 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8001 sw_if_index=self.pg2.sw_if_index)
8003 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8004 self.pg2.add_stream(pkts)
8005 self.pg_enable_capture(self.pg_interfaces)
8007 capture = self.pg1.get_capture(len(pkts))
8008 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8009 dst_ip=self.pg1.remote_ip4)
8011 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8012 self.pg1.add_stream(pkts)
8013 self.pg_enable_capture(self.pg_interfaces)
8015 capture = self.pg2.get_capture(len(pkts))
8016 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8018 def test_static(self):
8019 """ NAT64 static translation test """
8020 self.tcp_port_in = 60303
8021 self.udp_port_in = 60304
8022 self.icmp_id_in = 60305
8023 self.tcp_port_out = 60303
8024 self.udp_port_out = 60304
8025 self.icmp_id_out = 60305
8027 ses_num_start = self.nat64_get_ses_num()
8029 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8030 end_addr=self.nat_addr,
8033 flags = self.config_flags.NAT_IS_INSIDE
8034 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8035 sw_if_index=self.pg0.sw_if_index)
8036 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8037 sw_if_index=self.pg1.sw_if_index)
8039 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8040 o_addr=self.nat_addr,
8041 i_port=self.tcp_port_in,
8042 o_port=self.tcp_port_out,
8043 proto=IP_PROTOS.tcp, vrf_id=0,
8045 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8046 o_addr=self.nat_addr,
8047 i_port=self.udp_port_in,
8048 o_port=self.udp_port_out,
8049 proto=IP_PROTOS.udp, vrf_id=0,
8051 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8052 o_addr=self.nat_addr,
8053 i_port=self.icmp_id_in,
8054 o_port=self.icmp_id_out,
8055 proto=IP_PROTOS.icmp, vrf_id=0,
8059 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8060 self.pg0.add_stream(pkts)
8061 self.pg_enable_capture(self.pg_interfaces)
8063 capture = self.pg1.get_capture(len(pkts))
8064 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8065 dst_ip=self.pg1.remote_ip4, same_port=True)
8068 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8069 self.pg1.add_stream(pkts)
8070 self.pg_enable_capture(self.pg_interfaces)
8072 capture = self.pg0.get_capture(len(pkts))
8073 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8074 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8076 ses_num_end = self.nat64_get_ses_num()
8078 self.assertEqual(ses_num_end - ses_num_start, 3)
8080 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8081 def test_session_timeout(self):
8082 """ NAT64 session timeout """
8083 self.icmp_id_in = 1234
8084 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8085 end_addr=self.nat_addr,
8088 flags = self.config_flags.NAT_IS_INSIDE
8089 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8090 sw_if_index=self.pg0.sw_if_index)
8091 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8092 sw_if_index=self.pg1.sw_if_index)
8093 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8097 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8098 self.pg0.add_stream(pkts)
8099 self.pg_enable_capture(self.pg_interfaces)
8101 capture = self.pg1.get_capture(len(pkts))
8103 ses_num_before_timeout = self.nat64_get_ses_num()
8107 # ICMP and TCP session after timeout
8108 ses_num_after_timeout = self.nat64_get_ses_num()
8109 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8111 def test_icmp_error(self):
8112 """ NAT64 ICMP Error message translation """
8113 self.tcp_port_in = 6303
8114 self.udp_port_in = 6304
8115 self.icmp_id_in = 6305
8117 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8118 end_addr=self.nat_addr,
8121 flags = self.config_flags.NAT_IS_INSIDE
8122 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8123 sw_if_index=self.pg0.sw_if_index)
8124 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8125 sw_if_index=self.pg1.sw_if_index)
8127 # send some packets to create sessions
8128 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8129 self.pg0.add_stream(pkts)
8130 self.pg_enable_capture(self.pg_interfaces)
8132 capture_ip4 = self.pg1.get_capture(len(pkts))
8133 self.verify_capture_out(capture_ip4,
8134 nat_ip=self.nat_addr,
8135 dst_ip=self.pg1.remote_ip4)
8137 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8138 self.pg1.add_stream(pkts)
8139 self.pg_enable_capture(self.pg_interfaces)
8141 capture_ip6 = self.pg0.get_capture(len(pkts))
8142 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8143 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8144 self.pg0.remote_ip6)
8147 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8148 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8149 ICMPv6DestUnreach(code=1) /
8150 packet[IPv6] for packet in capture_ip6]
8151 self.pg0.add_stream(pkts)
8152 self.pg_enable_capture(self.pg_interfaces)
8154 capture = self.pg1.get_capture(len(pkts))
8155 for packet in capture:
8157 self.assertEqual(packet[IP].src, self.nat_addr)
8158 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8159 self.assertEqual(packet[ICMP].type, 3)
8160 self.assertEqual(packet[ICMP].code, 13)
8161 inner = packet[IPerror]
8162 self.assertEqual(inner.src, self.pg1.remote_ip4)
8163 self.assertEqual(inner.dst, self.nat_addr)
8164 self.assert_packet_checksums_valid(packet)
8165 if inner.haslayer(TCPerror):
8166 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8167 elif inner.haslayer(UDPerror):
8168 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8170 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8172 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8176 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8177 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8178 ICMP(type=3, code=13) /
8179 packet[IP] for packet in capture_ip4]
8180 self.pg1.add_stream(pkts)
8181 self.pg_enable_capture(self.pg_interfaces)
8183 capture = self.pg0.get_capture(len(pkts))
8184 for packet in capture:
8186 self.assertEqual(packet[IPv6].src, ip.src)
8187 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8188 icmp = packet[ICMPv6DestUnreach]
8189 self.assertEqual(icmp.code, 1)
8190 inner = icmp[IPerror6]
8191 self.assertEqual(inner.src, self.pg0.remote_ip6)
8192 self.assertEqual(inner.dst, ip.src)
8193 self.assert_icmpv6_checksum_valid(packet)
8194 if inner.haslayer(TCPerror):
8195 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8196 elif inner.haslayer(UDPerror):
8197 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8199 self.assertEqual(inner[ICMPv6EchoRequest].id,
8202 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8205 def test_hairpinning(self):
8206 """ NAT64 hairpinning """
8208 client = self.pg0.remote_hosts[0]
8209 server = self.pg0.remote_hosts[1]
8210 server_tcp_in_port = 22
8211 server_tcp_out_port = 4022
8212 server_udp_in_port = 23
8213 server_udp_out_port = 4023
8214 client_tcp_in_port = 1234
8215 client_udp_in_port = 1235
8216 client_tcp_out_port = 0
8217 client_udp_out_port = 0
8218 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8219 nat_addr_ip6 = ip.src
8221 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8222 end_addr=self.nat_addr,
8225 flags = self.config_flags.NAT_IS_INSIDE
8226 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8227 sw_if_index=self.pg0.sw_if_index)
8228 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8229 sw_if_index=self.pg1.sw_if_index)
8231 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8232 o_addr=self.nat_addr,
8233 i_port=server_tcp_in_port,
8234 o_port=server_tcp_out_port,
8235 proto=IP_PROTOS.tcp, vrf_id=0,
8237 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8238 o_addr=self.nat_addr,
8239 i_port=server_udp_in_port,
8240 o_port=server_udp_out_port,
8241 proto=IP_PROTOS.udp, vrf_id=0,
8246 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8247 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8248 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8250 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8251 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8252 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8254 self.pg0.add_stream(pkts)
8255 self.pg_enable_capture(self.pg_interfaces)
8257 capture = self.pg0.get_capture(len(pkts))
8258 for packet in capture:
8260 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8261 self.assertEqual(packet[IPv6].dst, server.ip6)
8262 self.assert_packet_checksums_valid(packet)
8263 if packet.haslayer(TCP):
8264 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8265 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8266 client_tcp_out_port = packet[TCP].sport
8268 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8269 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8270 client_udp_out_port = packet[UDP].sport
8272 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8278 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8279 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8282 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8283 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8285 self.pg0.add_stream(pkts)
8286 self.pg_enable_capture(self.pg_interfaces)
8288 capture = self.pg0.get_capture(len(pkts))
8289 for packet in capture:
8291 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8292 self.assertEqual(packet[IPv6].dst, client.ip6)
8293 self.assert_packet_checksums_valid(packet)
8294 if packet.haslayer(TCP):
8295 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8296 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8298 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8299 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8301 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8306 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8307 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8308 ICMPv6DestUnreach(code=1) /
8309 packet[IPv6] for packet in capture]
8310 self.pg0.add_stream(pkts)
8311 self.pg_enable_capture(self.pg_interfaces)
8313 capture = self.pg0.get_capture(len(pkts))
8314 for packet in capture:
8316 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8317 self.assertEqual(packet[IPv6].dst, server.ip6)
8318 icmp = packet[ICMPv6DestUnreach]
8319 self.assertEqual(icmp.code, 1)
8320 inner = icmp[IPerror6]
8321 self.assertEqual(inner.src, server.ip6)
8322 self.assertEqual(inner.dst, nat_addr_ip6)
8323 self.assert_packet_checksums_valid(packet)
8324 if inner.haslayer(TCPerror):
8325 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8326 self.assertEqual(inner[TCPerror].dport,
8327 client_tcp_out_port)
8329 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8330 self.assertEqual(inner[UDPerror].dport,
8331 client_udp_out_port)
8333 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8336 def test_prefix(self):
8337 """ NAT64 Network-Specific Prefix """
8339 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8340 end_addr=self.nat_addr,
8343 flags = self.config_flags.NAT_IS_INSIDE
8344 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8345 sw_if_index=self.pg0.sw_if_index)
8346 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8347 sw_if_index=self.pg1.sw_if_index)
8348 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8349 end_addr=self.vrf1_nat_addr,
8350 vrf_id=self.vrf1_id, is_add=1)
8351 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8352 sw_if_index=self.pg2.sw_if_index)
8355 global_pref64 = "2001:db8::"
8356 global_pref64_len = 32
8357 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8358 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8361 prefix = self.vapi.nat64_prefix_dump()
8362 self.assertEqual(len(prefix), 1)
8363 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8364 self.assertEqual(prefix[0].vrf_id, 0)
8366 # Add tenant specific prefix
8367 vrf1_pref64 = "2001:db8:122:300::"
8368 vrf1_pref64_len = 56
8369 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8370 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8371 vrf_id=self.vrf1_id, is_add=1)
8373 prefix = self.vapi.nat64_prefix_dump()
8374 self.assertEqual(len(prefix), 2)
8377 pkts = self.create_stream_in_ip6(self.pg0,
8380 plen=global_pref64_len)
8381 self.pg0.add_stream(pkts)
8382 self.pg_enable_capture(self.pg_interfaces)
8384 capture = self.pg1.get_capture(len(pkts))
8385 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8386 dst_ip=self.pg1.remote_ip4)
8388 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8389 self.pg1.add_stream(pkts)
8390 self.pg_enable_capture(self.pg_interfaces)
8392 capture = self.pg0.get_capture(len(pkts))
8393 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8396 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8398 # Tenant specific prefix
8399 pkts = self.create_stream_in_ip6(self.pg2,
8402 plen=vrf1_pref64_len)
8403 self.pg2.add_stream(pkts)
8404 self.pg_enable_capture(self.pg_interfaces)
8406 capture = self.pg1.get_capture(len(pkts))
8407 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8408 dst_ip=self.pg1.remote_ip4)
8410 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8411 self.pg1.add_stream(pkts)
8412 self.pg_enable_capture(self.pg_interfaces)
8414 capture = self.pg2.get_capture(len(pkts))
8415 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8418 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8420 def test_unknown_proto(self):
8421 """ NAT64 translate packet with unknown protocol """
8423 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8424 end_addr=self.nat_addr,
8427 flags = self.config_flags.NAT_IS_INSIDE
8428 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8429 sw_if_index=self.pg0.sw_if_index)
8430 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8431 sw_if_index=self.pg1.sw_if_index)
8432 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8435 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8436 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8437 TCP(sport=self.tcp_port_in, dport=20))
8438 self.pg0.add_stream(p)
8439 self.pg_enable_capture(self.pg_interfaces)
8441 p = self.pg1.get_capture(1)
8443 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8444 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8446 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8447 TCP(sport=1234, dport=1234))
8448 self.pg0.add_stream(p)
8449 self.pg_enable_capture(self.pg_interfaces)
8451 p = self.pg1.get_capture(1)
8454 self.assertEqual(packet[IP].src, self.nat_addr)
8455 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8456 self.assertEqual(packet.haslayer(GRE), 1)
8457 self.assert_packet_checksums_valid(packet)
8459 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8463 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8464 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8466 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8467 TCP(sport=1234, dport=1234))
8468 self.pg1.add_stream(p)
8469 self.pg_enable_capture(self.pg_interfaces)
8471 p = self.pg0.get_capture(1)
8474 self.assertEqual(packet[IPv6].src, remote_ip6)
8475 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8476 self.assertEqual(packet[IPv6].nh, 47)
8478 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8481 def test_hairpinning_unknown_proto(self):
8482 """ NAT64 translate packet with unknown protocol - hairpinning """
8484 client = self.pg0.remote_hosts[0]
8485 server = self.pg0.remote_hosts[1]
8486 server_tcp_in_port = 22
8487 server_tcp_out_port = 4022
8488 client_tcp_in_port = 1234
8489 client_tcp_out_port = 1235
8490 server_nat_ip = "10.0.0.100"
8491 client_nat_ip = "10.0.0.110"
8492 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8493 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8495 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8496 end_addr=client_nat_ip,
8499 flags = self.config_flags.NAT_IS_INSIDE
8500 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8501 sw_if_index=self.pg0.sw_if_index)
8502 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8503 sw_if_index=self.pg1.sw_if_index)
8505 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8506 o_addr=server_nat_ip,
8507 i_port=server_tcp_in_port,
8508 o_port=server_tcp_out_port,
8509 proto=IP_PROTOS.tcp, vrf_id=0,
8512 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8513 o_addr=server_nat_ip, i_port=0,
8515 proto=IP_PROTOS.gre, vrf_id=0,
8518 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8519 o_addr=client_nat_ip,
8520 i_port=client_tcp_in_port,
8521 o_port=client_tcp_out_port,
8522 proto=IP_PROTOS.tcp, vrf_id=0,
8526 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8527 IPv6(src=client.ip6, dst=server_nat_ip6) /
8528 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8529 self.pg0.add_stream(p)
8530 self.pg_enable_capture(self.pg_interfaces)
8532 p = self.pg0.get_capture(1)
8534 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8535 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8537 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8538 TCP(sport=1234, dport=1234))
8539 self.pg0.add_stream(p)
8540 self.pg_enable_capture(self.pg_interfaces)
8542 p = self.pg0.get_capture(1)
8545 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8546 self.assertEqual(packet[IPv6].dst, server.ip6)
8547 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8549 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8553 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8554 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8556 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8557 TCP(sport=1234, dport=1234))
8558 self.pg0.add_stream(p)
8559 self.pg_enable_capture(self.pg_interfaces)
8561 p = self.pg0.get_capture(1)
8564 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8565 self.assertEqual(packet[IPv6].dst, client.ip6)
8566 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8568 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8571 def test_one_armed_nat64(self):
8572 """ One armed NAT64 """
8574 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8578 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8579 end_addr=self.nat_addr,
8582 flags = self.config_flags.NAT_IS_INSIDE
8583 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8584 sw_if_index=self.pg3.sw_if_index)
8585 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8586 sw_if_index=self.pg3.sw_if_index)
8589 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8590 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8591 TCP(sport=12345, dport=80))
8592 self.pg3.add_stream(p)
8593 self.pg_enable_capture(self.pg_interfaces)
8595 capture = self.pg3.get_capture(1)
8600 self.assertEqual(ip.src, self.nat_addr)
8601 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8602 self.assertNotEqual(tcp.sport, 12345)
8603 external_port = tcp.sport
8604 self.assertEqual(tcp.dport, 80)
8605 self.assert_packet_checksums_valid(p)
8607 self.logger.error(ppp("Unexpected or invalid packet:", p))
8611 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8612 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8613 TCP(sport=80, dport=external_port))
8614 self.pg3.add_stream(p)
8615 self.pg_enable_capture(self.pg_interfaces)
8617 capture = self.pg3.get_capture(1)
8622 self.assertEqual(ip.src, remote_host_ip6)
8623 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8624 self.assertEqual(tcp.sport, 80)
8625 self.assertEqual(tcp.dport, 12345)
8626 self.assert_packet_checksums_valid(p)
8628 self.logger.error(ppp("Unexpected or invalid packet:", p))
8631 def test_frag_in_order(self):
8632 """ NAT64 translate fragments arriving in order """
8633 self.tcp_port_in = random.randint(1025, 65535)
8635 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8636 end_addr=self.nat_addr,
8639 flags = self.config_flags.NAT_IS_INSIDE
8640 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8641 sw_if_index=self.pg0.sw_if_index)
8642 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8643 sw_if_index=self.pg1.sw_if_index)
8647 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8648 self.tcp_port_in, 20, data)
8649 self.pg0.add_stream(pkts)
8650 self.pg_enable_capture(self.pg_interfaces)
8652 frags = self.pg1.get_capture(len(pkts))
8653 p = self.reass_frags_and_verify(frags,
8655 self.pg1.remote_ip4)
8656 self.assertEqual(p[TCP].dport, 20)
8657 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8658 self.tcp_port_out = p[TCP].sport
8659 self.assertEqual(data, p[Raw].load)
8662 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8663 pkts = self.create_stream_frag(self.pg1,
8668 self.pg1.add_stream(pkts)
8669 self.pg_enable_capture(self.pg_interfaces)
8671 frags = self.pg0.get_capture(len(pkts))
8672 self.logger.debug(ppc("Captured:", frags))
8673 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8674 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8675 self.assertEqual(p[TCP].sport, 20)
8676 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8677 self.assertEqual(data, p[Raw].load)
8679 def test_reass_hairpinning(self):
8680 """ NAT64 fragments hairpinning """
8682 server = self.pg0.remote_hosts[1]
8683 server_in_port = random.randint(1025, 65535)
8684 server_out_port = random.randint(1025, 65535)
8685 client_in_port = random.randint(1025, 65535)
8686 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8687 nat_addr_ip6 = ip.src
8689 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8690 end_addr=self.nat_addr,
8693 flags = self.config_flags.NAT_IS_INSIDE
8694 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8695 sw_if_index=self.pg0.sw_if_index)
8696 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8697 sw_if_index=self.pg1.sw_if_index)
8699 # add static BIB entry for server
8700 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8701 o_addr=self.nat_addr,
8702 i_port=server_in_port,
8703 o_port=server_out_port,
8704 proto=IP_PROTOS.tcp, vrf_id=0,
8707 # send packet from host to server
8708 pkts = self.create_stream_frag_ip6(self.pg0,
8713 self.pg0.add_stream(pkts)
8714 self.pg_enable_capture(self.pg_interfaces)
8716 frags = self.pg0.get_capture(len(pkts))
8717 self.logger.debug(ppc("Captured:", frags))
8718 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8719 self.assertNotEqual(p[TCP].sport, client_in_port)
8720 self.assertEqual(p[TCP].dport, server_in_port)
8721 self.assertEqual(data, p[Raw].load)
8723 def test_frag_out_of_order(self):
8724 """ NAT64 translate fragments arriving out of order """
8725 self.tcp_port_in = random.randint(1025, 65535)
8727 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8728 end_addr=self.nat_addr,
8731 flags = self.config_flags.NAT_IS_INSIDE
8732 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8733 sw_if_index=self.pg0.sw_if_index)
8734 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8735 sw_if_index=self.pg1.sw_if_index)
8739 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8740 self.tcp_port_in, 20, data)
8742 self.pg0.add_stream(pkts)
8743 self.pg_enable_capture(self.pg_interfaces)
8745 frags = self.pg1.get_capture(len(pkts))
8746 p = self.reass_frags_and_verify(frags,
8748 self.pg1.remote_ip4)
8749 self.assertEqual(p[TCP].dport, 20)
8750 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8751 self.tcp_port_out = p[TCP].sport
8752 self.assertEqual(data, p[Raw].load)
8755 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8756 pkts = self.create_stream_frag(self.pg1,
8762 self.pg1.add_stream(pkts)
8763 self.pg_enable_capture(self.pg_interfaces)
8765 frags = self.pg0.get_capture(len(pkts))
8766 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8767 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8768 self.assertEqual(p[TCP].sport, 20)
8769 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8770 self.assertEqual(data, p[Raw].load)
8772 def test_interface_addr(self):
8773 """ Acquire NAT64 pool addresses from interface """
8774 self.vapi.nat64_add_del_interface_addr(
8776 sw_if_index=self.pg4.sw_if_index)
8778 # no address in NAT64 pool
8779 addresses = self.vapi.nat44_address_dump()
8780 self.assertEqual(0, len(addresses))
8782 # configure interface address and check NAT64 address pool
8783 self.pg4.config_ip4()
8784 addresses = self.vapi.nat64_pool_addr_dump()
8785 self.assertEqual(len(addresses), 1)
8787 self.assertEqual(str(addresses[0].address),
8790 # remove interface address and check NAT64 address pool
8791 self.pg4.unconfig_ip4()
8792 addresses = self.vapi.nat64_pool_addr_dump()
8793 self.assertEqual(0, len(addresses))
8795 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8796 def test_ipfix_max_bibs_sessions(self):
8797 """ IPFIX logging maximum session and BIB entries exceeded """
8800 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8804 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8805 end_addr=self.nat_addr,
8808 flags = self.config_flags.NAT_IS_INSIDE
8809 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8810 sw_if_index=self.pg0.sw_if_index)
8811 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8812 sw_if_index=self.pg1.sw_if_index)
8816 for i in range(0, max_bibs):
8817 src = "fd01:aa::%x" % (i)
8818 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8819 IPv6(src=src, dst=remote_host_ip6) /
8820 TCP(sport=12345, dport=80))
8822 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8823 IPv6(src=src, dst=remote_host_ip6) /
8824 TCP(sport=12345, dport=22))
8826 self.pg0.add_stream(pkts)
8827 self.pg_enable_capture(self.pg_interfaces)
8829 self.pg1.get_capture(max_sessions)
8831 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8832 src_address=self.pg3.local_ip4,
8834 template_interval=10)
8835 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8836 src_port=self.ipfix_src_port,
8839 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8840 IPv6(src=src, dst=remote_host_ip6) /
8841 TCP(sport=12345, dport=25))
8842 self.pg0.add_stream(p)
8843 self.pg_enable_capture(self.pg_interfaces)
8845 self.pg1.assert_nothing_captured()
8847 self.vapi.ipfix_flush()
8848 capture = self.pg3.get_capture(9)
8849 ipfix = IPFIXDecoder()
8850 # first load template
8852 self.assertTrue(p.haslayer(IPFIX))
8853 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8854 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8855 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8856 self.assertEqual(p[UDP].dport, 4739)
8857 self.assertEqual(p[IPFIX].observationDomainID,
8858 self.ipfix_domain_id)
8859 if p.haslayer(Template):
8860 ipfix.add_template(p.getlayer(Template))
8861 # verify events in data set
8863 if p.haslayer(Data):
8864 data = ipfix.decode_data_set(p.getlayer(Set))
8865 self.verify_ipfix_max_sessions(data, max_sessions)
8867 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8868 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8869 TCP(sport=12345, dport=80))
8870 self.pg0.add_stream(p)
8871 self.pg_enable_capture(self.pg_interfaces)
8873 self.pg1.assert_nothing_captured()
8875 self.vapi.ipfix_flush()
8876 capture = self.pg3.get_capture(1)
8877 # verify events in data set
8879 self.assertTrue(p.haslayer(IPFIX))
8880 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8881 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8882 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8883 self.assertEqual(p[UDP].dport, 4739)
8884 self.assertEqual(p[IPFIX].observationDomainID,
8885 self.ipfix_domain_id)
8886 if p.haslayer(Data):
8887 data = ipfix.decode_data_set(p.getlayer(Set))
8888 self.verify_ipfix_max_bibs(data, max_bibs)
8890 def test_ipfix_bib_ses(self):
8891 """ IPFIX logging NAT64 BIB/session create and delete events """
8892 self.tcp_port_in = random.randint(1025, 65535)
8893 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8897 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8898 end_addr=self.nat_addr,
8901 flags = self.config_flags.NAT_IS_INSIDE
8902 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8903 sw_if_index=self.pg0.sw_if_index)
8904 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8905 sw_if_index=self.pg1.sw_if_index)
8906 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8907 src_address=self.pg3.local_ip4,
8909 template_interval=10)
8910 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8911 src_port=self.ipfix_src_port,
8915 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8916 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8917 TCP(sport=self.tcp_port_in, dport=25))
8918 self.pg0.add_stream(p)
8919 self.pg_enable_capture(self.pg_interfaces)
8921 p = self.pg1.get_capture(1)
8922 self.tcp_port_out = p[0][TCP].sport
8923 self.vapi.ipfix_flush()
8924 capture = self.pg3.get_capture(10)
8925 ipfix = IPFIXDecoder()
8926 # first load template
8928 self.assertTrue(p.haslayer(IPFIX))
8929 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8930 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8931 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8932 self.assertEqual(p[UDP].dport, 4739)
8933 self.assertEqual(p[IPFIX].observationDomainID,
8934 self.ipfix_domain_id)
8935 if p.haslayer(Template):
8936 ipfix.add_template(p.getlayer(Template))
8937 # verify events in data set
8939 if p.haslayer(Data):
8940 data = ipfix.decode_data_set(p.getlayer(Set))
8941 if scapy.compat.orb(data[0][230]) == 10:
8942 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8943 elif scapy.compat.orb(data[0][230]) == 6:
8944 self.verify_ipfix_nat64_ses(data,
8946 self.pg0.remote_ip6n,
8947 self.pg1.remote_ip4,
8950 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8953 self.pg_enable_capture(self.pg_interfaces)
8954 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8955 end_addr=self.nat_addr,
8958 self.vapi.ipfix_flush()
8959 capture = self.pg3.get_capture(2)
8960 # verify events in data set
8962 self.assertTrue(p.haslayer(IPFIX))
8963 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8964 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8965 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8966 self.assertEqual(p[UDP].dport, 4739)
8967 self.assertEqual(p[IPFIX].observationDomainID,
8968 self.ipfix_domain_id)
8969 if p.haslayer(Data):
8970 data = ipfix.decode_data_set(p.getlayer(Set))
8971 if scapy.compat.orb(data[0][230]) == 11:
8972 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8973 elif scapy.compat.orb(data[0][230]) == 7:
8974 self.verify_ipfix_nat64_ses(data,
8976 self.pg0.remote_ip6n,
8977 self.pg1.remote_ip4,
8980 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8982 def test_syslog_sess(self):
8983 """ Test syslog session creation and deletion """
8984 self.tcp_port_in = random.randint(1025, 65535)
8985 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8989 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8990 end_addr=self.nat_addr,
8993 flags = self.config_flags.NAT_IS_INSIDE
8994 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8995 sw_if_index=self.pg0.sw_if_index)
8996 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8997 sw_if_index=self.pg1.sw_if_index)
8998 self.vapi.syslog_set_filter(
8999 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9000 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9002 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9003 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9004 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9005 self.pg0.add_stream(p)
9006 self.pg_enable_capture(self.pg_interfaces)
9008 p = self.pg1.get_capture(1)
9009 self.tcp_port_out = p[0][TCP].sport
9010 capture = self.pg3.get_capture(1)
9011 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9013 self.pg_enable_capture(self.pg_interfaces)
9015 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9016 end_addr=self.nat_addr,
9019 capture = self.pg3.get_capture(1)
9020 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9022 def nat64_get_ses_num(self):
9024 Return number of active NAT64 sessions.
9026 st = self.vapi.nat64_st_dump(proto=255)
9029 def clear_nat64(self):
9031 Clear NAT64 configuration.
9033 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9034 src_port=self.ipfix_src_port,
9036 self.ipfix_src_port = 4739
9037 self.ipfix_domain_id = 1
9039 self.vapi.syslog_set_filter(
9040 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9042 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9043 tcp_transitory=240, icmp=60)
9045 interfaces = self.vapi.nat64_interface_dump()
9046 for intf in interfaces:
9047 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9048 sw_if_index=intf.sw_if_index)
9050 bib = self.vapi.nat64_bib_dump(proto=255)
9052 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9053 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9061 adresses = self.vapi.nat64_pool_addr_dump()
9062 for addr in adresses:
9063 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9064 end_addr=addr.address,
9068 prefixes = self.vapi.nat64_prefix_dump()
9069 for prefix in prefixes:
9070 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9071 vrf_id=prefix.vrf_id, is_add=0)
9073 bibs = self.statistics.get_counter('/nat64/total-bibs')
9074 self.assertEqual(bibs[0][0], 0)
9075 sessions = self.statistics.get_counter('/nat64/total-sessions')
9076 self.assertEqual(sessions[0][0], 0)
9079 super(TestNAT64, self).tearDown()
9080 if not self.vpp_dead:
9083 def show_commands_at_teardown(self):
9084 self.logger.info(self.vapi.cli("show nat64 pool"))
9085 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9086 self.logger.info(self.vapi.cli("show nat64 prefix"))
9087 self.logger.info(self.vapi.cli("show nat64 bib all"))
9088 self.logger.info(self.vapi.cli("show nat64 session table all"))
9091 class TestNAT66(MethodHolder):
9092 """ NAT66 Test Cases """
9095 def setUpClass(cls):
9096 super(TestNAT66, cls).setUpClass()
9098 cls.nat_addr = 'fd01:ff::2'
9100 cls.create_pg_interfaces(range(2))
9101 cls.interfaces = list(cls.pg_interfaces)
9103 for i in cls.interfaces:
9106 i.configure_ipv6_neighbors()
9109 def tearDownClass(cls):
9110 super(TestNAT66, cls).tearDownClass()
9112 def test_static(self):
9113 """ 1:1 NAT66 test """
9114 flags = self.config_flags.NAT_IS_INSIDE
9115 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9116 sw_if_index=self.pg0.sw_if_index)
9117 self.vapi.nat66_add_del_interface(is_add=1,
9118 sw_if_index=self.pg1.sw_if_index)
9119 self.vapi.nat66_add_del_static_mapping(
9120 local_ip_address=self.pg0.remote_ip6n,
9121 external_ip_address=self.nat_addr,
9126 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9127 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9130 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9131 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9134 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9135 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9136 ICMPv6EchoRequest())
9138 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9139 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9140 GRE() / IP() / TCP())
9142 self.pg0.add_stream(pkts)
9143 self.pg_enable_capture(self.pg_interfaces)
9145 capture = self.pg1.get_capture(len(pkts))
9147 for packet in capture:
9149 self.assertEqual(packet[IPv6].src, self.nat_addr)
9150 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9151 self.assert_packet_checksums_valid(packet)
9153 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9158 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9159 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9162 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9163 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9166 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9167 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9170 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9171 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9172 GRE() / IP() / TCP())
9174 self.pg1.add_stream(pkts)
9175 self.pg_enable_capture(self.pg_interfaces)
9177 capture = self.pg0.get_capture(len(pkts))
9178 for packet in capture:
9180 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9181 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9182 self.assert_packet_checksums_valid(packet)
9184 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9187 sm = self.vapi.nat66_static_mapping_dump()
9188 self.assertEqual(len(sm), 1)
9189 self.assertEqual(sm[0].total_pkts, 8)
9191 def test_check_no_translate(self):
9192 """ NAT66 translate only when egress interface is outside interface """
9193 flags = self.config_flags.NAT_IS_INSIDE
9194 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9195 sw_if_index=self.pg0.sw_if_index)
9196 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9197 sw_if_index=self.pg1.sw_if_index)
9198 self.vapi.nat66_add_del_static_mapping(
9199 local_ip_address=self.pg0.remote_ip6n,
9200 external_ip_address=self.nat_addr,
9204 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9205 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9207 self.pg0.add_stream([p])
9208 self.pg_enable_capture(self.pg_interfaces)
9210 capture = self.pg1.get_capture(1)
9213 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9214 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9216 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9219 def clear_nat66(self):
9221 Clear NAT66 configuration.
9223 interfaces = self.vapi.nat66_interface_dump()
9224 for intf in interfaces:
9225 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9226 sw_if_index=intf.sw_if_index)
9228 static_mappings = self.vapi.nat66_static_mapping_dump()
9229 for sm in static_mappings:
9230 self.vapi.nat66_add_del_static_mapping(
9231 local_ip_address=sm.local_ip_address,
9232 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9236 super(TestNAT66, self).tearDown()
9239 def show_commands_at_teardown(self):
9240 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9241 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9244 if __name__ == '__main__':
9245 unittest.main(testRunner=VppTestRunner)