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")
1461 cls.tcp_port_in = 6303
1462 cls.tcp_port_out = 6303
1463 cls.udp_port_in = 6304
1464 cls.udp_port_out = 6304
1465 cls.icmp_id_in = 6305
1466 cls.icmp_id_out = 6305
1467 cls.nat_addr = '10.0.0.3'
1468 cls.ipfix_src_port = 4739
1469 cls.ipfix_domain_id = 1
1470 cls.tcp_external_port = 80
1471 cls.udp_external_port = 69
1473 cls.create_pg_interfaces(range(10))
1474 cls.interfaces = list(cls.pg_interfaces[0:4])
1476 for i in cls.interfaces:
1481 cls.pg0.generate_remote_hosts(3)
1482 cls.pg0.configure_ipv4_neighbors()
1484 cls.pg1.generate_remote_hosts(1)
1485 cls.pg1.configure_ipv4_neighbors()
1487 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1488 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1489 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1491 cls.pg4._local_ip4 = "172.16.255.1"
1492 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1493 cls.pg4.set_table_ip4(10)
1494 cls.pg5._local_ip4 = "172.17.255.3"
1495 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1496 cls.pg5.set_table_ip4(10)
1497 cls.pg6._local_ip4 = "172.16.255.1"
1498 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1499 cls.pg6.set_table_ip4(20)
1500 for i in cls.overlapping_interfaces:
1508 cls.pg9.generate_remote_hosts(2)
1509 cls.pg9.config_ip4()
1510 cls.vapi.sw_interface_add_del_address(
1511 sw_if_index=cls.pg9.sw_if_index,
1512 prefix="10.0.0.1/24")
1515 cls.pg9.resolve_arp()
1516 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1517 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1518 cls.pg9.resolve_arp()
1521 super(TestNAT44, cls).tearDownClass()
1525 def tearDownClass(cls):
1526 super(TestNAT44, cls).tearDownClass()
1528 def test_dynamic(self):
1529 """ NAT44 dynamic translation test """
1530 self.nat44_add_address(self.nat_addr)
1531 flags = self.config_flags.NAT_IS_INSIDE
1532 self.vapi.nat44_interface_add_del_feature(
1533 sw_if_index=self.pg0.sw_if_index,
1534 flags=flags, is_add=1)
1535 self.vapi.nat44_interface_add_del_feature(
1536 sw_if_index=self.pg1.sw_if_index,
1540 tcpn = self.statistics.get_err_counter(
1541 '/err/nat44-in2out-slowpath/TCP packets')
1542 udpn = self.statistics.get_err_counter(
1543 '/err/nat44-in2out-slowpath/UDP packets')
1544 icmpn = self.statistics.get_err_counter(
1545 '/err/nat44-in2out-slowpath/ICMP packets')
1546 totaln = self.statistics.get_err_counter(
1547 '/err/nat44-in2out-slowpath/good in2out packets processed')
1549 pkts = self.create_stream_in(self.pg0, self.pg1)
1550 self.pg0.add_stream(pkts)
1551 self.pg_enable_capture(self.pg_interfaces)
1553 capture = self.pg1.get_capture(len(pkts))
1554 self.verify_capture_out(capture)
1556 err = self.statistics.get_err_counter(
1557 '/err/nat44-in2out-slowpath/TCP packets')
1558 self.assertEqual(err - tcpn, 2)
1559 err = self.statistics.get_err_counter(
1560 '/err/nat44-in2out-slowpath/UDP packets')
1561 self.assertEqual(err - udpn, 1)
1562 err = self.statistics.get_err_counter(
1563 '/err/nat44-in2out-slowpath/ICMP packets')
1564 self.assertEqual(err - icmpn, 1)
1565 err = self.statistics.get_err_counter(
1566 '/err/nat44-in2out-slowpath/good in2out packets processed')
1567 self.assertEqual(err - totaln, 4)
1570 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1571 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1572 icmpn = self.statistics.get_err_counter(
1573 '/err/nat44-out2in/ICMP packets')
1574 totaln = self.statistics.get_err_counter(
1575 '/err/nat44-out2in/good out2in packets processed')
1577 pkts = self.create_stream_out(self.pg1)
1578 self.pg1.add_stream(pkts)
1579 self.pg_enable_capture(self.pg_interfaces)
1581 capture = self.pg0.get_capture(len(pkts))
1582 self.verify_capture_in(capture, self.pg0)
1584 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1585 self.assertEqual(err - tcpn, 2)
1586 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1587 self.assertEqual(err - udpn, 1)
1588 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1589 self.assertEqual(err - icmpn, 1)
1590 err = self.statistics.get_err_counter(
1591 '/err/nat44-out2in/good out2in packets processed')
1592 self.assertEqual(err - totaln, 4)
1594 users = self.statistics.get_counter('/nat44/total-users')
1595 self.assertEqual(users[0][0], 1)
1596 sessions = self.statistics.get_counter('/nat44/total-sessions')
1597 self.assertEqual(sessions[0][0], 3)
1599 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1600 """ NAT44 handling of client packets with TTL=1 """
1602 self.nat44_add_address(self.nat_addr)
1603 flags = self.config_flags.NAT_IS_INSIDE
1604 self.vapi.nat44_interface_add_del_feature(
1605 sw_if_index=self.pg0.sw_if_index,
1606 flags=flags, is_add=1)
1607 self.vapi.nat44_interface_add_del_feature(
1608 sw_if_index=self.pg1.sw_if_index,
1611 # Client side - generate traffic
1612 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1613 self.pg0.add_stream(pkts)
1614 self.pg_enable_capture(self.pg_interfaces)
1617 # Client side - verify ICMP type 11 packets
1618 capture = self.pg0.get_capture(len(pkts))
1619 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1621 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1622 """ NAT44 handling of server packets with TTL=1 """
1624 self.nat44_add_address(self.nat_addr)
1625 flags = self.config_flags.NAT_IS_INSIDE
1626 self.vapi.nat44_interface_add_del_feature(
1627 sw_if_index=self.pg0.sw_if_index,
1628 flags=flags, is_add=1)
1629 self.vapi.nat44_interface_add_del_feature(
1630 sw_if_index=self.pg1.sw_if_index,
1633 # Client side - create sessions
1634 pkts = self.create_stream_in(self.pg0, self.pg1)
1635 self.pg0.add_stream(pkts)
1636 self.pg_enable_capture(self.pg_interfaces)
1639 # Server side - generate traffic
1640 capture = self.pg1.get_capture(len(pkts))
1641 self.verify_capture_out(capture)
1642 pkts = self.create_stream_out(self.pg1, ttl=1)
1643 self.pg1.add_stream(pkts)
1644 self.pg_enable_capture(self.pg_interfaces)
1647 # Server side - verify ICMP type 11 packets
1648 capture = self.pg1.get_capture(len(pkts))
1649 self.verify_capture_out_with_icmp_errors(capture,
1650 src_ip=self.pg1.local_ip4)
1652 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1653 """ NAT44 handling of error responses to client packets with TTL=2 """
1655 self.nat44_add_address(self.nat_addr)
1656 flags = self.config_flags.NAT_IS_INSIDE
1657 self.vapi.nat44_interface_add_del_feature(
1658 sw_if_index=self.pg0.sw_if_index,
1659 flags=flags, is_add=1)
1660 self.vapi.nat44_interface_add_del_feature(
1661 sw_if_index=self.pg1.sw_if_index,
1664 # Client side - generate traffic
1665 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1666 self.pg0.add_stream(pkts)
1667 self.pg_enable_capture(self.pg_interfaces)
1670 # Server side - simulate ICMP type 11 response
1671 capture = self.pg1.get_capture(len(pkts))
1672 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1673 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1674 ICMP(type=11) / packet[IP] for packet in capture]
1675 self.pg1.add_stream(pkts)
1676 self.pg_enable_capture(self.pg_interfaces)
1679 # Client side - verify ICMP type 11 packets
1680 capture = self.pg0.get_capture(len(pkts))
1681 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1683 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1684 """ NAT44 handling of error responses to server packets with TTL=2 """
1686 self.nat44_add_address(self.nat_addr)
1687 flags = self.config_flags.NAT_IS_INSIDE
1688 self.vapi.nat44_interface_add_del_feature(
1689 sw_if_index=self.pg0.sw_if_index,
1690 flags=flags, is_add=1)
1691 self.vapi.nat44_interface_add_del_feature(
1692 sw_if_index=self.pg1.sw_if_index,
1695 # Client side - create sessions
1696 pkts = self.create_stream_in(self.pg0, self.pg1)
1697 self.pg0.add_stream(pkts)
1698 self.pg_enable_capture(self.pg_interfaces)
1701 # Server side - generate traffic
1702 capture = self.pg1.get_capture(len(pkts))
1703 self.verify_capture_out(capture)
1704 pkts = self.create_stream_out(self.pg1, ttl=2)
1705 self.pg1.add_stream(pkts)
1706 self.pg_enable_capture(self.pg_interfaces)
1709 # Client side - simulate ICMP type 11 response
1710 capture = self.pg0.get_capture(len(pkts))
1711 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1712 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1713 ICMP(type=11) / packet[IP] for packet in capture]
1714 self.pg0.add_stream(pkts)
1715 self.pg_enable_capture(self.pg_interfaces)
1718 # Server side - verify ICMP type 11 packets
1719 capture = self.pg1.get_capture(len(pkts))
1720 self.verify_capture_out_with_icmp_errors(capture)
1722 def test_ping_out_interface_from_outside(self):
1723 """ Ping NAT44 out interface from outside network """
1725 self.nat44_add_address(self.nat_addr)
1726 flags = self.config_flags.NAT_IS_INSIDE
1727 self.vapi.nat44_interface_add_del_feature(
1728 sw_if_index=self.pg0.sw_if_index,
1729 flags=flags, is_add=1)
1730 self.vapi.nat44_interface_add_del_feature(
1731 sw_if_index=self.pg1.sw_if_index,
1734 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1735 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1736 ICMP(id=self.icmp_id_out, type='echo-request'))
1738 self.pg1.add_stream(pkts)
1739 self.pg_enable_capture(self.pg_interfaces)
1741 capture = self.pg1.get_capture(len(pkts))
1744 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1745 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1746 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1747 self.assertEqual(packet[ICMP].type, 0) # echo reply
1749 self.logger.error(ppp("Unexpected or invalid packet "
1750 "(outside network):", packet))
1753 def test_ping_internal_host_from_outside(self):
1754 """ Ping internal host from outside network """
1756 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1757 flags = self.config_flags.NAT_IS_INSIDE
1758 self.vapi.nat44_interface_add_del_feature(
1759 sw_if_index=self.pg0.sw_if_index,
1760 flags=flags, is_add=1)
1761 self.vapi.nat44_interface_add_del_feature(
1762 sw_if_index=self.pg1.sw_if_index,
1766 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1767 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1768 ICMP(id=self.icmp_id_out, type='echo-request'))
1769 self.pg1.add_stream(pkt)
1770 self.pg_enable_capture(self.pg_interfaces)
1772 capture = self.pg0.get_capture(1)
1773 self.verify_capture_in(capture, self.pg0)
1774 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1777 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1778 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1779 ICMP(id=self.icmp_id_in, type='echo-reply'))
1780 self.pg0.add_stream(pkt)
1781 self.pg_enable_capture(self.pg_interfaces)
1783 capture = self.pg1.get_capture(1)
1784 self.verify_capture_out(capture, same_port=True)
1785 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1787 def test_forwarding(self):
1788 """ NAT44 forwarding test """
1790 flags = self.config_flags.NAT_IS_INSIDE
1791 self.vapi.nat44_interface_add_del_feature(
1792 sw_if_index=self.pg0.sw_if_index,
1793 flags=flags, is_add=1)
1794 self.vapi.nat44_interface_add_del_feature(
1795 sw_if_index=self.pg1.sw_if_index,
1797 self.vapi.nat44_forwarding_enable_disable(enable=1)
1799 real_ip = self.pg0.remote_ip4
1800 alias_ip = self.nat_addr
1801 flags = self.config_flags.NAT_IS_ADDR_ONLY
1802 self.vapi.nat44_add_del_static_mapping(is_add=1,
1803 local_ip_address=real_ip,
1804 external_ip_address=alias_ip,
1805 external_sw_if_index=0xFFFFFFFF,
1809 # static mapping match
1811 pkts = self.create_stream_out(self.pg1)
1812 self.pg1.add_stream(pkts)
1813 self.pg_enable_capture(self.pg_interfaces)
1815 capture = self.pg0.get_capture(len(pkts))
1816 self.verify_capture_in(capture, self.pg0)
1818 pkts = self.create_stream_in(self.pg0, self.pg1)
1819 self.pg0.add_stream(pkts)
1820 self.pg_enable_capture(self.pg_interfaces)
1822 capture = self.pg1.get_capture(len(pkts))
1823 self.verify_capture_out(capture, same_port=True)
1825 # no static mapping match
1827 host0 = self.pg0.remote_hosts[0]
1828 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1830 pkts = self.create_stream_out(self.pg1,
1831 dst_ip=self.pg0.remote_ip4,
1832 use_inside_ports=True)
1833 self.pg1.add_stream(pkts)
1834 self.pg_enable_capture(self.pg_interfaces)
1836 capture = self.pg0.get_capture(len(pkts))
1837 self.verify_capture_in(capture, self.pg0)
1839 pkts = self.create_stream_in(self.pg0, self.pg1)
1840 self.pg0.add_stream(pkts)
1841 self.pg_enable_capture(self.pg_interfaces)
1843 capture = self.pg1.get_capture(len(pkts))
1844 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1847 self.pg0.remote_hosts[0] = host0
1850 self.vapi.nat44_forwarding_enable_disable(enable=0)
1851 flags = self.config_flags.NAT_IS_ADDR_ONLY
1852 self.vapi.nat44_add_del_static_mapping(
1854 local_ip_address=real_ip,
1855 external_ip_address=alias_ip,
1856 external_sw_if_index=0xFFFFFFFF,
1859 def test_static_in(self):
1860 """ 1:1 NAT initialized from inside network """
1862 nat_ip = "10.0.0.10"
1863 self.tcp_port_out = 6303
1864 self.udp_port_out = 6304
1865 self.icmp_id_out = 6305
1867 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1868 flags = self.config_flags.NAT_IS_INSIDE
1869 self.vapi.nat44_interface_add_del_feature(
1870 sw_if_index=self.pg0.sw_if_index,
1871 flags=flags, is_add=1)
1872 self.vapi.nat44_interface_add_del_feature(
1873 sw_if_index=self.pg1.sw_if_index,
1875 sm = self.vapi.nat44_static_mapping_dump()
1876 self.assertEqual(len(sm), 1)
1877 self.assertEqual(sm[0].tag, '')
1878 self.assertEqual(sm[0].protocol, 0)
1879 self.assertEqual(sm[0].local_port, 0)
1880 self.assertEqual(sm[0].external_port, 0)
1883 pkts = self.create_stream_in(self.pg0, self.pg1)
1884 self.pg0.add_stream(pkts)
1885 self.pg_enable_capture(self.pg_interfaces)
1887 capture = self.pg1.get_capture(len(pkts))
1888 self.verify_capture_out(capture, nat_ip, True)
1891 pkts = self.create_stream_out(self.pg1, nat_ip)
1892 self.pg1.add_stream(pkts)
1893 self.pg_enable_capture(self.pg_interfaces)
1895 capture = self.pg0.get_capture(len(pkts))
1896 self.verify_capture_in(capture, self.pg0)
1898 def test_static_out(self):
1899 """ 1:1 NAT initialized from outside network """
1901 nat_ip = "10.0.0.20"
1902 self.tcp_port_out = 6303
1903 self.udp_port_out = 6304
1904 self.icmp_id_out = 6305
1907 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1908 flags = self.config_flags.NAT_IS_INSIDE
1909 self.vapi.nat44_interface_add_del_feature(
1910 sw_if_index=self.pg0.sw_if_index,
1911 flags=flags, is_add=1)
1912 self.vapi.nat44_interface_add_del_feature(
1913 sw_if_index=self.pg1.sw_if_index,
1915 sm = self.vapi.nat44_static_mapping_dump()
1916 self.assertEqual(len(sm), 1)
1917 self.assertEqual(sm[0].tag, tag)
1920 pkts = self.create_stream_out(self.pg1, nat_ip)
1921 self.pg1.add_stream(pkts)
1922 self.pg_enable_capture(self.pg_interfaces)
1924 capture = self.pg0.get_capture(len(pkts))
1925 self.verify_capture_in(capture, self.pg0)
1928 pkts = self.create_stream_in(self.pg0, self.pg1)
1929 self.pg0.add_stream(pkts)
1930 self.pg_enable_capture(self.pg_interfaces)
1932 capture = self.pg1.get_capture(len(pkts))
1933 self.verify_capture_out(capture, nat_ip, True)
1935 def test_static_with_port_in(self):
1936 """ 1:1 NAPT initialized from inside network """
1938 self.tcp_port_out = 3606
1939 self.udp_port_out = 3607
1940 self.icmp_id_out = 3608
1942 self.nat44_add_address(self.nat_addr)
1943 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1944 self.tcp_port_in, self.tcp_port_out,
1945 proto=IP_PROTOS.tcp)
1946 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1947 self.udp_port_in, self.udp_port_out,
1948 proto=IP_PROTOS.udp)
1949 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1950 self.icmp_id_in, self.icmp_id_out,
1951 proto=IP_PROTOS.icmp)
1952 flags = self.config_flags.NAT_IS_INSIDE
1953 self.vapi.nat44_interface_add_del_feature(
1954 sw_if_index=self.pg0.sw_if_index,
1955 flags=flags, is_add=1)
1956 self.vapi.nat44_interface_add_del_feature(
1957 sw_if_index=self.pg1.sw_if_index,
1961 pkts = self.create_stream_in(self.pg0, self.pg1)
1962 self.pg0.add_stream(pkts)
1963 self.pg_enable_capture(self.pg_interfaces)
1965 capture = self.pg1.get_capture(len(pkts))
1966 self.verify_capture_out(capture)
1969 pkts = self.create_stream_out(self.pg1)
1970 self.pg1.add_stream(pkts)
1971 self.pg_enable_capture(self.pg_interfaces)
1973 capture = self.pg0.get_capture(len(pkts))
1974 self.verify_capture_in(capture, self.pg0)
1976 def test_static_with_port_out(self):
1977 """ 1:1 NAPT initialized from outside network """
1979 self.tcp_port_out = 30606
1980 self.udp_port_out = 30607
1981 self.icmp_id_out = 30608
1983 self.nat44_add_address(self.nat_addr)
1984 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1985 self.tcp_port_in, self.tcp_port_out,
1986 proto=IP_PROTOS.tcp)
1987 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1988 self.udp_port_in, self.udp_port_out,
1989 proto=IP_PROTOS.udp)
1990 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1991 self.icmp_id_in, self.icmp_id_out,
1992 proto=IP_PROTOS.icmp)
1993 flags = self.config_flags.NAT_IS_INSIDE
1994 self.vapi.nat44_interface_add_del_feature(
1995 sw_if_index=self.pg0.sw_if_index,
1996 flags=flags, is_add=1)
1997 self.vapi.nat44_interface_add_del_feature(
1998 sw_if_index=self.pg1.sw_if_index,
2002 pkts = self.create_stream_out(self.pg1)
2003 self.pg1.add_stream(pkts)
2004 self.pg_enable_capture(self.pg_interfaces)
2006 capture = self.pg0.get_capture(len(pkts))
2007 self.verify_capture_in(capture, self.pg0)
2010 pkts = self.create_stream_in(self.pg0, self.pg1)
2011 self.pg0.add_stream(pkts)
2012 self.pg_enable_capture(self.pg_interfaces)
2014 capture = self.pg1.get_capture(len(pkts))
2015 self.verify_capture_out(capture)
2017 def test_static_vrf_aware(self):
2018 """ 1:1 NAT VRF awareness """
2020 nat_ip1 = "10.0.0.30"
2021 nat_ip2 = "10.0.0.40"
2022 self.tcp_port_out = 6303
2023 self.udp_port_out = 6304
2024 self.icmp_id_out = 6305
2026 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2028 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2030 flags = self.config_flags.NAT_IS_INSIDE
2031 self.vapi.nat44_interface_add_del_feature(
2032 sw_if_index=self.pg3.sw_if_index,
2034 self.vapi.nat44_interface_add_del_feature(
2035 sw_if_index=self.pg0.sw_if_index,
2036 flags=flags, is_add=1)
2037 self.vapi.nat44_interface_add_del_feature(
2038 sw_if_index=self.pg4.sw_if_index,
2039 flags=flags, is_add=1)
2041 # inside interface VRF match NAT44 static mapping VRF
2042 pkts = self.create_stream_in(self.pg4, self.pg3)
2043 self.pg4.add_stream(pkts)
2044 self.pg_enable_capture(self.pg_interfaces)
2046 capture = self.pg3.get_capture(len(pkts))
2047 self.verify_capture_out(capture, nat_ip1, True)
2049 # inside interface VRF don't match NAT44 static mapping VRF (packets
2051 pkts = self.create_stream_in(self.pg0, self.pg3)
2052 self.pg0.add_stream(pkts)
2053 self.pg_enable_capture(self.pg_interfaces)
2055 self.pg3.assert_nothing_captured()
2057 def test_dynamic_to_static(self):
2058 """ Switch from dynamic translation to 1:1NAT """
2059 nat_ip = "10.0.0.10"
2060 self.tcp_port_out = 6303
2061 self.udp_port_out = 6304
2062 self.icmp_id_out = 6305
2064 self.nat44_add_address(self.nat_addr)
2065 flags = self.config_flags.NAT_IS_INSIDE
2066 self.vapi.nat44_interface_add_del_feature(
2067 sw_if_index=self.pg0.sw_if_index,
2068 flags=flags, is_add=1)
2069 self.vapi.nat44_interface_add_del_feature(
2070 sw_if_index=self.pg1.sw_if_index,
2074 pkts = self.create_stream_in(self.pg0, self.pg1)
2075 self.pg0.add_stream(pkts)
2076 self.pg_enable_capture(self.pg_interfaces)
2078 capture = self.pg1.get_capture(len(pkts))
2079 self.verify_capture_out(capture)
2082 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2083 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2084 self.assertEqual(len(sessions), 0)
2085 pkts = self.create_stream_in(self.pg0, self.pg1)
2086 self.pg0.add_stream(pkts)
2087 self.pg_enable_capture(self.pg_interfaces)
2089 capture = self.pg1.get_capture(len(pkts))
2090 self.verify_capture_out(capture, nat_ip, True)
2092 def test_identity_nat(self):
2093 """ Identity NAT """
2094 flags = self.config_flags.NAT_IS_ADDR_ONLY
2095 self.vapi.nat44_add_del_identity_mapping(
2096 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2097 flags=flags, is_add=1)
2098 flags = self.config_flags.NAT_IS_INSIDE
2099 self.vapi.nat44_interface_add_del_feature(
2100 sw_if_index=self.pg0.sw_if_index,
2101 flags=flags, is_add=1)
2102 self.vapi.nat44_interface_add_del_feature(
2103 sw_if_index=self.pg1.sw_if_index,
2106 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2107 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2108 TCP(sport=12345, dport=56789))
2109 self.pg1.add_stream(p)
2110 self.pg_enable_capture(self.pg_interfaces)
2112 capture = self.pg0.get_capture(1)
2117 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2118 self.assertEqual(ip.src, self.pg1.remote_ip4)
2119 self.assertEqual(tcp.dport, 56789)
2120 self.assertEqual(tcp.sport, 12345)
2121 self.assert_packet_checksums_valid(p)
2123 self.logger.error(ppp("Unexpected or invalid packet:", p))
2126 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2127 self.assertEqual(len(sessions), 0)
2128 flags = self.config_flags.NAT_IS_ADDR_ONLY
2129 self.vapi.nat44_add_del_identity_mapping(
2130 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2131 flags=flags, vrf_id=1, is_add=1)
2132 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2133 self.assertEqual(len(identity_mappings), 2)
2135 def test_multiple_inside_interfaces(self):
2136 """ NAT44 multiple non-overlapping address space inside interfaces """
2138 self.nat44_add_address(self.nat_addr)
2139 flags = self.config_flags.NAT_IS_INSIDE
2140 self.vapi.nat44_interface_add_del_feature(
2141 sw_if_index=self.pg0.sw_if_index,
2142 flags=flags, is_add=1)
2143 self.vapi.nat44_interface_add_del_feature(
2144 sw_if_index=self.pg1.sw_if_index,
2145 flags=flags, is_add=1)
2146 self.vapi.nat44_interface_add_del_feature(
2147 sw_if_index=self.pg3.sw_if_index,
2150 # between two NAT44 inside interfaces (no translation)
2151 pkts = self.create_stream_in(self.pg0, self.pg1)
2152 self.pg0.add_stream(pkts)
2153 self.pg_enable_capture(self.pg_interfaces)
2155 capture = self.pg1.get_capture(len(pkts))
2156 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2158 # from NAT44 inside to interface without NAT44 feature (no translation)
2159 pkts = self.create_stream_in(self.pg0, self.pg2)
2160 self.pg0.add_stream(pkts)
2161 self.pg_enable_capture(self.pg_interfaces)
2163 capture = self.pg2.get_capture(len(pkts))
2164 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2166 # in2out 1st interface
2167 pkts = self.create_stream_in(self.pg0, self.pg3)
2168 self.pg0.add_stream(pkts)
2169 self.pg_enable_capture(self.pg_interfaces)
2171 capture = self.pg3.get_capture(len(pkts))
2172 self.verify_capture_out(capture)
2174 # out2in 1st interface
2175 pkts = self.create_stream_out(self.pg3)
2176 self.pg3.add_stream(pkts)
2177 self.pg_enable_capture(self.pg_interfaces)
2179 capture = self.pg0.get_capture(len(pkts))
2180 self.verify_capture_in(capture, self.pg0)
2182 # in2out 2nd interface
2183 pkts = self.create_stream_in(self.pg1, self.pg3)
2184 self.pg1.add_stream(pkts)
2185 self.pg_enable_capture(self.pg_interfaces)
2187 capture = self.pg3.get_capture(len(pkts))
2188 self.verify_capture_out(capture)
2190 # out2in 2nd interface
2191 pkts = self.create_stream_out(self.pg3)
2192 self.pg3.add_stream(pkts)
2193 self.pg_enable_capture(self.pg_interfaces)
2195 capture = self.pg1.get_capture(len(pkts))
2196 self.verify_capture_in(capture, self.pg1)
2198 def test_inside_overlapping_interfaces(self):
2199 """ NAT44 multiple inside interfaces with overlapping address space """
2201 static_nat_ip = "10.0.0.10"
2202 self.nat44_add_address(self.nat_addr)
2203 flags = self.config_flags.NAT_IS_INSIDE
2204 self.vapi.nat44_interface_add_del_feature(
2205 sw_if_index=self.pg3.sw_if_index,
2207 self.vapi.nat44_interface_add_del_feature(
2208 sw_if_index=self.pg4.sw_if_index,
2209 flags=flags, is_add=1)
2210 self.vapi.nat44_interface_add_del_feature(
2211 sw_if_index=self.pg5.sw_if_index,
2212 flags=flags, is_add=1)
2213 self.vapi.nat44_interface_add_del_feature(
2214 sw_if_index=self.pg6.sw_if_index,
2215 flags=flags, is_add=1)
2216 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2219 # between NAT44 inside interfaces with same VRF (no translation)
2220 pkts = self.create_stream_in(self.pg4, self.pg5)
2221 self.pg4.add_stream(pkts)
2222 self.pg_enable_capture(self.pg_interfaces)
2224 capture = self.pg5.get_capture(len(pkts))
2225 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2227 # between NAT44 inside interfaces with different VRF (hairpinning)
2228 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2229 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2230 TCP(sport=1234, dport=5678))
2231 self.pg4.add_stream(p)
2232 self.pg_enable_capture(self.pg_interfaces)
2234 capture = self.pg6.get_capture(1)
2239 self.assertEqual(ip.src, self.nat_addr)
2240 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2241 self.assertNotEqual(tcp.sport, 1234)
2242 self.assertEqual(tcp.dport, 5678)
2244 self.logger.error(ppp("Unexpected or invalid packet:", p))
2247 # in2out 1st interface
2248 pkts = self.create_stream_in(self.pg4, self.pg3)
2249 self.pg4.add_stream(pkts)
2250 self.pg_enable_capture(self.pg_interfaces)
2252 capture = self.pg3.get_capture(len(pkts))
2253 self.verify_capture_out(capture)
2255 # out2in 1st interface
2256 pkts = self.create_stream_out(self.pg3)
2257 self.pg3.add_stream(pkts)
2258 self.pg_enable_capture(self.pg_interfaces)
2260 capture = self.pg4.get_capture(len(pkts))
2261 self.verify_capture_in(capture, self.pg4)
2263 # in2out 2nd interface
2264 pkts = self.create_stream_in(self.pg5, self.pg3)
2265 self.pg5.add_stream(pkts)
2266 self.pg_enable_capture(self.pg_interfaces)
2268 capture = self.pg3.get_capture(len(pkts))
2269 self.verify_capture_out(capture)
2271 # out2in 2nd interface
2272 pkts = self.create_stream_out(self.pg3)
2273 self.pg3.add_stream(pkts)
2274 self.pg_enable_capture(self.pg_interfaces)
2276 capture = self.pg5.get_capture(len(pkts))
2277 self.verify_capture_in(capture, self.pg5)
2280 addresses = self.vapi.nat44_address_dump()
2281 self.assertEqual(len(addresses), 1)
2282 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2283 self.assertEqual(len(sessions), 3)
2284 for session in sessions:
2285 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2286 self.assertEqual(str(session.inside_ip_address),
2287 self.pg5.remote_ip4)
2288 self.assertEqual(session.outside_ip_address,
2289 addresses[0].ip_address)
2290 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2291 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2292 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2293 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2294 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2295 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2296 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2297 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2298 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2300 # in2out 3rd interface
2301 pkts = self.create_stream_in(self.pg6, self.pg3)
2302 self.pg6.add_stream(pkts)
2303 self.pg_enable_capture(self.pg_interfaces)
2305 capture = self.pg3.get_capture(len(pkts))
2306 self.verify_capture_out(capture, static_nat_ip, True)
2308 # out2in 3rd interface
2309 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2310 self.pg3.add_stream(pkts)
2311 self.pg_enable_capture(self.pg_interfaces)
2313 capture = self.pg6.get_capture(len(pkts))
2314 self.verify_capture_in(capture, self.pg6)
2316 # general user and session dump verifications
2317 users = self.vapi.nat44_user_dump()
2318 self.assertGreaterEqual(len(users), 3)
2319 addresses = self.vapi.nat44_address_dump()
2320 self.assertEqual(len(addresses), 1)
2322 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2324 for session in sessions:
2325 self.assertEqual(user.ip_address, session.inside_ip_address)
2326 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2327 self.assertTrue(session.protocol in
2328 [IP_PROTOS.tcp, IP_PROTOS.udp,
2330 self.assertFalse(session.flags &
2331 self.config_flags.NAT_IS_EXT_HOST_VALID)
2334 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2335 self.assertGreaterEqual(len(sessions), 4)
2336 for session in sessions:
2337 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2338 self.assertEqual(str(session.inside_ip_address),
2339 self.pg4.remote_ip4)
2340 self.assertEqual(session.outside_ip_address,
2341 addresses[0].ip_address)
2344 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2345 self.assertGreaterEqual(len(sessions), 3)
2346 for session in sessions:
2347 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2348 self.assertEqual(str(session.inside_ip_address),
2349 self.pg6.remote_ip4)
2350 self.assertEqual(str(session.outside_ip_address),
2352 self.assertTrue(session.inside_port in
2353 [self.tcp_port_in, self.udp_port_in,
2356 def test_hairpinning(self):
2357 """ NAT44 hairpinning - 1:1 NAPT """
2359 host = self.pg0.remote_hosts[0]
2360 server = self.pg0.remote_hosts[1]
2363 server_in_port = 5678
2364 server_out_port = 8765
2366 self.nat44_add_address(self.nat_addr)
2367 flags = self.config_flags.NAT_IS_INSIDE
2368 self.vapi.nat44_interface_add_del_feature(
2369 sw_if_index=self.pg0.sw_if_index,
2370 flags=flags, is_add=1)
2371 self.vapi.nat44_interface_add_del_feature(
2372 sw_if_index=self.pg1.sw_if_index,
2375 # add static mapping for server
2376 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2377 server_in_port, server_out_port,
2378 proto=IP_PROTOS.tcp)
2380 # send packet from host to server
2381 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2382 IP(src=host.ip4, dst=self.nat_addr) /
2383 TCP(sport=host_in_port, dport=server_out_port))
2384 self.pg0.add_stream(p)
2385 self.pg_enable_capture(self.pg_interfaces)
2387 capture = self.pg0.get_capture(1)
2392 self.assertEqual(ip.src, self.nat_addr)
2393 self.assertEqual(ip.dst, server.ip4)
2394 self.assertNotEqual(tcp.sport, host_in_port)
2395 self.assertEqual(tcp.dport, server_in_port)
2396 self.assert_packet_checksums_valid(p)
2397 host_out_port = tcp.sport
2399 self.logger.error(ppp("Unexpected or invalid packet:", p))
2402 # send reply from server to host
2403 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2404 IP(src=server.ip4, dst=self.nat_addr) /
2405 TCP(sport=server_in_port, dport=host_out_port))
2406 self.pg0.add_stream(p)
2407 self.pg_enable_capture(self.pg_interfaces)
2409 capture = self.pg0.get_capture(1)
2414 self.assertEqual(ip.src, self.nat_addr)
2415 self.assertEqual(ip.dst, host.ip4)
2416 self.assertEqual(tcp.sport, server_out_port)
2417 self.assertEqual(tcp.dport, host_in_port)
2418 self.assert_packet_checksums_valid(p)
2420 self.logger.error(ppp("Unexpected or invalid packet:", p))
2423 def test_hairpinning2(self):
2424 """ NAT44 hairpinning - 1:1 NAT"""
2426 server1_nat_ip = "10.0.0.10"
2427 server2_nat_ip = "10.0.0.11"
2428 host = self.pg0.remote_hosts[0]
2429 server1 = self.pg0.remote_hosts[1]
2430 server2 = self.pg0.remote_hosts[2]
2431 server_tcp_port = 22
2432 server_udp_port = 20
2434 self.nat44_add_address(self.nat_addr)
2435 flags = self.config_flags.NAT_IS_INSIDE
2436 self.vapi.nat44_interface_add_del_feature(
2437 sw_if_index=self.pg0.sw_if_index,
2438 flags=flags, is_add=1)
2439 self.vapi.nat44_interface_add_del_feature(
2440 sw_if_index=self.pg1.sw_if_index,
2443 # add static mapping for servers
2444 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2445 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2449 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2450 IP(src=host.ip4, dst=server1_nat_ip) /
2451 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2453 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2454 IP(src=host.ip4, dst=server1_nat_ip) /
2455 UDP(sport=self.udp_port_in, dport=server_udp_port))
2457 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2458 IP(src=host.ip4, dst=server1_nat_ip) /
2459 ICMP(id=self.icmp_id_in, type='echo-request'))
2461 self.pg0.add_stream(pkts)
2462 self.pg_enable_capture(self.pg_interfaces)
2464 capture = self.pg0.get_capture(len(pkts))
2465 for packet in capture:
2467 self.assertEqual(packet[IP].src, self.nat_addr)
2468 self.assertEqual(packet[IP].dst, server1.ip4)
2469 if packet.haslayer(TCP):
2470 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2471 self.assertEqual(packet[TCP].dport, server_tcp_port)
2472 self.tcp_port_out = packet[TCP].sport
2473 self.assert_packet_checksums_valid(packet)
2474 elif packet.haslayer(UDP):
2475 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2476 self.assertEqual(packet[UDP].dport, server_udp_port)
2477 self.udp_port_out = packet[UDP].sport
2479 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2480 self.icmp_id_out = packet[ICMP].id
2482 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2487 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2488 IP(src=server1.ip4, dst=self.nat_addr) /
2489 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2491 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2492 IP(src=server1.ip4, dst=self.nat_addr) /
2493 UDP(sport=server_udp_port, dport=self.udp_port_out))
2495 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2496 IP(src=server1.ip4, dst=self.nat_addr) /
2497 ICMP(id=self.icmp_id_out, type='echo-reply'))
2499 self.pg0.add_stream(pkts)
2500 self.pg_enable_capture(self.pg_interfaces)
2502 capture = self.pg0.get_capture(len(pkts))
2503 for packet in capture:
2505 self.assertEqual(packet[IP].src, server1_nat_ip)
2506 self.assertEqual(packet[IP].dst, host.ip4)
2507 if packet.haslayer(TCP):
2508 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2509 self.assertEqual(packet[TCP].sport, server_tcp_port)
2510 self.assert_packet_checksums_valid(packet)
2511 elif packet.haslayer(UDP):
2512 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2513 self.assertEqual(packet[UDP].sport, server_udp_port)
2515 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2517 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2520 # server2 to server1
2522 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2523 IP(src=server2.ip4, dst=server1_nat_ip) /
2524 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2526 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2527 IP(src=server2.ip4, dst=server1_nat_ip) /
2528 UDP(sport=self.udp_port_in, dport=server_udp_port))
2530 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2531 IP(src=server2.ip4, dst=server1_nat_ip) /
2532 ICMP(id=self.icmp_id_in, type='echo-request'))
2534 self.pg0.add_stream(pkts)
2535 self.pg_enable_capture(self.pg_interfaces)
2537 capture = self.pg0.get_capture(len(pkts))
2538 for packet in capture:
2540 self.assertEqual(packet[IP].src, server2_nat_ip)
2541 self.assertEqual(packet[IP].dst, server1.ip4)
2542 if packet.haslayer(TCP):
2543 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2544 self.assertEqual(packet[TCP].dport, server_tcp_port)
2545 self.tcp_port_out = packet[TCP].sport
2546 self.assert_packet_checksums_valid(packet)
2547 elif packet.haslayer(UDP):
2548 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2549 self.assertEqual(packet[UDP].dport, server_udp_port)
2550 self.udp_port_out = packet[UDP].sport
2552 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2553 self.icmp_id_out = packet[ICMP].id
2555 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2558 # server1 to server2
2560 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2561 IP(src=server1.ip4, dst=server2_nat_ip) /
2562 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2564 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2565 IP(src=server1.ip4, dst=server2_nat_ip) /
2566 UDP(sport=server_udp_port, dport=self.udp_port_out))
2568 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2569 IP(src=server1.ip4, dst=server2_nat_ip) /
2570 ICMP(id=self.icmp_id_out, type='echo-reply'))
2572 self.pg0.add_stream(pkts)
2573 self.pg_enable_capture(self.pg_interfaces)
2575 capture = self.pg0.get_capture(len(pkts))
2576 for packet in capture:
2578 self.assertEqual(packet[IP].src, server1_nat_ip)
2579 self.assertEqual(packet[IP].dst, server2.ip4)
2580 if packet.haslayer(TCP):
2581 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2582 self.assertEqual(packet[TCP].sport, server_tcp_port)
2583 self.assert_packet_checksums_valid(packet)
2584 elif packet.haslayer(UDP):
2585 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2586 self.assertEqual(packet[UDP].sport, server_udp_port)
2588 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2590 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2593 def test_interface_addr(self):
2594 """ Acquire NAT44 addresses from interface """
2595 self.vapi.nat44_add_del_interface_addr(
2597 sw_if_index=self.pg7.sw_if_index)
2599 # no address in NAT pool
2600 addresses = self.vapi.nat44_address_dump()
2601 self.assertEqual(0, len(addresses))
2603 # configure interface address and check NAT address pool
2604 self.pg7.config_ip4()
2605 addresses = self.vapi.nat44_address_dump()
2606 self.assertEqual(1, len(addresses))
2607 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2609 # remove interface address and check NAT address pool
2610 self.pg7.unconfig_ip4()
2611 addresses = self.vapi.nat44_address_dump()
2612 self.assertEqual(0, len(addresses))
2614 def test_interface_addr_static_mapping(self):
2615 """ Static mapping with addresses from interface """
2618 self.vapi.nat44_add_del_interface_addr(
2620 sw_if_index=self.pg7.sw_if_index)
2621 self.nat44_add_static_mapping(
2623 external_sw_if_index=self.pg7.sw_if_index,
2626 # static mappings with external interface
2627 static_mappings = self.vapi.nat44_static_mapping_dump()
2628 self.assertEqual(1, len(static_mappings))
2629 self.assertEqual(self.pg7.sw_if_index,
2630 static_mappings[0].external_sw_if_index)
2631 self.assertEqual(static_mappings[0].tag, tag)
2633 # configure interface address and check static mappings
2634 self.pg7.config_ip4()
2635 static_mappings = self.vapi.nat44_static_mapping_dump()
2636 self.assertEqual(2, len(static_mappings))
2638 for sm in static_mappings:
2639 if sm.external_sw_if_index == 0xFFFFFFFF:
2640 self.assertEqual(str(sm.external_ip_address),
2642 self.assertEqual(sm.tag, tag)
2644 self.assertTrue(resolved)
2646 # remove interface address and check static mappings
2647 self.pg7.unconfig_ip4()
2648 static_mappings = self.vapi.nat44_static_mapping_dump()
2649 self.assertEqual(1, len(static_mappings))
2650 self.assertEqual(self.pg7.sw_if_index,
2651 static_mappings[0].external_sw_if_index)
2652 self.assertEqual(static_mappings[0].tag, tag)
2654 # configure interface address again and check static mappings
2655 self.pg7.config_ip4()
2656 static_mappings = self.vapi.nat44_static_mapping_dump()
2657 self.assertEqual(2, len(static_mappings))
2659 for sm in static_mappings:
2660 if sm.external_sw_if_index == 0xFFFFFFFF:
2661 self.assertEqual(str(sm.external_ip_address),
2663 self.assertEqual(sm.tag, tag)
2665 self.assertTrue(resolved)
2667 # remove static mapping
2668 self.nat44_add_static_mapping(
2670 external_sw_if_index=self.pg7.sw_if_index,
2673 static_mappings = self.vapi.nat44_static_mapping_dump()
2674 self.assertEqual(0, len(static_mappings))
2676 def test_interface_addr_identity_nat(self):
2677 """ Identity NAT with addresses from interface """
2680 self.vapi.nat44_add_del_interface_addr(
2682 sw_if_index=self.pg7.sw_if_index)
2683 self.vapi.nat44_add_del_identity_mapping(
2685 sw_if_index=self.pg7.sw_if_index,
2687 protocol=IP_PROTOS.tcp,
2690 # identity mappings with external interface
2691 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2692 self.assertEqual(1, len(identity_mappings))
2693 self.assertEqual(self.pg7.sw_if_index,
2694 identity_mappings[0].sw_if_index)
2696 # configure interface address and check identity mappings
2697 self.pg7.config_ip4()
2698 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2700 self.assertEqual(2, len(identity_mappings))
2701 for sm in identity_mappings:
2702 if sm.sw_if_index == 0xFFFFFFFF:
2703 self.assertEqual(str(identity_mappings[0].ip_address),
2705 self.assertEqual(port, identity_mappings[0].port)
2706 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2708 self.assertTrue(resolved)
2710 # remove interface address and check identity mappings
2711 self.pg7.unconfig_ip4()
2712 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2713 self.assertEqual(1, len(identity_mappings))
2714 self.assertEqual(self.pg7.sw_if_index,
2715 identity_mappings[0].sw_if_index)
2717 def test_ipfix_nat44_sess(self):
2718 """ IPFIX logging NAT44 session created/deleted """
2719 self.ipfix_domain_id = 10
2720 self.ipfix_src_port = 20202
2721 collector_port = 30303
2722 bind_layers(UDP, IPFIX, dport=30303)
2723 self.nat44_add_address(self.nat_addr)
2724 flags = self.config_flags.NAT_IS_INSIDE
2725 self.vapi.nat44_interface_add_del_feature(
2726 sw_if_index=self.pg0.sw_if_index,
2727 flags=flags, is_add=1)
2728 self.vapi.nat44_interface_add_del_feature(
2729 sw_if_index=self.pg1.sw_if_index,
2731 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2732 src_address=self.pg3.local_ip4,
2734 template_interval=10,
2735 collector_port=collector_port)
2736 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2737 src_port=self.ipfix_src_port,
2740 pkts = self.create_stream_in(self.pg0, self.pg1)
2741 self.pg0.add_stream(pkts)
2742 self.pg_enable_capture(self.pg_interfaces)
2744 capture = self.pg1.get_capture(len(pkts))
2745 self.verify_capture_out(capture)
2746 self.nat44_add_address(self.nat_addr, is_add=0)
2747 self.vapi.ipfix_flush()
2748 capture = self.pg3.get_capture(9)
2749 ipfix = IPFIXDecoder()
2750 # first load template
2752 self.assertTrue(p.haslayer(IPFIX))
2753 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2754 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2755 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2756 self.assertEqual(p[UDP].dport, collector_port)
2757 self.assertEqual(p[IPFIX].observationDomainID,
2758 self.ipfix_domain_id)
2759 if p.haslayer(Template):
2760 ipfix.add_template(p.getlayer(Template))
2761 # verify events in data set
2763 if p.haslayer(Data):
2764 data = ipfix.decode_data_set(p.getlayer(Set))
2765 self.verify_ipfix_nat44_ses(data)
2767 def test_ipfix_addr_exhausted(self):
2768 """ IPFIX logging NAT addresses exhausted """
2769 flags = self.config_flags.NAT_IS_INSIDE
2770 self.vapi.nat44_interface_add_del_feature(
2771 sw_if_index=self.pg0.sw_if_index,
2772 flags=flags, is_add=1)
2773 self.vapi.nat44_interface_add_del_feature(
2774 sw_if_index=self.pg1.sw_if_index,
2776 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2777 src_address=self.pg3.local_ip4,
2779 template_interval=10)
2780 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2781 src_port=self.ipfix_src_port,
2784 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2785 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2787 self.pg0.add_stream(p)
2788 self.pg_enable_capture(self.pg_interfaces)
2790 self.pg1.assert_nothing_captured()
2792 self.vapi.ipfix_flush()
2793 capture = self.pg3.get_capture(9)
2794 ipfix = IPFIXDecoder()
2795 # first load template
2797 self.assertTrue(p.haslayer(IPFIX))
2798 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2799 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2800 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2801 self.assertEqual(p[UDP].dport, 4739)
2802 self.assertEqual(p[IPFIX].observationDomainID,
2803 self.ipfix_domain_id)
2804 if p.haslayer(Template):
2805 ipfix.add_template(p.getlayer(Template))
2806 # verify events in data set
2808 if p.haslayer(Data):
2809 data = ipfix.decode_data_set(p.getlayer(Set))
2810 self.verify_ipfix_addr_exhausted(data)
2812 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2813 def test_ipfix_max_sessions(self):
2814 """ IPFIX logging maximum session entries exceeded """
2815 self.nat44_add_address(self.nat_addr)
2816 flags = self.config_flags.NAT_IS_INSIDE
2817 self.vapi.nat44_interface_add_del_feature(
2818 sw_if_index=self.pg0.sw_if_index,
2819 flags=flags, is_add=1)
2820 self.vapi.nat44_interface_add_del_feature(
2821 sw_if_index=self.pg1.sw_if_index,
2824 nat44_config = self.vapi.nat_show_config()
2825 max_sessions = 10 * nat44_config.translation_buckets
2828 for i in range(0, max_sessions):
2829 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2830 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2831 IP(src=src, dst=self.pg1.remote_ip4) /
2834 self.pg0.add_stream(pkts)
2835 self.pg_enable_capture(self.pg_interfaces)
2838 self.pg1.get_capture(max_sessions)
2839 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2840 src_address=self.pg3.local_ip4,
2842 template_interval=10)
2843 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2844 src_port=self.ipfix_src_port,
2847 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2848 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2850 self.pg0.add_stream(p)
2851 self.pg_enable_capture(self.pg_interfaces)
2853 self.pg1.assert_nothing_captured()
2855 self.vapi.ipfix_flush()
2856 capture = self.pg3.get_capture(9)
2857 ipfix = IPFIXDecoder()
2858 # first load template
2860 self.assertTrue(p.haslayer(IPFIX))
2861 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2862 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2863 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2864 self.assertEqual(p[UDP].dport, 4739)
2865 self.assertEqual(p[IPFIX].observationDomainID,
2866 self.ipfix_domain_id)
2867 if p.haslayer(Template):
2868 ipfix.add_template(p.getlayer(Template))
2869 # verify events in data set
2871 if p.haslayer(Data):
2872 data = ipfix.decode_data_set(p.getlayer(Set))
2873 self.verify_ipfix_max_sessions(data, max_sessions)
2875 def test_syslog_apmap(self):
2876 """ Test syslog address and port mapping creation and deletion """
2877 self.vapi.syslog_set_filter(
2878 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2879 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2880 self.nat44_add_address(self.nat_addr)
2881 flags = self.config_flags.NAT_IS_INSIDE
2882 self.vapi.nat44_interface_add_del_feature(
2883 sw_if_index=self.pg0.sw_if_index,
2884 flags=flags, is_add=1)
2885 self.vapi.nat44_interface_add_del_feature(
2886 sw_if_index=self.pg1.sw_if_index,
2889 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2890 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2891 TCP(sport=self.tcp_port_in, dport=20))
2892 self.pg0.add_stream(p)
2893 self.pg_enable_capture(self.pg_interfaces)
2895 capture = self.pg1.get_capture(1)
2896 self.tcp_port_out = capture[0][TCP].sport
2897 capture = self.pg3.get_capture(1)
2898 self.verify_syslog_apmap(capture[0][Raw].load)
2900 self.pg_enable_capture(self.pg_interfaces)
2902 self.nat44_add_address(self.nat_addr, is_add=0)
2903 capture = self.pg3.get_capture(1)
2904 self.verify_syslog_apmap(capture[0][Raw].load, False)
2906 def test_pool_addr_fib(self):
2907 """ NAT44 add pool addresses to FIB """
2908 static_addr = '10.0.0.10'
2909 self.nat44_add_address(self.nat_addr)
2910 flags = self.config_flags.NAT_IS_INSIDE
2911 self.vapi.nat44_interface_add_del_feature(
2912 sw_if_index=self.pg0.sw_if_index,
2913 flags=flags, is_add=1)
2914 self.vapi.nat44_interface_add_del_feature(
2915 sw_if_index=self.pg1.sw_if_index,
2917 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2920 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2921 ARP(op=ARP.who_has, pdst=self.nat_addr,
2922 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2923 self.pg1.add_stream(p)
2924 self.pg_enable_capture(self.pg_interfaces)
2926 capture = self.pg1.get_capture(1)
2927 self.assertTrue(capture[0].haslayer(ARP))
2928 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2931 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2932 ARP(op=ARP.who_has, pdst=static_addr,
2933 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2934 self.pg1.add_stream(p)
2935 self.pg_enable_capture(self.pg_interfaces)
2937 capture = self.pg1.get_capture(1)
2938 self.assertTrue(capture[0].haslayer(ARP))
2939 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2941 # send ARP to non-NAT44 interface
2942 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2943 ARP(op=ARP.who_has, pdst=self.nat_addr,
2944 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2945 self.pg2.add_stream(p)
2946 self.pg_enable_capture(self.pg_interfaces)
2948 self.pg1.assert_nothing_captured()
2950 # remove addresses and verify
2951 self.nat44_add_address(self.nat_addr, is_add=0)
2952 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2955 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2956 ARP(op=ARP.who_has, pdst=self.nat_addr,
2957 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2958 self.pg1.add_stream(p)
2959 self.pg_enable_capture(self.pg_interfaces)
2961 self.pg1.assert_nothing_captured()
2963 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2964 ARP(op=ARP.who_has, pdst=static_addr,
2965 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2966 self.pg1.add_stream(p)
2967 self.pg_enable_capture(self.pg_interfaces)
2969 self.pg1.assert_nothing_captured()
2971 def test_vrf_mode(self):
2972 """ NAT44 tenant VRF aware address pool mode """
2976 nat_ip1 = "10.0.0.10"
2977 nat_ip2 = "10.0.0.11"
2979 self.pg0.unconfig_ip4()
2980 self.pg1.unconfig_ip4()
2981 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2982 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2983 self.pg0.set_table_ip4(vrf_id1)
2984 self.pg1.set_table_ip4(vrf_id2)
2985 self.pg0.config_ip4()
2986 self.pg1.config_ip4()
2987 self.pg0.resolve_arp()
2988 self.pg1.resolve_arp()
2990 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2991 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2992 flags = self.config_flags.NAT_IS_INSIDE
2993 self.vapi.nat44_interface_add_del_feature(
2994 sw_if_index=self.pg0.sw_if_index,
2995 flags=flags, is_add=1)
2996 self.vapi.nat44_interface_add_del_feature(
2997 sw_if_index=self.pg1.sw_if_index,
2998 flags=flags, is_add=1)
2999 self.vapi.nat44_interface_add_del_feature(
3000 sw_if_index=self.pg2.sw_if_index,
3005 pkts = self.create_stream_in(self.pg0, self.pg2)
3006 self.pg0.add_stream(pkts)
3007 self.pg_enable_capture(self.pg_interfaces)
3009 capture = self.pg2.get_capture(len(pkts))
3010 self.verify_capture_out(capture, nat_ip1)
3013 pkts = self.create_stream_in(self.pg1, self.pg2)
3014 self.pg1.add_stream(pkts)
3015 self.pg_enable_capture(self.pg_interfaces)
3017 capture = self.pg2.get_capture(len(pkts))
3018 self.verify_capture_out(capture, nat_ip2)
3021 self.pg0.unconfig_ip4()
3022 self.pg1.unconfig_ip4()
3023 self.pg0.set_table_ip4(0)
3024 self.pg1.set_table_ip4(0)
3025 self.pg0.config_ip4()
3026 self.pg1.config_ip4()
3027 self.pg0.resolve_arp()
3028 self.pg1.resolve_arp()
3029 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3030 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3032 def test_vrf_feature_independent(self):
3033 """ NAT44 tenant VRF independent address pool mode """
3035 nat_ip1 = "10.0.0.10"
3036 nat_ip2 = "10.0.0.11"
3038 self.nat44_add_address(nat_ip1)
3039 self.nat44_add_address(nat_ip2, vrf_id=99)
3040 flags = self.config_flags.NAT_IS_INSIDE
3041 self.vapi.nat44_interface_add_del_feature(
3042 sw_if_index=self.pg0.sw_if_index,
3043 flags=flags, is_add=1)
3044 self.vapi.nat44_interface_add_del_feature(
3045 sw_if_index=self.pg1.sw_if_index,
3046 flags=flags, is_add=1)
3047 self.vapi.nat44_interface_add_del_feature(
3048 sw_if_index=self.pg2.sw_if_index,
3052 pkts = self.create_stream_in(self.pg0, self.pg2)
3053 self.pg0.add_stream(pkts)
3054 self.pg_enable_capture(self.pg_interfaces)
3056 capture = self.pg2.get_capture(len(pkts))
3057 self.verify_capture_out(capture, nat_ip1)
3060 pkts = self.create_stream_in(self.pg1, self.pg2)
3061 self.pg1.add_stream(pkts)
3062 self.pg_enable_capture(self.pg_interfaces)
3064 capture = self.pg2.get_capture(len(pkts))
3065 self.verify_capture_out(capture, nat_ip1)
3067 def create_routes_and_neigbors(self):
3068 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3069 [VppRoutePath(self.pg7.remote_ip4,
3070 self.pg7.sw_if_index)])
3071 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3072 [VppRoutePath(self.pg8.remote_ip4,
3073 self.pg8.sw_if_index)])
3077 n1 = VppNeighbor(self,
3078 self.pg7.sw_if_index,
3079 self.pg7.remote_mac,
3080 self.pg7.remote_ip4,
3082 n2 = VppNeighbor(self,
3083 self.pg8.sw_if_index,
3084 self.pg8.remote_mac,
3085 self.pg8.remote_ip4,
3090 def test_dynamic_ipless_interfaces(self):
3091 """ NAT44 interfaces without configured IP address """
3092 self.create_routes_and_neigbors()
3093 self.nat44_add_address(self.nat_addr)
3094 flags = self.config_flags.NAT_IS_INSIDE
3095 self.vapi.nat44_interface_add_del_feature(
3096 sw_if_index=self.pg7.sw_if_index,
3097 flags=flags, is_add=1)
3098 self.vapi.nat44_interface_add_del_feature(
3099 sw_if_index=self.pg8.sw_if_index,
3103 pkts = self.create_stream_in(self.pg7, self.pg8)
3104 self.pg7.add_stream(pkts)
3105 self.pg_enable_capture(self.pg_interfaces)
3107 capture = self.pg8.get_capture(len(pkts))
3108 self.verify_capture_out(capture)
3111 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3112 self.pg8.add_stream(pkts)
3113 self.pg_enable_capture(self.pg_interfaces)
3115 capture = self.pg7.get_capture(len(pkts))
3116 self.verify_capture_in(capture, self.pg7)
3118 def test_static_ipless_interfaces(self):
3119 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3121 self.create_routes_and_neigbors()
3122 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3123 flags = self.config_flags.NAT_IS_INSIDE
3124 self.vapi.nat44_interface_add_del_feature(
3125 sw_if_index=self.pg7.sw_if_index,
3126 flags=flags, is_add=1)
3127 self.vapi.nat44_interface_add_del_feature(
3128 sw_if_index=self.pg8.sw_if_index,
3132 pkts = self.create_stream_out(self.pg8)
3133 self.pg8.add_stream(pkts)
3134 self.pg_enable_capture(self.pg_interfaces)
3136 capture = self.pg7.get_capture(len(pkts))
3137 self.verify_capture_in(capture, self.pg7)
3140 pkts = self.create_stream_in(self.pg7, self.pg8)
3141 self.pg7.add_stream(pkts)
3142 self.pg_enable_capture(self.pg_interfaces)
3144 capture = self.pg8.get_capture(len(pkts))
3145 self.verify_capture_out(capture, self.nat_addr, True)
3147 def test_static_with_port_ipless_interfaces(self):
3148 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3150 self.tcp_port_out = 30606
3151 self.udp_port_out = 30607
3152 self.icmp_id_out = 30608
3154 self.create_routes_and_neigbors()
3155 self.nat44_add_address(self.nat_addr)
3156 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3157 self.tcp_port_in, self.tcp_port_out,
3158 proto=IP_PROTOS.tcp)
3159 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3160 self.udp_port_in, self.udp_port_out,
3161 proto=IP_PROTOS.udp)
3162 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3163 self.icmp_id_in, self.icmp_id_out,
3164 proto=IP_PROTOS.icmp)
3165 flags = self.config_flags.NAT_IS_INSIDE
3166 self.vapi.nat44_interface_add_del_feature(
3167 sw_if_index=self.pg7.sw_if_index,
3168 flags=flags, is_add=1)
3169 self.vapi.nat44_interface_add_del_feature(
3170 sw_if_index=self.pg8.sw_if_index,
3174 pkts = self.create_stream_out(self.pg8)
3175 self.pg8.add_stream(pkts)
3176 self.pg_enable_capture(self.pg_interfaces)
3178 capture = self.pg7.get_capture(len(pkts))
3179 self.verify_capture_in(capture, self.pg7)
3182 pkts = self.create_stream_in(self.pg7, self.pg8)
3183 self.pg7.add_stream(pkts)
3184 self.pg_enable_capture(self.pg_interfaces)
3186 capture = self.pg8.get_capture(len(pkts))
3187 self.verify_capture_out(capture)
3189 def test_static_unknown_proto(self):
3190 """ 1:1 NAT translate packet with unknown protocol """
3191 nat_ip = "10.0.0.10"
3192 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3193 flags = self.config_flags.NAT_IS_INSIDE
3194 self.vapi.nat44_interface_add_del_feature(
3195 sw_if_index=self.pg0.sw_if_index,
3196 flags=flags, is_add=1)
3197 self.vapi.nat44_interface_add_del_feature(
3198 sw_if_index=self.pg1.sw_if_index,
3202 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3203 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3205 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3206 TCP(sport=1234, dport=1234))
3207 self.pg0.add_stream(p)
3208 self.pg_enable_capture(self.pg_interfaces)
3210 p = self.pg1.get_capture(1)
3213 self.assertEqual(packet[IP].src, nat_ip)
3214 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3215 self.assertEqual(packet.haslayer(GRE), 1)
3216 self.assert_packet_checksums_valid(packet)
3218 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3222 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3223 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3225 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3226 TCP(sport=1234, dport=1234))
3227 self.pg1.add_stream(p)
3228 self.pg_enable_capture(self.pg_interfaces)
3230 p = self.pg0.get_capture(1)
3233 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3234 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3235 self.assertEqual(packet.haslayer(GRE), 1)
3236 self.assert_packet_checksums_valid(packet)
3238 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3241 def test_hairpinning_static_unknown_proto(self):
3242 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3244 host = self.pg0.remote_hosts[0]
3245 server = self.pg0.remote_hosts[1]
3247 host_nat_ip = "10.0.0.10"
3248 server_nat_ip = "10.0.0.11"
3250 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3251 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3252 flags = self.config_flags.NAT_IS_INSIDE
3253 self.vapi.nat44_interface_add_del_feature(
3254 sw_if_index=self.pg0.sw_if_index,
3255 flags=flags, is_add=1)
3256 self.vapi.nat44_interface_add_del_feature(
3257 sw_if_index=self.pg1.sw_if_index,
3261 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3262 IP(src=host.ip4, dst=server_nat_ip) /
3264 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3265 TCP(sport=1234, dport=1234))
3266 self.pg0.add_stream(p)
3267 self.pg_enable_capture(self.pg_interfaces)
3269 p = self.pg0.get_capture(1)
3272 self.assertEqual(packet[IP].src, host_nat_ip)
3273 self.assertEqual(packet[IP].dst, server.ip4)
3274 self.assertEqual(packet.haslayer(GRE), 1)
3275 self.assert_packet_checksums_valid(packet)
3277 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3281 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3282 IP(src=server.ip4, dst=host_nat_ip) /
3284 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3285 TCP(sport=1234, dport=1234))
3286 self.pg0.add_stream(p)
3287 self.pg_enable_capture(self.pg_interfaces)
3289 p = self.pg0.get_capture(1)
3292 self.assertEqual(packet[IP].src, server_nat_ip)
3293 self.assertEqual(packet[IP].dst, host.ip4)
3294 self.assertEqual(packet.haslayer(GRE), 1)
3295 self.assert_packet_checksums_valid(packet)
3297 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3300 def test_output_feature(self):
3301 """ NAT44 interface output feature (in2out postrouting) """
3302 self.nat44_add_address(self.nat_addr)
3303 flags = self.config_flags.NAT_IS_INSIDE
3304 self.vapi.nat44_interface_add_del_output_feature(
3305 is_add=1, flags=flags,
3306 sw_if_index=self.pg0.sw_if_index)
3307 self.vapi.nat44_interface_add_del_output_feature(
3308 is_add=1, flags=flags,
3309 sw_if_index=self.pg1.sw_if_index)
3310 self.vapi.nat44_interface_add_del_output_feature(
3312 sw_if_index=self.pg3.sw_if_index)
3315 pkts = self.create_stream_in(self.pg0, self.pg3)
3316 self.pg0.add_stream(pkts)
3317 self.pg_enable_capture(self.pg_interfaces)
3319 capture = self.pg3.get_capture(len(pkts))
3320 self.verify_capture_out(capture)
3323 pkts = self.create_stream_out(self.pg3)
3324 self.pg3.add_stream(pkts)
3325 self.pg_enable_capture(self.pg_interfaces)
3327 capture = self.pg0.get_capture(len(pkts))
3328 self.verify_capture_in(capture, self.pg0)
3330 # from non-NAT interface to NAT inside interface
3331 pkts = self.create_stream_in(self.pg2, self.pg0)
3332 self.pg2.add_stream(pkts)
3333 self.pg_enable_capture(self.pg_interfaces)
3335 capture = self.pg0.get_capture(len(pkts))
3336 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3338 def test_output_feature_vrf_aware(self):
3339 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3340 nat_ip_vrf10 = "10.0.0.10"
3341 nat_ip_vrf20 = "10.0.0.20"
3343 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3344 [VppRoutePath(self.pg3.remote_ip4,
3345 self.pg3.sw_if_index)],
3347 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3348 [VppRoutePath(self.pg3.remote_ip4,
3349 self.pg3.sw_if_index)],
3354 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3355 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3356 flags = self.config_flags.NAT_IS_INSIDE
3357 self.vapi.nat44_interface_add_del_output_feature(
3358 is_add=1, flags=flags,
3359 sw_if_index=self.pg4.sw_if_index)
3360 self.vapi.nat44_interface_add_del_output_feature(
3361 is_add=1, flags=flags,
3362 sw_if_index=self.pg6.sw_if_index)
3363 self.vapi.nat44_interface_add_del_output_feature(
3365 sw_if_index=self.pg3.sw_if_index)
3368 pkts = self.create_stream_in(self.pg4, self.pg3)
3369 self.pg4.add_stream(pkts)
3370 self.pg_enable_capture(self.pg_interfaces)
3372 capture = self.pg3.get_capture(len(pkts))
3373 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3376 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3377 self.pg3.add_stream(pkts)
3378 self.pg_enable_capture(self.pg_interfaces)
3380 capture = self.pg4.get_capture(len(pkts))
3381 self.verify_capture_in(capture, self.pg4)
3384 pkts = self.create_stream_in(self.pg6, self.pg3)
3385 self.pg6.add_stream(pkts)
3386 self.pg_enable_capture(self.pg_interfaces)
3388 capture = self.pg3.get_capture(len(pkts))
3389 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3392 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3393 self.pg3.add_stream(pkts)
3394 self.pg_enable_capture(self.pg_interfaces)
3396 capture = self.pg6.get_capture(len(pkts))
3397 self.verify_capture_in(capture, self.pg6)
3399 def test_output_feature_hairpinning(self):
3400 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3401 host = self.pg0.remote_hosts[0]
3402 server = self.pg0.remote_hosts[1]
3405 server_in_port = 5678
3406 server_out_port = 8765
3408 self.nat44_add_address(self.nat_addr)
3409 flags = self.config_flags.NAT_IS_INSIDE
3410 self.vapi.nat44_interface_add_del_output_feature(
3411 is_add=1, flags=flags,
3412 sw_if_index=self.pg0.sw_if_index)
3413 self.vapi.nat44_interface_add_del_output_feature(
3415 sw_if_index=self.pg1.sw_if_index)
3417 # add static mapping for server
3418 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3419 server_in_port, server_out_port,
3420 proto=IP_PROTOS.tcp)
3422 # send packet from host to server
3423 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3424 IP(src=host.ip4, dst=self.nat_addr) /
3425 TCP(sport=host_in_port, dport=server_out_port))
3426 self.pg0.add_stream(p)
3427 self.pg_enable_capture(self.pg_interfaces)
3429 capture = self.pg0.get_capture(1)
3434 self.assertEqual(ip.src, self.nat_addr)
3435 self.assertEqual(ip.dst, server.ip4)
3436 self.assertNotEqual(tcp.sport, host_in_port)
3437 self.assertEqual(tcp.dport, server_in_port)
3438 self.assert_packet_checksums_valid(p)
3439 host_out_port = tcp.sport
3441 self.logger.error(ppp("Unexpected or invalid packet:", p))
3444 # send reply from server to host
3445 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3446 IP(src=server.ip4, dst=self.nat_addr) /
3447 TCP(sport=server_in_port, dport=host_out_port))
3448 self.pg0.add_stream(p)
3449 self.pg_enable_capture(self.pg_interfaces)
3451 capture = self.pg0.get_capture(1)
3456 self.assertEqual(ip.src, self.nat_addr)
3457 self.assertEqual(ip.dst, host.ip4)
3458 self.assertEqual(tcp.sport, server_out_port)
3459 self.assertEqual(tcp.dport, host_in_port)
3460 self.assert_packet_checksums_valid(p)
3462 self.logger.error(ppp("Unexpected or invalid packet:", p))
3465 def test_one_armed_nat44(self):
3466 """ One armed NAT44 """
3467 remote_host = self.pg9.remote_hosts[0]
3468 local_host = self.pg9.remote_hosts[1]
3471 self.nat44_add_address(self.nat_addr)
3472 flags = self.config_flags.NAT_IS_INSIDE
3473 self.vapi.nat44_interface_add_del_feature(
3474 sw_if_index=self.pg9.sw_if_index,
3476 self.vapi.nat44_interface_add_del_feature(
3477 sw_if_index=self.pg9.sw_if_index,
3478 flags=flags, is_add=1)
3481 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3482 IP(src=local_host.ip4, dst=remote_host.ip4) /
3483 TCP(sport=12345, dport=80))
3484 self.pg9.add_stream(p)
3485 self.pg_enable_capture(self.pg_interfaces)
3487 capture = self.pg9.get_capture(1)
3492 self.assertEqual(ip.src, self.nat_addr)
3493 self.assertEqual(ip.dst, remote_host.ip4)
3494 self.assertNotEqual(tcp.sport, 12345)
3495 external_port = tcp.sport
3496 self.assertEqual(tcp.dport, 80)
3497 self.assert_packet_checksums_valid(p)
3499 self.logger.error(ppp("Unexpected or invalid packet:", p))
3503 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3504 IP(src=remote_host.ip4, dst=self.nat_addr) /
3505 TCP(sport=80, dport=external_port))
3506 self.pg9.add_stream(p)
3507 self.pg_enable_capture(self.pg_interfaces)
3509 capture = self.pg9.get_capture(1)
3514 self.assertEqual(ip.src, remote_host.ip4)
3515 self.assertEqual(ip.dst, local_host.ip4)
3516 self.assertEqual(tcp.sport, 80)
3517 self.assertEqual(tcp.dport, 12345)
3518 self.assert_packet_checksums_valid(p)
3520 self.logger.error(ppp("Unexpected or invalid packet:", p))
3523 err = self.statistics.get_err_counter(
3524 '/err/nat44-classify/next in2out')
3525 self.assertEqual(err, 1)
3526 err = self.statistics.get_err_counter(
3527 '/err/nat44-classify/next out2in')
3528 self.assertEqual(err, 1)
3530 def test_del_session(self):
3531 """ Delete NAT44 session """
3532 self.nat44_add_address(self.nat_addr)
3533 flags = self.config_flags.NAT_IS_INSIDE
3534 self.vapi.nat44_interface_add_del_feature(
3535 sw_if_index=self.pg0.sw_if_index,
3536 flags=flags, is_add=1)
3537 self.vapi.nat44_interface_add_del_feature(
3538 sw_if_index=self.pg1.sw_if_index,
3541 pkts = self.create_stream_in(self.pg0, self.pg1)
3542 self.pg0.add_stream(pkts)
3543 self.pg_enable_capture(self.pg_interfaces)
3545 self.pg1.get_capture(len(pkts))
3547 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3548 nsessions = len(sessions)
3550 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3551 port=sessions[0].inside_port,
3552 protocol=sessions[0].protocol,
3553 flags=self.config_flags.NAT_IS_INSIDE)
3554 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3555 port=sessions[1].outside_port,
3556 protocol=sessions[1].protocol)
3558 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3559 self.assertEqual(nsessions - len(sessions), 2)
3561 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3562 port=sessions[0].inside_port,
3563 protocol=sessions[0].protocol,
3564 flags=self.config_flags.NAT_IS_INSIDE)
3566 self.verify_no_nat44_user()
3568 def test_frag_in_order(self):
3569 """ NAT44 translate fragments arriving in order """
3571 self.nat44_add_address(self.nat_addr)
3572 flags = self.config_flags.NAT_IS_INSIDE
3573 self.vapi.nat44_interface_add_del_feature(
3574 sw_if_index=self.pg0.sw_if_index,
3575 flags=flags, is_add=1)
3576 self.vapi.nat44_interface_add_del_feature(
3577 sw_if_index=self.pg1.sw_if_index,
3580 self.frag_in_order(proto=IP_PROTOS.tcp)
3581 self.frag_in_order(proto=IP_PROTOS.udp)
3582 self.frag_in_order(proto=IP_PROTOS.icmp)
3584 def test_frag_forwarding(self):
3585 """ NAT44 forwarding fragment test """
3586 self.vapi.nat44_add_del_interface_addr(
3588 sw_if_index=self.pg1.sw_if_index)
3589 flags = self.config_flags.NAT_IS_INSIDE
3590 self.vapi.nat44_interface_add_del_feature(
3591 sw_if_index=self.pg0.sw_if_index,
3592 flags=flags, is_add=1)
3593 self.vapi.nat44_interface_add_del_feature(
3594 sw_if_index=self.pg1.sw_if_index,
3596 self.vapi.nat44_forwarding_enable_disable(enable=1)
3598 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3599 pkts = self.create_stream_frag(self.pg1,
3600 self.pg0.remote_ip4,
3604 proto=IP_PROTOS.udp)
3605 self.pg1.add_stream(pkts)
3606 self.pg_enable_capture(self.pg_interfaces)
3608 frags = self.pg0.get_capture(len(pkts))
3609 p = self.reass_frags_and_verify(frags,
3610 self.pg1.remote_ip4,
3611 self.pg0.remote_ip4)
3612 self.assertEqual(p[UDP].sport, 4789)
3613 self.assertEqual(p[UDP].dport, 4789)
3614 self.assertEqual(data, p[Raw].load)
3616 def test_reass_hairpinning(self):
3617 """ NAT44 fragments hairpinning """
3619 self.server = self.pg0.remote_hosts[1]
3620 self.host_in_port = random.randint(1025, 65535)
3621 self.server_in_port = random.randint(1025, 65535)
3622 self.server_out_port = random.randint(1025, 65535)
3624 self.nat44_add_address(self.nat_addr)
3625 flags = self.config_flags.NAT_IS_INSIDE
3626 self.vapi.nat44_interface_add_del_feature(
3627 sw_if_index=self.pg0.sw_if_index,
3628 flags=flags, is_add=1)
3629 self.vapi.nat44_interface_add_del_feature(
3630 sw_if_index=self.pg1.sw_if_index,
3632 # add static mapping for server
3633 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3634 self.server_in_port,
3635 self.server_out_port,
3636 proto=IP_PROTOS.tcp)
3637 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3638 self.server_in_port,
3639 self.server_out_port,
3640 proto=IP_PROTOS.udp)
3641 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3643 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3644 self.reass_hairpinning(proto=IP_PROTOS.udp)
3645 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3647 def test_frag_out_of_order(self):
3648 """ NAT44 translate fragments arriving out of order """
3650 self.nat44_add_address(self.nat_addr)
3651 flags = self.config_flags.NAT_IS_INSIDE
3652 self.vapi.nat44_interface_add_del_feature(
3653 sw_if_index=self.pg0.sw_if_index,
3654 flags=flags, is_add=1)
3655 self.vapi.nat44_interface_add_del_feature(
3656 sw_if_index=self.pg1.sw_if_index,
3659 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3660 self.frag_out_of_order(proto=IP_PROTOS.udp)
3661 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3663 def test_port_restricted(self):
3664 """ Port restricted NAT44 (MAP-E CE) """
3665 self.nat44_add_address(self.nat_addr)
3666 flags = self.config_flags.NAT_IS_INSIDE
3667 self.vapi.nat44_interface_add_del_feature(
3668 sw_if_index=self.pg0.sw_if_index,
3669 flags=flags, is_add=1)
3670 self.vapi.nat44_interface_add_del_feature(
3671 sw_if_index=self.pg1.sw_if_index,
3673 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3678 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3679 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3680 TCP(sport=4567, dport=22))
3681 self.pg0.add_stream(p)
3682 self.pg_enable_capture(self.pg_interfaces)
3684 capture = self.pg1.get_capture(1)
3689 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3690 self.assertEqual(ip.src, self.nat_addr)
3691 self.assertEqual(tcp.dport, 22)
3692 self.assertNotEqual(tcp.sport, 4567)
3693 self.assertEqual((tcp.sport >> 6) & 63, 10)
3694 self.assert_packet_checksums_valid(p)
3696 self.logger.error(ppp("Unexpected or invalid packet:", p))
3699 def test_port_range(self):
3700 """ External address port range """
3701 self.nat44_add_address(self.nat_addr)
3702 flags = self.config_flags.NAT_IS_INSIDE
3703 self.vapi.nat44_interface_add_del_feature(
3704 sw_if_index=self.pg0.sw_if_index,
3705 flags=flags, is_add=1)
3706 self.vapi.nat44_interface_add_del_feature(
3707 sw_if_index=self.pg1.sw_if_index,
3709 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3714 for port in range(0, 5):
3715 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3716 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3717 TCP(sport=1125 + port))
3719 self.pg0.add_stream(pkts)
3720 self.pg_enable_capture(self.pg_interfaces)
3722 capture = self.pg1.get_capture(3)
3725 self.assertGreaterEqual(tcp.sport, 1025)
3726 self.assertLessEqual(tcp.sport, 1027)
3728 def test_multiple_outside_vrf(self):
3729 """ Multiple outside VRF """
3733 self.pg1.unconfig_ip4()
3734 self.pg2.unconfig_ip4()
3735 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3736 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3737 self.pg1.set_table_ip4(vrf_id1)
3738 self.pg2.set_table_ip4(vrf_id2)
3739 self.pg1.config_ip4()
3740 self.pg2.config_ip4()
3741 self.pg1.resolve_arp()
3742 self.pg2.resolve_arp()
3744 self.nat44_add_address(self.nat_addr)
3745 flags = self.config_flags.NAT_IS_INSIDE
3746 self.vapi.nat44_interface_add_del_feature(
3747 sw_if_index=self.pg0.sw_if_index,
3748 flags=flags, is_add=1)
3749 self.vapi.nat44_interface_add_del_feature(
3750 sw_if_index=self.pg1.sw_if_index,
3752 self.vapi.nat44_interface_add_del_feature(
3753 sw_if_index=self.pg2.sw_if_index,
3758 pkts = self.create_stream_in(self.pg0, self.pg1)
3759 self.pg0.add_stream(pkts)
3760 self.pg_enable_capture(self.pg_interfaces)
3762 capture = self.pg1.get_capture(len(pkts))
3763 self.verify_capture_out(capture, self.nat_addr)
3765 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3766 self.pg1.add_stream(pkts)
3767 self.pg_enable_capture(self.pg_interfaces)
3769 capture = self.pg0.get_capture(len(pkts))
3770 self.verify_capture_in(capture, self.pg0)
3772 self.tcp_port_in = 60303
3773 self.udp_port_in = 60304
3774 self.icmp_id_in = 60305
3777 pkts = self.create_stream_in(self.pg0, self.pg2)
3778 self.pg0.add_stream(pkts)
3779 self.pg_enable_capture(self.pg_interfaces)
3781 capture = self.pg2.get_capture(len(pkts))
3782 self.verify_capture_out(capture, self.nat_addr)
3784 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3785 self.pg2.add_stream(pkts)
3786 self.pg_enable_capture(self.pg_interfaces)
3788 capture = self.pg0.get_capture(len(pkts))
3789 self.verify_capture_in(capture, self.pg0)
3792 self.nat44_add_address(self.nat_addr, is_add=0)
3793 self.pg1.unconfig_ip4()
3794 self.pg2.unconfig_ip4()
3795 self.pg1.set_table_ip4(0)
3796 self.pg2.set_table_ip4(0)
3797 self.pg1.config_ip4()
3798 self.pg2.config_ip4()
3799 self.pg1.resolve_arp()
3800 self.pg2.resolve_arp()
3802 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3803 def test_session_timeout(self):
3804 """ NAT44 session timeouts """
3805 self.nat44_add_address(self.nat_addr)
3806 flags = self.config_flags.NAT_IS_INSIDE
3807 self.vapi.nat44_interface_add_del_feature(
3808 sw_if_index=self.pg0.sw_if_index,
3809 flags=flags, is_add=1)
3810 self.vapi.nat44_interface_add_del_feature(
3811 sw_if_index=self.pg1.sw_if_index,
3813 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3814 tcp_transitory=240, icmp=60)
3818 for i in range(0, max_sessions):
3819 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3820 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3821 IP(src=src, dst=self.pg1.remote_ip4) /
3822 UDP(sport=1025, dport=53))
3824 self.pg0.add_stream(pkts)
3825 self.pg_enable_capture(self.pg_interfaces)
3827 self.pg1.get_capture(max_sessions)
3832 for i in range(0, max_sessions):
3833 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3834 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3835 IP(src=src, dst=self.pg1.remote_ip4) /
3836 UDP(sport=1026, dport=53))
3838 self.pg0.add_stream(pkts)
3839 self.pg_enable_capture(self.pg_interfaces)
3841 self.pg1.get_capture(max_sessions)
3844 users = self.vapi.nat44_user_dump()
3846 nsessions = nsessions + user.nsessions
3847 self.assertLess(nsessions, 2 * max_sessions)
3849 def test_mss_clamping(self):
3850 """ TCP MSS clamping """
3851 self.nat44_add_address(self.nat_addr)
3852 flags = self.config_flags.NAT_IS_INSIDE
3853 self.vapi.nat44_interface_add_del_feature(
3854 sw_if_index=self.pg0.sw_if_index,
3855 flags=flags, is_add=1)
3856 self.vapi.nat44_interface_add_del_feature(
3857 sw_if_index=self.pg1.sw_if_index,
3860 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3861 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3862 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3863 flags="S", options=[('MSS', 1400)]))
3865 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3866 self.pg0.add_stream(p)
3867 self.pg_enable_capture(self.pg_interfaces)
3869 capture = self.pg1.get_capture(1)
3870 # Negotiated MSS value greater than configured - changed
3871 self.verify_mss_value(capture[0], 1000)
3873 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3874 self.pg0.add_stream(p)
3875 self.pg_enable_capture(self.pg_interfaces)
3877 capture = self.pg1.get_capture(1)
3878 # MSS clamping disabled - negotiated MSS unchanged
3879 self.verify_mss_value(capture[0], 1400)
3881 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3882 self.pg0.add_stream(p)
3883 self.pg_enable_capture(self.pg_interfaces)
3885 capture = self.pg1.get_capture(1)
3886 # Negotiated MSS value smaller than configured - unchanged
3887 self.verify_mss_value(capture[0], 1400)
3889 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3890 def test_ha_send(self):
3891 """ Send HA session synchronization events (active) """
3892 self.nat44_add_address(self.nat_addr)
3893 flags = self.config_flags.NAT_IS_INSIDE
3894 self.vapi.nat44_interface_add_del_feature(
3895 sw_if_index=self.pg0.sw_if_index,
3896 flags=flags, is_add=1)
3897 self.vapi.nat44_interface_add_del_feature(
3898 sw_if_index=self.pg1.sw_if_index,
3900 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3903 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3904 port=12346, session_refresh_interval=10)
3905 bind_layers(UDP, HANATStateSync, sport=12345)
3908 pkts = self.create_stream_in(self.pg0, self.pg1)
3909 self.pg0.add_stream(pkts)
3910 self.pg_enable_capture(self.pg_interfaces)
3912 capture = self.pg1.get_capture(len(pkts))
3913 self.verify_capture_out(capture)
3914 # active send HA events
3915 self.vapi.nat_ha_flush()
3916 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3917 self.assertEqual(stats[0][0], 3)
3918 capture = self.pg3.get_capture(1)
3920 self.assert_packet_checksums_valid(p)
3924 hanat = p[HANATStateSync]
3926 self.logger.error(ppp("Invalid packet:", p))
3929 self.assertEqual(ip.src, self.pg3.local_ip4)
3930 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3931 self.assertEqual(udp.sport, 12345)
3932 self.assertEqual(udp.dport, 12346)
3933 self.assertEqual(hanat.version, 1)
3934 self.assertEqual(hanat.thread_index, 0)
3935 self.assertEqual(hanat.count, 3)
3936 seq = hanat.sequence_number
3937 for event in hanat.events:
3938 self.assertEqual(event.event_type, 1)
3939 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3940 self.assertEqual(event.out_addr, self.nat_addr)
3941 self.assertEqual(event.fib_index, 0)
3943 # ACK received events
3944 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3945 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3946 UDP(sport=12346, dport=12345) /
3947 HANATStateSync(sequence_number=seq, flags='ACK'))
3948 self.pg3.add_stream(ack)
3950 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3951 self.assertEqual(stats[0][0], 1)
3953 # delete one session
3954 self.pg_enable_capture(self.pg_interfaces)
3955 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3956 port=self.tcp_port_in,
3957 protocol=IP_PROTOS.tcp,
3958 flags=self.config_flags.NAT_IS_INSIDE)
3959 self.vapi.nat_ha_flush()
3960 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3961 self.assertEqual(stats[0][0], 1)
3962 capture = self.pg3.get_capture(1)
3965 hanat = p[HANATStateSync]
3967 self.logger.error(ppp("Invalid packet:", p))
3970 self.assertGreater(hanat.sequence_number, seq)
3972 # do not send ACK, active retry send HA event again
3973 self.pg_enable_capture(self.pg_interfaces)
3975 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3976 self.assertEqual(stats[0][0], 3)
3977 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3978 self.assertEqual(stats[0][0], 1)
3979 capture = self.pg3.get_capture(3)
3980 for packet in capture:
3981 self.assertEqual(packet, p)
3983 # session counters refresh
3984 pkts = self.create_stream_out(self.pg1)
3985 self.pg1.add_stream(pkts)
3986 self.pg_enable_capture(self.pg_interfaces)
3988 self.pg0.get_capture(2)
3989 self.vapi.nat_ha_flush()
3990 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3991 self.assertEqual(stats[0][0], 2)
3992 capture = self.pg3.get_capture(1)
3994 self.assert_packet_checksums_valid(p)
3998 hanat = p[HANATStateSync]
4000 self.logger.error(ppp("Invalid packet:", p))
4003 self.assertEqual(ip.src, self.pg3.local_ip4)
4004 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4005 self.assertEqual(udp.sport, 12345)
4006 self.assertEqual(udp.dport, 12346)
4007 self.assertEqual(hanat.version, 1)
4008 self.assertEqual(hanat.count, 2)
4009 seq = hanat.sequence_number
4010 for event in hanat.events:
4011 self.assertEqual(event.event_type, 3)
4012 self.assertEqual(event.out_addr, self.nat_addr)
4013 self.assertEqual(event.fib_index, 0)
4014 self.assertEqual(event.total_pkts, 2)
4015 self.assertGreater(event.total_bytes, 0)
4017 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4018 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4019 UDP(sport=12346, dport=12345) /
4020 HANATStateSync(sequence_number=seq, flags='ACK'))
4021 self.pg3.add_stream(ack)
4023 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4024 self.assertEqual(stats[0][0], 2)
4026 def test_ha_recv(self):
4027 """ Receive HA session synchronization events (passive) """
4028 self.nat44_add_address(self.nat_addr)
4029 flags = self.config_flags.NAT_IS_INSIDE
4030 self.vapi.nat44_interface_add_del_feature(
4031 sw_if_index=self.pg0.sw_if_index,
4032 flags=flags, is_add=1)
4033 self.vapi.nat44_interface_add_del_feature(
4034 sw_if_index=self.pg1.sw_if_index,
4036 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4039 bind_layers(UDP, HANATStateSync, sport=12345)
4041 self.tcp_port_out = random.randint(1025, 65535)
4042 self.udp_port_out = random.randint(1025, 65535)
4044 # send HA session add events to failover/passive
4045 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4046 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4047 UDP(sport=12346, dport=12345) /
4048 HANATStateSync(sequence_number=1, events=[
4049 Event(event_type='add', protocol='tcp',
4050 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4051 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4052 eh_addr=self.pg1.remote_ip4,
4053 ehn_addr=self.pg1.remote_ip4,
4054 eh_port=self.tcp_external_port,
4055 ehn_port=self.tcp_external_port, fib_index=0),
4056 Event(event_type='add', protocol='udp',
4057 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4058 in_port=self.udp_port_in, out_port=self.udp_port_out,
4059 eh_addr=self.pg1.remote_ip4,
4060 ehn_addr=self.pg1.remote_ip4,
4061 eh_port=self.udp_external_port,
4062 ehn_port=self.udp_external_port, fib_index=0)]))
4064 self.pg3.add_stream(p)
4065 self.pg_enable_capture(self.pg_interfaces)
4068 capture = self.pg3.get_capture(1)
4071 hanat = p[HANATStateSync]
4073 self.logger.error(ppp("Invalid packet:", p))
4076 self.assertEqual(hanat.sequence_number, 1)
4077 self.assertEqual(hanat.flags, 'ACK')
4078 self.assertEqual(hanat.version, 1)
4079 self.assertEqual(hanat.thread_index, 0)
4080 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4081 self.assertEqual(stats[0][0], 1)
4082 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4083 self.assertEqual(stats[0][0], 2)
4084 users = self.statistics.get_counter('/nat44/total-users')
4085 self.assertEqual(users[0][0], 1)
4086 sessions = self.statistics.get_counter('/nat44/total-sessions')
4087 self.assertEqual(sessions[0][0], 2)
4088 users = self.vapi.nat44_user_dump()
4089 self.assertEqual(len(users), 1)
4090 self.assertEqual(str(users[0].ip_address),
4091 self.pg0.remote_ip4)
4092 # there should be 2 sessions created by HA
4093 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4095 self.assertEqual(len(sessions), 2)
4096 for session in sessions:
4097 self.assertEqual(str(session.inside_ip_address),
4098 self.pg0.remote_ip4)
4099 self.assertEqual(str(session.outside_ip_address),
4101 self.assertIn(session.inside_port,
4102 [self.tcp_port_in, self.udp_port_in])
4103 self.assertIn(session.outside_port,
4104 [self.tcp_port_out, self.udp_port_out])
4105 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4107 # send HA session delete event to failover/passive
4108 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4109 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4110 UDP(sport=12346, dport=12345) /
4111 HANATStateSync(sequence_number=2, events=[
4112 Event(event_type='del', protocol='udp',
4113 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4114 in_port=self.udp_port_in, out_port=self.udp_port_out,
4115 eh_addr=self.pg1.remote_ip4,
4116 ehn_addr=self.pg1.remote_ip4,
4117 eh_port=self.udp_external_port,
4118 ehn_port=self.udp_external_port, fib_index=0)]))
4120 self.pg3.add_stream(p)
4121 self.pg_enable_capture(self.pg_interfaces)
4124 capture = self.pg3.get_capture(1)
4127 hanat = p[HANATStateSync]
4129 self.logger.error(ppp("Invalid packet:", p))
4132 self.assertEqual(hanat.sequence_number, 2)
4133 self.assertEqual(hanat.flags, 'ACK')
4134 self.assertEqual(hanat.version, 1)
4135 users = self.vapi.nat44_user_dump()
4136 self.assertEqual(len(users), 1)
4137 self.assertEqual(str(users[0].ip_address),
4138 self.pg0.remote_ip4)
4139 # now we should have only 1 session, 1 deleted by HA
4140 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4142 self.assertEqual(len(sessions), 1)
4143 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4144 self.assertEqual(stats[0][0], 1)
4146 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4147 self.assertEqual(stats, 2)
4149 # send HA session refresh event to failover/passive
4150 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4151 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4152 UDP(sport=12346, dport=12345) /
4153 HANATStateSync(sequence_number=3, events=[
4154 Event(event_type='refresh', protocol='tcp',
4155 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4156 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4157 eh_addr=self.pg1.remote_ip4,
4158 ehn_addr=self.pg1.remote_ip4,
4159 eh_port=self.tcp_external_port,
4160 ehn_port=self.tcp_external_port, fib_index=0,
4161 total_bytes=1024, total_pkts=2)]))
4162 self.pg3.add_stream(p)
4163 self.pg_enable_capture(self.pg_interfaces)
4166 capture = self.pg3.get_capture(1)
4169 hanat = p[HANATStateSync]
4171 self.logger.error(ppp("Invalid packet:", p))
4174 self.assertEqual(hanat.sequence_number, 3)
4175 self.assertEqual(hanat.flags, 'ACK')
4176 self.assertEqual(hanat.version, 1)
4177 users = self.vapi.nat44_user_dump()
4178 self.assertEqual(len(users), 1)
4179 self.assertEqual(str(users[0].ip_address),
4180 self.pg0.remote_ip4)
4181 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4183 self.assertEqual(len(sessions), 1)
4184 session = sessions[0]
4185 self.assertEqual(session.total_bytes, 1024)
4186 self.assertEqual(session.total_pkts, 2)
4187 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4188 self.assertEqual(stats[0][0], 1)
4190 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4191 self.assertEqual(stats, 3)
4193 # send packet to test session created by HA
4194 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4195 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4196 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4197 self.pg1.add_stream(p)
4198 self.pg_enable_capture(self.pg_interfaces)
4200 capture = self.pg0.get_capture(1)
4206 self.logger.error(ppp("Invalid packet:", p))
4209 self.assertEqual(ip.src, self.pg1.remote_ip4)
4210 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4211 self.assertEqual(tcp.sport, self.tcp_external_port)
4212 self.assertEqual(tcp.dport, self.tcp_port_in)
4215 super(TestNAT44, self).tearDown()
4217 self.vapi.cli("clear logging")
4219 def show_commands_at_teardown(self):
4220 self.logger.info(self.vapi.cli("show nat44 addresses"))
4221 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4222 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4223 self.logger.info(self.vapi.cli("show nat44 interface address"))
4224 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4225 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4226 self.logger.info(self.vapi.cli("show nat timeouts"))
4228 self.vapi.cli("show nat addr-port-assignment-alg"))
4229 self.logger.info(self.vapi.cli("show nat ha"))
4232 class TestNAT44EndpointDependent2(MethodHolder):
4233 """ Endpoint-Dependent session test cases """
4238 def setUpConstants(cls):
4239 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4240 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent",
4241 "translation", "hash", "buckets", "1",
4242 "icmp", "timeout", str(cls.icmp_timeout), "}"])
4245 def setUpClass(cls):
4246 super(TestNAT44EndpointDependent2, cls).setUpClass()
4248 translation_buckets = 1
4249 cls.max_translations = 10 * translation_buckets
4251 cls.create_pg_interfaces(range(2))
4252 cls.interfaces = list(cls.pg_interfaces[0:2])
4254 for i in cls.interfaces:
4259 cls.pg0.generate_remote_hosts(1)
4260 cls.pg0.configure_ipv4_neighbors()
4262 cls.pg1.generate_remote_hosts(1)
4263 cls.pg1.configure_ipv4_neighbors()
4266 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4269 def create_icmp_stream(self, in_if, out_if, count):
4271 Create ICMP packet stream for inside network
4273 :param in_if: Inside interface
4274 :param out_if: Outside interface
4275 :param count: Number of packets
4278 self.assertTrue(count > 0)
4279 icmp_id = random.randint(0, 65535 - (count - 1))
4282 for i in range(count):
4283 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4284 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4285 ICMP(id=icmp_id + i, type='echo-request'))
4289 def send_pkts(self, pkts, expected=None):
4290 self.pg0.add_stream(pkts)
4291 self.pg_enable_capture(self.pg_interfaces)
4293 return self.pg1.get_capture(
4294 len(pkts) if expected is None else expected)
4296 def test_session_cleanup(self):
4297 """ NAT44 session cleanup test """
4299 self.nat44_add_address(self.pg1.local_ip4)
4300 flags = self.config_flags.NAT_IS_INSIDE
4301 self.vapi.nat44_interface_add_del_feature(
4302 sw_if_index=self.pg0.sw_if_index,
4303 flags=flags, is_add=1)
4304 self.vapi.nat44_interface_add_del_feature(
4305 sw_if_index=self.pg1.sw_if_index,
4308 nat_config = self.vapi.nat_show_config()
4309 self.assertEqual(1, nat_config.endpoint_dependent)
4311 pkts = self.create_icmp_stream(self.pg0, self.pg1,
4312 self.max_translations + 2)
4316 self.send_pkts(pkts[0:self.max_translations])
4318 # false positive test
4319 self.send_pkts(pkts[self.max_translations:sz - 1], 0)
4321 sleep(self.icmp_timeout)
4324 self.send_pkts(pkts[self.max_translations + 1:sz])
4327 class TestNAT44EndpointDependent(MethodHolder):
4328 """ Endpoint-Dependent mapping and filtering test cases """
4331 def setUpConstants(cls):
4332 super(TestNAT44EndpointDependent, cls).setUpConstants()
4333 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4336 def setUpClass(cls):
4337 super(TestNAT44EndpointDependent, cls).setUpClass()
4338 cls.vapi.cli("set log class nat level debug")
4340 cls.tcp_port_in = 6303
4341 cls.tcp_port_out = 6303
4342 cls.udp_port_in = 6304
4343 cls.udp_port_out = 6304
4344 cls.icmp_id_in = 6305
4345 cls.icmp_id_out = 6305
4346 cls.nat_addr = '10.0.0.3'
4347 cls.ipfix_src_port = 4739
4348 cls.ipfix_domain_id = 1
4349 cls.tcp_external_port = 80
4351 cls.create_pg_interfaces(range(9))
4352 cls.interfaces = list(cls.pg_interfaces[0:3])
4354 for i in cls.interfaces:
4359 cls.pg0.generate_remote_hosts(3)
4360 cls.pg0.configure_ipv4_neighbors()
4364 cls.pg4.generate_remote_hosts(2)
4365 cls.pg4.config_ip4()
4366 cls.vapi.sw_interface_add_del_address(
4367 sw_if_index=cls.pg4.sw_if_index,
4368 prefix="10.0.0.1/24")
4371 cls.pg4.resolve_arp()
4372 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4373 cls.pg4.resolve_arp()
4375 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4376 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4378 cls.pg5._local_ip4 = "10.1.1.1"
4379 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4380 cls.pg5.set_table_ip4(1)
4381 cls.pg5.config_ip4()
4383 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4384 [VppRoutePath("0.0.0.0",
4385 cls.pg5.sw_if_index)],
4390 cls.pg6._local_ip4 = "10.1.2.1"
4391 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4392 cls.pg6.set_table_ip4(1)
4393 cls.pg6.config_ip4()
4396 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4397 [VppRoutePath("0.0.0.0",
4398 cls.pg6.sw_if_index)],
4401 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4402 [VppRoutePath("0.0.0.0",
4407 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4408 [VppRoutePath("0.0.0.0", 0xffffffff,
4412 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4413 [VppRoutePath(cls.pg1.local_ip4,
4414 cls.pg1.sw_if_index)],
4421 cls.pg5.resolve_arp()
4422 cls.pg6.resolve_arp()
4425 cls.pg7.config_ip4()
4426 cls.pg7.resolve_arp()
4427 cls.pg7.generate_remote_hosts(3)
4428 cls.pg7.configure_ipv4_neighbors()
4431 cls.pg8.config_ip4()
4432 cls.pg8.resolve_arp()
4435 super(TestNAT44EndpointDependent, cls).tearDownClass()
4439 def tearDownClass(cls):
4440 super(TestNAT44EndpointDependent, cls).tearDownClass()
4442 def test_frag_in_order(self):
4443 """ NAT44 translate fragments arriving in order """
4444 self.nat44_add_address(self.nat_addr)
4445 flags = self.config_flags.NAT_IS_INSIDE
4446 self.vapi.nat44_interface_add_del_feature(
4447 sw_if_index=self.pg0.sw_if_index,
4448 flags=flags, is_add=1)
4449 self.vapi.nat44_interface_add_del_feature(
4450 sw_if_index=self.pg1.sw_if_index,
4452 self.frag_in_order(proto=IP_PROTOS.tcp)
4453 self.frag_in_order(proto=IP_PROTOS.udp)
4454 self.frag_in_order(proto=IP_PROTOS.icmp)
4456 def test_frag_in_order_dont_translate(self):
4457 """ NAT44 don't translate fragments arriving in order """
4458 flags = self.config_flags.NAT_IS_INSIDE
4459 self.vapi.nat44_interface_add_del_feature(
4460 sw_if_index=self.pg0.sw_if_index,
4461 flags=flags, is_add=1)
4462 self.vapi.nat44_interface_add_del_feature(
4463 sw_if_index=self.pg1.sw_if_index,
4465 self.vapi.nat44_forwarding_enable_disable(enable=True)
4466 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4468 def test_frag_out_of_order(self):
4469 """ NAT44 translate fragments arriving out of order """
4470 self.nat44_add_address(self.nat_addr)
4471 flags = self.config_flags.NAT_IS_INSIDE
4472 self.vapi.nat44_interface_add_del_feature(
4473 sw_if_index=self.pg0.sw_if_index,
4474 flags=flags, is_add=1)
4475 self.vapi.nat44_interface_add_del_feature(
4476 sw_if_index=self.pg1.sw_if_index,
4478 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4479 self.frag_out_of_order(proto=IP_PROTOS.udp)
4480 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4482 def test_frag_out_of_order_dont_translate(self):
4483 """ NAT44 don't translate fragments arriving out of order """
4484 flags = self.config_flags.NAT_IS_INSIDE
4485 self.vapi.nat44_interface_add_del_feature(
4486 sw_if_index=self.pg0.sw_if_index,
4487 flags=flags, is_add=1)
4488 self.vapi.nat44_interface_add_del_feature(
4489 sw_if_index=self.pg1.sw_if_index,
4491 self.vapi.nat44_forwarding_enable_disable(enable=True)
4492 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4494 def test_frag_in_order_in_plus_out(self):
4495 """ in+out interface fragments in order """
4496 flags = self.config_flags.NAT_IS_INSIDE
4497 self.vapi.nat44_interface_add_del_feature(
4498 sw_if_index=self.pg0.sw_if_index,
4500 self.vapi.nat44_interface_add_del_feature(
4501 sw_if_index=self.pg0.sw_if_index,
4502 flags=flags, is_add=1)
4503 self.vapi.nat44_interface_add_del_feature(
4504 sw_if_index=self.pg1.sw_if_index,
4506 self.vapi.nat44_interface_add_del_feature(
4507 sw_if_index=self.pg1.sw_if_index,
4508 flags=flags, is_add=1)
4510 self.server = self.pg1.remote_hosts[0]
4512 self.server_in_addr = self.server.ip4
4513 self.server_out_addr = '11.11.11.11'
4514 self.server_in_port = random.randint(1025, 65535)
4515 self.server_out_port = random.randint(1025, 65535)
4517 self.nat44_add_address(self.server_out_addr)
4519 # add static mappings for server
4520 self.nat44_add_static_mapping(self.server_in_addr,
4521 self.server_out_addr,
4522 self.server_in_port,
4523 self.server_out_port,
4524 proto=IP_PROTOS.tcp)
4525 self.nat44_add_static_mapping(self.server_in_addr,
4526 self.server_out_addr,
4527 self.server_in_port,
4528 self.server_out_port,
4529 proto=IP_PROTOS.udp)
4530 self.nat44_add_static_mapping(self.server_in_addr,
4531 self.server_out_addr,
4532 proto=IP_PROTOS.icmp)
4534 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4535 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4536 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4538 def test_frag_out_of_order_in_plus_out(self):
4539 """ in+out interface fragments out of order """
4540 flags = self.config_flags.NAT_IS_INSIDE
4541 self.vapi.nat44_interface_add_del_feature(
4542 sw_if_index=self.pg0.sw_if_index,
4544 self.vapi.nat44_interface_add_del_feature(
4545 sw_if_index=self.pg0.sw_if_index,
4546 flags=flags, is_add=1)
4547 self.vapi.nat44_interface_add_del_feature(
4548 sw_if_index=self.pg1.sw_if_index,
4550 self.vapi.nat44_interface_add_del_feature(
4551 sw_if_index=self.pg1.sw_if_index,
4552 flags=flags, is_add=1)
4554 self.server = self.pg1.remote_hosts[0]
4556 self.server_in_addr = self.server.ip4
4557 self.server_out_addr = '11.11.11.11'
4558 self.server_in_port = random.randint(1025, 65535)
4559 self.server_out_port = random.randint(1025, 65535)
4561 self.nat44_add_address(self.server_out_addr)
4563 # add static mappings for server
4564 self.nat44_add_static_mapping(self.server_in_addr,
4565 self.server_out_addr,
4566 self.server_in_port,
4567 self.server_out_port,
4568 proto=IP_PROTOS.tcp)
4569 self.nat44_add_static_mapping(self.server_in_addr,
4570 self.server_out_addr,
4571 self.server_in_port,
4572 self.server_out_port,
4573 proto=IP_PROTOS.udp)
4574 self.nat44_add_static_mapping(self.server_in_addr,
4575 self.server_out_addr,
4576 proto=IP_PROTOS.icmp)
4578 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4579 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4580 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4582 def test_reass_hairpinning(self):
4583 """ NAT44 fragments hairpinning """
4584 self.server = self.pg0.remote_hosts[1]
4585 self.host_in_port = random.randint(1025, 65535)
4586 self.server_in_port = random.randint(1025, 65535)
4587 self.server_out_port = random.randint(1025, 65535)
4589 self.nat44_add_address(self.nat_addr)
4590 flags = self.config_flags.NAT_IS_INSIDE
4591 self.vapi.nat44_interface_add_del_feature(
4592 sw_if_index=self.pg0.sw_if_index,
4593 flags=flags, is_add=1)
4594 self.vapi.nat44_interface_add_del_feature(
4595 sw_if_index=self.pg1.sw_if_index,
4597 # add static mapping for server
4598 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4599 self.server_in_port,
4600 self.server_out_port,
4601 proto=IP_PROTOS.tcp)
4602 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4603 self.server_in_port,
4604 self.server_out_port,
4605 proto=IP_PROTOS.udp)
4606 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4608 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4609 self.reass_hairpinning(proto=IP_PROTOS.udp)
4610 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4612 def test_dynamic(self):
4613 """ NAT44 dynamic translation test """
4615 self.nat44_add_address(self.nat_addr)
4616 flags = self.config_flags.NAT_IS_INSIDE
4617 self.vapi.nat44_interface_add_del_feature(
4618 sw_if_index=self.pg0.sw_if_index,
4619 flags=flags, is_add=1)
4620 self.vapi.nat44_interface_add_del_feature(
4621 sw_if_index=self.pg1.sw_if_index,
4624 nat_config = self.vapi.nat_show_config()
4625 self.assertEqual(1, nat_config.endpoint_dependent)
4628 tcpn = self.statistics.get_err_counter(
4629 '/err/nat44-ed-in2out-slowpath/TCP packets')
4630 udpn = self.statistics.get_err_counter(
4631 '/err/nat44-ed-in2out-slowpath/UDP packets')
4632 icmpn = self.statistics.get_err_counter(
4633 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4634 totaln = self.statistics.get_err_counter(
4635 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4637 pkts = self.create_stream_in(self.pg0, self.pg1)
4638 self.pg0.add_stream(pkts)
4639 self.pg_enable_capture(self.pg_interfaces)
4641 capture = self.pg1.get_capture(len(pkts))
4642 self.verify_capture_out(capture)
4644 err = self.statistics.get_err_counter(
4645 '/err/nat44-ed-in2out-slowpath/TCP packets')
4646 self.assertEqual(err - tcpn, 2)
4647 err = self.statistics.get_err_counter(
4648 '/err/nat44-ed-in2out-slowpath/UDP packets')
4649 self.assertEqual(err - udpn, 1)
4650 err = self.statistics.get_err_counter(
4651 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4652 self.assertEqual(err - icmpn, 1)
4653 err = self.statistics.get_err_counter(
4654 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4655 self.assertEqual(err - totaln, 4)
4658 tcpn = self.statistics.get_err_counter(
4659 '/err/nat44-ed-out2in/TCP packets')
4660 udpn = self.statistics.get_err_counter(
4661 '/err/nat44-ed-out2in/UDP packets')
4662 icmpn = self.statistics.get_err_counter(
4663 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4664 totaln = self.statistics.get_err_counter(
4665 '/err/nat44-ed-out2in/good out2in packets processed')
4667 pkts = self.create_stream_out(self.pg1)
4668 self.pg1.add_stream(pkts)
4669 self.pg_enable_capture(self.pg_interfaces)
4671 capture = self.pg0.get_capture(len(pkts))
4672 self.verify_capture_in(capture, self.pg0)
4674 err = self.statistics.get_err_counter(
4675 '/err/nat44-ed-out2in/TCP packets')
4676 self.assertEqual(err - tcpn, 2)
4677 err = self.statistics.get_err_counter(
4678 '/err/nat44-ed-out2in/UDP packets')
4679 self.assertEqual(err - udpn, 1)
4680 err = self.statistics.get_err_counter(
4681 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4682 self.assertEqual(err - icmpn, 1)
4683 err = self.statistics.get_err_counter(
4684 '/err/nat44-ed-out2in/good out2in packets processed')
4685 self.assertEqual(err - totaln, 3)
4687 users = self.statistics.get_counter('/nat44/total-users')
4688 self.assertEqual(users[0][0], 1)
4689 sessions = self.statistics.get_counter('/nat44/total-sessions')
4690 self.assertEqual(sessions[0][0], 3)
4692 def test_dynamic_output_feature_vrf(self):
4693 """ NAT44 dynamic translation test: output-feature, VRF"""
4695 # other then default (0)
4698 self.nat44_add_address(self.nat_addr)
4699 flags = self.config_flags.NAT_IS_INSIDE
4700 self.vapi.nat44_interface_add_del_output_feature(
4701 sw_if_index=self.pg7.sw_if_index,
4702 flags=flags, is_add=1)
4703 self.vapi.nat44_interface_add_del_output_feature(
4704 sw_if_index=self.pg8.sw_if_index,
4708 self.vapi.ip_table_add_del(is_add=1,
4709 table={'table_id': new_vrf_id})
4711 self.pg7.unconfig_ip4()
4712 self.pg7.set_table_ip4(new_vrf_id)
4713 self.pg7.config_ip4()
4714 self.pg7.resolve_arp()
4716 self.pg8.unconfig_ip4()
4717 self.pg8.set_table_ip4(new_vrf_id)
4718 self.pg8.config_ip4()
4719 self.pg8.resolve_arp()
4721 nat_config = self.vapi.nat_show_config()
4722 self.assertEqual(1, nat_config.endpoint_dependent)
4725 tcpn = self.statistics.get_err_counter(
4726 '/err/nat44-ed-in2out-slowpath/TCP packets')
4727 udpn = self.statistics.get_err_counter(
4728 '/err/nat44-ed-in2out-slowpath/UDP packets')
4729 icmpn = self.statistics.get_err_counter(
4730 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4731 totaln = self.statistics.get_err_counter(
4732 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4734 pkts = self.create_stream_in(self.pg7, self.pg8)
4735 self.pg7.add_stream(pkts)
4736 self.pg_enable_capture(self.pg_interfaces)
4738 capture = self.pg8.get_capture(len(pkts))
4739 self.verify_capture_out(capture)
4741 err = self.statistics.get_err_counter(
4742 '/err/nat44-ed-in2out-slowpath/TCP packets')
4743 self.assertEqual(err - tcpn, 2)
4744 err = self.statistics.get_err_counter(
4745 '/err/nat44-ed-in2out-slowpath/UDP packets')
4746 self.assertEqual(err - udpn, 1)
4747 err = self.statistics.get_err_counter(
4748 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4749 self.assertEqual(err - icmpn, 1)
4750 err = self.statistics.get_err_counter(
4751 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4752 self.assertEqual(err - totaln, 4)
4755 tcpn = self.statistics.get_err_counter(
4756 '/err/nat44-ed-out2in/TCP packets')
4757 udpn = self.statistics.get_err_counter(
4758 '/err/nat44-ed-out2in/UDP packets')
4759 icmpn = self.statistics.get_err_counter(
4760 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4761 totaln = self.statistics.get_err_counter(
4762 '/err/nat44-ed-out2in/good out2in packets processed')
4764 pkts = self.create_stream_out(self.pg8)
4765 self.pg8.add_stream(pkts)
4766 self.pg_enable_capture(self.pg_interfaces)
4768 capture = self.pg7.get_capture(len(pkts))
4769 self.verify_capture_in(capture, self.pg7)
4771 err = self.statistics.get_err_counter(
4772 '/err/nat44-ed-out2in/TCP packets')
4773 self.assertEqual(err - tcpn, 2)
4774 err = self.statistics.get_err_counter(
4775 '/err/nat44-ed-out2in/UDP packets')
4776 self.assertEqual(err - udpn, 1)
4777 err = self.statistics.get_err_counter(
4778 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4779 self.assertEqual(err - icmpn, 1)
4780 err = self.statistics.get_err_counter(
4781 '/err/nat44-ed-out2in/good out2in packets processed')
4782 self.assertEqual(err - totaln, 3)
4784 users = self.statistics.get_counter('/nat44/total-users')
4785 self.assertEqual(users[0][0], 1)
4786 sessions = self.statistics.get_counter('/nat44/total-sessions')
4787 self.assertEqual(sessions[0][0], 3)
4790 self.pg7.unconfig_ip4()
4791 self.pg7.set_table_ip4(1)
4792 self.pg7.config_ip4()
4793 self.pg7.resolve_arp()
4795 self.pg8.unconfig_ip4()
4796 self.pg8.set_table_ip4(1)
4797 self.pg8.config_ip4()
4798 self.pg8.resolve_arp()
4800 self.vapi.ip_table_add_del(is_add=0,
4801 table={'table_id': new_vrf_id})
4803 def test_forwarding(self):
4804 """ NAT44 forwarding test """
4806 flags = self.config_flags.NAT_IS_INSIDE
4807 self.vapi.nat44_interface_add_del_feature(
4808 sw_if_index=self.pg0.sw_if_index,
4809 flags=flags, is_add=1)
4810 self.vapi.nat44_interface_add_del_feature(
4811 sw_if_index=self.pg1.sw_if_index,
4813 self.vapi.nat44_forwarding_enable_disable(enable=1)
4815 real_ip = self.pg0.remote_ip4
4816 alias_ip = self.nat_addr
4817 flags = self.config_flags.NAT_IS_ADDR_ONLY
4818 self.vapi.nat44_add_del_static_mapping(is_add=1,
4819 local_ip_address=real_ip,
4820 external_ip_address=alias_ip,
4821 external_sw_if_index=0xFFFFFFFF,
4825 # in2out - static mapping match
4827 pkts = self.create_stream_out(self.pg1)
4828 self.pg1.add_stream(pkts)
4829 self.pg_enable_capture(self.pg_interfaces)
4831 capture = self.pg0.get_capture(len(pkts))
4832 self.verify_capture_in(capture, self.pg0)
4834 pkts = self.create_stream_in(self.pg0, self.pg1)
4835 self.pg0.add_stream(pkts)
4836 self.pg_enable_capture(self.pg_interfaces)
4838 capture = self.pg1.get_capture(len(pkts))
4839 self.verify_capture_out(capture, same_port=True)
4841 # in2out - no static mapping match
4843 host0 = self.pg0.remote_hosts[0]
4844 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4846 pkts = self.create_stream_out(self.pg1,
4847 dst_ip=self.pg0.remote_ip4,
4848 use_inside_ports=True)
4849 self.pg1.add_stream(pkts)
4850 self.pg_enable_capture(self.pg_interfaces)
4852 capture = self.pg0.get_capture(len(pkts))
4853 self.verify_capture_in(capture, self.pg0)
4855 pkts = self.create_stream_in(self.pg0, self.pg1)
4856 self.pg0.add_stream(pkts)
4857 self.pg_enable_capture(self.pg_interfaces)
4859 capture = self.pg1.get_capture(len(pkts))
4860 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4863 self.pg0.remote_hosts[0] = host0
4865 user = self.pg0.remote_hosts[1]
4866 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4867 self.assertEqual(len(sessions), 3)
4868 self.assertTrue(sessions[0].flags &
4869 self.config_flags.NAT_IS_EXT_HOST_VALID)
4870 self.vapi.nat44_del_session(
4871 address=sessions[0].inside_ip_address,
4872 port=sessions[0].inside_port,
4873 protocol=sessions[0].protocol,
4874 flags=(self.config_flags.NAT_IS_INSIDE |
4875 self.config_flags.NAT_IS_EXT_HOST_VALID),
4876 ext_host_address=sessions[0].ext_host_address,
4877 ext_host_port=sessions[0].ext_host_port)
4878 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4879 self.assertEqual(len(sessions), 2)
4882 self.vapi.nat44_forwarding_enable_disable(enable=0)
4883 flags = self.config_flags.NAT_IS_ADDR_ONLY
4884 self.vapi.nat44_add_del_static_mapping(
4886 local_ip_address=real_ip,
4887 external_ip_address=alias_ip,
4888 external_sw_if_index=0xFFFFFFFF,
4891 def test_static_lb(self):
4892 """ NAT44 local service load balancing """
4893 external_addr_n = self.nat_addr
4896 server1 = self.pg0.remote_hosts[0]
4897 server2 = self.pg0.remote_hosts[1]
4899 locals = [{'addr': server1.ip4,
4903 {'addr': server2.ip4,
4908 self.nat44_add_address(self.nat_addr)
4909 self.vapi.nat44_add_del_lb_static_mapping(
4911 external_addr=external_addr_n,
4912 external_port=external_port,
4913 protocol=IP_PROTOS.tcp,
4914 local_num=len(locals),
4916 flags = self.config_flags.NAT_IS_INSIDE
4917 self.vapi.nat44_interface_add_del_feature(
4918 sw_if_index=self.pg0.sw_if_index,
4919 flags=flags, is_add=1)
4920 self.vapi.nat44_interface_add_del_feature(
4921 sw_if_index=self.pg1.sw_if_index,
4924 # from client to service
4925 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4926 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4927 TCP(sport=12345, dport=external_port))
4928 self.pg1.add_stream(p)
4929 self.pg_enable_capture(self.pg_interfaces)
4931 capture = self.pg0.get_capture(1)
4937 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4938 if ip.dst == server1.ip4:
4942 self.assertEqual(tcp.dport, local_port)
4943 self.assert_packet_checksums_valid(p)
4945 self.logger.error(ppp("Unexpected or invalid packet:", p))
4948 # from service back to client
4949 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4950 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4951 TCP(sport=local_port, dport=12345))
4952 self.pg0.add_stream(p)
4953 self.pg_enable_capture(self.pg_interfaces)
4955 capture = self.pg1.get_capture(1)
4960 self.assertEqual(ip.src, self.nat_addr)
4961 self.assertEqual(tcp.sport, external_port)
4962 self.assert_packet_checksums_valid(p)
4964 self.logger.error(ppp("Unexpected or invalid packet:", p))
4967 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4968 self.assertEqual(len(sessions), 1)
4969 self.assertTrue(sessions[0].flags &
4970 self.config_flags.NAT_IS_EXT_HOST_VALID)
4971 self.vapi.nat44_del_session(
4972 address=sessions[0].inside_ip_address,
4973 port=sessions[0].inside_port,
4974 protocol=sessions[0].protocol,
4975 flags=(self.config_flags.NAT_IS_INSIDE |
4976 self.config_flags.NAT_IS_EXT_HOST_VALID),
4977 ext_host_address=sessions[0].ext_host_address,
4978 ext_host_port=sessions[0].ext_host_port)
4979 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4980 self.assertEqual(len(sessions), 0)
4982 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4983 def test_static_lb_multi_clients(self):
4984 """ NAT44 local service load balancing - multiple clients"""
4986 external_addr = self.nat_addr
4989 server1 = self.pg0.remote_hosts[0]
4990 server2 = self.pg0.remote_hosts[1]
4991 server3 = self.pg0.remote_hosts[2]
4993 locals = [{'addr': server1.ip4,
4997 {'addr': server2.ip4,
5002 self.nat44_add_address(self.nat_addr)
5003 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5004 external_addr=external_addr,
5005 external_port=external_port,
5006 protocol=IP_PROTOS.tcp,
5007 local_num=len(locals),
5009 flags = self.config_flags.NAT_IS_INSIDE
5010 self.vapi.nat44_interface_add_del_feature(
5011 sw_if_index=self.pg0.sw_if_index,
5012 flags=flags, is_add=1)
5013 self.vapi.nat44_interface_add_del_feature(
5014 sw_if_index=self.pg1.sw_if_index,
5019 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5021 for client in clients:
5022 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5023 IP(src=client, dst=self.nat_addr) /
5024 TCP(sport=12345, dport=external_port))
5026 self.pg1.add_stream(pkts)
5027 self.pg_enable_capture(self.pg_interfaces)
5029 capture = self.pg0.get_capture(len(pkts))
5031 if p[IP].dst == server1.ip4:
5035 self.assertGreater(server1_n, server2_n)
5038 'addr': server3.ip4,
5045 self.vapi.nat44_lb_static_mapping_add_del_local(
5047 external_addr=external_addr,
5048 external_port=external_port,
5050 protocol=IP_PROTOS.tcp)
5054 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5056 for client in clients:
5057 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5058 IP(src=client, dst=self.nat_addr) /
5059 TCP(sport=12346, dport=external_port))
5061 self.assertGreater(len(pkts), 0)
5062 self.pg1.add_stream(pkts)
5063 self.pg_enable_capture(self.pg_interfaces)
5065 capture = self.pg0.get_capture(len(pkts))
5067 if p[IP].dst == server1.ip4:
5069 elif p[IP].dst == server2.ip4:
5073 self.assertGreater(server1_n, 0)
5074 self.assertGreater(server2_n, 0)
5075 self.assertGreater(server3_n, 0)
5078 'addr': server2.ip4,
5084 # remove one back-end
5085 self.vapi.nat44_lb_static_mapping_add_del_local(
5087 external_addr=external_addr,
5088 external_port=external_port,
5090 protocol=IP_PROTOS.tcp)
5094 self.pg1.add_stream(pkts)
5095 self.pg_enable_capture(self.pg_interfaces)
5097 capture = self.pg0.get_capture(len(pkts))
5099 if p[IP].dst == server1.ip4:
5101 elif p[IP].dst == server2.ip4:
5105 self.assertGreater(server1_n, 0)
5106 self.assertEqual(server2_n, 0)
5107 self.assertGreater(server3_n, 0)
5109 def test_static_lb_2(self):
5110 """ NAT44 local service load balancing (asymmetrical rule) """
5111 external_addr = self.nat_addr
5114 server1 = self.pg0.remote_hosts[0]
5115 server2 = self.pg0.remote_hosts[1]
5117 locals = [{'addr': server1.ip4,
5121 {'addr': server2.ip4,
5126 self.vapi.nat44_forwarding_enable_disable(enable=1)
5127 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5128 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5129 external_addr=external_addr,
5130 external_port=external_port,
5131 protocol=IP_PROTOS.tcp,
5132 local_num=len(locals),
5134 flags = self.config_flags.NAT_IS_INSIDE
5135 self.vapi.nat44_interface_add_del_feature(
5136 sw_if_index=self.pg0.sw_if_index,
5137 flags=flags, is_add=1)
5138 self.vapi.nat44_interface_add_del_feature(
5139 sw_if_index=self.pg1.sw_if_index,
5142 # from client to service
5143 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5144 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5145 TCP(sport=12345, dport=external_port))
5146 self.pg1.add_stream(p)
5147 self.pg_enable_capture(self.pg_interfaces)
5149 capture = self.pg0.get_capture(1)
5155 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5156 if ip.dst == server1.ip4:
5160 self.assertEqual(tcp.dport, local_port)
5161 self.assert_packet_checksums_valid(p)
5163 self.logger.error(ppp("Unexpected or invalid packet:", p))
5166 # from service back to client
5167 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5168 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5169 TCP(sport=local_port, dport=12345))
5170 self.pg0.add_stream(p)
5171 self.pg_enable_capture(self.pg_interfaces)
5173 capture = self.pg1.get_capture(1)
5178 self.assertEqual(ip.src, self.nat_addr)
5179 self.assertEqual(tcp.sport, external_port)
5180 self.assert_packet_checksums_valid(p)
5182 self.logger.error(ppp("Unexpected or invalid packet:", p))
5185 # from client to server (no translation)
5186 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5187 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5188 TCP(sport=12346, dport=local_port))
5189 self.pg1.add_stream(p)
5190 self.pg_enable_capture(self.pg_interfaces)
5192 capture = self.pg0.get_capture(1)
5198 self.assertEqual(ip.dst, server1.ip4)
5199 self.assertEqual(tcp.dport, local_port)
5200 self.assert_packet_checksums_valid(p)
5202 self.logger.error(ppp("Unexpected or invalid packet:", p))
5205 # from service back to client (no translation)
5206 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5207 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5208 TCP(sport=local_port, dport=12346))
5209 self.pg0.add_stream(p)
5210 self.pg_enable_capture(self.pg_interfaces)
5212 capture = self.pg1.get_capture(1)
5217 self.assertEqual(ip.src, server1.ip4)
5218 self.assertEqual(tcp.sport, local_port)
5219 self.assert_packet_checksums_valid(p)
5221 self.logger.error(ppp("Unexpected or invalid packet:", p))
5224 def test_lb_affinity(self):
5225 """ NAT44 local service load balancing affinity """
5226 external_addr = self.nat_addr
5229 server1 = self.pg0.remote_hosts[0]
5230 server2 = self.pg0.remote_hosts[1]
5232 locals = [{'addr': server1.ip4,
5236 {'addr': server2.ip4,
5241 self.nat44_add_address(self.nat_addr)
5242 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5243 external_addr=external_addr,
5244 external_port=external_port,
5245 protocol=IP_PROTOS.tcp,
5247 local_num=len(locals),
5249 flags = self.config_flags.NAT_IS_INSIDE
5250 self.vapi.nat44_interface_add_del_feature(
5251 sw_if_index=self.pg0.sw_if_index,
5252 flags=flags, is_add=1)
5253 self.vapi.nat44_interface_add_del_feature(
5254 sw_if_index=self.pg1.sw_if_index,
5257 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5258 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5259 TCP(sport=1025, dport=external_port))
5260 self.pg1.add_stream(p)
5261 self.pg_enable_capture(self.pg_interfaces)
5263 capture = self.pg0.get_capture(1)
5264 backend = capture[0][IP].dst
5266 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5267 self.assertEqual(len(sessions), 1)
5268 self.assertTrue(sessions[0].flags &
5269 self.config_flags.NAT_IS_EXT_HOST_VALID)
5270 self.vapi.nat44_del_session(
5271 address=sessions[0].inside_ip_address,
5272 port=sessions[0].inside_port,
5273 protocol=sessions[0].protocol,
5274 flags=(self.config_flags.NAT_IS_INSIDE |
5275 self.config_flags.NAT_IS_EXT_HOST_VALID),
5276 ext_host_address=sessions[0].ext_host_address,
5277 ext_host_port=sessions[0].ext_host_port)
5280 for port in range(1030, 1100):
5281 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5282 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5283 TCP(sport=port, dport=external_port))
5285 self.pg1.add_stream(pkts)
5286 self.pg_enable_capture(self.pg_interfaces)
5288 capture = self.pg0.get_capture(len(pkts))
5290 self.assertEqual(p[IP].dst, backend)
5292 def test_unknown_proto(self):
5293 """ NAT44 translate packet with unknown protocol """
5294 self.nat44_add_address(self.nat_addr)
5295 flags = self.config_flags.NAT_IS_INSIDE
5296 self.vapi.nat44_interface_add_del_feature(
5297 sw_if_index=self.pg0.sw_if_index,
5298 flags=flags, is_add=1)
5299 self.vapi.nat44_interface_add_del_feature(
5300 sw_if_index=self.pg1.sw_if_index,
5304 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5305 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5306 TCP(sport=self.tcp_port_in, dport=20))
5307 self.pg0.add_stream(p)
5308 self.pg_enable_capture(self.pg_interfaces)
5310 p = self.pg1.get_capture(1)
5312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5313 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5315 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5316 TCP(sport=1234, dport=1234))
5317 self.pg0.add_stream(p)
5318 self.pg_enable_capture(self.pg_interfaces)
5320 p = self.pg1.get_capture(1)
5323 self.assertEqual(packet[IP].src, self.nat_addr)
5324 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5325 self.assertEqual(packet.haslayer(GRE), 1)
5326 self.assert_packet_checksums_valid(packet)
5328 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5332 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5333 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5335 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5336 TCP(sport=1234, dport=1234))
5337 self.pg1.add_stream(p)
5338 self.pg_enable_capture(self.pg_interfaces)
5340 p = self.pg0.get_capture(1)
5343 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5344 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5345 self.assertEqual(packet.haslayer(GRE), 1)
5346 self.assert_packet_checksums_valid(packet)
5348 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5351 def test_hairpinning_unknown_proto(self):
5352 """ NAT44 translate packet with unknown protocol - hairpinning """
5353 host = self.pg0.remote_hosts[0]
5354 server = self.pg0.remote_hosts[1]
5356 server_out_port = 8765
5357 server_nat_ip = "10.0.0.11"
5359 self.nat44_add_address(self.nat_addr)
5360 flags = self.config_flags.NAT_IS_INSIDE
5361 self.vapi.nat44_interface_add_del_feature(
5362 sw_if_index=self.pg0.sw_if_index,
5363 flags=flags, is_add=1)
5364 self.vapi.nat44_interface_add_del_feature(
5365 sw_if_index=self.pg1.sw_if_index,
5368 # add static mapping for server
5369 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5372 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5373 IP(src=host.ip4, dst=server_nat_ip) /
5374 TCP(sport=host_in_port, dport=server_out_port))
5375 self.pg0.add_stream(p)
5376 self.pg_enable_capture(self.pg_interfaces)
5378 self.pg0.get_capture(1)
5380 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5381 IP(src=host.ip4, dst=server_nat_ip) /
5383 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5384 TCP(sport=1234, dport=1234))
5385 self.pg0.add_stream(p)
5386 self.pg_enable_capture(self.pg_interfaces)
5388 p = self.pg0.get_capture(1)
5391 self.assertEqual(packet[IP].src, self.nat_addr)
5392 self.assertEqual(packet[IP].dst, server.ip4)
5393 self.assertEqual(packet.haslayer(GRE), 1)
5394 self.assert_packet_checksums_valid(packet)
5396 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5400 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5401 IP(src=server.ip4, dst=self.nat_addr) /
5403 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5404 TCP(sport=1234, dport=1234))
5405 self.pg0.add_stream(p)
5406 self.pg_enable_capture(self.pg_interfaces)
5408 p = self.pg0.get_capture(1)
5411 self.assertEqual(packet[IP].src, server_nat_ip)
5412 self.assertEqual(packet[IP].dst, host.ip4)
5413 self.assertEqual(packet.haslayer(GRE), 1)
5414 self.assert_packet_checksums_valid(packet)
5416 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5419 def test_output_feature_and_service(self):
5420 """ NAT44 interface output feature and services """
5421 external_addr = '1.2.3.4'
5425 self.vapi.nat44_forwarding_enable_disable(enable=1)
5426 self.nat44_add_address(self.nat_addr)
5427 flags = self.config_flags.NAT_IS_ADDR_ONLY
5428 self.vapi.nat44_add_del_identity_mapping(
5429 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5430 flags=flags, is_add=1)
5431 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5432 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5433 local_port, external_port,
5434 proto=IP_PROTOS.tcp, flags=flags)
5435 flags = self.config_flags.NAT_IS_INSIDE
5436 self.vapi.nat44_interface_add_del_feature(
5437 sw_if_index=self.pg0.sw_if_index,
5439 self.vapi.nat44_interface_add_del_feature(
5440 sw_if_index=self.pg0.sw_if_index,
5441 flags=flags, is_add=1)
5442 self.vapi.nat44_interface_add_del_output_feature(
5444 sw_if_index=self.pg1.sw_if_index)
5446 # from client to service
5447 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5448 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5449 TCP(sport=12345, dport=external_port))
5450 self.pg1.add_stream(p)
5451 self.pg_enable_capture(self.pg_interfaces)
5453 capture = self.pg0.get_capture(1)
5458 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5459 self.assertEqual(tcp.dport, local_port)
5460 self.assert_packet_checksums_valid(p)
5462 self.logger.error(ppp("Unexpected or invalid packet:", p))
5465 # from service back to client
5466 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5467 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5468 TCP(sport=local_port, dport=12345))
5469 self.pg0.add_stream(p)
5470 self.pg_enable_capture(self.pg_interfaces)
5472 capture = self.pg1.get_capture(1)
5477 self.assertEqual(ip.src, external_addr)
5478 self.assertEqual(tcp.sport, external_port)
5479 self.assert_packet_checksums_valid(p)
5481 self.logger.error(ppp("Unexpected or invalid packet:", p))
5484 # from local network host to external network
5485 pkts = self.create_stream_in(self.pg0, self.pg1)
5486 self.pg0.add_stream(pkts)
5487 self.pg_enable_capture(self.pg_interfaces)
5489 capture = self.pg1.get_capture(len(pkts))
5490 self.verify_capture_out(capture)
5491 pkts = self.create_stream_in(self.pg0, self.pg1)
5492 self.pg0.add_stream(pkts)
5493 self.pg_enable_capture(self.pg_interfaces)
5495 capture = self.pg1.get_capture(len(pkts))
5496 self.verify_capture_out(capture)
5498 # from external network back to local network host
5499 pkts = self.create_stream_out(self.pg1)
5500 self.pg1.add_stream(pkts)
5501 self.pg_enable_capture(self.pg_interfaces)
5503 capture = self.pg0.get_capture(len(pkts))
5504 self.verify_capture_in(capture, self.pg0)
5506 def test_output_feature_and_service2(self):
5507 """ NAT44 interface output feature and service host direct access """
5508 self.vapi.nat44_forwarding_enable_disable(enable=1)
5509 self.nat44_add_address(self.nat_addr)
5510 self.vapi.nat44_interface_add_del_output_feature(
5512 sw_if_index=self.pg1.sw_if_index)
5514 # session initiated from service host - translate
5515 pkts = self.create_stream_in(self.pg0, self.pg1)
5516 self.pg0.add_stream(pkts)
5517 self.pg_enable_capture(self.pg_interfaces)
5519 capture = self.pg1.get_capture(len(pkts))
5520 self.verify_capture_out(capture)
5522 pkts = self.create_stream_out(self.pg1)
5523 self.pg1.add_stream(pkts)
5524 self.pg_enable_capture(self.pg_interfaces)
5526 capture = self.pg0.get_capture(len(pkts))
5527 self.verify_capture_in(capture, self.pg0)
5529 # session initiated from remote host - do not translate
5530 self.tcp_port_in = 60303
5531 self.udp_port_in = 60304
5532 self.icmp_id_in = 60305
5533 pkts = self.create_stream_out(self.pg1,
5534 self.pg0.remote_ip4,
5535 use_inside_ports=True)
5536 self.pg1.add_stream(pkts)
5537 self.pg_enable_capture(self.pg_interfaces)
5539 capture = self.pg0.get_capture(len(pkts))
5540 self.verify_capture_in(capture, self.pg0)
5542 pkts = self.create_stream_in(self.pg0, self.pg1)
5543 self.pg0.add_stream(pkts)
5544 self.pg_enable_capture(self.pg_interfaces)
5546 capture = self.pg1.get_capture(len(pkts))
5547 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5550 def test_output_feature_and_service3(self):
5551 """ NAT44 interface output feature and DST NAT """
5552 external_addr = '1.2.3.4'
5556 self.vapi.nat44_forwarding_enable_disable(enable=1)
5557 self.nat44_add_address(self.nat_addr)
5558 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5559 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5560 local_port, external_port,
5561 proto=IP_PROTOS.tcp, flags=flags)
5562 flags = self.config_flags.NAT_IS_INSIDE
5563 self.vapi.nat44_interface_add_del_feature(
5564 sw_if_index=self.pg0.sw_if_index,
5566 self.vapi.nat44_interface_add_del_feature(
5567 sw_if_index=self.pg0.sw_if_index,
5568 flags=flags, is_add=1)
5569 self.vapi.nat44_interface_add_del_output_feature(
5571 sw_if_index=self.pg1.sw_if_index)
5573 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5574 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5575 TCP(sport=12345, dport=external_port))
5576 self.pg0.add_stream(p)
5577 self.pg_enable_capture(self.pg_interfaces)
5579 capture = self.pg1.get_capture(1)
5584 self.assertEqual(ip.src, self.pg0.remote_ip4)
5585 self.assertEqual(tcp.sport, 12345)
5586 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5587 self.assertEqual(tcp.dport, local_port)
5588 self.assert_packet_checksums_valid(p)
5590 self.logger.error(ppp("Unexpected or invalid packet:", p))
5593 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5594 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5595 TCP(sport=local_port, dport=12345))
5596 self.pg1.add_stream(p)
5597 self.pg_enable_capture(self.pg_interfaces)
5599 capture = self.pg0.get_capture(1)
5604 self.assertEqual(ip.src, external_addr)
5605 self.assertEqual(tcp.sport, external_port)
5606 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5607 self.assertEqual(tcp.dport, 12345)
5608 self.assert_packet_checksums_valid(p)
5610 self.logger.error(ppp("Unexpected or invalid packet:", p))
5613 def test_next_src_nat(self):
5614 """ On way back forward packet to nat44-in2out node. """
5615 twice_nat_addr = '10.0.1.3'
5618 post_twice_nat_port = 0
5620 self.vapi.nat44_forwarding_enable_disable(enable=1)
5621 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5622 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5623 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5624 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5625 local_port, external_port,
5626 proto=IP_PROTOS.tcp, vrf_id=1,
5628 self.vapi.nat44_interface_add_del_feature(
5629 sw_if_index=self.pg6.sw_if_index,
5632 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5633 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5634 TCP(sport=12345, dport=external_port))
5635 self.pg6.add_stream(p)
5636 self.pg_enable_capture(self.pg_interfaces)
5638 capture = self.pg6.get_capture(1)
5643 self.assertEqual(ip.src, twice_nat_addr)
5644 self.assertNotEqual(tcp.sport, 12345)
5645 post_twice_nat_port = tcp.sport
5646 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5647 self.assertEqual(tcp.dport, local_port)
5648 self.assert_packet_checksums_valid(p)
5650 self.logger.error(ppp("Unexpected or invalid packet:", p))
5653 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5654 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5655 TCP(sport=local_port, dport=post_twice_nat_port))
5656 self.pg6.add_stream(p)
5657 self.pg_enable_capture(self.pg_interfaces)
5659 capture = self.pg6.get_capture(1)
5664 self.assertEqual(ip.src, self.pg1.remote_ip4)
5665 self.assertEqual(tcp.sport, external_port)
5666 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5667 self.assertEqual(tcp.dport, 12345)
5668 self.assert_packet_checksums_valid(p)
5670 self.logger.error(ppp("Unexpected or invalid packet:", p))
5673 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5675 twice_nat_addr = '10.0.1.3'
5683 port_in1 = port_in + 1
5684 port_in2 = port_in + 2
5689 server1 = self.pg0.remote_hosts[0]
5690 server2 = self.pg0.remote_hosts[1]
5702 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5705 self.nat44_add_address(self.nat_addr)
5706 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5710 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5712 flags |= self.config_flags.NAT_IS_TWICE_NAT
5715 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5717 proto=IP_PROTOS.tcp,
5720 locals = [{'addr': server1.ip4,
5724 {'addr': server2.ip4,
5728 out_addr = self.nat_addr
5730 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5731 external_addr=out_addr,
5732 external_port=port_out,
5733 protocol=IP_PROTOS.tcp,
5734 local_num=len(locals),
5736 flags = self.config_flags.NAT_IS_INSIDE
5737 self.vapi.nat44_interface_add_del_feature(
5738 sw_if_index=pg0.sw_if_index,
5739 flags=flags, is_add=1)
5740 self.vapi.nat44_interface_add_del_feature(
5741 sw_if_index=pg1.sw_if_index,
5748 assert client_id is not None
5750 client = self.pg0.remote_hosts[0]
5751 elif client_id == 2:
5752 client = self.pg0.remote_hosts[1]
5754 client = pg1.remote_hosts[0]
5755 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5756 IP(src=client.ip4, dst=self.nat_addr) /
5757 TCP(sport=eh_port_out, dport=port_out))
5759 self.pg_enable_capture(self.pg_interfaces)
5761 capture = pg0.get_capture(1)
5767 if ip.dst == server1.ip4:
5773 self.assertEqual(ip.dst, server.ip4)
5775 self.assertIn(tcp.dport, [port_in1, port_in2])
5777 self.assertEqual(tcp.dport, port_in)
5779 self.assertEqual(ip.src, twice_nat_addr)
5780 self.assertNotEqual(tcp.sport, eh_port_out)
5782 self.assertEqual(ip.src, client.ip4)
5783 self.assertEqual(tcp.sport, eh_port_out)
5785 eh_port_in = tcp.sport
5786 saved_port_in = tcp.dport
5787 self.assert_packet_checksums_valid(p)
5789 self.logger.error(ppp("Unexpected or invalid packet:", p))
5792 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5793 IP(src=server.ip4, dst=eh_addr_in) /
5794 TCP(sport=saved_port_in, dport=eh_port_in))
5796 self.pg_enable_capture(self.pg_interfaces)
5798 capture = pg1.get_capture(1)
5803 self.assertEqual(ip.dst, client.ip4)
5804 self.assertEqual(ip.src, self.nat_addr)
5805 self.assertEqual(tcp.dport, eh_port_out)
5806 self.assertEqual(tcp.sport, port_out)
5807 self.assert_packet_checksums_valid(p)
5809 self.logger.error(ppp("Unexpected or invalid packet:", p))
5813 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5814 self.assertEqual(len(sessions), 1)
5815 self.assertTrue(sessions[0].flags &
5816 self.config_flags.NAT_IS_EXT_HOST_VALID)
5817 self.assertTrue(sessions[0].flags &
5818 self.config_flags.NAT_IS_TWICE_NAT)
5819 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5820 self.vapi.nat44_del_session(
5821 address=sessions[0].inside_ip_address,
5822 port=sessions[0].inside_port,
5823 protocol=sessions[0].protocol,
5824 flags=(self.config_flags.NAT_IS_INSIDE |
5825 self.config_flags.NAT_IS_EXT_HOST_VALID),
5826 ext_host_address=sessions[0].ext_host_nat_address,
5827 ext_host_port=sessions[0].ext_host_nat_port)
5828 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5829 self.assertEqual(len(sessions), 0)
5831 def test_twice_nat(self):
5833 self.twice_nat_common()
5835 def test_self_twice_nat_positive(self):
5836 """ Self Twice NAT44 (positive test) """
5837 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5839 def test_self_twice_nat_negative(self):
5840 """ Self Twice NAT44 (negative test) """
5841 self.twice_nat_common(self_twice_nat=True)
5843 def test_twice_nat_lb(self):
5844 """ Twice NAT44 local service load balancing """
5845 self.twice_nat_common(lb=True)
5847 def test_self_twice_nat_lb_positive(self):
5848 """ Self Twice NAT44 local service load balancing (positive test) """
5849 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5852 def test_self_twice_nat_lb_negative(self):
5853 """ Self Twice NAT44 local service load balancing (negative test) """
5854 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5857 def test_twice_nat_interface_addr(self):
5858 """ Acquire twice NAT44 addresses from interface """
5859 flags = self.config_flags.NAT_IS_TWICE_NAT
5860 self.vapi.nat44_add_del_interface_addr(
5862 sw_if_index=self.pg3.sw_if_index,
5865 # no address in NAT pool
5866 adresses = self.vapi.nat44_address_dump()
5867 self.assertEqual(0, len(adresses))
5869 # configure interface address and check NAT address pool
5870 self.pg3.config_ip4()
5871 adresses = self.vapi.nat44_address_dump()
5872 self.assertEqual(1, len(adresses))
5873 self.assertEqual(str(adresses[0].ip_address),
5875 self.assertEqual(adresses[0].flags, flags)
5877 # remove interface address and check NAT address pool
5878 self.pg3.unconfig_ip4()
5879 adresses = self.vapi.nat44_address_dump()
5880 self.assertEqual(0, len(adresses))
5882 def test_tcp_close(self):
5883 """ Close TCP session from inside network - output feature """
5884 self.vapi.nat44_forwarding_enable_disable(enable=1)
5885 self.nat44_add_address(self.pg1.local_ip4)
5886 twice_nat_addr = '10.0.1.3'
5887 service_ip = '192.168.16.150'
5888 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5889 flags = self.config_flags.NAT_IS_INSIDE
5890 self.vapi.nat44_interface_add_del_feature(
5891 sw_if_index=self.pg0.sw_if_index,
5893 self.vapi.nat44_interface_add_del_feature(
5894 sw_if_index=self.pg0.sw_if_index,
5895 flags=flags, is_add=1)
5896 self.vapi.nat44_interface_add_del_output_feature(
5898 sw_if_index=self.pg1.sw_if_index)
5899 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5900 self.config_flags.NAT_IS_TWICE_NAT)
5901 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5905 proto=IP_PROTOS.tcp,
5907 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5908 start_sessnum = len(sessions)
5910 # SYN packet out->in
5911 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5912 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5913 TCP(sport=33898, dport=80, flags="S"))
5914 self.pg1.add_stream(p)
5915 self.pg_enable_capture(self.pg_interfaces)
5917 capture = self.pg0.get_capture(1)
5919 tcp_port = p[TCP].sport
5921 # SYN + ACK packet in->out
5922 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5923 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5924 TCP(sport=80, dport=tcp_port, flags="SA"))
5925 self.pg0.add_stream(p)
5926 self.pg_enable_capture(self.pg_interfaces)
5928 self.pg1.get_capture(1)
5930 # ACK packet out->in
5931 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5932 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5933 TCP(sport=33898, dport=80, flags="A"))
5934 self.pg1.add_stream(p)
5935 self.pg_enable_capture(self.pg_interfaces)
5937 self.pg0.get_capture(1)
5939 # FIN packet in -> out
5940 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5941 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5942 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5943 self.pg0.add_stream(p)
5944 self.pg_enable_capture(self.pg_interfaces)
5946 self.pg1.get_capture(1)
5948 # FIN+ACK packet out -> in
5949 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5950 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5951 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5952 self.pg1.add_stream(p)
5953 self.pg_enable_capture(self.pg_interfaces)
5955 self.pg0.get_capture(1)
5957 # ACK packet in -> out
5958 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5959 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5960 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5961 self.pg0.add_stream(p)
5962 self.pg_enable_capture(self.pg_interfaces)
5964 self.pg1.get_capture(1)
5966 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5968 self.assertEqual(len(sessions) - start_sessnum, 0)
5970 def test_tcp_session_close_in(self):
5971 """ Close TCP session from inside network """
5972 self.tcp_port_out = 10505
5973 self.nat44_add_address(self.nat_addr)
5974 flags = self.config_flags.NAT_IS_TWICE_NAT
5975 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5979 proto=IP_PROTOS.tcp,
5981 flags = self.config_flags.NAT_IS_INSIDE
5982 self.vapi.nat44_interface_add_del_feature(
5983 sw_if_index=self.pg0.sw_if_index,
5984 flags=flags, is_add=1)
5985 self.vapi.nat44_interface_add_del_feature(
5986 sw_if_index=self.pg1.sw_if_index,
5989 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5990 start_sessnum = len(sessions)
5992 self.initiate_tcp_session(self.pg0, self.pg1)
5994 # FIN packet in -> out
5995 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5996 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5997 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5998 flags="FA", seq=100, ack=300))
5999 self.pg0.add_stream(p)
6000 self.pg_enable_capture(self.pg_interfaces)
6002 self.pg1.get_capture(1)
6006 # ACK packet out -> in
6007 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6008 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6009 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6010 flags="A", seq=300, ack=101))
6013 # FIN packet out -> in
6014 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6015 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6016 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6017 flags="FA", seq=300, ack=101))
6020 self.pg1.add_stream(pkts)
6021 self.pg_enable_capture(self.pg_interfaces)
6023 self.pg0.get_capture(2)
6025 # ACK packet in -> out
6026 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6027 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6028 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6029 flags="A", seq=101, ack=301))
6030 self.pg0.add_stream(p)
6031 self.pg_enable_capture(self.pg_interfaces)
6033 self.pg1.get_capture(1)
6035 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6037 self.assertEqual(len(sessions) - start_sessnum, 0)
6039 def test_tcp_session_close_out(self):
6040 """ Close TCP session from outside network """
6041 self.tcp_port_out = 10505
6042 self.nat44_add_address(self.nat_addr)
6043 flags = self.config_flags.NAT_IS_TWICE_NAT
6044 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6048 proto=IP_PROTOS.tcp,
6050 flags = self.config_flags.NAT_IS_INSIDE
6051 self.vapi.nat44_interface_add_del_feature(
6052 sw_if_index=self.pg0.sw_if_index,
6053 flags=flags, is_add=1)
6054 self.vapi.nat44_interface_add_del_feature(
6055 sw_if_index=self.pg1.sw_if_index,
6058 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6059 start_sessnum = len(sessions)
6061 self.initiate_tcp_session(self.pg0, self.pg1)
6063 # FIN packet out -> in
6064 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6065 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6066 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6067 flags="FA", seq=100, ack=300))
6068 self.pg1.add_stream(p)
6069 self.pg_enable_capture(self.pg_interfaces)
6071 self.pg0.get_capture(1)
6073 # FIN+ACK packet in -> out
6074 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6075 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6076 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6077 flags="FA", seq=300, ack=101))
6079 self.pg0.add_stream(p)
6080 self.pg_enable_capture(self.pg_interfaces)
6082 self.pg1.get_capture(1)
6084 # ACK packet out -> in
6085 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6086 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6087 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6088 flags="A", seq=101, ack=301))
6089 self.pg1.add_stream(p)
6090 self.pg_enable_capture(self.pg_interfaces)
6092 self.pg0.get_capture(1)
6094 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6096 self.assertEqual(len(sessions) - start_sessnum, 0)
6098 def test_tcp_session_close_simultaneous(self):
6099 """ Close TCP session from inside network """
6100 self.tcp_port_out = 10505
6101 self.nat44_add_address(self.nat_addr)
6102 flags = self.config_flags.NAT_IS_TWICE_NAT
6103 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6107 proto=IP_PROTOS.tcp,
6109 flags = self.config_flags.NAT_IS_INSIDE
6110 self.vapi.nat44_interface_add_del_feature(
6111 sw_if_index=self.pg0.sw_if_index,
6112 flags=flags, is_add=1)
6113 self.vapi.nat44_interface_add_del_feature(
6114 sw_if_index=self.pg1.sw_if_index,
6117 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6118 start_sessnum = len(sessions)
6120 self.initiate_tcp_session(self.pg0, self.pg1)
6122 # FIN packet in -> out
6123 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6124 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6125 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6126 flags="FA", seq=100, ack=300))
6127 self.pg0.add_stream(p)
6128 self.pg_enable_capture(self.pg_interfaces)
6130 self.pg1.get_capture(1)
6132 # FIN packet out -> in
6133 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6134 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6135 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6136 flags="FA", seq=300, ack=100))
6137 self.pg1.add_stream(p)
6138 self.pg_enable_capture(self.pg_interfaces)
6140 self.pg0.get_capture(1)
6142 # ACK packet in -> out
6143 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6144 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6145 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6146 flags="A", seq=101, ack=301))
6147 self.pg0.add_stream(p)
6148 self.pg_enable_capture(self.pg_interfaces)
6150 self.pg1.get_capture(1)
6152 # ACK packet out -> in
6153 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6154 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6155 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6156 flags="A", seq=301, ack=101))
6157 self.pg1.add_stream(p)
6158 self.pg_enable_capture(self.pg_interfaces)
6160 self.pg0.get_capture(1)
6162 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6164 self.assertEqual(len(sessions) - start_sessnum, 0)
6166 def test_one_armed_nat44_static(self):
6167 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6168 remote_host = self.pg4.remote_hosts[0]
6169 local_host = self.pg4.remote_hosts[1]
6174 self.vapi.nat44_forwarding_enable_disable(enable=1)
6175 self.nat44_add_address(self.nat_addr, twice_nat=1)
6176 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6177 self.config_flags.NAT_IS_TWICE_NAT)
6178 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6179 local_port, external_port,
6180 proto=IP_PROTOS.tcp, flags=flags)
6181 flags = self.config_flags.NAT_IS_INSIDE
6182 self.vapi.nat44_interface_add_del_feature(
6183 sw_if_index=self.pg4.sw_if_index,
6185 self.vapi.nat44_interface_add_del_feature(
6186 sw_if_index=self.pg4.sw_if_index,
6187 flags=flags, is_add=1)
6189 # from client to service
6190 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6191 IP(src=remote_host.ip4, dst=self.nat_addr) /
6192 TCP(sport=12345, dport=external_port))
6193 self.pg4.add_stream(p)
6194 self.pg_enable_capture(self.pg_interfaces)
6196 capture = self.pg4.get_capture(1)
6201 self.assertEqual(ip.dst, local_host.ip4)
6202 self.assertEqual(ip.src, self.nat_addr)
6203 self.assertEqual(tcp.dport, local_port)
6204 self.assertNotEqual(tcp.sport, 12345)
6205 eh_port_in = tcp.sport
6206 self.assert_packet_checksums_valid(p)
6208 self.logger.error(ppp("Unexpected or invalid packet:", p))
6211 # from service back to client
6212 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6213 IP(src=local_host.ip4, dst=self.nat_addr) /
6214 TCP(sport=local_port, dport=eh_port_in))
6215 self.pg4.add_stream(p)
6216 self.pg_enable_capture(self.pg_interfaces)
6218 capture = self.pg4.get_capture(1)
6223 self.assertEqual(ip.src, self.nat_addr)
6224 self.assertEqual(ip.dst, remote_host.ip4)
6225 self.assertEqual(tcp.sport, external_port)
6226 self.assertEqual(tcp.dport, 12345)
6227 self.assert_packet_checksums_valid(p)
6229 self.logger.error(ppp("Unexpected or invalid packet:", p))
6232 def test_static_with_port_out2(self):
6233 """ 1:1 NAPT asymmetrical rule """
6238 self.vapi.nat44_forwarding_enable_disable(enable=1)
6239 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6240 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6241 local_port, external_port,
6242 proto=IP_PROTOS.tcp, flags=flags)
6243 flags = self.config_flags.NAT_IS_INSIDE
6244 self.vapi.nat44_interface_add_del_feature(
6245 sw_if_index=self.pg0.sw_if_index,
6246 flags=flags, is_add=1)
6247 self.vapi.nat44_interface_add_del_feature(
6248 sw_if_index=self.pg1.sw_if_index,
6251 # from client to service
6252 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6253 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6254 TCP(sport=12345, dport=external_port))
6255 self.pg1.add_stream(p)
6256 self.pg_enable_capture(self.pg_interfaces)
6258 capture = self.pg0.get_capture(1)
6263 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6264 self.assertEqual(tcp.dport, local_port)
6265 self.assert_packet_checksums_valid(p)
6267 self.logger.error(ppp("Unexpected or invalid packet:", p))
6271 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6272 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6273 ICMP(type=11) / capture[0][IP])
6274 self.pg0.add_stream(p)
6275 self.pg_enable_capture(self.pg_interfaces)
6277 capture = self.pg1.get_capture(1)
6280 self.assertEqual(p[IP].src, self.nat_addr)
6282 self.assertEqual(inner.dst, self.nat_addr)
6283 self.assertEqual(inner[TCPerror].dport, external_port)
6285 self.logger.error(ppp("Unexpected or invalid packet:", p))
6288 # from service back to client
6289 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6290 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6291 TCP(sport=local_port, dport=12345))
6292 self.pg0.add_stream(p)
6293 self.pg_enable_capture(self.pg_interfaces)
6295 capture = self.pg1.get_capture(1)
6300 self.assertEqual(ip.src, self.nat_addr)
6301 self.assertEqual(tcp.sport, external_port)
6302 self.assert_packet_checksums_valid(p)
6304 self.logger.error(ppp("Unexpected or invalid packet:", p))
6308 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6309 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6310 ICMP(type=11) / capture[0][IP])
6311 self.pg1.add_stream(p)
6312 self.pg_enable_capture(self.pg_interfaces)
6314 capture = self.pg0.get_capture(1)
6317 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6319 self.assertEqual(inner.src, self.pg0.remote_ip4)
6320 self.assertEqual(inner[TCPerror].sport, local_port)
6322 self.logger.error(ppp("Unexpected or invalid packet:", p))
6325 # from client to server (no translation)
6326 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6327 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6328 TCP(sport=12346, dport=local_port))
6329 self.pg1.add_stream(p)
6330 self.pg_enable_capture(self.pg_interfaces)
6332 capture = self.pg0.get_capture(1)
6337 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6338 self.assertEqual(tcp.dport, local_port)
6339 self.assert_packet_checksums_valid(p)
6341 self.logger.error(ppp("Unexpected or invalid packet:", p))
6344 # from service back to client (no translation)
6345 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6346 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6347 TCP(sport=local_port, dport=12346))
6348 self.pg0.add_stream(p)
6349 self.pg_enable_capture(self.pg_interfaces)
6351 capture = self.pg1.get_capture(1)
6356 self.assertEqual(ip.src, self.pg0.remote_ip4)
6357 self.assertEqual(tcp.sport, local_port)
6358 self.assert_packet_checksums_valid(p)
6360 self.logger.error(ppp("Unexpected or invalid packet:", p))
6363 def test_output_feature(self):
6364 """ NAT44 interface output feature (in2out postrouting) """
6365 self.vapi.nat44_forwarding_enable_disable(enable=1)
6366 self.nat44_add_address(self.nat_addr)
6367 self.vapi.nat44_interface_add_del_feature(
6368 sw_if_index=self.pg0.sw_if_index,
6370 self.vapi.nat44_interface_add_del_output_feature(
6372 sw_if_index=self.pg1.sw_if_index)
6375 pkts = self.create_stream_in(self.pg0, self.pg1)
6376 self.pg0.add_stream(pkts)
6377 self.pg_enable_capture(self.pg_interfaces)
6379 capture = self.pg1.get_capture(len(pkts))
6380 self.verify_capture_out(capture)
6383 pkts = self.create_stream_out(self.pg1)
6384 self.pg1.add_stream(pkts)
6385 self.pg_enable_capture(self.pg_interfaces)
6387 capture = self.pg0.get_capture(len(pkts))
6388 self.verify_capture_in(capture, self.pg0)
6390 def test_output_feature_stateful_acl(self):
6391 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6392 self.nat44_add_address(self.nat_addr)
6393 self.vapi.nat44_interface_add_del_output_feature(
6394 sw_if_index=self.pg0.sw_if_index,
6395 flags=self.config_flags.NAT_IS_INSIDE,
6397 self.vapi.nat44_interface_add_del_output_feature(
6398 sw_if_index=self.pg1.sw_if_index,
6399 flags=self.config_flags.NAT_IS_OUTSIDE,
6402 # First ensure that the NAT is working sans ACL
6404 # send packets out2in, no sessions yet so packets should drop
6405 pkts_out2in = self.create_stream_out(self.pg1)
6406 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6408 # send packets into inside intf, ensure received via outside intf
6409 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6410 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6412 self.verify_capture_out(capture)
6414 # send out2in again, with sessions created it should work now
6415 pkts_out2in = self.create_stream_out(self.pg1)
6416 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6418 self.verify_capture_in(capture, self.pg0)
6420 # Create an ACL blocking everything
6421 out2in_deny_rule = {
6424 'src_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6425 'src_ip_prefix_len': 0,
6426 'dst_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6427 'dst_ip_prefix_len': 0,
6428 'srcport_or_icmptype_first': 0,
6429 'srcport_or_icmptype_last': 65535,
6430 'dstport_or_icmpcode_first': 0,
6431 'dstport_or_icmpcode_last': 65535,
6434 out2in_rules = [out2in_deny_rule]
6435 res = self.vapi.acl_add_replace(0xffffffff, out2in_rules)
6436 self.assertEqual(res.retval, 0, "error adding out2in ACL")
6437 out2in_acl = res.acl_index
6439 # apply as input acl on interface and confirm it blocks everything
6440 self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
6443 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6445 # create an ACL to permit/reflect everything
6446 in2out_reflect_rule = {
6449 'src_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6450 'src_ip_prefix_len': 0,
6451 'dst_ip_addr': inet_pton(AF_INET, "0.0.0.0"),
6452 'dst_ip_prefix_len': 0,
6453 'srcport_or_icmptype_first': 0,
6454 'srcport_or_icmptype_last': 65535,
6455 'dstport_or_icmpcode_first': 0,
6456 'dstport_or_icmpcode_last': 65535,
6459 in2out_rules = [in2out_reflect_rule]
6460 res = self.vapi.acl_add_replace(0xffffffff, in2out_rules)
6461 self.assertEqual(res.retval, 0, "error adding in2out ACL")
6462 in2out_acl = res.acl_index
6465 self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
6467 acls=[out2in_acl, in2out_acl])
6468 # send in2out to generate ACL state (NAT state was created earlier)
6469 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6471 self.verify_capture_out(capture)
6473 # send out2in again. ACL state exists so it should work now.
6474 # TCP packets with the syn flag set also need the ack flag
6475 for p in pkts_out2in:
6476 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6477 p[TCP].flags |= 0x10
6478 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6480 self.verify_capture_in(capture, self.pg0)
6481 self.logger.info(self.vapi.cli("show trace"))
6484 # Remove ACLs from interface
6485 self.vapi.acl_interface_set_acl_list(sw_if_index=self.pg1.sw_if_index,
6489 self.vapi.acl_del(acl_index=out2in_acl, expected_retval=0)
6490 self.vapi.acl_del(acl_index=in2out_acl, expected_retval=0)
6492 def test_multiple_vrf(self):
6493 """ Multiple VRF setup """
6494 external_addr = '1.2.3.4'
6499 self.vapi.nat44_forwarding_enable_disable(enable=1)
6500 self.nat44_add_address(self.nat_addr)
6501 flags = self.config_flags.NAT_IS_INSIDE
6502 self.vapi.nat44_interface_add_del_feature(
6503 sw_if_index=self.pg0.sw_if_index,
6505 self.vapi.nat44_interface_add_del_feature(
6506 sw_if_index=self.pg0.sw_if_index,
6507 flags=flags, is_add=1)
6508 self.vapi.nat44_interface_add_del_output_feature(
6510 sw_if_index=self.pg1.sw_if_index)
6511 self.vapi.nat44_interface_add_del_feature(
6512 sw_if_index=self.pg5.sw_if_index,
6514 self.vapi.nat44_interface_add_del_feature(
6515 sw_if_index=self.pg5.sw_if_index,
6516 flags=flags, is_add=1)
6517 self.vapi.nat44_interface_add_del_feature(
6518 sw_if_index=self.pg6.sw_if_index,
6520 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6521 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6522 local_port, external_port, vrf_id=1,
6523 proto=IP_PROTOS.tcp, flags=flags)
6524 self.nat44_add_static_mapping(
6525 self.pg0.remote_ip4,
6526 external_sw_if_index=self.pg0.sw_if_index,
6527 local_port=local_port,
6529 external_port=external_port,
6530 proto=IP_PROTOS.tcp,
6534 # from client to service (both VRF1)
6535 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6536 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6537 TCP(sport=12345, dport=external_port))
6538 self.pg6.add_stream(p)
6539 self.pg_enable_capture(self.pg_interfaces)
6541 capture = self.pg5.get_capture(1)
6546 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6547 self.assertEqual(tcp.dport, local_port)
6548 self.assert_packet_checksums_valid(p)
6550 self.logger.error(ppp("Unexpected or invalid packet:", p))
6553 # from service back to client (both VRF1)
6554 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6555 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6556 TCP(sport=local_port, dport=12345))
6557 self.pg5.add_stream(p)
6558 self.pg_enable_capture(self.pg_interfaces)
6560 capture = self.pg6.get_capture(1)
6565 self.assertEqual(ip.src, external_addr)
6566 self.assertEqual(tcp.sport, external_port)
6567 self.assert_packet_checksums_valid(p)
6569 self.logger.error(ppp("Unexpected or invalid packet:", p))
6572 # dynamic NAT from VRF1 to VRF0 (output-feature)
6573 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6574 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6575 TCP(sport=2345, dport=22))
6576 self.pg5.add_stream(p)
6577 self.pg_enable_capture(self.pg_interfaces)
6579 capture = self.pg1.get_capture(1)
6584 self.assertEqual(ip.src, self.nat_addr)
6585 self.assertNotEqual(tcp.sport, 2345)
6586 self.assert_packet_checksums_valid(p)
6589 self.logger.error(ppp("Unexpected or invalid packet:", p))
6592 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6593 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6594 TCP(sport=22, dport=port))
6595 self.pg1.add_stream(p)
6596 self.pg_enable_capture(self.pg_interfaces)
6598 capture = self.pg5.get_capture(1)
6603 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6604 self.assertEqual(tcp.dport, 2345)
6605 self.assert_packet_checksums_valid(p)
6607 self.logger.error(ppp("Unexpected or invalid packet:", p))
6610 # from client VRF1 to service VRF0
6611 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6612 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6613 TCP(sport=12346, dport=external_port))
6614 self.pg6.add_stream(p)
6615 self.pg_enable_capture(self.pg_interfaces)
6617 capture = self.pg0.get_capture(1)
6622 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6623 self.assertEqual(tcp.dport, local_port)
6624 self.assert_packet_checksums_valid(p)
6626 self.logger.error(ppp("Unexpected or invalid packet:", p))
6629 # from service VRF0 back to client VRF1
6630 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6631 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6632 TCP(sport=local_port, dport=12346))
6633 self.pg0.add_stream(p)
6634 self.pg_enable_capture(self.pg_interfaces)
6636 capture = self.pg6.get_capture(1)
6641 self.assertEqual(ip.src, self.pg0.local_ip4)
6642 self.assertEqual(tcp.sport, external_port)
6643 self.assert_packet_checksums_valid(p)
6645 self.logger.error(ppp("Unexpected or invalid packet:", p))
6648 # from client VRF0 to service VRF1
6649 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6650 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6651 TCP(sport=12347, dport=external_port))
6652 self.pg0.add_stream(p)
6653 self.pg_enable_capture(self.pg_interfaces)
6655 capture = self.pg5.get_capture(1)
6660 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6661 self.assertEqual(tcp.dport, local_port)
6662 self.assert_packet_checksums_valid(p)
6664 self.logger.error(ppp("Unexpected or invalid packet:", p))
6667 # from service VRF1 back to client VRF0
6668 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6669 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6670 TCP(sport=local_port, dport=12347))
6671 self.pg5.add_stream(p)
6672 self.pg_enable_capture(self.pg_interfaces)
6674 capture = self.pg0.get_capture(1)
6679 self.assertEqual(ip.src, external_addr)
6680 self.assertEqual(tcp.sport, external_port)
6681 self.assert_packet_checksums_valid(p)
6683 self.logger.error(ppp("Unexpected or invalid packet:", p))
6686 # from client to server (both VRF1, no translation)
6687 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6688 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6689 TCP(sport=12348, dport=local_port))
6690 self.pg6.add_stream(p)
6691 self.pg_enable_capture(self.pg_interfaces)
6693 capture = self.pg5.get_capture(1)
6698 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6699 self.assertEqual(tcp.dport, local_port)
6700 self.assert_packet_checksums_valid(p)
6702 self.logger.error(ppp("Unexpected or invalid packet:", p))
6705 # from server back to client (both VRF1, no translation)
6706 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6707 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6708 TCP(sport=local_port, dport=12348))
6709 self.pg5.add_stream(p)
6710 self.pg_enable_capture(self.pg_interfaces)
6712 capture = self.pg6.get_capture(1)
6717 self.assertEqual(ip.src, self.pg5.remote_ip4)
6718 self.assertEqual(tcp.sport, local_port)
6719 self.assert_packet_checksums_valid(p)
6721 self.logger.error(ppp("Unexpected or invalid packet:", p))
6724 # from client VRF1 to server VRF0 (no translation)
6725 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6726 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6727 TCP(sport=local_port, dport=12349))
6728 self.pg0.add_stream(p)
6729 self.pg_enable_capture(self.pg_interfaces)
6731 capture = self.pg6.get_capture(1)
6736 self.assertEqual(ip.src, self.pg0.remote_ip4)
6737 self.assertEqual(tcp.sport, local_port)
6738 self.assert_packet_checksums_valid(p)
6740 self.logger.error(ppp("Unexpected or invalid packet:", p))
6743 # from server VRF0 back to client VRF1 (no translation)
6744 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6745 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6746 TCP(sport=local_port, dport=12349))
6747 self.pg0.add_stream(p)
6748 self.pg_enable_capture(self.pg_interfaces)
6750 capture = self.pg6.get_capture(1)
6755 self.assertEqual(ip.src, self.pg0.remote_ip4)
6756 self.assertEqual(tcp.sport, local_port)
6757 self.assert_packet_checksums_valid(p)
6759 self.logger.error(ppp("Unexpected or invalid packet:", p))
6762 # from client VRF0 to server VRF1 (no translation)
6763 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6764 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6765 TCP(sport=12344, dport=local_port))
6766 self.pg0.add_stream(p)
6767 self.pg_enable_capture(self.pg_interfaces)
6769 capture = self.pg5.get_capture(1)
6774 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6775 self.assertEqual(tcp.dport, local_port)
6776 self.assert_packet_checksums_valid(p)
6778 self.logger.error(ppp("Unexpected or invalid packet:", p))
6781 # from server VRF1 back to client VRF0 (no translation)
6782 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6783 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6784 TCP(sport=local_port, dport=12344))
6785 self.pg5.add_stream(p)
6786 self.pg_enable_capture(self.pg_interfaces)
6788 capture = self.pg0.get_capture(1)
6793 self.assertEqual(ip.src, self.pg5.remote_ip4)
6794 self.assertEqual(tcp.sport, local_port)
6795 self.assert_packet_checksums_valid(p)
6797 self.logger.error(ppp("Unexpected or invalid packet:", p))
6800 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6801 def test_session_timeout(self):
6802 """ NAT44 session timeouts """
6803 self.nat44_add_address(self.nat_addr)
6804 flags = self.config_flags.NAT_IS_INSIDE
6805 self.vapi.nat44_interface_add_del_feature(
6806 sw_if_index=self.pg0.sw_if_index,
6807 flags=flags, is_add=1)
6808 self.vapi.nat44_interface_add_del_feature(
6809 sw_if_index=self.pg1.sw_if_index,
6811 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6812 tcp_transitory=240, icmp=5)
6816 for i in range(0, max_sessions):
6817 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6818 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6819 IP(src=src, dst=self.pg1.remote_ip4) /
6820 ICMP(id=1025, type='echo-request'))
6822 self.pg0.add_stream(pkts)
6823 self.pg_enable_capture(self.pg_interfaces)
6825 self.pg1.get_capture(max_sessions)
6830 for i in range(0, max_sessions):
6831 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6832 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6833 IP(src=src, dst=self.pg1.remote_ip4) /
6834 ICMP(id=1026, type='echo-request'))
6836 self.pg0.add_stream(pkts)
6837 self.pg_enable_capture(self.pg_interfaces)
6839 self.pg1.get_capture(max_sessions)
6842 users = self.vapi.nat44_user_dump()
6844 nsessions = nsessions + user.nsessions
6845 self.assertLess(nsessions, 2 * max_sessions)
6847 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6848 def test_session_rst_timeout(self):
6849 """ NAT44 session RST timeouts """
6850 self.nat44_add_address(self.nat_addr)
6851 flags = self.config_flags.NAT_IS_INSIDE
6852 self.vapi.nat44_interface_add_del_feature(
6853 sw_if_index=self.pg0.sw_if_index,
6854 flags=flags, is_add=1)
6855 self.vapi.nat44_interface_add_del_feature(
6856 sw_if_index=self.pg1.sw_if_index,
6858 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6859 tcp_transitory=5, icmp=60)
6861 self.initiate_tcp_session(self.pg0, self.pg1)
6862 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6863 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6864 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6866 self.pg0.add_stream(p)
6867 self.pg_enable_capture(self.pg_interfaces)
6869 self.pg1.get_capture(1)
6873 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6874 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6875 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6877 self.pg0.add_stream(p)
6878 self.pg_enable_capture(self.pg_interfaces)
6880 self.pg1.get_capture(1)
6883 users = self.vapi.nat44_user_dump()
6884 self.assertEqual(len(users), 1)
6885 self.assertEqual(str(users[0].ip_address),
6886 self.pg0.remote_ip4)
6887 self.assertEqual(users[0].nsessions, 1)
6889 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6890 def test_session_limit_per_user(self):
6891 """ Maximum sessions per user limit """
6892 self.nat44_add_address(self.nat_addr)
6893 flags = self.config_flags.NAT_IS_INSIDE
6894 self.vapi.nat44_interface_add_del_feature(
6895 sw_if_index=self.pg0.sw_if_index,
6896 flags=flags, is_add=1)
6897 self.vapi.nat44_interface_add_del_feature(
6898 sw_if_index=self.pg1.sw_if_index,
6900 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
6901 src_address=self.pg2.local_ip4,
6903 template_interval=10)
6904 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6905 tcp_transitory=240, icmp=60)
6907 # get maximum number of translations per user
6908 nat44_config = self.vapi.nat_show_config()
6911 for port in range(0, nat44_config.max_translations_per_user):
6912 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6913 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6914 UDP(sport=1025 + port, dport=1025 + port))
6917 self.pg0.add_stream(pkts)
6918 self.pg_enable_capture(self.pg_interfaces)
6920 capture = self.pg1.get_capture(len(pkts))
6922 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6923 src_port=self.ipfix_src_port,
6926 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6927 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6928 UDP(sport=3001, dport=3002))
6929 self.pg0.add_stream(p)
6930 self.pg_enable_capture(self.pg_interfaces)
6932 capture = self.pg1.assert_nothing_captured()
6934 # verify IPFIX logging
6935 self.vapi.ipfix_flush()
6937 capture = self.pg2.get_capture(10)
6938 ipfix = IPFIXDecoder()
6939 # first load template
6941 self.assertTrue(p.haslayer(IPFIX))
6942 if p.haslayer(Template):
6943 ipfix.add_template(p.getlayer(Template))
6944 # verify events in data set
6946 if p.haslayer(Data):
6947 data = ipfix.decode_data_set(p.getlayer(Set))
6948 self.verify_ipfix_max_entries_per_user(
6950 nat44_config.max_translations_per_user,
6951 self.pg0.remote_ip4)
6954 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6955 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6956 UDP(sport=3001, dport=3002))
6957 self.pg0.add_stream(p)
6958 self.pg_enable_capture(self.pg_interfaces)
6960 self.pg1.get_capture(1)
6962 def test_syslog_sess(self):
6963 """ Test syslog session creation and deletion """
6964 self.vapi.syslog_set_filter(
6965 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6966 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6967 self.nat44_add_address(self.nat_addr)
6968 flags = self.config_flags.NAT_IS_INSIDE
6969 self.vapi.nat44_interface_add_del_feature(
6970 sw_if_index=self.pg0.sw_if_index,
6971 flags=flags, is_add=1)
6972 self.vapi.nat44_interface_add_del_feature(
6973 sw_if_index=self.pg1.sw_if_index,
6976 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6977 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6978 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6979 self.pg0.add_stream(p)
6980 self.pg_enable_capture(self.pg_interfaces)
6982 capture = self.pg1.get_capture(1)
6983 self.tcp_port_out = capture[0][TCP].sport
6984 capture = self.pg2.get_capture(1)
6985 self.verify_syslog_sess(capture[0][Raw].load)
6987 self.pg_enable_capture(self.pg_interfaces)
6989 self.nat44_add_address(self.nat_addr, is_add=0)
6990 capture = self.pg2.get_capture(1)
6991 self.verify_syslog_sess(capture[0][Raw].load, False)
6994 super(TestNAT44EndpointDependent, self).tearDown()
6995 if not self.vpp_dead:
6997 self.vapi.cli("clear logging")
6999 def show_commands_at_teardown(self):
7000 self.logger.info(self.vapi.cli("show nat44 addresses"))
7001 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7002 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7003 self.logger.info(self.vapi.cli("show nat44 interface address"))
7004 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7005 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7006 self.logger.info(self.vapi.cli("show nat timeouts"))
7009 class TestNAT44Out2InDPO(MethodHolder):
7010 """ NAT44 Test Cases using out2in DPO """
7013 def setUpConstants(cls):
7014 super(TestNAT44Out2InDPO, cls).setUpConstants()
7015 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7018 def setUpClass(cls):
7019 super(TestNAT44Out2InDPO, cls).setUpClass()
7020 cls.vapi.cli("set log class nat level debug")
7023 cls.tcp_port_in = 6303
7024 cls.tcp_port_out = 6303
7025 cls.udp_port_in = 6304
7026 cls.udp_port_out = 6304
7027 cls.icmp_id_in = 6305
7028 cls.icmp_id_out = 6305
7029 cls.nat_addr = '10.0.0.3'
7030 cls.dst_ip4 = '192.168.70.1'
7032 cls.create_pg_interfaces(range(2))
7035 cls.pg0.config_ip4()
7036 cls.pg0.resolve_arp()
7039 cls.pg1.config_ip6()
7040 cls.pg1.resolve_ndp()
7042 r1 = VppIpRoute(cls, "::", 0,
7043 [VppRoutePath(cls.pg1.remote_ip6,
7044 cls.pg1.sw_if_index)],
7049 super(TestNAT44Out2InDPO, cls).tearDownClass()
7053 def tearDownClass(cls):
7054 super(TestNAT44Out2InDPO, cls).tearDownClass()
7056 def configure_xlat(self):
7057 self.dst_ip6_pfx = '1:2:3::'
7058 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7060 self.dst_ip6_pfx_len = 96
7061 self.src_ip6_pfx = '4:5:6::'
7062 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7064 self.src_ip6_pfx_len = 96
7065 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7066 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7067 '\x00\x00\x00\x00', 0)
7069 @unittest.skip('Temporary disabled')
7070 def test_464xlat_ce(self):
7071 """ Test 464XLAT CE with NAT44 """
7073 nat_config = self.vapi.nat_show_config()
7074 self.assertEqual(1, nat_config.out2in_dpo)
7076 self.configure_xlat()
7078 flags = self.config_flags.NAT_IS_INSIDE
7079 self.vapi.nat44_interface_add_del_feature(
7080 sw_if_index=self.pg0.sw_if_index,
7081 flags=flags, is_add=1)
7082 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7083 last_ip_address=self.nat_addr_n,
7084 vrf_id=0xFFFFFFFF, is_add=1)
7086 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7087 self.dst_ip6_pfx_len)
7088 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7089 self.src_ip6_pfx_len)
7092 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7093 self.pg0.add_stream(pkts)
7094 self.pg_enable_capture(self.pg_interfaces)
7096 capture = self.pg1.get_capture(len(pkts))
7097 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7100 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7102 self.pg1.add_stream(pkts)
7103 self.pg_enable_capture(self.pg_interfaces)
7105 capture = self.pg0.get_capture(len(pkts))
7106 self.verify_capture_in(capture, self.pg0)
7108 self.vapi.nat44_interface_add_del_feature(
7109 sw_if_index=self.pg0.sw_if_index,
7111 self.vapi.nat44_add_del_address_range(
7112 first_ip_address=self.nat_addr_n,
7113 last_ip_address=self.nat_addr_n,
7116 @unittest.skip('Temporary disabled')
7117 def test_464xlat_ce_no_nat(self):
7118 """ Test 464XLAT CE without NAT44 """
7120 self.configure_xlat()
7122 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7123 self.dst_ip6_pfx_len)
7124 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7125 self.src_ip6_pfx_len)
7127 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7128 self.pg0.add_stream(pkts)
7129 self.pg_enable_capture(self.pg_interfaces)
7131 capture = self.pg1.get_capture(len(pkts))
7132 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7133 nat_ip=out_dst_ip6, same_port=True)
7135 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7136 self.pg1.add_stream(pkts)
7137 self.pg_enable_capture(self.pg_interfaces)
7139 capture = self.pg0.get_capture(len(pkts))
7140 self.verify_capture_in(capture, self.pg0)
7143 class TestDeterministicNAT(MethodHolder):
7144 """ Deterministic NAT Test Cases """
7147 def setUpConstants(cls):
7148 super(TestDeterministicNAT, cls).setUpConstants()
7149 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7152 def setUpClass(cls):
7153 super(TestDeterministicNAT, cls).setUpClass()
7154 cls.vapi.cli("set log class nat level debug")
7157 cls.tcp_port_in = 6303
7158 cls.tcp_external_port = 6303
7159 cls.udp_port_in = 6304
7160 cls.udp_external_port = 6304
7161 cls.icmp_id_in = 6305
7162 cls.nat_addr = '10.0.0.3'
7164 cls.create_pg_interfaces(range(3))
7165 cls.interfaces = list(cls.pg_interfaces)
7167 for i in cls.interfaces:
7172 cls.pg0.generate_remote_hosts(2)
7173 cls.pg0.configure_ipv4_neighbors()
7176 super(TestDeterministicNAT, cls).tearDownClass()
7180 def tearDownClass(cls):
7181 super(TestDeterministicNAT, cls).tearDownClass()
7183 def create_stream_in(self, in_if, out_if, ttl=64):
7185 Create packet stream for inside network
7187 :param in_if: Inside interface
7188 :param out_if: Outside interface
7189 :param ttl: TTL of generated packets
7193 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7194 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7195 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7199 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7200 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7201 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7205 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7206 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7207 ICMP(id=self.icmp_id_in, type='echo-request'))
7212 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7214 Create packet stream for outside network
7216 :param out_if: Outside interface
7217 :param dst_ip: Destination IP address (Default use global NAT address)
7218 :param ttl: TTL of generated packets
7221 dst_ip = self.nat_addr
7224 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7225 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7226 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7230 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7231 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7232 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7236 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7237 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7238 ICMP(id=self.icmp_external_id, type='echo-reply'))
7243 def verify_capture_out(self, capture, nat_ip=None):
7245 Verify captured packets on outside network
7247 :param capture: Captured packets
7248 :param nat_ip: Translated IP address (Default use global NAT address)
7249 :param same_port: Source port number is not translated (Default False)
7252 nat_ip = self.nat_addr
7253 for packet in capture:
7255 self.assertEqual(packet[IP].src, nat_ip)
7256 if packet.haslayer(TCP):
7257 self.tcp_port_out = packet[TCP].sport
7258 elif packet.haslayer(UDP):
7259 self.udp_port_out = packet[UDP].sport
7261 self.icmp_external_id = packet[ICMP].id
7263 self.logger.error(ppp("Unexpected or invalid packet "
7264 "(outside network):", packet))
7267 def test_deterministic_mode(self):
7268 """ NAT plugin run deterministic mode """
7269 in_addr = '172.16.255.0'
7270 out_addr = '172.17.255.50'
7271 in_addr_t = '172.16.255.20'
7275 nat_config = self.vapi.nat_show_config()
7276 self.assertEqual(1, nat_config.deterministic)
7278 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7279 in_plen=in_plen, out_addr=out_addr,
7282 rep1 = self.vapi.nat_det_forward(in_addr_t)
7283 self.assertEqual(str(rep1.out_addr), out_addr)
7284 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7286 self.assertEqual(str(rep2.in_addr), in_addr_t)
7288 deterministic_mappings = self.vapi.nat_det_map_dump()
7289 self.assertEqual(len(deterministic_mappings), 1)
7290 dsm = deterministic_mappings[0]
7291 self.assertEqual(in_addr, str(dsm.in_addr))
7292 self.assertEqual(in_plen, dsm.in_plen)
7293 self.assertEqual(out_addr, str(dsm.out_addr))
7294 self.assertEqual(out_plen, dsm.out_plen)
7296 self.clear_nat_det()
7297 deterministic_mappings = self.vapi.nat_det_map_dump()
7298 self.assertEqual(len(deterministic_mappings), 0)
7300 def test_set_timeouts(self):
7301 """ Set deterministic NAT timeouts """
7302 timeouts_before = self.vapi.nat_get_timeouts()
7304 self.vapi.nat_set_timeouts(
7305 udp=timeouts_before.udp + 10,
7306 tcp_established=timeouts_before.tcp_established + 10,
7307 tcp_transitory=timeouts_before.tcp_transitory + 10,
7308 icmp=timeouts_before.icmp + 10)
7310 timeouts_after = self.vapi.nat_get_timeouts()
7312 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7313 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7314 self.assertNotEqual(timeouts_before.tcp_established,
7315 timeouts_after.tcp_established)
7316 self.assertNotEqual(timeouts_before.tcp_transitory,
7317 timeouts_after.tcp_transitory)
7319 def test_det_in(self):
7320 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7322 nat_ip = "10.0.0.10"
7324 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7326 out_addr=socket.inet_aton(nat_ip),
7329 flags = self.config_flags.NAT_IS_INSIDE
7330 self.vapi.nat44_interface_add_del_feature(
7331 sw_if_index=self.pg0.sw_if_index,
7332 flags=flags, is_add=1)
7333 self.vapi.nat44_interface_add_del_feature(
7334 sw_if_index=self.pg1.sw_if_index,
7338 pkts = self.create_stream_in(self.pg0, self.pg1)
7339 self.pg0.add_stream(pkts)
7340 self.pg_enable_capture(self.pg_interfaces)
7342 capture = self.pg1.get_capture(len(pkts))
7343 self.verify_capture_out(capture, nat_ip)
7346 pkts = self.create_stream_out(self.pg1, nat_ip)
7347 self.pg1.add_stream(pkts)
7348 self.pg_enable_capture(self.pg_interfaces)
7350 capture = self.pg0.get_capture(len(pkts))
7351 self.verify_capture_in(capture, self.pg0)
7354 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7355 self.assertEqual(len(sessions), 3)
7359 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7360 self.assertEqual(s.in_port, self.tcp_port_in)
7361 self.assertEqual(s.out_port, self.tcp_port_out)
7362 self.assertEqual(s.ext_port, self.tcp_external_port)
7366 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7367 self.assertEqual(s.in_port, self.udp_port_in)
7368 self.assertEqual(s.out_port, self.udp_port_out)
7369 self.assertEqual(s.ext_port, self.udp_external_port)
7373 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7374 self.assertEqual(s.in_port, self.icmp_id_in)
7375 self.assertEqual(s.out_port, self.icmp_external_id)
7377 def test_multiple_users(self):
7378 """ Deterministic NAT multiple users """
7380 nat_ip = "10.0.0.10"
7382 external_port = 6303
7384 host0 = self.pg0.remote_hosts[0]
7385 host1 = self.pg0.remote_hosts[1]
7387 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7388 out_addr=socket.inet_aton(nat_ip),
7390 flags = self.config_flags.NAT_IS_INSIDE
7391 self.vapi.nat44_interface_add_del_feature(
7392 sw_if_index=self.pg0.sw_if_index,
7393 flags=flags, is_add=1)
7394 self.vapi.nat44_interface_add_del_feature(
7395 sw_if_index=self.pg1.sw_if_index,
7399 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7400 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7401 TCP(sport=port_in, dport=external_port))
7402 self.pg0.add_stream(p)
7403 self.pg_enable_capture(self.pg_interfaces)
7405 capture = self.pg1.get_capture(1)
7410 self.assertEqual(ip.src, nat_ip)
7411 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7412 self.assertEqual(tcp.dport, external_port)
7413 port_out0 = tcp.sport
7415 self.logger.error(ppp("Unexpected or invalid packet:", p))
7419 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7420 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7421 TCP(sport=port_in, dport=external_port))
7422 self.pg0.add_stream(p)
7423 self.pg_enable_capture(self.pg_interfaces)
7425 capture = self.pg1.get_capture(1)
7430 self.assertEqual(ip.src, nat_ip)
7431 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7432 self.assertEqual(tcp.dport, external_port)
7433 port_out1 = tcp.sport
7435 self.logger.error(ppp("Unexpected or invalid packet:", p))
7438 dms = self.vapi.nat_det_map_dump()
7439 self.assertEqual(1, len(dms))
7440 self.assertEqual(2, dms[0].ses_num)
7443 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7444 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7445 TCP(sport=external_port, dport=port_out0))
7446 self.pg1.add_stream(p)
7447 self.pg_enable_capture(self.pg_interfaces)
7449 capture = self.pg0.get_capture(1)
7454 self.assertEqual(ip.src, self.pg1.remote_ip4)
7455 self.assertEqual(ip.dst, host0.ip4)
7456 self.assertEqual(tcp.dport, port_in)
7457 self.assertEqual(tcp.sport, external_port)
7459 self.logger.error(ppp("Unexpected or invalid packet:", p))
7463 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7464 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7465 TCP(sport=external_port, dport=port_out1))
7466 self.pg1.add_stream(p)
7467 self.pg_enable_capture(self.pg_interfaces)
7469 capture = self.pg0.get_capture(1)
7474 self.assertEqual(ip.src, self.pg1.remote_ip4)
7475 self.assertEqual(ip.dst, host1.ip4)
7476 self.assertEqual(tcp.dport, port_in)
7477 self.assertEqual(tcp.sport, external_port)
7479 self.logger.error(ppp("Unexpected or invalid packet", p))
7482 # session close api test
7483 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7485 self.pg1.remote_ip4,
7487 dms = self.vapi.nat_det_map_dump()
7488 self.assertEqual(dms[0].ses_num, 1)
7490 self.vapi.nat_det_close_session_in(host0.ip4,
7492 self.pg1.remote_ip4,
7494 dms = self.vapi.nat_det_map_dump()
7495 self.assertEqual(dms[0].ses_num, 0)
7497 def test_tcp_session_close_detection_in(self):
7498 """ Deterministic NAT TCP session close from inside network """
7499 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7501 out_addr=socket.inet_aton(self.nat_addr),
7503 flags = self.config_flags.NAT_IS_INSIDE
7504 self.vapi.nat44_interface_add_del_feature(
7505 sw_if_index=self.pg0.sw_if_index,
7506 flags=flags, is_add=1)
7507 self.vapi.nat44_interface_add_del_feature(
7508 sw_if_index=self.pg1.sw_if_index,
7511 self.initiate_tcp_session(self.pg0, self.pg1)
7513 # close the session from inside
7515 # FIN packet in -> out
7516 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7517 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7518 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7520 self.pg0.add_stream(p)
7521 self.pg_enable_capture(self.pg_interfaces)
7523 self.pg1.get_capture(1)
7527 # ACK packet out -> in
7528 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7529 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7530 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7534 # FIN packet out -> in
7535 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7536 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7537 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7541 self.pg1.add_stream(pkts)
7542 self.pg_enable_capture(self.pg_interfaces)
7544 self.pg0.get_capture(2)
7546 # ACK packet in -> out
7547 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7548 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7549 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7551 self.pg0.add_stream(p)
7552 self.pg_enable_capture(self.pg_interfaces)
7554 self.pg1.get_capture(1)
7556 # Check if deterministic NAT44 closed the session
7557 dms = self.vapi.nat_det_map_dump()
7558 self.assertEqual(0, dms[0].ses_num)
7560 self.logger.error("TCP session termination failed")
7563 def test_tcp_session_close_detection_out(self):
7564 """ Deterministic NAT TCP session close from outside network """
7565 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7567 out_addr=socket.inet_aton(self.nat_addr),
7569 flags = self.config_flags.NAT_IS_INSIDE
7570 self.vapi.nat44_interface_add_del_feature(
7571 sw_if_index=self.pg0.sw_if_index,
7572 flags=flags, is_add=1)
7573 self.vapi.nat44_interface_add_del_feature(
7574 sw_if_index=self.pg1.sw_if_index,
7577 self.initiate_tcp_session(self.pg0, self.pg1)
7579 # close the session from outside
7581 # FIN packet out -> in
7582 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7583 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7584 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7586 self.pg1.add_stream(p)
7587 self.pg_enable_capture(self.pg_interfaces)
7589 self.pg0.get_capture(1)
7593 # ACK packet in -> out
7594 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7595 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7596 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7600 # ACK packet in -> out
7601 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7602 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7603 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7607 self.pg0.add_stream(pkts)
7608 self.pg_enable_capture(self.pg_interfaces)
7610 self.pg1.get_capture(2)
7612 # ACK packet out -> in
7613 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7614 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7615 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7617 self.pg1.add_stream(p)
7618 self.pg_enable_capture(self.pg_interfaces)
7620 self.pg0.get_capture(1)
7622 # Check if deterministic NAT44 closed the session
7623 dms = self.vapi.nat_det_map_dump()
7624 self.assertEqual(0, dms[0].ses_num)
7626 self.logger.error("TCP session termination failed")
7629 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7630 def test_session_timeout(self):
7631 """ Deterministic NAT session timeouts """
7632 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7634 out_addr=socket.inet_aton(self.nat_addr),
7636 flags = self.config_flags.NAT_IS_INSIDE
7637 self.vapi.nat44_interface_add_del_feature(
7638 sw_if_index=self.pg0.sw_if_index,
7639 flags=flags, is_add=1)
7640 self.vapi.nat44_interface_add_del_feature(
7641 sw_if_index=self.pg1.sw_if_index,
7644 self.initiate_tcp_session(self.pg0, self.pg1)
7645 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7647 pkts = self.create_stream_in(self.pg0, self.pg1)
7648 self.pg0.add_stream(pkts)
7649 self.pg_enable_capture(self.pg_interfaces)
7651 capture = self.pg1.get_capture(len(pkts))
7654 dms = self.vapi.nat_det_map_dump()
7655 self.assertEqual(0, dms[0].ses_num)
7657 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7658 def test_session_limit_per_user(self):
7659 """ Deterministic NAT maximum sessions per user limit """
7660 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7662 out_addr=socket.inet_aton(self.nat_addr),
7664 flags = self.config_flags.NAT_IS_INSIDE
7665 self.vapi.nat44_interface_add_del_feature(
7666 sw_if_index=self.pg0.sw_if_index,
7667 flags=flags, is_add=1)
7668 self.vapi.nat44_interface_add_del_feature(
7669 sw_if_index=self.pg1.sw_if_index,
7671 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7672 src_address=self.pg2.local_ip4,
7674 template_interval=10)
7675 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7679 for port in range(1025, 2025):
7680 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7681 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7682 UDP(sport=port, dport=port))
7685 self.pg0.add_stream(pkts)
7686 self.pg_enable_capture(self.pg_interfaces)
7688 capture = self.pg1.get_capture(len(pkts))
7690 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7691 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7692 UDP(sport=3001, dport=3002))
7693 self.pg0.add_stream(p)
7694 self.pg_enable_capture(self.pg_interfaces)
7696 capture = self.pg1.assert_nothing_captured()
7698 # verify ICMP error packet
7699 capture = self.pg0.get_capture(1)
7701 self.assertTrue(p.haslayer(ICMP))
7703 self.assertEqual(icmp.type, 3)
7704 self.assertEqual(icmp.code, 1)
7705 self.assertTrue(icmp.haslayer(IPerror))
7706 inner_ip = icmp[IPerror]
7707 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7708 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7710 dms = self.vapi.nat_det_map_dump()
7712 self.assertEqual(1000, dms[0].ses_num)
7714 # verify IPFIX logging
7715 self.vapi.ipfix_flush()
7717 capture = self.pg2.get_capture(2)
7718 ipfix = IPFIXDecoder()
7719 # first load template
7721 self.assertTrue(p.haslayer(IPFIX))
7722 if p.haslayer(Template):
7723 ipfix.add_template(p.getlayer(Template))
7724 # verify events in data set
7726 if p.haslayer(Data):
7727 data = ipfix.decode_data_set(p.getlayer(Set))
7728 self.verify_ipfix_max_entries_per_user(data,
7730 self.pg0.remote_ip4)
7732 def clear_nat_det(self):
7734 Clear deterministic NAT configuration.
7736 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7738 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7739 tcp_transitory=240, icmp=60)
7740 deterministic_mappings = self.vapi.nat_det_map_dump()
7741 for dsm in deterministic_mappings:
7742 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7743 in_plen=dsm.in_plen,
7744 out_addr=dsm.out_addr,
7745 out_plen=dsm.out_plen)
7747 interfaces = self.vapi.nat44_interface_dump()
7748 for intf in interfaces:
7749 self.vapi.nat44_interface_add_del_feature(
7750 sw_if_index=intf.sw_if_index,
7754 super(TestDeterministicNAT, self).tearDown()
7755 if not self.vpp_dead:
7756 self.clear_nat_det()
7758 def show_commands_at_teardown(self):
7759 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7760 self.logger.info(self.vapi.cli("show nat timeouts"))
7762 self.vapi.cli("show nat44 deterministic mappings"))
7764 self.vapi.cli("show nat44 deterministic sessions"))
7767 class TestNAT64(MethodHolder):
7768 """ NAT64 Test Cases """
7771 def setUpConstants(cls):
7772 super(TestNAT64, cls).setUpConstants()
7773 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7774 "nat64 st hash buckets 256", "}"])
7777 def setUpClass(cls):
7778 super(TestNAT64, cls).setUpClass()
7781 cls.tcp_port_in = 6303
7782 cls.tcp_port_out = 6303
7783 cls.udp_port_in = 6304
7784 cls.udp_port_out = 6304
7785 cls.icmp_id_in = 6305
7786 cls.icmp_id_out = 6305
7787 cls.tcp_external_port = 80
7788 cls.nat_addr = '10.0.0.3'
7789 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7791 cls.vrf1_nat_addr = '10.0.10.3'
7792 cls.ipfix_src_port = 4739
7793 cls.ipfix_domain_id = 1
7795 cls.create_pg_interfaces(range(6))
7796 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7797 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7798 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7800 cls.vapi.ip_table_add_del(is_add=1,
7801 table={'table_id': cls.vrf1_id,
7804 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7806 cls.pg0.generate_remote_hosts(2)
7808 for i in cls.ip6_interfaces:
7811 i.configure_ipv6_neighbors()
7813 for i in cls.ip4_interfaces:
7819 cls.pg3.config_ip4()
7820 cls.pg3.resolve_arp()
7821 cls.pg3.config_ip6()
7822 cls.pg3.configure_ipv6_neighbors()
7825 cls.pg5.config_ip6()
7828 super(TestNAT64, cls).tearDownClass()
7832 def tearDownClass(cls):
7833 super(TestNAT64, cls).tearDownClass()
7835 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7836 """ NAT64 inside interface handles Neighbor Advertisement """
7838 flags = self.config_flags.NAT_IS_INSIDE
7839 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7840 sw_if_index=self.pg5.sw_if_index)
7843 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7844 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7845 ICMPv6EchoRequest())
7847 self.pg5.add_stream(pkts)
7848 self.pg_enable_capture(self.pg_interfaces)
7851 # Wait for Neighbor Solicitation
7852 capture = self.pg5.get_capture(len(pkts))
7855 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7856 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7857 tgt = packet[ICMPv6ND_NS].tgt
7859 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7862 # Send Neighbor Advertisement
7863 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7864 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7865 ICMPv6ND_NA(tgt=tgt) /
7866 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7868 self.pg5.add_stream(pkts)
7869 self.pg_enable_capture(self.pg_interfaces)
7872 # Try to send ping again
7874 self.pg5.add_stream(pkts)
7875 self.pg_enable_capture(self.pg_interfaces)
7878 # Wait for ping reply
7879 capture = self.pg5.get_capture(len(pkts))
7882 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7883 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7884 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7886 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7889 def test_pool(self):
7890 """ Add/delete address to NAT64 pool """
7891 nat_addr = '1.2.3.4'
7893 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7895 vrf_id=0xFFFFFFFF, is_add=1)
7897 addresses = self.vapi.nat64_pool_addr_dump()
7898 self.assertEqual(len(addresses), 1)
7899 self.assertEqual(str(addresses[0].address), nat_addr)
7901 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7903 vrf_id=0xFFFFFFFF, is_add=0)
7905 addresses = self.vapi.nat64_pool_addr_dump()
7906 self.assertEqual(len(addresses), 0)
7908 def test_interface(self):
7909 """ Enable/disable NAT64 feature on the interface """
7910 flags = self.config_flags.NAT_IS_INSIDE
7911 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7912 sw_if_index=self.pg0.sw_if_index)
7913 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7914 sw_if_index=self.pg1.sw_if_index)
7916 interfaces = self.vapi.nat64_interface_dump()
7917 self.assertEqual(len(interfaces), 2)
7920 for intf in interfaces:
7921 if intf.sw_if_index == self.pg0.sw_if_index:
7922 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7924 elif intf.sw_if_index == self.pg1.sw_if_index:
7925 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7927 self.assertTrue(pg0_found)
7928 self.assertTrue(pg1_found)
7930 features = self.vapi.cli("show interface features pg0")
7931 self.assertIn('nat64-in2out', features)
7932 features = self.vapi.cli("show interface features pg1")
7933 self.assertIn('nat64-out2in', features)
7935 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7936 sw_if_index=self.pg0.sw_if_index)
7937 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7938 sw_if_index=self.pg1.sw_if_index)
7940 interfaces = self.vapi.nat64_interface_dump()
7941 self.assertEqual(len(interfaces), 0)
7943 def test_static_bib(self):
7944 """ Add/delete static BIB entry """
7945 in_addr = '2001:db8:85a3::8a2e:370:7334'
7946 out_addr = '10.1.1.3'
7949 proto = IP_PROTOS.tcp
7951 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7952 i_port=in_port, o_port=out_port,
7953 proto=proto, vrf_id=0, is_add=1)
7954 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7957 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7959 self.assertEqual(str(bibe.i_addr), in_addr)
7960 self.assertEqual(str(bibe.o_addr), out_addr)
7961 self.assertEqual(bibe.i_port, in_port)
7962 self.assertEqual(bibe.o_port, out_port)
7963 self.assertEqual(static_bib_num, 1)
7964 bibs = self.statistics.get_counter('/nat64/total-bibs')
7965 self.assertEqual(bibs[0][0], 1)
7967 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7968 i_port=in_port, o_port=out_port,
7969 proto=proto, vrf_id=0, is_add=0)
7970 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7973 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7975 self.assertEqual(static_bib_num, 0)
7976 bibs = self.statistics.get_counter('/nat64/total-bibs')
7977 self.assertEqual(bibs[0][0], 0)
7979 def test_set_timeouts(self):
7980 """ Set NAT64 timeouts """
7981 # verify default values
7982 timeouts = self.vapi.nat_get_timeouts()
7983 self.assertEqual(timeouts.udp, 300)
7984 self.assertEqual(timeouts.icmp, 60)
7985 self.assertEqual(timeouts.tcp_transitory, 240)
7986 self.assertEqual(timeouts.tcp_established, 7440)
7988 # set and verify custom values
7989 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7990 tcp_transitory=250, icmp=30)
7991 timeouts = self.vapi.nat_get_timeouts()
7992 self.assertEqual(timeouts.udp, 200)
7993 self.assertEqual(timeouts.icmp, 30)
7994 self.assertEqual(timeouts.tcp_transitory, 250)
7995 self.assertEqual(timeouts.tcp_established, 7450)
7997 def test_dynamic(self):
7998 """ NAT64 dynamic translation test """
7999 self.tcp_port_in = 6303
8000 self.udp_port_in = 6304
8001 self.icmp_id_in = 6305
8003 ses_num_start = self.nat64_get_ses_num()
8005 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8006 end_addr=self.nat_addr,
8009 flags = self.config_flags.NAT_IS_INSIDE
8010 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8011 sw_if_index=self.pg0.sw_if_index)
8012 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8013 sw_if_index=self.pg1.sw_if_index)
8016 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8017 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8018 icmpn = self.statistics.get_err_counter(
8019 '/err/nat64-in2out/ICMP packets')
8020 totaln = self.statistics.get_err_counter(
8021 '/err/nat64-in2out/good in2out packets processed')
8023 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8024 self.pg0.add_stream(pkts)
8025 self.pg_enable_capture(self.pg_interfaces)
8027 capture = self.pg1.get_capture(len(pkts))
8028 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8029 dst_ip=self.pg1.remote_ip4)
8031 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8032 self.assertEqual(err - tcpn, 1)
8033 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8034 self.assertEqual(err - udpn, 1)
8035 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8036 self.assertEqual(err - icmpn, 1)
8037 err = self.statistics.get_err_counter(
8038 '/err/nat64-in2out/good in2out packets processed')
8039 self.assertEqual(err - totaln, 3)
8042 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8043 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8044 icmpn = self.statistics.get_err_counter(
8045 '/err/nat64-out2in/ICMP packets')
8046 totaln = self.statistics.get_err_counter(
8047 '/err/nat64-out2in/good out2in packets processed')
8049 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8050 self.pg1.add_stream(pkts)
8051 self.pg_enable_capture(self.pg_interfaces)
8053 capture = self.pg0.get_capture(len(pkts))
8054 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8055 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8057 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8058 self.assertEqual(err - tcpn, 2)
8059 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8060 self.assertEqual(err - udpn, 1)
8061 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8062 self.assertEqual(err - icmpn, 1)
8063 err = self.statistics.get_err_counter(
8064 '/err/nat64-out2in/good out2in packets processed')
8065 self.assertEqual(err - totaln, 4)
8067 bibs = self.statistics.get_counter('/nat64/total-bibs')
8068 self.assertEqual(bibs[0][0], 3)
8069 sessions = self.statistics.get_counter('/nat64/total-sessions')
8070 self.assertEqual(sessions[0][0], 3)
8073 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8074 self.pg0.add_stream(pkts)
8075 self.pg_enable_capture(self.pg_interfaces)
8077 capture = self.pg1.get_capture(len(pkts))
8078 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8079 dst_ip=self.pg1.remote_ip4)
8082 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8083 self.pg1.add_stream(pkts)
8084 self.pg_enable_capture(self.pg_interfaces)
8086 capture = self.pg0.get_capture(len(pkts))
8087 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8089 ses_num_end = self.nat64_get_ses_num()
8091 self.assertEqual(ses_num_end - ses_num_start, 3)
8093 # tenant with specific VRF
8094 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8095 end_addr=self.vrf1_nat_addr,
8096 vrf_id=self.vrf1_id, is_add=1)
8097 flags = self.config_flags.NAT_IS_INSIDE
8098 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8099 sw_if_index=self.pg2.sw_if_index)
8101 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8102 self.pg2.add_stream(pkts)
8103 self.pg_enable_capture(self.pg_interfaces)
8105 capture = self.pg1.get_capture(len(pkts))
8106 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8107 dst_ip=self.pg1.remote_ip4)
8109 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8110 self.pg1.add_stream(pkts)
8111 self.pg_enable_capture(self.pg_interfaces)
8113 capture = self.pg2.get_capture(len(pkts))
8114 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8116 def test_static(self):
8117 """ NAT64 static translation test """
8118 self.tcp_port_in = 60303
8119 self.udp_port_in = 60304
8120 self.icmp_id_in = 60305
8121 self.tcp_port_out = 60303
8122 self.udp_port_out = 60304
8123 self.icmp_id_out = 60305
8125 ses_num_start = self.nat64_get_ses_num()
8127 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8128 end_addr=self.nat_addr,
8131 flags = self.config_flags.NAT_IS_INSIDE
8132 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8133 sw_if_index=self.pg0.sw_if_index)
8134 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8135 sw_if_index=self.pg1.sw_if_index)
8137 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8138 o_addr=self.nat_addr,
8139 i_port=self.tcp_port_in,
8140 o_port=self.tcp_port_out,
8141 proto=IP_PROTOS.tcp, vrf_id=0,
8143 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8144 o_addr=self.nat_addr,
8145 i_port=self.udp_port_in,
8146 o_port=self.udp_port_out,
8147 proto=IP_PROTOS.udp, vrf_id=0,
8149 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8150 o_addr=self.nat_addr,
8151 i_port=self.icmp_id_in,
8152 o_port=self.icmp_id_out,
8153 proto=IP_PROTOS.icmp, vrf_id=0,
8157 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8158 self.pg0.add_stream(pkts)
8159 self.pg_enable_capture(self.pg_interfaces)
8161 capture = self.pg1.get_capture(len(pkts))
8162 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8163 dst_ip=self.pg1.remote_ip4, same_port=True)
8166 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8167 self.pg1.add_stream(pkts)
8168 self.pg_enable_capture(self.pg_interfaces)
8170 capture = self.pg0.get_capture(len(pkts))
8171 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8172 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8174 ses_num_end = self.nat64_get_ses_num()
8176 self.assertEqual(ses_num_end - ses_num_start, 3)
8178 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8179 def test_session_timeout(self):
8180 """ NAT64 session timeout """
8181 self.icmp_id_in = 1234
8182 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8183 end_addr=self.nat_addr,
8186 flags = self.config_flags.NAT_IS_INSIDE
8187 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8188 sw_if_index=self.pg0.sw_if_index)
8189 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8190 sw_if_index=self.pg1.sw_if_index)
8191 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8195 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8196 self.pg0.add_stream(pkts)
8197 self.pg_enable_capture(self.pg_interfaces)
8199 capture = self.pg1.get_capture(len(pkts))
8201 ses_num_before_timeout = self.nat64_get_ses_num()
8205 # ICMP and TCP session after timeout
8206 ses_num_after_timeout = self.nat64_get_ses_num()
8207 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8209 def test_icmp_error(self):
8210 """ NAT64 ICMP Error message translation """
8211 self.tcp_port_in = 6303
8212 self.udp_port_in = 6304
8213 self.icmp_id_in = 6305
8215 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8216 end_addr=self.nat_addr,
8219 flags = self.config_flags.NAT_IS_INSIDE
8220 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8221 sw_if_index=self.pg0.sw_if_index)
8222 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8223 sw_if_index=self.pg1.sw_if_index)
8225 # send some packets to create sessions
8226 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8227 self.pg0.add_stream(pkts)
8228 self.pg_enable_capture(self.pg_interfaces)
8230 capture_ip4 = self.pg1.get_capture(len(pkts))
8231 self.verify_capture_out(capture_ip4,
8232 nat_ip=self.nat_addr,
8233 dst_ip=self.pg1.remote_ip4)
8235 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8236 self.pg1.add_stream(pkts)
8237 self.pg_enable_capture(self.pg_interfaces)
8239 capture_ip6 = self.pg0.get_capture(len(pkts))
8240 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8241 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8242 self.pg0.remote_ip6)
8245 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8246 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8247 ICMPv6DestUnreach(code=1) /
8248 packet[IPv6] for packet in capture_ip6]
8249 self.pg0.add_stream(pkts)
8250 self.pg_enable_capture(self.pg_interfaces)
8252 capture = self.pg1.get_capture(len(pkts))
8253 for packet in capture:
8255 self.assertEqual(packet[IP].src, self.nat_addr)
8256 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8257 self.assertEqual(packet[ICMP].type, 3)
8258 self.assertEqual(packet[ICMP].code, 13)
8259 inner = packet[IPerror]
8260 self.assertEqual(inner.src, self.pg1.remote_ip4)
8261 self.assertEqual(inner.dst, self.nat_addr)
8262 self.assert_packet_checksums_valid(packet)
8263 if inner.haslayer(TCPerror):
8264 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8265 elif inner.haslayer(UDPerror):
8266 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8268 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8270 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8274 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8275 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8276 ICMP(type=3, code=13) /
8277 packet[IP] for packet in capture_ip4]
8278 self.pg1.add_stream(pkts)
8279 self.pg_enable_capture(self.pg_interfaces)
8281 capture = self.pg0.get_capture(len(pkts))
8282 for packet in capture:
8284 self.assertEqual(packet[IPv6].src, ip.src)
8285 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8286 icmp = packet[ICMPv6DestUnreach]
8287 self.assertEqual(icmp.code, 1)
8288 inner = icmp[IPerror6]
8289 self.assertEqual(inner.src, self.pg0.remote_ip6)
8290 self.assertEqual(inner.dst, ip.src)
8291 self.assert_icmpv6_checksum_valid(packet)
8292 if inner.haslayer(TCPerror):
8293 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8294 elif inner.haslayer(UDPerror):
8295 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8297 self.assertEqual(inner[ICMPv6EchoRequest].id,
8300 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8303 def test_hairpinning(self):
8304 """ NAT64 hairpinning """
8306 client = self.pg0.remote_hosts[0]
8307 server = self.pg0.remote_hosts[1]
8308 server_tcp_in_port = 22
8309 server_tcp_out_port = 4022
8310 server_udp_in_port = 23
8311 server_udp_out_port = 4023
8312 client_tcp_in_port = 1234
8313 client_udp_in_port = 1235
8314 client_tcp_out_port = 0
8315 client_udp_out_port = 0
8316 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8317 nat_addr_ip6 = ip.src
8319 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8320 end_addr=self.nat_addr,
8323 flags = self.config_flags.NAT_IS_INSIDE
8324 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8325 sw_if_index=self.pg0.sw_if_index)
8326 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8327 sw_if_index=self.pg1.sw_if_index)
8329 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8330 o_addr=self.nat_addr,
8331 i_port=server_tcp_in_port,
8332 o_port=server_tcp_out_port,
8333 proto=IP_PROTOS.tcp, vrf_id=0,
8335 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8336 o_addr=self.nat_addr,
8337 i_port=server_udp_in_port,
8338 o_port=server_udp_out_port,
8339 proto=IP_PROTOS.udp, vrf_id=0,
8344 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8345 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8346 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8348 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8349 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8350 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8352 self.pg0.add_stream(pkts)
8353 self.pg_enable_capture(self.pg_interfaces)
8355 capture = self.pg0.get_capture(len(pkts))
8356 for packet in capture:
8358 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8359 self.assertEqual(packet[IPv6].dst, server.ip6)
8360 self.assert_packet_checksums_valid(packet)
8361 if packet.haslayer(TCP):
8362 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8363 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8364 client_tcp_out_port = packet[TCP].sport
8366 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8367 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8368 client_udp_out_port = packet[UDP].sport
8370 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8376 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8377 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8379 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8380 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8381 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8383 self.pg0.add_stream(pkts)
8384 self.pg_enable_capture(self.pg_interfaces)
8386 capture = self.pg0.get_capture(len(pkts))
8387 for packet in capture:
8389 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8390 self.assertEqual(packet[IPv6].dst, client.ip6)
8391 self.assert_packet_checksums_valid(packet)
8392 if packet.haslayer(TCP):
8393 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8394 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8396 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8397 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8399 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8404 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8405 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8406 ICMPv6DestUnreach(code=1) /
8407 packet[IPv6] for packet in capture]
8408 self.pg0.add_stream(pkts)
8409 self.pg_enable_capture(self.pg_interfaces)
8411 capture = self.pg0.get_capture(len(pkts))
8412 for packet in capture:
8414 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8415 self.assertEqual(packet[IPv6].dst, server.ip6)
8416 icmp = packet[ICMPv6DestUnreach]
8417 self.assertEqual(icmp.code, 1)
8418 inner = icmp[IPerror6]
8419 self.assertEqual(inner.src, server.ip6)
8420 self.assertEqual(inner.dst, nat_addr_ip6)
8421 self.assert_packet_checksums_valid(packet)
8422 if inner.haslayer(TCPerror):
8423 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8424 self.assertEqual(inner[TCPerror].dport,
8425 client_tcp_out_port)
8427 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8428 self.assertEqual(inner[UDPerror].dport,
8429 client_udp_out_port)
8431 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8434 def test_prefix(self):
8435 """ NAT64 Network-Specific Prefix """
8437 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8438 end_addr=self.nat_addr,
8441 flags = self.config_flags.NAT_IS_INSIDE
8442 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8443 sw_if_index=self.pg0.sw_if_index)
8444 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8445 sw_if_index=self.pg1.sw_if_index)
8446 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8447 end_addr=self.vrf1_nat_addr,
8448 vrf_id=self.vrf1_id, is_add=1)
8449 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8450 sw_if_index=self.pg2.sw_if_index)
8453 global_pref64 = "2001:db8::"
8454 global_pref64_len = 32
8455 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8456 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8459 prefix = self.vapi.nat64_prefix_dump()
8460 self.assertEqual(len(prefix), 1)
8461 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8462 self.assertEqual(prefix[0].vrf_id, 0)
8464 # Add tenant specific prefix
8465 vrf1_pref64 = "2001:db8:122:300::"
8466 vrf1_pref64_len = 56
8467 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8468 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8469 vrf_id=self.vrf1_id, is_add=1)
8471 prefix = self.vapi.nat64_prefix_dump()
8472 self.assertEqual(len(prefix), 2)
8475 pkts = self.create_stream_in_ip6(self.pg0,
8478 plen=global_pref64_len)
8479 self.pg0.add_stream(pkts)
8480 self.pg_enable_capture(self.pg_interfaces)
8482 capture = self.pg1.get_capture(len(pkts))
8483 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8484 dst_ip=self.pg1.remote_ip4)
8486 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8487 self.pg1.add_stream(pkts)
8488 self.pg_enable_capture(self.pg_interfaces)
8490 capture = self.pg0.get_capture(len(pkts))
8491 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8494 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8496 # Tenant specific prefix
8497 pkts = self.create_stream_in_ip6(self.pg2,
8500 plen=vrf1_pref64_len)
8501 self.pg2.add_stream(pkts)
8502 self.pg_enable_capture(self.pg_interfaces)
8504 capture = self.pg1.get_capture(len(pkts))
8505 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8506 dst_ip=self.pg1.remote_ip4)
8508 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8509 self.pg1.add_stream(pkts)
8510 self.pg_enable_capture(self.pg_interfaces)
8512 capture = self.pg2.get_capture(len(pkts))
8513 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8516 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8518 def test_unknown_proto(self):
8519 """ NAT64 translate packet with unknown protocol """
8521 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8522 end_addr=self.nat_addr,
8525 flags = self.config_flags.NAT_IS_INSIDE
8526 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8527 sw_if_index=self.pg0.sw_if_index)
8528 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8529 sw_if_index=self.pg1.sw_if_index)
8530 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8533 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8534 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8535 TCP(sport=self.tcp_port_in, dport=20))
8536 self.pg0.add_stream(p)
8537 self.pg_enable_capture(self.pg_interfaces)
8539 p = self.pg1.get_capture(1)
8541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8542 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8544 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8545 TCP(sport=1234, dport=1234))
8546 self.pg0.add_stream(p)
8547 self.pg_enable_capture(self.pg_interfaces)
8549 p = self.pg1.get_capture(1)
8552 self.assertEqual(packet[IP].src, self.nat_addr)
8553 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8554 self.assertEqual(packet.haslayer(GRE), 1)
8555 self.assert_packet_checksums_valid(packet)
8557 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8561 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8562 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8564 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8565 TCP(sport=1234, dport=1234))
8566 self.pg1.add_stream(p)
8567 self.pg_enable_capture(self.pg_interfaces)
8569 p = self.pg0.get_capture(1)
8572 self.assertEqual(packet[IPv6].src, remote_ip6)
8573 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8574 self.assertEqual(packet[IPv6].nh, 47)
8576 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8579 def test_hairpinning_unknown_proto(self):
8580 """ NAT64 translate packet with unknown protocol - hairpinning """
8582 client = self.pg0.remote_hosts[0]
8583 server = self.pg0.remote_hosts[1]
8584 server_tcp_in_port = 22
8585 server_tcp_out_port = 4022
8586 client_tcp_in_port = 1234
8587 client_tcp_out_port = 1235
8588 server_nat_ip = "10.0.0.100"
8589 client_nat_ip = "10.0.0.110"
8590 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8591 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8593 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8594 end_addr=client_nat_ip,
8597 flags = self.config_flags.NAT_IS_INSIDE
8598 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8599 sw_if_index=self.pg0.sw_if_index)
8600 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8601 sw_if_index=self.pg1.sw_if_index)
8603 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8604 o_addr=server_nat_ip,
8605 i_port=server_tcp_in_port,
8606 o_port=server_tcp_out_port,
8607 proto=IP_PROTOS.tcp, vrf_id=0,
8610 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8611 o_addr=server_nat_ip, i_port=0,
8613 proto=IP_PROTOS.gre, vrf_id=0,
8616 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8617 o_addr=client_nat_ip,
8618 i_port=client_tcp_in_port,
8619 o_port=client_tcp_out_port,
8620 proto=IP_PROTOS.tcp, vrf_id=0,
8624 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8625 IPv6(src=client.ip6, dst=server_nat_ip6) /
8626 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8627 self.pg0.add_stream(p)
8628 self.pg_enable_capture(self.pg_interfaces)
8630 p = self.pg0.get_capture(1)
8632 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8633 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8635 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8636 TCP(sport=1234, dport=1234))
8637 self.pg0.add_stream(p)
8638 self.pg_enable_capture(self.pg_interfaces)
8640 p = self.pg0.get_capture(1)
8643 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8644 self.assertEqual(packet[IPv6].dst, server.ip6)
8645 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8647 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8651 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8652 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8654 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8655 TCP(sport=1234, dport=1234))
8656 self.pg0.add_stream(p)
8657 self.pg_enable_capture(self.pg_interfaces)
8659 p = self.pg0.get_capture(1)
8662 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8663 self.assertEqual(packet[IPv6].dst, client.ip6)
8664 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8666 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8669 def test_one_armed_nat64(self):
8670 """ One armed NAT64 """
8672 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8676 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8677 end_addr=self.nat_addr,
8680 flags = self.config_flags.NAT_IS_INSIDE
8681 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8682 sw_if_index=self.pg3.sw_if_index)
8683 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8684 sw_if_index=self.pg3.sw_if_index)
8687 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8688 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8689 TCP(sport=12345, dport=80))
8690 self.pg3.add_stream(p)
8691 self.pg_enable_capture(self.pg_interfaces)
8693 capture = self.pg3.get_capture(1)
8698 self.assertEqual(ip.src, self.nat_addr)
8699 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8700 self.assertNotEqual(tcp.sport, 12345)
8701 external_port = tcp.sport
8702 self.assertEqual(tcp.dport, 80)
8703 self.assert_packet_checksums_valid(p)
8705 self.logger.error(ppp("Unexpected or invalid packet:", p))
8709 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8710 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8711 TCP(sport=80, dport=external_port))
8712 self.pg3.add_stream(p)
8713 self.pg_enable_capture(self.pg_interfaces)
8715 capture = self.pg3.get_capture(1)
8720 self.assertEqual(ip.src, remote_host_ip6)
8721 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8722 self.assertEqual(tcp.sport, 80)
8723 self.assertEqual(tcp.dport, 12345)
8724 self.assert_packet_checksums_valid(p)
8726 self.logger.error(ppp("Unexpected or invalid packet:", p))
8729 def test_frag_in_order(self):
8730 """ NAT64 translate fragments arriving in order """
8731 self.tcp_port_in = random.randint(1025, 65535)
8733 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8734 end_addr=self.nat_addr,
8737 flags = self.config_flags.NAT_IS_INSIDE
8738 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8739 sw_if_index=self.pg0.sw_if_index)
8740 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8741 sw_if_index=self.pg1.sw_if_index)
8745 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8746 self.tcp_port_in, 20, data)
8747 self.pg0.add_stream(pkts)
8748 self.pg_enable_capture(self.pg_interfaces)
8750 frags = self.pg1.get_capture(len(pkts))
8751 p = self.reass_frags_and_verify(frags,
8753 self.pg1.remote_ip4)
8754 self.assertEqual(p[TCP].dport, 20)
8755 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8756 self.tcp_port_out = p[TCP].sport
8757 self.assertEqual(data, p[Raw].load)
8760 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8761 pkts = self.create_stream_frag(self.pg1,
8766 self.pg1.add_stream(pkts)
8767 self.pg_enable_capture(self.pg_interfaces)
8769 frags = self.pg0.get_capture(len(pkts))
8770 self.logger.debug(ppc("Captured:", frags))
8771 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8772 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8773 self.assertEqual(p[TCP].sport, 20)
8774 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8775 self.assertEqual(data, p[Raw].load)
8777 def test_reass_hairpinning(self):
8778 """ NAT64 fragments hairpinning """
8780 server = self.pg0.remote_hosts[1]
8781 server_in_port = random.randint(1025, 65535)
8782 server_out_port = random.randint(1025, 65535)
8783 client_in_port = random.randint(1025, 65535)
8784 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8785 nat_addr_ip6 = ip.src
8787 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8788 end_addr=self.nat_addr,
8791 flags = self.config_flags.NAT_IS_INSIDE
8792 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8793 sw_if_index=self.pg0.sw_if_index)
8794 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8795 sw_if_index=self.pg1.sw_if_index)
8797 # add static BIB entry for server
8798 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8799 o_addr=self.nat_addr,
8800 i_port=server_in_port,
8801 o_port=server_out_port,
8802 proto=IP_PROTOS.tcp, vrf_id=0,
8805 # send packet from host to server
8806 pkts = self.create_stream_frag_ip6(self.pg0,
8811 self.pg0.add_stream(pkts)
8812 self.pg_enable_capture(self.pg_interfaces)
8814 frags = self.pg0.get_capture(len(pkts))
8815 self.logger.debug(ppc("Captured:", frags))
8816 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8817 self.assertNotEqual(p[TCP].sport, client_in_port)
8818 self.assertEqual(p[TCP].dport, server_in_port)
8819 self.assertEqual(data, p[Raw].load)
8821 def test_frag_out_of_order(self):
8822 """ NAT64 translate fragments arriving out of order """
8823 self.tcp_port_in = random.randint(1025, 65535)
8825 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8826 end_addr=self.nat_addr,
8829 flags = self.config_flags.NAT_IS_INSIDE
8830 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8831 sw_if_index=self.pg0.sw_if_index)
8832 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8833 sw_if_index=self.pg1.sw_if_index)
8837 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8838 self.tcp_port_in, 20, data)
8840 self.pg0.add_stream(pkts)
8841 self.pg_enable_capture(self.pg_interfaces)
8843 frags = self.pg1.get_capture(len(pkts))
8844 p = self.reass_frags_and_verify(frags,
8846 self.pg1.remote_ip4)
8847 self.assertEqual(p[TCP].dport, 20)
8848 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8849 self.tcp_port_out = p[TCP].sport
8850 self.assertEqual(data, p[Raw].load)
8853 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8854 pkts = self.create_stream_frag(self.pg1,
8860 self.pg1.add_stream(pkts)
8861 self.pg_enable_capture(self.pg_interfaces)
8863 frags = self.pg0.get_capture(len(pkts))
8864 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8865 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8866 self.assertEqual(p[TCP].sport, 20)
8867 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8868 self.assertEqual(data, p[Raw].load)
8870 def test_interface_addr(self):
8871 """ Acquire NAT64 pool addresses from interface """
8872 self.vapi.nat64_add_del_interface_addr(
8874 sw_if_index=self.pg4.sw_if_index)
8876 # no address in NAT64 pool
8877 addresses = self.vapi.nat44_address_dump()
8878 self.assertEqual(0, len(addresses))
8880 # configure interface address and check NAT64 address pool
8881 self.pg4.config_ip4()
8882 addresses = self.vapi.nat64_pool_addr_dump()
8883 self.assertEqual(len(addresses), 1)
8885 self.assertEqual(str(addresses[0].address),
8888 # remove interface address and check NAT64 address pool
8889 self.pg4.unconfig_ip4()
8890 addresses = self.vapi.nat64_pool_addr_dump()
8891 self.assertEqual(0, len(addresses))
8893 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8894 def test_ipfix_max_bibs_sessions(self):
8895 """ IPFIX logging maximum session and BIB entries exceeded """
8898 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8902 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8903 end_addr=self.nat_addr,
8906 flags = self.config_flags.NAT_IS_INSIDE
8907 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8908 sw_if_index=self.pg0.sw_if_index)
8909 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8910 sw_if_index=self.pg1.sw_if_index)
8914 for i in range(0, max_bibs):
8915 src = "fd01:aa::%x" % (i)
8916 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8917 IPv6(src=src, dst=remote_host_ip6) /
8918 TCP(sport=12345, dport=80))
8920 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8921 IPv6(src=src, dst=remote_host_ip6) /
8922 TCP(sport=12345, dport=22))
8924 self.pg0.add_stream(pkts)
8925 self.pg_enable_capture(self.pg_interfaces)
8927 self.pg1.get_capture(max_sessions)
8929 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8930 src_address=self.pg3.local_ip4,
8932 template_interval=10)
8933 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8934 src_port=self.ipfix_src_port,
8937 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8938 IPv6(src=src, dst=remote_host_ip6) /
8939 TCP(sport=12345, dport=25))
8940 self.pg0.add_stream(p)
8941 self.pg_enable_capture(self.pg_interfaces)
8943 self.pg1.assert_nothing_captured()
8945 self.vapi.ipfix_flush()
8946 capture = self.pg3.get_capture(9)
8947 ipfix = IPFIXDecoder()
8948 # first load template
8950 self.assertTrue(p.haslayer(IPFIX))
8951 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8952 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8953 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8954 self.assertEqual(p[UDP].dport, 4739)
8955 self.assertEqual(p[IPFIX].observationDomainID,
8956 self.ipfix_domain_id)
8957 if p.haslayer(Template):
8958 ipfix.add_template(p.getlayer(Template))
8959 # verify events in data set
8961 if p.haslayer(Data):
8962 data = ipfix.decode_data_set(p.getlayer(Set))
8963 self.verify_ipfix_max_sessions(data, max_sessions)
8965 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8966 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8967 TCP(sport=12345, dport=80))
8968 self.pg0.add_stream(p)
8969 self.pg_enable_capture(self.pg_interfaces)
8971 self.pg1.assert_nothing_captured()
8973 self.vapi.ipfix_flush()
8974 capture = self.pg3.get_capture(1)
8975 # verify events in data set
8977 self.assertTrue(p.haslayer(IPFIX))
8978 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8979 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8980 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8981 self.assertEqual(p[UDP].dport, 4739)
8982 self.assertEqual(p[IPFIX].observationDomainID,
8983 self.ipfix_domain_id)
8984 if p.haslayer(Data):
8985 data = ipfix.decode_data_set(p.getlayer(Set))
8986 self.verify_ipfix_max_bibs(data, max_bibs)
8988 def test_ipfix_bib_ses(self):
8989 """ IPFIX logging NAT64 BIB/session create and delete events """
8990 self.tcp_port_in = random.randint(1025, 65535)
8991 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8995 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8996 end_addr=self.nat_addr,
8999 flags = self.config_flags.NAT_IS_INSIDE
9000 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9001 sw_if_index=self.pg0.sw_if_index)
9002 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9003 sw_if_index=self.pg1.sw_if_index)
9004 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9005 src_address=self.pg3.local_ip4,
9007 template_interval=10)
9008 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9009 src_port=self.ipfix_src_port,
9013 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9014 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9015 TCP(sport=self.tcp_port_in, dport=25))
9016 self.pg0.add_stream(p)
9017 self.pg_enable_capture(self.pg_interfaces)
9019 p = self.pg1.get_capture(1)
9020 self.tcp_port_out = p[0][TCP].sport
9021 self.vapi.ipfix_flush()
9022 capture = self.pg3.get_capture(10)
9023 ipfix = IPFIXDecoder()
9024 # first load template
9026 self.assertTrue(p.haslayer(IPFIX))
9027 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9028 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9029 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9030 self.assertEqual(p[UDP].dport, 4739)
9031 self.assertEqual(p[IPFIX].observationDomainID,
9032 self.ipfix_domain_id)
9033 if p.haslayer(Template):
9034 ipfix.add_template(p.getlayer(Template))
9035 # verify events in data set
9037 if p.haslayer(Data):
9038 data = ipfix.decode_data_set(p.getlayer(Set))
9039 if scapy.compat.orb(data[0][230]) == 10:
9040 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
9041 elif scapy.compat.orb(data[0][230]) == 6:
9042 self.verify_ipfix_nat64_ses(data,
9044 self.pg0.remote_ip6n,
9045 self.pg1.remote_ip4,
9048 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9051 self.pg_enable_capture(self.pg_interfaces)
9052 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9053 end_addr=self.nat_addr,
9056 self.vapi.ipfix_flush()
9057 capture = self.pg3.get_capture(2)
9058 # verify events in data set
9060 self.assertTrue(p.haslayer(IPFIX))
9061 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9062 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9063 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9064 self.assertEqual(p[UDP].dport, 4739)
9065 self.assertEqual(p[IPFIX].observationDomainID,
9066 self.ipfix_domain_id)
9067 if p.haslayer(Data):
9068 data = ipfix.decode_data_set(p.getlayer(Set))
9069 if scapy.compat.orb(data[0][230]) == 11:
9070 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
9071 elif scapy.compat.orb(data[0][230]) == 7:
9072 self.verify_ipfix_nat64_ses(data,
9074 self.pg0.remote_ip6n,
9075 self.pg1.remote_ip4,
9078 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9080 def test_syslog_sess(self):
9081 """ Test syslog session creation and deletion """
9082 self.tcp_port_in = random.randint(1025, 65535)
9083 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9087 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9088 end_addr=self.nat_addr,
9091 flags = self.config_flags.NAT_IS_INSIDE
9092 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9093 sw_if_index=self.pg0.sw_if_index)
9094 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9095 sw_if_index=self.pg1.sw_if_index)
9096 self.vapi.syslog_set_filter(
9097 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9098 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9100 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9101 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9102 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9103 self.pg0.add_stream(p)
9104 self.pg_enable_capture(self.pg_interfaces)
9106 p = self.pg1.get_capture(1)
9107 self.tcp_port_out = p[0][TCP].sport
9108 capture = self.pg3.get_capture(1)
9109 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9111 self.pg_enable_capture(self.pg_interfaces)
9113 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9114 end_addr=self.nat_addr,
9117 capture = self.pg3.get_capture(1)
9118 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9120 def nat64_get_ses_num(self):
9122 Return number of active NAT64 sessions.
9124 st = self.vapi.nat64_st_dump(proto=255)
9127 def clear_nat64(self):
9129 Clear NAT64 configuration.
9131 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9132 src_port=self.ipfix_src_port,
9134 self.ipfix_src_port = 4739
9135 self.ipfix_domain_id = 1
9137 self.vapi.syslog_set_filter(
9138 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9140 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9141 tcp_transitory=240, icmp=60)
9143 interfaces = self.vapi.nat64_interface_dump()
9144 for intf in interfaces:
9145 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9146 sw_if_index=intf.sw_if_index)
9148 bib = self.vapi.nat64_bib_dump(proto=255)
9150 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9151 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9159 adresses = self.vapi.nat64_pool_addr_dump()
9160 for addr in adresses:
9161 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9162 end_addr=addr.address,
9166 prefixes = self.vapi.nat64_prefix_dump()
9167 for prefix in prefixes:
9168 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9169 vrf_id=prefix.vrf_id, is_add=0)
9171 bibs = self.statistics.get_counter('/nat64/total-bibs')
9172 self.assertEqual(bibs[0][0], 0)
9173 sessions = self.statistics.get_counter('/nat64/total-sessions')
9174 self.assertEqual(sessions[0][0], 0)
9177 super(TestNAT64, self).tearDown()
9178 if not self.vpp_dead:
9181 def show_commands_at_teardown(self):
9182 self.logger.info(self.vapi.cli("show nat64 pool"))
9183 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9184 self.logger.info(self.vapi.cli("show nat64 prefix"))
9185 self.logger.info(self.vapi.cli("show nat64 bib all"))
9186 self.logger.info(self.vapi.cli("show nat64 session table all"))
9189 class TestNAT66(MethodHolder):
9190 """ NAT66 Test Cases """
9193 def setUpClass(cls):
9194 super(TestNAT66, cls).setUpClass()
9197 cls.nat_addr = 'fd01:ff::2'
9199 cls.create_pg_interfaces(range(2))
9200 cls.interfaces = list(cls.pg_interfaces)
9202 for i in cls.interfaces:
9205 i.configure_ipv6_neighbors()
9208 super(TestNAT66, cls).tearDownClass()
9212 def tearDownClass(cls):
9213 super(TestNAT66, cls).tearDownClass()
9215 def test_static(self):
9216 """ 1:1 NAT66 test """
9217 flags = self.config_flags.NAT_IS_INSIDE
9218 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9219 sw_if_index=self.pg0.sw_if_index)
9220 self.vapi.nat66_add_del_interface(is_add=1,
9221 sw_if_index=self.pg1.sw_if_index)
9222 self.vapi.nat66_add_del_static_mapping(
9223 local_ip_address=self.pg0.remote_ip6n,
9224 external_ip_address=self.nat_addr,
9229 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9230 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9233 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9234 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9237 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9238 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9239 ICMPv6EchoRequest())
9241 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9242 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9243 GRE() / IP() / TCP())
9245 self.pg0.add_stream(pkts)
9246 self.pg_enable_capture(self.pg_interfaces)
9248 capture = self.pg1.get_capture(len(pkts))
9250 for packet in capture:
9252 self.assertEqual(packet[IPv6].src, self.nat_addr)
9253 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9254 self.assert_packet_checksums_valid(packet)
9256 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9261 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9262 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9265 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9266 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9269 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9270 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9273 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9274 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9275 GRE() / IP() / TCP())
9277 self.pg1.add_stream(pkts)
9278 self.pg_enable_capture(self.pg_interfaces)
9280 capture = self.pg0.get_capture(len(pkts))
9281 for packet in capture:
9283 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9284 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9285 self.assert_packet_checksums_valid(packet)
9287 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9290 sm = self.vapi.nat66_static_mapping_dump()
9291 self.assertEqual(len(sm), 1)
9292 self.assertEqual(sm[0].total_pkts, 8)
9294 def test_check_no_translate(self):
9295 """ NAT66 translate only when egress interface is outside interface """
9296 flags = self.config_flags.NAT_IS_INSIDE
9297 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9298 sw_if_index=self.pg0.sw_if_index)
9299 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9300 sw_if_index=self.pg1.sw_if_index)
9301 self.vapi.nat66_add_del_static_mapping(
9302 local_ip_address=self.pg0.remote_ip6n,
9303 external_ip_address=self.nat_addr,
9307 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9308 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9310 self.pg0.add_stream([p])
9311 self.pg_enable_capture(self.pg_interfaces)
9313 capture = self.pg1.get_capture(1)
9316 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9317 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9319 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9322 def clear_nat66(self):
9324 Clear NAT66 configuration.
9326 interfaces = self.vapi.nat66_interface_dump()
9327 for intf in interfaces:
9328 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9329 sw_if_index=intf.sw_if_index)
9331 static_mappings = self.vapi.nat66_static_mapping_dump()
9332 for sm in static_mappings:
9333 self.vapi.nat66_add_del_static_mapping(
9334 local_ip_address=sm.local_ip_address,
9335 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9339 super(TestNAT66, self).tearDown()
9342 def show_commands_at_teardown(self):
9343 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9344 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9347 if __name__ == '__main__':
9348 unittest.main(testRunner=VppTestRunner)