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
37 # NAT HA protocol event data
40 fields_desc = [ByteEnumField("event_type", None,
41 {1: "add", 2: "del", 3: "refresh"}),
42 ByteEnumField("protocol", None,
43 {0: "udp", 1: "tcp", 2: "icmp"}),
44 ShortField("flags", 0),
45 IPField("in_addr", None),
46 IPField("out_addr", None),
47 ShortField("in_port", None),
48 ShortField("out_port", None),
49 IPField("eh_addr", None),
50 IPField("ehn_addr", None),
51 ShortField("eh_port", None),
52 ShortField("ehn_port", None),
53 IntField("fib_index", None),
54 IntField("total_pkts", 0),
55 LongField("total_bytes", 0)]
57 def extract_padding(self, s):
61 # NAT HA protocol header
62 class HANATStateSync(Packet):
63 name = "HA NAT state sync"
64 fields_desc = [XByteField("version", 1),
65 FlagsField("flags", 0, 8, ['ACK']),
66 FieldLenField("count", None, count_of="events"),
67 IntField("sequence_number", 1),
68 IntField("thread_index", 0),
69 PacketListField("events", [], Event,
70 count_from=lambda pkt: pkt.count)]
73 class MethodHolder(VppTestCase):
74 """ NAT create capture and verify method holder """
77 def config_flags(self):
78 return VppEnum.vl_api_nat_config_flags_t
81 def SYSLOG_SEVERITY(self):
82 return VppEnum.vl_api_syslog_severity_t
84 def clear_nat44(self):
86 Clear NAT44 configuration.
88 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
89 if self.pg7.has_ip4_config:
90 self.pg7.unconfig_ip4()
92 self.vapi.nat44_forwarding_enable_disable(enable=0)
94 interfaces = self.vapi.nat44_interface_addr_dump()
95 for intf in interfaces:
96 self.vapi.nat44_add_del_interface_addr(
98 sw_if_index=intf.sw_if_index,
101 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
102 src_port=self.ipfix_src_port,
104 self.ipfix_src_port = 4739
105 self.ipfix_domain_id = 1
107 self.vapi.syslog_set_filter(
108 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
110 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
112 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
113 session_refresh_interval=10)
115 interfaces = self.vapi.nat44_interface_dump()
116 for intf in interfaces:
117 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
118 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
119 self.vapi.nat44_interface_add_del_feature(
120 sw_if_index=intf.sw_if_index)
121 self.vapi.nat44_interface_add_del_feature(
122 sw_if_index=intf.sw_if_index,
125 interfaces = self.vapi.nat44_interface_output_feature_dump()
126 for intf in interfaces:
127 self.vapi.nat44_interface_add_del_output_feature(
130 sw_if_index=intf.sw_if_index)
131 static_mappings = self.vapi.nat44_static_mapping_dump()
132 for sm in static_mappings:
133 self.vapi.nat44_add_del_static_mapping(
135 local_ip_address=sm.local_ip_address,
136 external_ip_address=sm.external_ip_address,
137 external_sw_if_index=sm.external_sw_if_index,
138 local_port=sm.local_port,
139 external_port=sm.external_port,
141 protocol=sm.protocol,
142 flags=sm.flags, tag=sm.tag)
144 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
145 for lb_sm in lb_static_mappings:
146 self.vapi.nat44_add_del_lb_static_mapping(
149 external_addr=lb_sm.external_addr,
150 external_port=lb_sm.external_port,
151 protocol=lb_sm.protocol,
152 local_num=0, locals=[],
155 identity_mappings = self.vapi.nat44_identity_mapping_dump()
156 for id_m in identity_mappings:
157 self.vapi.nat44_add_del_identity_mapping(
158 ip_address=id_m.ip_address,
159 sw_if_index=id_m.sw_if_index,
163 protocol=id_m.protocol)
165 addresses = self.vapi.nat44_address_dump()
166 for addr in addresses:
167 self.vapi.nat44_add_del_address_range(
168 first_ip_address=addr.ip_address,
169 last_ip_address=addr.ip_address,
170 vrf_id=0xFFFFFFFF, flags=addr.flags)
172 self.verify_no_nat44_user()
173 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
174 tcp_transitory=240, icmp=60)
175 self.vapi.nat_set_addr_and_port_alloc_alg()
176 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
178 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
179 local_port=0, external_port=0, vrf_id=0,
180 is_add=1, external_sw_if_index=0xFFFFFFFF,
181 proto=0, tag="", flags=0):
183 Add/delete NAT44 static mapping
185 :param local_ip: Local IP address
186 :param external_ip: External IP address
187 :param local_port: Local port number (Optional)
188 :param external_port: External port number (Optional)
189 :param vrf_id: VRF ID (Default 0)
190 :param is_add: 1 if add, 0 if delete (Default add)
191 :param external_sw_if_index: External interface instead of IP address
192 :param proto: IP protocol (Mandatory if port specified)
193 :param tag: Opaque string tag
194 :param flags: NAT configuration flags
197 if not (local_port and external_port):
198 flags |= self.config_flags.NAT_IS_ADDR_ONLY
200 self.vapi.nat44_add_del_static_mapping(
202 local_ip_address=local_ip,
203 external_ip_address=external_ip,
204 external_sw_if_index=external_sw_if_index,
205 local_port=local_port,
206 external_port=external_port,
207 vrf_id=vrf_id, protocol=proto,
211 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
213 Add/delete NAT44 address
215 :param ip: IP address
216 :param is_add: 1 if add, 0 if delete (Default add)
217 :param twice_nat: twice NAT address for external hosts
219 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
220 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
226 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
228 Create packet stream for inside network
230 :param in_if: Inside interface
231 :param out_if: Outside interface
232 :param dst_ip: Destination address
233 :param ttl: TTL of generated packets
236 dst_ip = out_if.remote_ip4
240 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
241 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
242 TCP(sport=self.tcp_port_in, dport=20))
246 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
247 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
248 UDP(sport=self.udp_port_in, dport=20))
252 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
253 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
254 ICMP(id=self.icmp_id_in, type='echo-request'))
259 def compose_ip6(self, ip4, pref, plen):
261 Compose IPv4-embedded IPv6 addresses
263 :param ip4: IPv4 address
264 :param pref: IPv6 prefix
265 :param plen: IPv6 prefix length
266 :returns: IPv4-embedded IPv6 addresses
268 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
269 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
284 pref_n[10] = ip4_n[3]
288 pref_n[10] = ip4_n[2]
289 pref_n[11] = ip4_n[3]
292 pref_n[10] = ip4_n[1]
293 pref_n[11] = ip4_n[2]
294 pref_n[12] = ip4_n[3]
296 pref_n[12] = ip4_n[0]
297 pref_n[13] = ip4_n[1]
298 pref_n[14] = ip4_n[2]
299 pref_n[15] = ip4_n[3]
300 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
301 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
303 def extract_ip4(self, ip6, plen):
305 Extract IPv4 address embedded in IPv6 addresses
307 :param ip6: IPv6 address
308 :param plen: IPv6 prefix length
309 :returns: extracted IPv4 address
311 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
343 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
345 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
347 Create IPv6 packet stream for inside network
349 :param in_if: Inside interface
350 :param out_if: Outside interface
351 :param ttl: Hop Limit of generated packets
352 :param pref: NAT64 prefix
353 :param plen: NAT64 prefix length
357 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
359 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
362 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
363 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
364 TCP(sport=self.tcp_port_in, dport=20))
368 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
369 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
370 UDP(sport=self.udp_port_in, dport=20))
374 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
375 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
376 ICMPv6EchoRequest(id=self.icmp_id_in))
381 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
382 use_inside_ports=False):
384 Create packet stream for outside network
386 :param out_if: Outside interface
387 :param dst_ip: Destination IP address (Default use global NAT address)
388 :param ttl: TTL of generated packets
389 :param use_inside_ports: Use inside NAT ports as destination ports
390 instead of outside ports
393 dst_ip = self.nat_addr
394 if not use_inside_ports:
395 tcp_port = self.tcp_port_out
396 udp_port = self.udp_port_out
397 icmp_id = self.icmp_id_out
399 tcp_port = self.tcp_port_in
400 udp_port = self.udp_port_in
401 icmp_id = self.icmp_id_in
404 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
405 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
406 TCP(dport=tcp_port, sport=20))
410 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
411 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
412 UDP(dport=udp_port, sport=20))
416 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
417 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
418 ICMP(id=icmp_id, type='echo-reply'))
423 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
425 Create packet stream for outside network
427 :param out_if: Outside interface
428 :param dst_ip: Destination IP address (Default use global NAT address)
429 :param hl: HL of generated packets
433 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
434 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
435 TCP(dport=self.tcp_port_out, sport=20))
439 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
440 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
441 UDP(dport=self.udp_port_out, sport=20))
445 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
446 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
447 ICMPv6EchoReply(id=self.icmp_id_out))
452 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
453 dst_ip=None, is_ip6=False):
455 Verify captured packets on outside network
457 :param capture: Captured packets
458 :param nat_ip: Translated IP address (Default use global NAT address)
459 :param same_port: Source port number is not translated (Default False)
460 :param dst_ip: Destination IP address (Default do not verify)
461 :param is_ip6: If L3 protocol is IPv6 (Default False)
465 ICMP46 = ICMPv6EchoRequest
470 nat_ip = self.nat_addr
471 for packet in capture:
474 self.assert_packet_checksums_valid(packet)
475 self.assertEqual(packet[IP46].src, nat_ip)
476 if dst_ip is not None:
477 self.assertEqual(packet[IP46].dst, dst_ip)
478 if packet.haslayer(TCP):
480 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
483 packet[TCP].sport, self.tcp_port_in)
484 self.tcp_port_out = packet[TCP].sport
485 self.assert_packet_checksums_valid(packet)
486 elif packet.haslayer(UDP):
488 self.assertEqual(packet[UDP].sport, self.udp_port_in)
491 packet[UDP].sport, self.udp_port_in)
492 self.udp_port_out = packet[UDP].sport
495 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
497 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
498 self.icmp_id_out = packet[ICMP46].id
499 self.assert_packet_checksums_valid(packet)
501 self.logger.error(ppp("Unexpected or invalid packet "
502 "(outside network):", packet))
505 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
508 Verify captured packets on outside network
510 :param capture: Captured packets
511 :param nat_ip: Translated IP address
512 :param same_port: Source port number is not translated (Default False)
513 :param dst_ip: Destination IP address (Default do not verify)
515 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
518 def verify_capture_in(self, capture, in_if):
520 Verify captured packets on inside network
522 :param capture: Captured packets
523 :param in_if: Inside interface
525 for packet in capture:
527 self.assert_packet_checksums_valid(packet)
528 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
529 if packet.haslayer(TCP):
530 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
531 elif packet.haslayer(UDP):
532 self.assertEqual(packet[UDP].dport, self.udp_port_in)
534 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
536 self.logger.error(ppp("Unexpected or invalid packet "
537 "(inside network):", packet))
540 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
542 Verify captured IPv6 packets on inside network
544 :param capture: Captured packets
545 :param src_ip: Source IP
546 :param dst_ip: Destination IP address
548 for packet in capture:
550 self.assertEqual(packet[IPv6].src, src_ip)
551 self.assertEqual(packet[IPv6].dst, dst_ip)
552 self.assert_packet_checksums_valid(packet)
553 if packet.haslayer(TCP):
554 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
555 elif packet.haslayer(UDP):
556 self.assertEqual(packet[UDP].dport, self.udp_port_in)
558 self.assertEqual(packet[ICMPv6EchoReply].id,
561 self.logger.error(ppp("Unexpected or invalid packet "
562 "(inside network):", packet))
565 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
567 Verify captured packet that don't have to be translated
569 :param capture: Captured packets
570 :param ingress_if: Ingress interface
571 :param egress_if: Egress interface
573 for packet in capture:
575 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
576 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
577 if packet.haslayer(TCP):
578 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
579 elif packet.haslayer(UDP):
580 self.assertEqual(packet[UDP].sport, self.udp_port_in)
582 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
584 self.logger.error(ppp("Unexpected or invalid packet "
585 "(inside network):", packet))
588 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
591 Verify captured packets with ICMP errors on outside network
593 :param capture: Captured packets
594 :param src_ip: Translated IP address or IP address of VPP
595 (Default use global NAT address)
596 :param icmp_type: Type of error ICMP packet
597 we are expecting (Default 11)
600 src_ip = self.nat_addr
601 for packet in capture:
603 self.assertEqual(packet[IP].src, src_ip)
604 self.assertEqual(packet.haslayer(ICMP), 1)
606 self.assertEqual(icmp.type, icmp_type)
607 self.assertTrue(icmp.haslayer(IPerror))
608 inner_ip = icmp[IPerror]
609 if inner_ip.haslayer(TCPerror):
610 self.assertEqual(inner_ip[TCPerror].dport,
612 elif inner_ip.haslayer(UDPerror):
613 self.assertEqual(inner_ip[UDPerror].dport,
616 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
618 self.logger.error(ppp("Unexpected or invalid packet "
619 "(outside network):", packet))
622 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
624 Verify captured packets with ICMP errors on inside network
626 :param capture: Captured packets
627 :param in_if: Inside interface
628 :param icmp_type: Type of error ICMP packet
629 we are expecting (Default 11)
631 for packet in capture:
633 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
634 self.assertEqual(packet.haslayer(ICMP), 1)
636 self.assertEqual(icmp.type, icmp_type)
637 self.assertTrue(icmp.haslayer(IPerror))
638 inner_ip = icmp[IPerror]
639 if inner_ip.haslayer(TCPerror):
640 self.assertEqual(inner_ip[TCPerror].sport,
642 elif inner_ip.haslayer(UDPerror):
643 self.assertEqual(inner_ip[UDPerror].sport,
646 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
648 self.logger.error(ppp("Unexpected or invalid packet "
649 "(inside network):", packet))
652 def create_stream_frag(self, src_if, dst, sport, dport, data,
653 proto=IP_PROTOS.tcp, echo_reply=False):
655 Create fragmented packet stream
657 :param src_if: Source interface
658 :param dst: Destination IPv4 address
659 :param sport: Source port
660 :param dport: Destination port
661 :param data: Payload data
662 :param proto: protocol (TCP, UDP, ICMP)
663 :param echo_reply: use echo_reply if protocol is ICMP
666 if proto == IP_PROTOS.tcp:
667 p = (IP(src=src_if.remote_ip4, dst=dst) /
668 TCP(sport=sport, dport=dport) /
670 p = p.__class__(scapy.compat.raw(p))
671 chksum = p[TCP].chksum
672 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
673 elif proto == IP_PROTOS.udp:
674 proto_header = UDP(sport=sport, dport=dport)
675 elif proto == IP_PROTOS.icmp:
677 proto_header = ICMP(id=sport, type='echo-request')
679 proto_header = ICMP(id=sport, type='echo-reply')
681 raise Exception("Unsupported protocol")
682 id = random.randint(0, 65535)
684 if proto == IP_PROTOS.tcp:
687 raw = Raw(data[0:16])
688 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
689 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
693 if proto == IP_PROTOS.tcp:
694 raw = Raw(data[4:20])
696 raw = Raw(data[16:32])
697 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
698 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
702 if proto == IP_PROTOS.tcp:
706 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
707 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
713 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
714 pref=None, plen=0, frag_size=128):
716 Create fragmented packet stream
718 :param src_if: Source interface
719 :param dst: Destination IPv4 address
720 :param sport: Source TCP port
721 :param dport: Destination TCP port
722 :param data: Payload data
723 :param pref: NAT64 prefix
724 :param plen: NAT64 prefix length
725 :param fragsize: size of fragments
729 dst_ip6 = ''.join(['64:ff9b::', dst])
731 dst_ip6 = self.compose_ip6(dst, pref, plen)
733 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
734 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
735 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
736 TCP(sport=sport, dport=dport) /
739 return fragment6(p, frag_size)
741 def reass_frags_and_verify(self, frags, src, dst):
743 Reassemble and verify fragmented packet
745 :param frags: Captured fragments
746 :param src: Source IPv4 address to verify
747 :param dst: Destination IPv4 address to verify
749 :returns: Reassembled IPv4 packet
753 self.assertEqual(p[IP].src, src)
754 self.assertEqual(p[IP].dst, dst)
755 self.assert_ip_checksum_valid(p)
756 buffer.seek(p[IP].frag * 8)
757 buffer.write(bytes(p[IP].payload))
758 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
759 proto=frags[0][IP].proto)
760 if ip.proto == IP_PROTOS.tcp:
761 p = (ip / TCP(buffer.getvalue()))
762 self.logger.debug(ppp("Reassembled:", p))
763 self.assert_tcp_checksum_valid(p)
764 elif ip.proto == IP_PROTOS.udp:
765 p = (ip / UDP(buffer.getvalue()[:8]) /
766 Raw(buffer.getvalue()[8:]))
767 elif ip.proto == IP_PROTOS.icmp:
768 p = (ip / ICMP(buffer.getvalue()))
771 def reass_frags_and_verify_ip6(self, frags, src, dst):
773 Reassemble and verify fragmented packet
775 :param frags: Captured fragments
776 :param src: Source IPv6 address to verify
777 :param dst: Destination IPv6 address to verify
779 :returns: Reassembled IPv6 packet
783 self.assertEqual(p[IPv6].src, src)
784 self.assertEqual(p[IPv6].dst, dst)
785 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
786 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
787 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
788 nh=frags[0][IPv6ExtHdrFragment].nh)
789 if ip.nh == IP_PROTOS.tcp:
790 p = (ip / TCP(buffer.getvalue()))
791 elif ip.nh == IP_PROTOS.udp:
792 p = (ip / UDP(buffer.getvalue()))
793 self.logger.debug(ppp("Reassembled:", p))
794 self.assert_packet_checksums_valid(p)
797 def initiate_tcp_session(self, in_if, out_if):
799 Initiates TCP session
801 :param in_if: Inside interface
802 :param out_if: Outside interface
806 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
807 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
808 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
811 self.pg_enable_capture(self.pg_interfaces)
813 capture = out_if.get_capture(1)
815 self.tcp_port_out = p[TCP].sport
817 # SYN + ACK packet out->in
818 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
819 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
820 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
823 self.pg_enable_capture(self.pg_interfaces)
828 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
829 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
830 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
833 self.pg_enable_capture(self.pg_interfaces)
835 out_if.get_capture(1)
838 self.logger.error("TCP 3 way handshake failed")
841 def verify_ipfix_nat44_ses(self, data):
843 Verify IPFIX NAT44 session create/delete event
845 :param data: Decoded IPFIX data records
847 nat44_ses_create_num = 0
848 nat44_ses_delete_num = 0
849 self.assertEqual(6, len(data))
852 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
853 if scapy.compat.orb(record[230]) == 4:
854 nat44_ses_create_num += 1
856 nat44_ses_delete_num += 1
858 self.assertEqual(self.pg0.remote_ip4n, record[8])
859 # postNATSourceIPv4Address
860 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
863 self.assertEqual(struct.pack("!I", 0), record[234])
864 # protocolIdentifier/sourceTransportPort
865 # /postNAPTSourceTransportPort
866 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
867 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
868 self.assertEqual(struct.pack("!H", self.icmp_id_out),
870 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
871 self.assertEqual(struct.pack("!H", self.tcp_port_in),
873 self.assertEqual(struct.pack("!H", self.tcp_port_out),
875 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
876 self.assertEqual(struct.pack("!H", self.udp_port_in),
878 self.assertEqual(struct.pack("!H", self.udp_port_out),
881 self.fail("Invalid protocol")
882 self.assertEqual(3, nat44_ses_create_num)
883 self.assertEqual(3, nat44_ses_delete_num)
885 def verify_ipfix_addr_exhausted(self, data):
887 Verify IPFIX NAT addresses event
889 :param data: Decoded IPFIX data records
891 self.assertEqual(1, len(data))
894 self.assertEqual(scapy.compat.orb(record[230]), 3)
896 self.assertEqual(struct.pack("!I", 0), record[283])
898 def verify_ipfix_max_sessions(self, data, limit):
900 Verify IPFIX maximum session entries exceeded event
902 :param data: Decoded IPFIX data records
903 :param limit: Number of maximum session entries that can be created.
905 self.assertEqual(1, len(data))
908 self.assertEqual(scapy.compat.orb(record[230]), 13)
909 # natQuotaExceededEvent
910 self.assertEqual(struct.pack("I", 1), record[466])
912 self.assertEqual(struct.pack("I", limit), record[471])
914 def verify_ipfix_max_bibs(self, data, limit):
916 Verify IPFIX maximum BIB entries exceeded event
918 :param data: Decoded IPFIX data records
919 :param limit: Number of maximum BIB entries that can be created.
921 self.assertEqual(1, len(data))
924 self.assertEqual(scapy.compat.orb(record[230]), 13)
925 # natQuotaExceededEvent
926 self.assertEqual(struct.pack("I", 2), record[466])
928 self.assertEqual(struct.pack("I", limit), record[472])
930 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
932 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
934 :param data: Decoded IPFIX data records
935 :param limit: Number of maximum fragments pending reassembly
936 :param src_addr: IPv6 source address
938 self.assertEqual(1, len(data))
941 self.assertEqual(scapy.compat.orb(record[230]), 13)
942 # natQuotaExceededEvent
943 self.assertEqual(struct.pack("I", 5), record[466])
944 # maxFragmentsPendingReassembly
945 self.assertEqual(struct.pack("I", limit), record[475])
947 self.assertEqual(src_addr, record[27])
949 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
951 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
953 :param data: Decoded IPFIX data records
954 :param limit: Number of maximum fragments pending reassembly
955 :param src_addr: IPv4 source address
957 self.assertEqual(1, len(data))
960 self.assertEqual(scapy.compat.orb(record[230]), 13)
961 # natQuotaExceededEvent
962 self.assertEqual(struct.pack("I", 5), record[466])
963 # maxFragmentsPendingReassembly
964 self.assertEqual(struct.pack("I", limit), record[475])
966 self.assertEqual(src_addr, record[8])
968 def verify_ipfix_bib(self, data, is_create, src_addr):
970 Verify IPFIX NAT64 BIB create and delete events
972 :param data: Decoded IPFIX data records
973 :param is_create: Create event if nonzero value otherwise delete event
974 :param src_addr: IPv6 source address
976 self.assertEqual(1, len(data))
980 self.assertEqual(scapy.compat.orb(record[230]), 10)
982 self.assertEqual(scapy.compat.orb(record[230]), 11)
984 self.assertEqual(src_addr, record[27])
985 # postNATSourceIPv4Address
986 self.assertEqual(self.nat_addr_n, record[225])
988 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
990 self.assertEqual(struct.pack("!I", 0), record[234])
991 # sourceTransportPort
992 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
993 # postNAPTSourceTransportPort
994 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
996 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
999 Verify IPFIX NAT64 session create and delete events
1001 :param data: Decoded IPFIX data records
1002 :param is_create: Create event if nonzero value otherwise delete event
1003 :param src_addr: IPv6 source address
1004 :param dst_addr: IPv4 destination address
1005 :param dst_port: destination TCP port
1007 self.assertEqual(1, len(data))
1011 self.assertEqual(scapy.compat.orb(record[230]), 6)
1013 self.assertEqual(scapy.compat.orb(record[230]), 7)
1015 self.assertEqual(src_addr, record[27])
1016 # destinationIPv6Address
1017 self.assertEqual(socket.inet_pton(socket.AF_INET6,
1018 self.compose_ip6(dst_addr,
1022 # postNATSourceIPv4Address
1023 self.assertEqual(self.nat_addr_n, record[225])
1024 # postNATDestinationIPv4Address
1025 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1027 # protocolIdentifier
1028 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
1030 self.assertEqual(struct.pack("!I", 0), record[234])
1031 # sourceTransportPort
1032 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1033 # postNAPTSourceTransportPort
1034 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1035 # destinationTransportPort
1036 self.assertEqual(struct.pack("!H", dst_port), record[11])
1037 # postNAPTDestinationTransportPort
1038 self.assertEqual(struct.pack("!H", dst_port), record[228])
1040 def verify_no_nat44_user(self):
1041 """ Verify that there is no NAT44 user """
1042 users = self.vapi.nat44_user_dump()
1043 self.assertEqual(len(users), 0)
1044 users = self.statistics.get_counter('/nat44/total-users')
1045 self.assertEqual(users[0][0], 0)
1046 sessions = self.statistics.get_counter('/nat44/total-sessions')
1047 self.assertEqual(sessions[0][0], 0)
1049 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1051 Verify IPFIX maximum entries per user exceeded event
1053 :param data: Decoded IPFIX data records
1054 :param limit: Number of maximum entries per user
1055 :param src_addr: IPv4 source address
1057 self.assertEqual(1, len(data))
1060 self.assertEqual(scapy.compat.orb(record[230]), 13)
1061 # natQuotaExceededEvent
1062 self.assertEqual(struct.pack("I", 3), record[466])
1064 self.assertEqual(struct.pack("I", limit), record[473])
1066 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1068 def verify_syslog_apmap(self, data, is_add=True):
1069 message = data.decode('utf-8')
1071 message = SyslogMessage.parse(message)
1072 except ParseError as e:
1073 self.logger.error(e)
1076 self.assertEqual(message.severity, SyslogSeverity.info)
1077 self.assertEqual(message.appname, 'NAT')
1078 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1079 sd_params = message.sd.get('napmap')
1080 self.assertTrue(sd_params is not None)
1081 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1082 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1083 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1084 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1085 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1086 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1087 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1088 self.assertTrue(sd_params.get('SSUBIX') is not None)
1089 self.assertEqual(sd_params.get('SVLAN'), '0')
1091 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1092 message = data.decode('utf-8')
1094 message = SyslogMessage.parse(message)
1095 except ParseError as e:
1096 self.logger.error(e)
1099 self.assertEqual(message.severity, SyslogSeverity.info)
1100 self.assertEqual(message.appname, 'NAT')
1101 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1102 sd_params = message.sd.get('nsess')
1103 self.assertTrue(sd_params is not None)
1105 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1106 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1108 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1109 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1110 self.assertTrue(sd_params.get('SSUBIX') is not None)
1111 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1112 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1113 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1114 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1115 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1116 self.assertEqual(sd_params.get('SVLAN'), '0')
1117 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1118 self.assertEqual(sd_params.get('XDPORT'),
1119 "%d" % self.tcp_external_port)
1121 def verify_mss_value(self, pkt, mss):
1123 Verify TCP MSS value
1128 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1129 raise TypeError("Not a TCP/IP packet")
1131 for option in pkt[TCP].options:
1132 if option[0] == 'MSS':
1133 self.assertEqual(option[1], mss)
1134 self.assert_tcp_checksum_valid(pkt)
1137 def proto2layer(proto):
1138 if proto == IP_PROTOS.tcp:
1140 elif proto == IP_PROTOS.udp:
1142 elif proto == IP_PROTOS.icmp:
1145 raise Exception("Unsupported protocol")
1147 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1148 layer = self.proto2layer(proto)
1150 if proto == IP_PROTOS.tcp:
1151 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1153 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1154 self.port_in = random.randint(1025, 65535)
1157 pkts = self.create_stream_frag(self.pg0,
1158 self.pg1.remote_ip4,
1163 self.pg0.add_stream(pkts)
1164 self.pg_enable_capture(self.pg_interfaces)
1166 frags = self.pg1.get_capture(len(pkts))
1167 if not dont_translate:
1168 p = self.reass_frags_and_verify(frags,
1170 self.pg1.remote_ip4)
1172 p = self.reass_frags_and_verify(frags,
1173 self.pg0.remote_ip4,
1174 self.pg1.remote_ip4)
1175 if proto != IP_PROTOS.icmp:
1176 if not dont_translate:
1177 self.assertEqual(p[layer].dport, 20)
1178 self.assertNotEqual(p[layer].sport, self.port_in)
1180 self.assertEqual(p[layer].sport, self.port_in)
1182 if not dont_translate:
1183 self.assertNotEqual(p[layer].id, self.port_in)
1185 self.assertEqual(p[layer].id, self.port_in)
1186 self.assertEqual(data, p[Raw].load)
1189 if not dont_translate:
1190 dst_addr = self.nat_addr
1192 dst_addr = self.pg0.remote_ip4
1193 if proto != IP_PROTOS.icmp:
1195 dport = p[layer].sport
1199 pkts = self.create_stream_frag(self.pg1,
1206 self.pg1.add_stream(pkts)
1207 self.pg_enable_capture(self.pg_interfaces)
1209 frags = self.pg0.get_capture(len(pkts))
1210 p = self.reass_frags_and_verify(frags,
1211 self.pg1.remote_ip4,
1212 self.pg0.remote_ip4)
1213 if proto != IP_PROTOS.icmp:
1214 self.assertEqual(p[layer].sport, 20)
1215 self.assertEqual(p[layer].dport, self.port_in)
1217 self.assertEqual(p[layer].id, self.port_in)
1218 self.assertEqual(data, p[Raw].load)
1220 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1221 layer = self.proto2layer(proto)
1223 if proto == IP_PROTOS.tcp:
1224 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1226 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1227 self.port_in = random.randint(1025, 65535)
1231 pkts = self.create_stream_frag(self.pg0,
1232 self.server_out_addr,
1234 self.server_out_port,
1237 self.pg0.add_stream(pkts)
1238 self.pg_enable_capture(self.pg_interfaces)
1240 frags = self.pg1.get_capture(len(pkts))
1241 p = self.reass_frags_and_verify(frags,
1242 self.pg0.remote_ip4,
1243 self.server_in_addr)
1244 if proto != IP_PROTOS.icmp:
1245 self.assertEqual(p[layer].sport, self.port_in)
1246 self.assertEqual(p[layer].dport, self.server_in_port)
1248 self.assertEqual(p[layer].id, self.port_in)
1249 self.assertEqual(data, p[Raw].load)
1252 if proto != IP_PROTOS.icmp:
1253 pkts = self.create_stream_frag(self.pg1,
1254 self.pg0.remote_ip4,
1255 self.server_in_port,
1260 pkts = self.create_stream_frag(self.pg1,
1261 self.pg0.remote_ip4,
1267 self.pg1.add_stream(pkts)
1268 self.pg_enable_capture(self.pg_interfaces)
1270 frags = self.pg0.get_capture(len(pkts))
1271 p = self.reass_frags_and_verify(frags,
1272 self.server_out_addr,
1273 self.pg0.remote_ip4)
1274 if proto != IP_PROTOS.icmp:
1275 self.assertEqual(p[layer].sport, self.server_out_port)
1276 self.assertEqual(p[layer].dport, self.port_in)
1278 self.assertEqual(p[layer].id, self.port_in)
1279 self.assertEqual(data, p[Raw].load)
1281 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1282 layer = self.proto2layer(proto)
1284 if proto == IP_PROTOS.tcp:
1285 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1287 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1289 # send packet from host to server
1290 pkts = self.create_stream_frag(self.pg0,
1293 self.server_out_port,
1296 self.pg0.add_stream(pkts)
1297 self.pg_enable_capture(self.pg_interfaces)
1299 frags = self.pg0.get_capture(len(pkts))
1300 p = self.reass_frags_and_verify(frags,
1303 if proto != IP_PROTOS.icmp:
1304 self.assertNotEqual(p[layer].sport, self.host_in_port)
1305 self.assertEqual(p[layer].dport, self.server_in_port)
1307 self.assertNotEqual(p[layer].id, self.host_in_port)
1308 self.assertEqual(data, p[Raw].load)
1310 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1311 layer = self.proto2layer(proto)
1313 if proto == IP_PROTOS.tcp:
1314 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1316 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1317 self.port_in = random.randint(1025, 65535)
1321 pkts = self.create_stream_frag(self.pg0,
1322 self.pg1.remote_ip4,
1328 self.pg0.add_stream(pkts)
1329 self.pg_enable_capture(self.pg_interfaces)
1331 frags = self.pg1.get_capture(len(pkts))
1332 if not dont_translate:
1333 p = self.reass_frags_and_verify(frags,
1335 self.pg1.remote_ip4)
1337 p = self.reass_frags_and_verify(frags,
1338 self.pg0.remote_ip4,
1339 self.pg1.remote_ip4)
1340 if proto != IP_PROTOS.icmp:
1341 if not dont_translate:
1342 self.assertEqual(p[layer].dport, 20)
1343 self.assertNotEqual(p[layer].sport, self.port_in)
1345 self.assertEqual(p[layer].sport, self.port_in)
1347 if not dont_translate:
1348 self.assertNotEqual(p[layer].id, self.port_in)
1350 self.assertEqual(p[layer].id, self.port_in)
1351 self.assertEqual(data, p[Raw].load)
1354 if not dont_translate:
1355 dst_addr = self.nat_addr
1357 dst_addr = self.pg0.remote_ip4
1358 if proto != IP_PROTOS.icmp:
1360 dport = p[layer].sport
1364 pkts = self.create_stream_frag(self.pg1,
1372 self.pg1.add_stream(pkts)
1373 self.pg_enable_capture(self.pg_interfaces)
1375 frags = self.pg0.get_capture(len(pkts))
1376 p = self.reass_frags_and_verify(frags,
1377 self.pg1.remote_ip4,
1378 self.pg0.remote_ip4)
1379 if proto != IP_PROTOS.icmp:
1380 self.assertEqual(p[layer].sport, 20)
1381 self.assertEqual(p[layer].dport, self.port_in)
1383 self.assertEqual(p[layer].id, self.port_in)
1384 self.assertEqual(data, p[Raw].load)
1386 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1387 layer = self.proto2layer(proto)
1389 if proto == IP_PROTOS.tcp:
1390 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1392 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1393 self.port_in = random.randint(1025, 65535)
1397 pkts = self.create_stream_frag(self.pg0,
1398 self.server_out_addr,
1400 self.server_out_port,
1404 self.pg0.add_stream(pkts)
1405 self.pg_enable_capture(self.pg_interfaces)
1407 frags = self.pg1.get_capture(len(pkts))
1408 p = self.reass_frags_and_verify(frags,
1409 self.pg0.remote_ip4,
1410 self.server_in_addr)
1411 if proto != IP_PROTOS.icmp:
1412 self.assertEqual(p[layer].dport, self.server_in_port)
1413 self.assertEqual(p[layer].sport, self.port_in)
1414 self.assertEqual(p[layer].dport, self.server_in_port)
1416 self.assertEqual(p[layer].id, self.port_in)
1417 self.assertEqual(data, p[Raw].load)
1420 if proto != IP_PROTOS.icmp:
1421 pkts = self.create_stream_frag(self.pg1,
1422 self.pg0.remote_ip4,
1423 self.server_in_port,
1428 pkts = self.create_stream_frag(self.pg1,
1429 self.pg0.remote_ip4,
1436 self.pg1.add_stream(pkts)
1437 self.pg_enable_capture(self.pg_interfaces)
1439 frags = self.pg0.get_capture(len(pkts))
1440 p = self.reass_frags_and_verify(frags,
1441 self.server_out_addr,
1442 self.pg0.remote_ip4)
1443 if proto != IP_PROTOS.icmp:
1444 self.assertEqual(p[layer].sport, self.server_out_port)
1445 self.assertEqual(p[layer].dport, self.port_in)
1447 self.assertEqual(p[layer].id, self.port_in)
1448 self.assertEqual(data, p[Raw].load)
1451 class TestNAT44(MethodHolder):
1452 """ NAT44 Test Cases """
1455 def setUpClass(cls):
1456 super(TestNAT44, cls).setUpClass()
1457 cls.vapi.cli("set log class nat level debug")
1460 cls.tcp_port_in = 6303
1461 cls.tcp_port_out = 6303
1462 cls.udp_port_in = 6304
1463 cls.udp_port_out = 6304
1464 cls.icmp_id_in = 6305
1465 cls.icmp_id_out = 6305
1466 cls.nat_addr = '10.0.0.3'
1467 cls.ipfix_src_port = 4739
1468 cls.ipfix_domain_id = 1
1469 cls.tcp_external_port = 80
1470 cls.udp_external_port = 69
1472 cls.create_pg_interfaces(range(10))
1473 cls.interfaces = list(cls.pg_interfaces[0:4])
1475 for i in cls.interfaces:
1480 cls.pg0.generate_remote_hosts(3)
1481 cls.pg0.configure_ipv4_neighbors()
1483 cls.pg1.generate_remote_hosts(1)
1484 cls.pg1.configure_ipv4_neighbors()
1486 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1487 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1488 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1490 cls.pg4._local_ip4 = "172.16.255.1"
1491 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1492 cls.pg4.set_table_ip4(10)
1493 cls.pg5._local_ip4 = "172.17.255.3"
1494 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1495 cls.pg5.set_table_ip4(10)
1496 cls.pg6._local_ip4 = "172.16.255.1"
1497 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1498 cls.pg6.set_table_ip4(20)
1499 for i in cls.overlapping_interfaces:
1507 cls.pg9.generate_remote_hosts(2)
1508 cls.pg9.config_ip4()
1509 cls.vapi.sw_interface_add_del_address(
1510 sw_if_index=cls.pg9.sw_if_index,
1511 prefix="10.0.0.1/24")
1514 cls.pg9.resolve_arp()
1515 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1516 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1517 cls.pg9.resolve_arp()
1520 super(TestNAT44, cls).tearDownClass()
1524 def tearDownClass(cls):
1525 super(TestNAT44, cls).tearDownClass()
1527 def test_dynamic(self):
1528 """ NAT44 dynamic translation test """
1529 self.nat44_add_address(self.nat_addr)
1530 flags = self.config_flags.NAT_IS_INSIDE
1531 self.vapi.nat44_interface_add_del_feature(
1532 sw_if_index=self.pg0.sw_if_index,
1533 flags=flags, is_add=1)
1534 self.vapi.nat44_interface_add_del_feature(
1535 sw_if_index=self.pg1.sw_if_index,
1539 tcpn = self.statistics.get_err_counter(
1540 '/err/nat44-in2out-slowpath/TCP packets')
1541 udpn = self.statistics.get_err_counter(
1542 '/err/nat44-in2out-slowpath/UDP packets')
1543 icmpn = self.statistics.get_err_counter(
1544 '/err/nat44-in2out-slowpath/ICMP packets')
1545 totaln = self.statistics.get_err_counter(
1546 '/err/nat44-in2out-slowpath/good in2out packets processed')
1548 pkts = self.create_stream_in(self.pg0, self.pg1)
1549 self.pg0.add_stream(pkts)
1550 self.pg_enable_capture(self.pg_interfaces)
1552 capture = self.pg1.get_capture(len(pkts))
1553 self.verify_capture_out(capture)
1555 err = self.statistics.get_err_counter(
1556 '/err/nat44-in2out-slowpath/TCP packets')
1557 self.assertEqual(err - tcpn, 2)
1558 err = self.statistics.get_err_counter(
1559 '/err/nat44-in2out-slowpath/UDP packets')
1560 self.assertEqual(err - udpn, 1)
1561 err = self.statistics.get_err_counter(
1562 '/err/nat44-in2out-slowpath/ICMP packets')
1563 self.assertEqual(err - icmpn, 1)
1564 err = self.statistics.get_err_counter(
1565 '/err/nat44-in2out-slowpath/good in2out packets processed')
1566 self.assertEqual(err - totaln, 4)
1569 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1570 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1571 icmpn = self.statistics.get_err_counter(
1572 '/err/nat44-out2in/ICMP packets')
1573 totaln = self.statistics.get_err_counter(
1574 '/err/nat44-out2in/good out2in packets processed')
1576 pkts = self.create_stream_out(self.pg1)
1577 self.pg1.add_stream(pkts)
1578 self.pg_enable_capture(self.pg_interfaces)
1580 capture = self.pg0.get_capture(len(pkts))
1581 self.verify_capture_in(capture, self.pg0)
1583 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1584 self.assertEqual(err - tcpn, 2)
1585 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1586 self.assertEqual(err - udpn, 1)
1587 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1588 self.assertEqual(err - icmpn, 1)
1589 err = self.statistics.get_err_counter(
1590 '/err/nat44-out2in/good out2in packets processed')
1591 self.assertEqual(err - totaln, 4)
1593 users = self.statistics.get_counter('/nat44/total-users')
1594 self.assertEqual(users[0][0], 1)
1595 sessions = self.statistics.get_counter('/nat44/total-sessions')
1596 self.assertEqual(sessions[0][0], 3)
1598 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1599 """ NAT44 handling of client packets with TTL=1 """
1601 self.nat44_add_address(self.nat_addr)
1602 flags = self.config_flags.NAT_IS_INSIDE
1603 self.vapi.nat44_interface_add_del_feature(
1604 sw_if_index=self.pg0.sw_if_index,
1605 flags=flags, is_add=1)
1606 self.vapi.nat44_interface_add_del_feature(
1607 sw_if_index=self.pg1.sw_if_index,
1610 # Client side - generate traffic
1611 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1612 self.pg0.add_stream(pkts)
1613 self.pg_enable_capture(self.pg_interfaces)
1616 # Client side - verify ICMP type 11 packets
1617 capture = self.pg0.get_capture(len(pkts))
1618 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1620 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1621 """ NAT44 handling of server packets with TTL=1 """
1623 self.nat44_add_address(self.nat_addr)
1624 flags = self.config_flags.NAT_IS_INSIDE
1625 self.vapi.nat44_interface_add_del_feature(
1626 sw_if_index=self.pg0.sw_if_index,
1627 flags=flags, is_add=1)
1628 self.vapi.nat44_interface_add_del_feature(
1629 sw_if_index=self.pg1.sw_if_index,
1632 # Client side - create sessions
1633 pkts = self.create_stream_in(self.pg0, self.pg1)
1634 self.pg0.add_stream(pkts)
1635 self.pg_enable_capture(self.pg_interfaces)
1638 # Server side - generate traffic
1639 capture = self.pg1.get_capture(len(pkts))
1640 self.verify_capture_out(capture)
1641 pkts = self.create_stream_out(self.pg1, ttl=1)
1642 self.pg1.add_stream(pkts)
1643 self.pg_enable_capture(self.pg_interfaces)
1646 # Server side - verify ICMP type 11 packets
1647 capture = self.pg1.get_capture(len(pkts))
1648 self.verify_capture_out_with_icmp_errors(capture,
1649 src_ip=self.pg1.local_ip4)
1651 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1652 """ NAT44 handling of error responses to client packets with TTL=2 """
1654 self.nat44_add_address(self.nat_addr)
1655 flags = self.config_flags.NAT_IS_INSIDE
1656 self.vapi.nat44_interface_add_del_feature(
1657 sw_if_index=self.pg0.sw_if_index,
1658 flags=flags, is_add=1)
1659 self.vapi.nat44_interface_add_del_feature(
1660 sw_if_index=self.pg1.sw_if_index,
1663 # Client side - generate traffic
1664 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1665 self.pg0.add_stream(pkts)
1666 self.pg_enable_capture(self.pg_interfaces)
1669 # Server side - simulate ICMP type 11 response
1670 capture = self.pg1.get_capture(len(pkts))
1671 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1672 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1673 ICMP(type=11) / packet[IP] for packet in capture]
1674 self.pg1.add_stream(pkts)
1675 self.pg_enable_capture(self.pg_interfaces)
1678 # Client side - verify ICMP type 11 packets
1679 capture = self.pg0.get_capture(len(pkts))
1680 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1682 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1683 """ NAT44 handling of error responses to server packets with TTL=2 """
1685 self.nat44_add_address(self.nat_addr)
1686 flags = self.config_flags.NAT_IS_INSIDE
1687 self.vapi.nat44_interface_add_del_feature(
1688 sw_if_index=self.pg0.sw_if_index,
1689 flags=flags, is_add=1)
1690 self.vapi.nat44_interface_add_del_feature(
1691 sw_if_index=self.pg1.sw_if_index,
1694 # Client side - create sessions
1695 pkts = self.create_stream_in(self.pg0, self.pg1)
1696 self.pg0.add_stream(pkts)
1697 self.pg_enable_capture(self.pg_interfaces)
1700 # Server side - generate traffic
1701 capture = self.pg1.get_capture(len(pkts))
1702 self.verify_capture_out(capture)
1703 pkts = self.create_stream_out(self.pg1, ttl=2)
1704 self.pg1.add_stream(pkts)
1705 self.pg_enable_capture(self.pg_interfaces)
1708 # Client side - simulate ICMP type 11 response
1709 capture = self.pg0.get_capture(len(pkts))
1710 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1711 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1712 ICMP(type=11) / packet[IP] for packet in capture]
1713 self.pg0.add_stream(pkts)
1714 self.pg_enable_capture(self.pg_interfaces)
1717 # Server side - verify ICMP type 11 packets
1718 capture = self.pg1.get_capture(len(pkts))
1719 self.verify_capture_out_with_icmp_errors(capture)
1721 def test_ping_out_interface_from_outside(self):
1722 """ Ping NAT44 out interface from outside network """
1724 self.nat44_add_address(self.nat_addr)
1725 flags = self.config_flags.NAT_IS_INSIDE
1726 self.vapi.nat44_interface_add_del_feature(
1727 sw_if_index=self.pg0.sw_if_index,
1728 flags=flags, is_add=1)
1729 self.vapi.nat44_interface_add_del_feature(
1730 sw_if_index=self.pg1.sw_if_index,
1733 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1734 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1735 ICMP(id=self.icmp_id_out, type='echo-request'))
1737 self.pg1.add_stream(pkts)
1738 self.pg_enable_capture(self.pg_interfaces)
1740 capture = self.pg1.get_capture(len(pkts))
1743 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1744 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1745 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1746 self.assertEqual(packet[ICMP].type, 0) # echo reply
1748 self.logger.error(ppp("Unexpected or invalid packet "
1749 "(outside network):", packet))
1752 def test_ping_internal_host_from_outside(self):
1753 """ Ping internal host from outside network """
1755 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1756 flags = self.config_flags.NAT_IS_INSIDE
1757 self.vapi.nat44_interface_add_del_feature(
1758 sw_if_index=self.pg0.sw_if_index,
1759 flags=flags, is_add=1)
1760 self.vapi.nat44_interface_add_del_feature(
1761 sw_if_index=self.pg1.sw_if_index,
1765 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1766 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1767 ICMP(id=self.icmp_id_out, type='echo-request'))
1768 self.pg1.add_stream(pkt)
1769 self.pg_enable_capture(self.pg_interfaces)
1771 capture = self.pg0.get_capture(1)
1772 self.verify_capture_in(capture, self.pg0)
1773 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1776 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1777 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1778 ICMP(id=self.icmp_id_in, type='echo-reply'))
1779 self.pg0.add_stream(pkt)
1780 self.pg_enable_capture(self.pg_interfaces)
1782 capture = self.pg1.get_capture(1)
1783 self.verify_capture_out(capture, same_port=True)
1784 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1786 def test_forwarding(self):
1787 """ NAT44 forwarding test """
1789 flags = self.config_flags.NAT_IS_INSIDE
1790 self.vapi.nat44_interface_add_del_feature(
1791 sw_if_index=self.pg0.sw_if_index,
1792 flags=flags, is_add=1)
1793 self.vapi.nat44_interface_add_del_feature(
1794 sw_if_index=self.pg1.sw_if_index,
1796 self.vapi.nat44_forwarding_enable_disable(enable=1)
1798 real_ip = self.pg0.remote_ip4
1799 alias_ip = self.nat_addr
1800 flags = self.config_flags.NAT_IS_ADDR_ONLY
1801 self.vapi.nat44_add_del_static_mapping(is_add=1,
1802 local_ip_address=real_ip,
1803 external_ip_address=alias_ip,
1804 external_sw_if_index=0xFFFFFFFF,
1808 # static mapping match
1810 pkts = self.create_stream_out(self.pg1)
1811 self.pg1.add_stream(pkts)
1812 self.pg_enable_capture(self.pg_interfaces)
1814 capture = self.pg0.get_capture(len(pkts))
1815 self.verify_capture_in(capture, self.pg0)
1817 pkts = self.create_stream_in(self.pg0, self.pg1)
1818 self.pg0.add_stream(pkts)
1819 self.pg_enable_capture(self.pg_interfaces)
1821 capture = self.pg1.get_capture(len(pkts))
1822 self.verify_capture_out(capture, same_port=True)
1824 # no static mapping match
1826 host0 = self.pg0.remote_hosts[0]
1827 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1829 pkts = self.create_stream_out(self.pg1,
1830 dst_ip=self.pg0.remote_ip4,
1831 use_inside_ports=True)
1832 self.pg1.add_stream(pkts)
1833 self.pg_enable_capture(self.pg_interfaces)
1835 capture = self.pg0.get_capture(len(pkts))
1836 self.verify_capture_in(capture, self.pg0)
1838 pkts = self.create_stream_in(self.pg0, self.pg1)
1839 self.pg0.add_stream(pkts)
1840 self.pg_enable_capture(self.pg_interfaces)
1842 capture = self.pg1.get_capture(len(pkts))
1843 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1846 self.pg0.remote_hosts[0] = host0
1849 self.vapi.nat44_forwarding_enable_disable(enable=0)
1850 flags = self.config_flags.NAT_IS_ADDR_ONLY
1851 self.vapi.nat44_add_del_static_mapping(
1853 local_ip_address=real_ip,
1854 external_ip_address=alias_ip,
1855 external_sw_if_index=0xFFFFFFFF,
1858 def test_static_in(self):
1859 """ 1:1 NAT initialized from inside network """
1861 nat_ip = "10.0.0.10"
1862 self.tcp_port_out = 6303
1863 self.udp_port_out = 6304
1864 self.icmp_id_out = 6305
1866 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1867 flags = self.config_flags.NAT_IS_INSIDE
1868 self.vapi.nat44_interface_add_del_feature(
1869 sw_if_index=self.pg0.sw_if_index,
1870 flags=flags, is_add=1)
1871 self.vapi.nat44_interface_add_del_feature(
1872 sw_if_index=self.pg1.sw_if_index,
1874 sm = self.vapi.nat44_static_mapping_dump()
1875 self.assertEqual(len(sm), 1)
1876 self.assertEqual(sm[0].tag, '')
1877 self.assertEqual(sm[0].protocol, 0)
1878 self.assertEqual(sm[0].local_port, 0)
1879 self.assertEqual(sm[0].external_port, 0)
1882 pkts = self.create_stream_in(self.pg0, self.pg1)
1883 self.pg0.add_stream(pkts)
1884 self.pg_enable_capture(self.pg_interfaces)
1886 capture = self.pg1.get_capture(len(pkts))
1887 self.verify_capture_out(capture, nat_ip, True)
1890 pkts = self.create_stream_out(self.pg1, nat_ip)
1891 self.pg1.add_stream(pkts)
1892 self.pg_enable_capture(self.pg_interfaces)
1894 capture = self.pg0.get_capture(len(pkts))
1895 self.verify_capture_in(capture, self.pg0)
1897 def test_static_out(self):
1898 """ 1:1 NAT initialized from outside network """
1900 nat_ip = "10.0.0.20"
1901 self.tcp_port_out = 6303
1902 self.udp_port_out = 6304
1903 self.icmp_id_out = 6305
1906 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1907 flags = self.config_flags.NAT_IS_INSIDE
1908 self.vapi.nat44_interface_add_del_feature(
1909 sw_if_index=self.pg0.sw_if_index,
1910 flags=flags, is_add=1)
1911 self.vapi.nat44_interface_add_del_feature(
1912 sw_if_index=self.pg1.sw_if_index,
1914 sm = self.vapi.nat44_static_mapping_dump()
1915 self.assertEqual(len(sm), 1)
1916 self.assertEqual(sm[0].tag, tag)
1919 pkts = self.create_stream_out(self.pg1, nat_ip)
1920 self.pg1.add_stream(pkts)
1921 self.pg_enable_capture(self.pg_interfaces)
1923 capture = self.pg0.get_capture(len(pkts))
1924 self.verify_capture_in(capture, self.pg0)
1927 pkts = self.create_stream_in(self.pg0, self.pg1)
1928 self.pg0.add_stream(pkts)
1929 self.pg_enable_capture(self.pg_interfaces)
1931 capture = self.pg1.get_capture(len(pkts))
1932 self.verify_capture_out(capture, nat_ip, True)
1934 def test_static_with_port_in(self):
1935 """ 1:1 NAPT initialized from inside network """
1937 self.tcp_port_out = 3606
1938 self.udp_port_out = 3607
1939 self.icmp_id_out = 3608
1941 self.nat44_add_address(self.nat_addr)
1942 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1943 self.tcp_port_in, self.tcp_port_out,
1944 proto=IP_PROTOS.tcp)
1945 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1946 self.udp_port_in, self.udp_port_out,
1947 proto=IP_PROTOS.udp)
1948 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1949 self.icmp_id_in, self.icmp_id_out,
1950 proto=IP_PROTOS.icmp)
1951 flags = self.config_flags.NAT_IS_INSIDE
1952 self.vapi.nat44_interface_add_del_feature(
1953 sw_if_index=self.pg0.sw_if_index,
1954 flags=flags, is_add=1)
1955 self.vapi.nat44_interface_add_del_feature(
1956 sw_if_index=self.pg1.sw_if_index,
1960 pkts = self.create_stream_in(self.pg0, self.pg1)
1961 self.pg0.add_stream(pkts)
1962 self.pg_enable_capture(self.pg_interfaces)
1964 capture = self.pg1.get_capture(len(pkts))
1965 self.verify_capture_out(capture)
1968 pkts = self.create_stream_out(self.pg1)
1969 self.pg1.add_stream(pkts)
1970 self.pg_enable_capture(self.pg_interfaces)
1972 capture = self.pg0.get_capture(len(pkts))
1973 self.verify_capture_in(capture, self.pg0)
1975 def test_static_with_port_out(self):
1976 """ 1:1 NAPT initialized from outside network """
1978 self.tcp_port_out = 30606
1979 self.udp_port_out = 30607
1980 self.icmp_id_out = 30608
1982 self.nat44_add_address(self.nat_addr)
1983 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1984 self.tcp_port_in, self.tcp_port_out,
1985 proto=IP_PROTOS.tcp)
1986 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1987 self.udp_port_in, self.udp_port_out,
1988 proto=IP_PROTOS.udp)
1989 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1990 self.icmp_id_in, self.icmp_id_out,
1991 proto=IP_PROTOS.icmp)
1992 flags = self.config_flags.NAT_IS_INSIDE
1993 self.vapi.nat44_interface_add_del_feature(
1994 sw_if_index=self.pg0.sw_if_index,
1995 flags=flags, is_add=1)
1996 self.vapi.nat44_interface_add_del_feature(
1997 sw_if_index=self.pg1.sw_if_index,
2001 pkts = self.create_stream_out(self.pg1)
2002 self.pg1.add_stream(pkts)
2003 self.pg_enable_capture(self.pg_interfaces)
2005 capture = self.pg0.get_capture(len(pkts))
2006 self.verify_capture_in(capture, self.pg0)
2009 pkts = self.create_stream_in(self.pg0, self.pg1)
2010 self.pg0.add_stream(pkts)
2011 self.pg_enable_capture(self.pg_interfaces)
2013 capture = self.pg1.get_capture(len(pkts))
2014 self.verify_capture_out(capture)
2016 def test_static_vrf_aware(self):
2017 """ 1:1 NAT VRF awareness """
2019 nat_ip1 = "10.0.0.30"
2020 nat_ip2 = "10.0.0.40"
2021 self.tcp_port_out = 6303
2022 self.udp_port_out = 6304
2023 self.icmp_id_out = 6305
2025 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2027 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2029 flags = self.config_flags.NAT_IS_INSIDE
2030 self.vapi.nat44_interface_add_del_feature(
2031 sw_if_index=self.pg3.sw_if_index,
2033 self.vapi.nat44_interface_add_del_feature(
2034 sw_if_index=self.pg0.sw_if_index,
2035 flags=flags, is_add=1)
2036 self.vapi.nat44_interface_add_del_feature(
2037 sw_if_index=self.pg4.sw_if_index,
2038 flags=flags, is_add=1)
2040 # inside interface VRF match NAT44 static mapping VRF
2041 pkts = self.create_stream_in(self.pg4, self.pg3)
2042 self.pg4.add_stream(pkts)
2043 self.pg_enable_capture(self.pg_interfaces)
2045 capture = self.pg3.get_capture(len(pkts))
2046 self.verify_capture_out(capture, nat_ip1, True)
2048 # inside interface VRF don't match NAT44 static mapping VRF (packets
2050 pkts = self.create_stream_in(self.pg0, self.pg3)
2051 self.pg0.add_stream(pkts)
2052 self.pg_enable_capture(self.pg_interfaces)
2054 self.pg3.assert_nothing_captured()
2056 def test_dynamic_to_static(self):
2057 """ Switch from dynamic translation to 1:1NAT """
2058 nat_ip = "10.0.0.10"
2059 self.tcp_port_out = 6303
2060 self.udp_port_out = 6304
2061 self.icmp_id_out = 6305
2063 self.nat44_add_address(self.nat_addr)
2064 flags = self.config_flags.NAT_IS_INSIDE
2065 self.vapi.nat44_interface_add_del_feature(
2066 sw_if_index=self.pg0.sw_if_index,
2067 flags=flags, is_add=1)
2068 self.vapi.nat44_interface_add_del_feature(
2069 sw_if_index=self.pg1.sw_if_index,
2073 pkts = self.create_stream_in(self.pg0, self.pg1)
2074 self.pg0.add_stream(pkts)
2075 self.pg_enable_capture(self.pg_interfaces)
2077 capture = self.pg1.get_capture(len(pkts))
2078 self.verify_capture_out(capture)
2081 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2082 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2083 self.assertEqual(len(sessions), 0)
2084 pkts = self.create_stream_in(self.pg0, self.pg1)
2085 self.pg0.add_stream(pkts)
2086 self.pg_enable_capture(self.pg_interfaces)
2088 capture = self.pg1.get_capture(len(pkts))
2089 self.verify_capture_out(capture, nat_ip, True)
2091 def test_identity_nat(self):
2092 """ Identity NAT """
2093 flags = self.config_flags.NAT_IS_ADDR_ONLY
2094 self.vapi.nat44_add_del_identity_mapping(
2095 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2096 flags=flags, is_add=1)
2097 flags = self.config_flags.NAT_IS_INSIDE
2098 self.vapi.nat44_interface_add_del_feature(
2099 sw_if_index=self.pg0.sw_if_index,
2100 flags=flags, is_add=1)
2101 self.vapi.nat44_interface_add_del_feature(
2102 sw_if_index=self.pg1.sw_if_index,
2105 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2106 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2107 TCP(sport=12345, dport=56789))
2108 self.pg1.add_stream(p)
2109 self.pg_enable_capture(self.pg_interfaces)
2111 capture = self.pg0.get_capture(1)
2116 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2117 self.assertEqual(ip.src, self.pg1.remote_ip4)
2118 self.assertEqual(tcp.dport, 56789)
2119 self.assertEqual(tcp.sport, 12345)
2120 self.assert_packet_checksums_valid(p)
2122 self.logger.error(ppp("Unexpected or invalid packet:", p))
2125 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2126 self.assertEqual(len(sessions), 0)
2127 flags = self.config_flags.NAT_IS_ADDR_ONLY
2128 self.vapi.nat44_add_del_identity_mapping(
2129 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2130 flags=flags, vrf_id=1, is_add=1)
2131 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2132 self.assertEqual(len(identity_mappings), 2)
2134 def test_multiple_inside_interfaces(self):
2135 """ NAT44 multiple non-overlapping address space inside interfaces """
2137 self.nat44_add_address(self.nat_addr)
2138 flags = self.config_flags.NAT_IS_INSIDE
2139 self.vapi.nat44_interface_add_del_feature(
2140 sw_if_index=self.pg0.sw_if_index,
2141 flags=flags, is_add=1)
2142 self.vapi.nat44_interface_add_del_feature(
2143 sw_if_index=self.pg1.sw_if_index,
2144 flags=flags, is_add=1)
2145 self.vapi.nat44_interface_add_del_feature(
2146 sw_if_index=self.pg3.sw_if_index,
2149 # between two NAT44 inside interfaces (no translation)
2150 pkts = self.create_stream_in(self.pg0, self.pg1)
2151 self.pg0.add_stream(pkts)
2152 self.pg_enable_capture(self.pg_interfaces)
2154 capture = self.pg1.get_capture(len(pkts))
2155 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2157 # from NAT44 inside to interface without NAT44 feature (no translation)
2158 pkts = self.create_stream_in(self.pg0, self.pg2)
2159 self.pg0.add_stream(pkts)
2160 self.pg_enable_capture(self.pg_interfaces)
2162 capture = self.pg2.get_capture(len(pkts))
2163 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2165 # in2out 1st interface
2166 pkts = self.create_stream_in(self.pg0, self.pg3)
2167 self.pg0.add_stream(pkts)
2168 self.pg_enable_capture(self.pg_interfaces)
2170 capture = self.pg3.get_capture(len(pkts))
2171 self.verify_capture_out(capture)
2173 # out2in 1st interface
2174 pkts = self.create_stream_out(self.pg3)
2175 self.pg3.add_stream(pkts)
2176 self.pg_enable_capture(self.pg_interfaces)
2178 capture = self.pg0.get_capture(len(pkts))
2179 self.verify_capture_in(capture, self.pg0)
2181 # in2out 2nd interface
2182 pkts = self.create_stream_in(self.pg1, self.pg3)
2183 self.pg1.add_stream(pkts)
2184 self.pg_enable_capture(self.pg_interfaces)
2186 capture = self.pg3.get_capture(len(pkts))
2187 self.verify_capture_out(capture)
2189 # out2in 2nd interface
2190 pkts = self.create_stream_out(self.pg3)
2191 self.pg3.add_stream(pkts)
2192 self.pg_enable_capture(self.pg_interfaces)
2194 capture = self.pg1.get_capture(len(pkts))
2195 self.verify_capture_in(capture, self.pg1)
2197 def test_inside_overlapping_interfaces(self):
2198 """ NAT44 multiple inside interfaces with overlapping address space """
2200 static_nat_ip = "10.0.0.10"
2201 self.nat44_add_address(self.nat_addr)
2202 flags = self.config_flags.NAT_IS_INSIDE
2203 self.vapi.nat44_interface_add_del_feature(
2204 sw_if_index=self.pg3.sw_if_index,
2206 self.vapi.nat44_interface_add_del_feature(
2207 sw_if_index=self.pg4.sw_if_index,
2208 flags=flags, is_add=1)
2209 self.vapi.nat44_interface_add_del_feature(
2210 sw_if_index=self.pg5.sw_if_index,
2211 flags=flags, is_add=1)
2212 self.vapi.nat44_interface_add_del_feature(
2213 sw_if_index=self.pg6.sw_if_index,
2214 flags=flags, is_add=1)
2215 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2218 # between NAT44 inside interfaces with same VRF (no translation)
2219 pkts = self.create_stream_in(self.pg4, self.pg5)
2220 self.pg4.add_stream(pkts)
2221 self.pg_enable_capture(self.pg_interfaces)
2223 capture = self.pg5.get_capture(len(pkts))
2224 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2226 # between NAT44 inside interfaces with different VRF (hairpinning)
2227 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2228 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2229 TCP(sport=1234, dport=5678))
2230 self.pg4.add_stream(p)
2231 self.pg_enable_capture(self.pg_interfaces)
2233 capture = self.pg6.get_capture(1)
2238 self.assertEqual(ip.src, self.nat_addr)
2239 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2240 self.assertNotEqual(tcp.sport, 1234)
2241 self.assertEqual(tcp.dport, 5678)
2243 self.logger.error(ppp("Unexpected or invalid packet:", p))
2246 # in2out 1st interface
2247 pkts = self.create_stream_in(self.pg4, self.pg3)
2248 self.pg4.add_stream(pkts)
2249 self.pg_enable_capture(self.pg_interfaces)
2251 capture = self.pg3.get_capture(len(pkts))
2252 self.verify_capture_out(capture)
2254 # out2in 1st interface
2255 pkts = self.create_stream_out(self.pg3)
2256 self.pg3.add_stream(pkts)
2257 self.pg_enable_capture(self.pg_interfaces)
2259 capture = self.pg4.get_capture(len(pkts))
2260 self.verify_capture_in(capture, self.pg4)
2262 # in2out 2nd interface
2263 pkts = self.create_stream_in(self.pg5, self.pg3)
2264 self.pg5.add_stream(pkts)
2265 self.pg_enable_capture(self.pg_interfaces)
2267 capture = self.pg3.get_capture(len(pkts))
2268 self.verify_capture_out(capture)
2270 # out2in 2nd interface
2271 pkts = self.create_stream_out(self.pg3)
2272 self.pg3.add_stream(pkts)
2273 self.pg_enable_capture(self.pg_interfaces)
2275 capture = self.pg5.get_capture(len(pkts))
2276 self.verify_capture_in(capture, self.pg5)
2279 addresses = self.vapi.nat44_address_dump()
2280 self.assertEqual(len(addresses), 1)
2281 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2282 self.assertEqual(len(sessions), 3)
2283 for session in sessions:
2284 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2285 self.assertEqual(str(session.inside_ip_address),
2286 self.pg5.remote_ip4)
2287 self.assertEqual(session.outside_ip_address,
2288 addresses[0].ip_address)
2289 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2290 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2291 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2292 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2293 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2294 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2295 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2296 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2297 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2299 # in2out 3rd interface
2300 pkts = self.create_stream_in(self.pg6, self.pg3)
2301 self.pg6.add_stream(pkts)
2302 self.pg_enable_capture(self.pg_interfaces)
2304 capture = self.pg3.get_capture(len(pkts))
2305 self.verify_capture_out(capture, static_nat_ip, True)
2307 # out2in 3rd interface
2308 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2309 self.pg3.add_stream(pkts)
2310 self.pg_enable_capture(self.pg_interfaces)
2312 capture = self.pg6.get_capture(len(pkts))
2313 self.verify_capture_in(capture, self.pg6)
2315 # general user and session dump verifications
2316 users = self.vapi.nat44_user_dump()
2317 self.assertGreaterEqual(len(users), 3)
2318 addresses = self.vapi.nat44_address_dump()
2319 self.assertEqual(len(addresses), 1)
2321 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2323 for session in sessions:
2324 self.assertEqual(user.ip_address, session.inside_ip_address)
2325 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2326 self.assertTrue(session.protocol in
2327 [IP_PROTOS.tcp, IP_PROTOS.udp,
2329 self.assertFalse(session.flags &
2330 self.config_flags.NAT_IS_EXT_HOST_VALID)
2333 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2334 self.assertGreaterEqual(len(sessions), 4)
2335 for session in sessions:
2336 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2337 self.assertEqual(str(session.inside_ip_address),
2338 self.pg4.remote_ip4)
2339 self.assertEqual(session.outside_ip_address,
2340 addresses[0].ip_address)
2343 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2344 self.assertGreaterEqual(len(sessions), 3)
2345 for session in sessions:
2346 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2347 self.assertEqual(str(session.inside_ip_address),
2348 self.pg6.remote_ip4)
2349 self.assertEqual(str(session.outside_ip_address),
2351 self.assertTrue(session.inside_port in
2352 [self.tcp_port_in, self.udp_port_in,
2355 def test_hairpinning(self):
2356 """ NAT44 hairpinning - 1:1 NAPT """
2358 host = self.pg0.remote_hosts[0]
2359 server = self.pg0.remote_hosts[1]
2362 server_in_port = 5678
2363 server_out_port = 8765
2365 self.nat44_add_address(self.nat_addr)
2366 flags = self.config_flags.NAT_IS_INSIDE
2367 self.vapi.nat44_interface_add_del_feature(
2368 sw_if_index=self.pg0.sw_if_index,
2369 flags=flags, is_add=1)
2370 self.vapi.nat44_interface_add_del_feature(
2371 sw_if_index=self.pg1.sw_if_index,
2374 # add static mapping for server
2375 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2376 server_in_port, server_out_port,
2377 proto=IP_PROTOS.tcp)
2379 # send packet from host to server
2380 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2381 IP(src=host.ip4, dst=self.nat_addr) /
2382 TCP(sport=host_in_port, dport=server_out_port))
2383 self.pg0.add_stream(p)
2384 self.pg_enable_capture(self.pg_interfaces)
2386 capture = self.pg0.get_capture(1)
2391 self.assertEqual(ip.src, self.nat_addr)
2392 self.assertEqual(ip.dst, server.ip4)
2393 self.assertNotEqual(tcp.sport, host_in_port)
2394 self.assertEqual(tcp.dport, server_in_port)
2395 self.assert_packet_checksums_valid(p)
2396 host_out_port = tcp.sport
2398 self.logger.error(ppp("Unexpected or invalid packet:", p))
2401 # send reply from server to host
2402 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2403 IP(src=server.ip4, dst=self.nat_addr) /
2404 TCP(sport=server_in_port, dport=host_out_port))
2405 self.pg0.add_stream(p)
2406 self.pg_enable_capture(self.pg_interfaces)
2408 capture = self.pg0.get_capture(1)
2413 self.assertEqual(ip.src, self.nat_addr)
2414 self.assertEqual(ip.dst, host.ip4)
2415 self.assertEqual(tcp.sport, server_out_port)
2416 self.assertEqual(tcp.dport, host_in_port)
2417 self.assert_packet_checksums_valid(p)
2419 self.logger.error(ppp("Unexpected or invalid packet:", p))
2422 def test_hairpinning2(self):
2423 """ NAT44 hairpinning - 1:1 NAT"""
2425 server1_nat_ip = "10.0.0.10"
2426 server2_nat_ip = "10.0.0.11"
2427 host = self.pg0.remote_hosts[0]
2428 server1 = self.pg0.remote_hosts[1]
2429 server2 = self.pg0.remote_hosts[2]
2430 server_tcp_port = 22
2431 server_udp_port = 20
2433 self.nat44_add_address(self.nat_addr)
2434 flags = self.config_flags.NAT_IS_INSIDE
2435 self.vapi.nat44_interface_add_del_feature(
2436 sw_if_index=self.pg0.sw_if_index,
2437 flags=flags, is_add=1)
2438 self.vapi.nat44_interface_add_del_feature(
2439 sw_if_index=self.pg1.sw_if_index,
2442 # add static mapping for servers
2443 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2444 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2449 IP(src=host.ip4, dst=server1_nat_ip) /
2450 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2452 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2453 IP(src=host.ip4, dst=server1_nat_ip) /
2454 UDP(sport=self.udp_port_in, dport=server_udp_port))
2456 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2457 IP(src=host.ip4, dst=server1_nat_ip) /
2458 ICMP(id=self.icmp_id_in, type='echo-request'))
2460 self.pg0.add_stream(pkts)
2461 self.pg_enable_capture(self.pg_interfaces)
2463 capture = self.pg0.get_capture(len(pkts))
2464 for packet in capture:
2466 self.assertEqual(packet[IP].src, self.nat_addr)
2467 self.assertEqual(packet[IP].dst, server1.ip4)
2468 if packet.haslayer(TCP):
2469 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2470 self.assertEqual(packet[TCP].dport, server_tcp_port)
2471 self.tcp_port_out = packet[TCP].sport
2472 self.assert_packet_checksums_valid(packet)
2473 elif packet.haslayer(UDP):
2474 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2475 self.assertEqual(packet[UDP].dport, server_udp_port)
2476 self.udp_port_out = packet[UDP].sport
2478 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2479 self.icmp_id_out = packet[ICMP].id
2481 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2486 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2487 IP(src=server1.ip4, dst=self.nat_addr) /
2488 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2491 IP(src=server1.ip4, dst=self.nat_addr) /
2492 UDP(sport=server_udp_port, dport=self.udp_port_out))
2494 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2495 IP(src=server1.ip4, dst=self.nat_addr) /
2496 ICMP(id=self.icmp_id_out, type='echo-reply'))
2498 self.pg0.add_stream(pkts)
2499 self.pg_enable_capture(self.pg_interfaces)
2501 capture = self.pg0.get_capture(len(pkts))
2502 for packet in capture:
2504 self.assertEqual(packet[IP].src, server1_nat_ip)
2505 self.assertEqual(packet[IP].dst, host.ip4)
2506 if packet.haslayer(TCP):
2507 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2508 self.assertEqual(packet[TCP].sport, server_tcp_port)
2509 self.assert_packet_checksums_valid(packet)
2510 elif packet.haslayer(UDP):
2511 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2512 self.assertEqual(packet[UDP].sport, server_udp_port)
2514 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2516 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2519 # server2 to server1
2521 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2522 IP(src=server2.ip4, dst=server1_nat_ip) /
2523 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2525 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2526 IP(src=server2.ip4, dst=server1_nat_ip) /
2527 UDP(sport=self.udp_port_in, dport=server_udp_port))
2529 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2530 IP(src=server2.ip4, dst=server1_nat_ip) /
2531 ICMP(id=self.icmp_id_in, type='echo-request'))
2533 self.pg0.add_stream(pkts)
2534 self.pg_enable_capture(self.pg_interfaces)
2536 capture = self.pg0.get_capture(len(pkts))
2537 for packet in capture:
2539 self.assertEqual(packet[IP].src, server2_nat_ip)
2540 self.assertEqual(packet[IP].dst, server1.ip4)
2541 if packet.haslayer(TCP):
2542 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2543 self.assertEqual(packet[TCP].dport, server_tcp_port)
2544 self.tcp_port_out = packet[TCP].sport
2545 self.assert_packet_checksums_valid(packet)
2546 elif packet.haslayer(UDP):
2547 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2548 self.assertEqual(packet[UDP].dport, server_udp_port)
2549 self.udp_port_out = packet[UDP].sport
2551 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2552 self.icmp_id_out = packet[ICMP].id
2554 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2557 # server1 to server2
2559 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2560 IP(src=server1.ip4, dst=server2_nat_ip) /
2561 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2563 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2564 IP(src=server1.ip4, dst=server2_nat_ip) /
2565 UDP(sport=server_udp_port, dport=self.udp_port_out))
2567 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2568 IP(src=server1.ip4, dst=server2_nat_ip) /
2569 ICMP(id=self.icmp_id_out, type='echo-reply'))
2571 self.pg0.add_stream(pkts)
2572 self.pg_enable_capture(self.pg_interfaces)
2574 capture = self.pg0.get_capture(len(pkts))
2575 for packet in capture:
2577 self.assertEqual(packet[IP].src, server1_nat_ip)
2578 self.assertEqual(packet[IP].dst, server2.ip4)
2579 if packet.haslayer(TCP):
2580 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2581 self.assertEqual(packet[TCP].sport, server_tcp_port)
2582 self.assert_packet_checksums_valid(packet)
2583 elif packet.haslayer(UDP):
2584 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2585 self.assertEqual(packet[UDP].sport, server_udp_port)
2587 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2589 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2592 def test_interface_addr(self):
2593 """ Acquire NAT44 addresses from interface """
2594 self.vapi.nat44_add_del_interface_addr(
2596 sw_if_index=self.pg7.sw_if_index)
2598 # no address in NAT pool
2599 addresses = self.vapi.nat44_address_dump()
2600 self.assertEqual(0, len(addresses))
2602 # configure interface address and check NAT address pool
2603 self.pg7.config_ip4()
2604 addresses = self.vapi.nat44_address_dump()
2605 self.assertEqual(1, len(addresses))
2606 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2608 # remove interface address and check NAT address pool
2609 self.pg7.unconfig_ip4()
2610 addresses = self.vapi.nat44_address_dump()
2611 self.assertEqual(0, len(addresses))
2613 def test_interface_addr_static_mapping(self):
2614 """ Static mapping with addresses from interface """
2617 self.vapi.nat44_add_del_interface_addr(
2619 sw_if_index=self.pg7.sw_if_index)
2620 self.nat44_add_static_mapping(
2622 external_sw_if_index=self.pg7.sw_if_index,
2625 # static mappings with external interface
2626 static_mappings = self.vapi.nat44_static_mapping_dump()
2627 self.assertEqual(1, len(static_mappings))
2628 self.assertEqual(self.pg7.sw_if_index,
2629 static_mappings[0].external_sw_if_index)
2630 self.assertEqual(static_mappings[0].tag, tag)
2632 # configure interface address and check static mappings
2633 self.pg7.config_ip4()
2634 static_mappings = self.vapi.nat44_static_mapping_dump()
2635 self.assertEqual(2, len(static_mappings))
2637 for sm in static_mappings:
2638 if sm.external_sw_if_index == 0xFFFFFFFF:
2639 self.assertEqual(str(sm.external_ip_address),
2641 self.assertEqual(sm.tag, tag)
2643 self.assertTrue(resolved)
2645 # remove interface address and check static mappings
2646 self.pg7.unconfig_ip4()
2647 static_mappings = self.vapi.nat44_static_mapping_dump()
2648 self.assertEqual(1, len(static_mappings))
2649 self.assertEqual(self.pg7.sw_if_index,
2650 static_mappings[0].external_sw_if_index)
2651 self.assertEqual(static_mappings[0].tag, tag)
2653 # configure interface address again and check static mappings
2654 self.pg7.config_ip4()
2655 static_mappings = self.vapi.nat44_static_mapping_dump()
2656 self.assertEqual(2, len(static_mappings))
2658 for sm in static_mappings:
2659 if sm.external_sw_if_index == 0xFFFFFFFF:
2660 self.assertEqual(str(sm.external_ip_address),
2662 self.assertEqual(sm.tag, tag)
2664 self.assertTrue(resolved)
2666 # remove static mapping
2667 self.nat44_add_static_mapping(
2669 external_sw_if_index=self.pg7.sw_if_index,
2672 static_mappings = self.vapi.nat44_static_mapping_dump()
2673 self.assertEqual(0, len(static_mappings))
2675 def test_interface_addr_identity_nat(self):
2676 """ Identity NAT with addresses from interface """
2679 self.vapi.nat44_add_del_interface_addr(
2681 sw_if_index=self.pg7.sw_if_index)
2682 self.vapi.nat44_add_del_identity_mapping(
2684 sw_if_index=self.pg7.sw_if_index,
2686 protocol=IP_PROTOS.tcp,
2689 # identity mappings with external interface
2690 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2691 self.assertEqual(1, len(identity_mappings))
2692 self.assertEqual(self.pg7.sw_if_index,
2693 identity_mappings[0].sw_if_index)
2695 # configure interface address and check identity mappings
2696 self.pg7.config_ip4()
2697 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2699 self.assertEqual(2, len(identity_mappings))
2700 for sm in identity_mappings:
2701 if sm.sw_if_index == 0xFFFFFFFF:
2702 self.assertEqual(str(identity_mappings[0].ip_address),
2704 self.assertEqual(port, identity_mappings[0].port)
2705 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2707 self.assertTrue(resolved)
2709 # remove interface address and check identity mappings
2710 self.pg7.unconfig_ip4()
2711 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2712 self.assertEqual(1, len(identity_mappings))
2713 self.assertEqual(self.pg7.sw_if_index,
2714 identity_mappings[0].sw_if_index)
2716 def test_ipfix_nat44_sess(self):
2717 """ IPFIX logging NAT44 session created/deleted """
2718 self.ipfix_domain_id = 10
2719 self.ipfix_src_port = 20202
2720 collector_port = 30303
2721 bind_layers(UDP, IPFIX, dport=30303)
2722 self.nat44_add_address(self.nat_addr)
2723 flags = self.config_flags.NAT_IS_INSIDE
2724 self.vapi.nat44_interface_add_del_feature(
2725 sw_if_index=self.pg0.sw_if_index,
2726 flags=flags, is_add=1)
2727 self.vapi.nat44_interface_add_del_feature(
2728 sw_if_index=self.pg1.sw_if_index,
2730 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2731 src_address=self.pg3.local_ip4,
2733 template_interval=10,
2734 collector_port=collector_port)
2735 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2736 src_port=self.ipfix_src_port,
2739 pkts = self.create_stream_in(self.pg0, self.pg1)
2740 self.pg0.add_stream(pkts)
2741 self.pg_enable_capture(self.pg_interfaces)
2743 capture = self.pg1.get_capture(len(pkts))
2744 self.verify_capture_out(capture)
2745 self.nat44_add_address(self.nat_addr, is_add=0)
2746 self.vapi.ipfix_flush()
2747 capture = self.pg3.get_capture(9)
2748 ipfix = IPFIXDecoder()
2749 # first load template
2751 self.assertTrue(p.haslayer(IPFIX))
2752 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2753 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2754 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2755 self.assertEqual(p[UDP].dport, collector_port)
2756 self.assertEqual(p[IPFIX].observationDomainID,
2757 self.ipfix_domain_id)
2758 if p.haslayer(Template):
2759 ipfix.add_template(p.getlayer(Template))
2760 # verify events in data set
2762 if p.haslayer(Data):
2763 data = ipfix.decode_data_set(p.getlayer(Set))
2764 self.verify_ipfix_nat44_ses(data)
2766 def test_ipfix_addr_exhausted(self):
2767 """ IPFIX logging NAT addresses exhausted """
2768 flags = self.config_flags.NAT_IS_INSIDE
2769 self.vapi.nat44_interface_add_del_feature(
2770 sw_if_index=self.pg0.sw_if_index,
2771 flags=flags, is_add=1)
2772 self.vapi.nat44_interface_add_del_feature(
2773 sw_if_index=self.pg1.sw_if_index,
2775 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2776 src_address=self.pg3.local_ip4,
2778 template_interval=10)
2779 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2780 src_port=self.ipfix_src_port,
2783 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2784 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2786 self.pg0.add_stream(p)
2787 self.pg_enable_capture(self.pg_interfaces)
2789 self.pg1.assert_nothing_captured()
2791 self.vapi.ipfix_flush()
2792 capture = self.pg3.get_capture(9)
2793 ipfix = IPFIXDecoder()
2794 # first load template
2796 self.assertTrue(p.haslayer(IPFIX))
2797 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2798 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2799 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2800 self.assertEqual(p[UDP].dport, 4739)
2801 self.assertEqual(p[IPFIX].observationDomainID,
2802 self.ipfix_domain_id)
2803 if p.haslayer(Template):
2804 ipfix.add_template(p.getlayer(Template))
2805 # verify events in data set
2807 if p.haslayer(Data):
2808 data = ipfix.decode_data_set(p.getlayer(Set))
2809 self.verify_ipfix_addr_exhausted(data)
2811 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2812 def test_ipfix_max_sessions(self):
2813 """ IPFIX logging maximum session entries exceeded """
2814 self.nat44_add_address(self.nat_addr)
2815 flags = self.config_flags.NAT_IS_INSIDE
2816 self.vapi.nat44_interface_add_del_feature(
2817 sw_if_index=self.pg0.sw_if_index,
2818 flags=flags, is_add=1)
2819 self.vapi.nat44_interface_add_del_feature(
2820 sw_if_index=self.pg1.sw_if_index,
2823 nat44_config = self.vapi.nat_show_config()
2824 max_sessions = 10 * nat44_config.translation_buckets
2827 for i in range(0, max_sessions):
2828 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2829 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2830 IP(src=src, dst=self.pg1.remote_ip4) /
2833 self.pg0.add_stream(pkts)
2834 self.pg_enable_capture(self.pg_interfaces)
2837 self.pg1.get_capture(max_sessions)
2838 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2839 src_address=self.pg3.local_ip4,
2841 template_interval=10)
2842 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2843 src_port=self.ipfix_src_port,
2846 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2847 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2849 self.pg0.add_stream(p)
2850 self.pg_enable_capture(self.pg_interfaces)
2852 self.pg1.assert_nothing_captured()
2854 self.vapi.ipfix_flush()
2855 capture = self.pg3.get_capture(9)
2856 ipfix = IPFIXDecoder()
2857 # first load template
2859 self.assertTrue(p.haslayer(IPFIX))
2860 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2861 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2862 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2863 self.assertEqual(p[UDP].dport, 4739)
2864 self.assertEqual(p[IPFIX].observationDomainID,
2865 self.ipfix_domain_id)
2866 if p.haslayer(Template):
2867 ipfix.add_template(p.getlayer(Template))
2868 # verify events in data set
2870 if p.haslayer(Data):
2871 data = ipfix.decode_data_set(p.getlayer(Set))
2872 self.verify_ipfix_max_sessions(data, max_sessions)
2874 def test_syslog_apmap(self):
2875 """ Test syslog address and port mapping creation and deletion """
2876 self.vapi.syslog_set_filter(
2877 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2878 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2879 self.nat44_add_address(self.nat_addr)
2880 flags = self.config_flags.NAT_IS_INSIDE
2881 self.vapi.nat44_interface_add_del_feature(
2882 sw_if_index=self.pg0.sw_if_index,
2883 flags=flags, is_add=1)
2884 self.vapi.nat44_interface_add_del_feature(
2885 sw_if_index=self.pg1.sw_if_index,
2888 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2889 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2890 TCP(sport=self.tcp_port_in, dport=20))
2891 self.pg0.add_stream(p)
2892 self.pg_enable_capture(self.pg_interfaces)
2894 capture = self.pg1.get_capture(1)
2895 self.tcp_port_out = capture[0][TCP].sport
2896 capture = self.pg3.get_capture(1)
2897 self.verify_syslog_apmap(capture[0][Raw].load)
2899 self.pg_enable_capture(self.pg_interfaces)
2901 self.nat44_add_address(self.nat_addr, is_add=0)
2902 capture = self.pg3.get_capture(1)
2903 self.verify_syslog_apmap(capture[0][Raw].load, False)
2905 def test_pool_addr_fib(self):
2906 """ NAT44 add pool addresses to FIB """
2907 static_addr = '10.0.0.10'
2908 self.nat44_add_address(self.nat_addr)
2909 flags = self.config_flags.NAT_IS_INSIDE
2910 self.vapi.nat44_interface_add_del_feature(
2911 sw_if_index=self.pg0.sw_if_index,
2912 flags=flags, is_add=1)
2913 self.vapi.nat44_interface_add_del_feature(
2914 sw_if_index=self.pg1.sw_if_index,
2916 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2919 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2920 ARP(op=ARP.who_has, pdst=self.nat_addr,
2921 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2922 self.pg1.add_stream(p)
2923 self.pg_enable_capture(self.pg_interfaces)
2925 capture = self.pg1.get_capture(1)
2926 self.assertTrue(capture[0].haslayer(ARP))
2927 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2930 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2931 ARP(op=ARP.who_has, pdst=static_addr,
2932 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2933 self.pg1.add_stream(p)
2934 self.pg_enable_capture(self.pg_interfaces)
2936 capture = self.pg1.get_capture(1)
2937 self.assertTrue(capture[0].haslayer(ARP))
2938 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2940 # send ARP to non-NAT44 interface
2941 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2942 ARP(op=ARP.who_has, pdst=self.nat_addr,
2943 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2944 self.pg2.add_stream(p)
2945 self.pg_enable_capture(self.pg_interfaces)
2947 self.pg1.assert_nothing_captured()
2949 # remove addresses and verify
2950 self.nat44_add_address(self.nat_addr, is_add=0)
2951 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2954 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2955 ARP(op=ARP.who_has, pdst=self.nat_addr,
2956 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2957 self.pg1.add_stream(p)
2958 self.pg_enable_capture(self.pg_interfaces)
2960 self.pg1.assert_nothing_captured()
2962 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2963 ARP(op=ARP.who_has, pdst=static_addr,
2964 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2965 self.pg1.add_stream(p)
2966 self.pg_enable_capture(self.pg_interfaces)
2968 self.pg1.assert_nothing_captured()
2970 def test_vrf_mode(self):
2971 """ NAT44 tenant VRF aware address pool mode """
2975 nat_ip1 = "10.0.0.10"
2976 nat_ip2 = "10.0.0.11"
2978 self.pg0.unconfig_ip4()
2979 self.pg1.unconfig_ip4()
2980 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2981 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2982 self.pg0.set_table_ip4(vrf_id1)
2983 self.pg1.set_table_ip4(vrf_id2)
2984 self.pg0.config_ip4()
2985 self.pg1.config_ip4()
2986 self.pg0.resolve_arp()
2987 self.pg1.resolve_arp()
2989 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2990 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2991 flags = self.config_flags.NAT_IS_INSIDE
2992 self.vapi.nat44_interface_add_del_feature(
2993 sw_if_index=self.pg0.sw_if_index,
2994 flags=flags, is_add=1)
2995 self.vapi.nat44_interface_add_del_feature(
2996 sw_if_index=self.pg1.sw_if_index,
2997 flags=flags, is_add=1)
2998 self.vapi.nat44_interface_add_del_feature(
2999 sw_if_index=self.pg2.sw_if_index,
3004 pkts = self.create_stream_in(self.pg0, self.pg2)
3005 self.pg0.add_stream(pkts)
3006 self.pg_enable_capture(self.pg_interfaces)
3008 capture = self.pg2.get_capture(len(pkts))
3009 self.verify_capture_out(capture, nat_ip1)
3012 pkts = self.create_stream_in(self.pg1, self.pg2)
3013 self.pg1.add_stream(pkts)
3014 self.pg_enable_capture(self.pg_interfaces)
3016 capture = self.pg2.get_capture(len(pkts))
3017 self.verify_capture_out(capture, nat_ip2)
3020 self.pg0.unconfig_ip4()
3021 self.pg1.unconfig_ip4()
3022 self.pg0.set_table_ip4(0)
3023 self.pg1.set_table_ip4(0)
3024 self.pg0.config_ip4()
3025 self.pg1.config_ip4()
3026 self.pg0.resolve_arp()
3027 self.pg1.resolve_arp()
3028 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3029 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3031 def test_vrf_feature_independent(self):
3032 """ NAT44 tenant VRF independent address pool mode """
3034 nat_ip1 = "10.0.0.10"
3035 nat_ip2 = "10.0.0.11"
3037 self.nat44_add_address(nat_ip1)
3038 self.nat44_add_address(nat_ip2, vrf_id=99)
3039 flags = self.config_flags.NAT_IS_INSIDE
3040 self.vapi.nat44_interface_add_del_feature(
3041 sw_if_index=self.pg0.sw_if_index,
3042 flags=flags, is_add=1)
3043 self.vapi.nat44_interface_add_del_feature(
3044 sw_if_index=self.pg1.sw_if_index,
3045 flags=flags, is_add=1)
3046 self.vapi.nat44_interface_add_del_feature(
3047 sw_if_index=self.pg2.sw_if_index,
3051 pkts = self.create_stream_in(self.pg0, self.pg2)
3052 self.pg0.add_stream(pkts)
3053 self.pg_enable_capture(self.pg_interfaces)
3055 capture = self.pg2.get_capture(len(pkts))
3056 self.verify_capture_out(capture, nat_ip1)
3059 pkts = self.create_stream_in(self.pg1, self.pg2)
3060 self.pg1.add_stream(pkts)
3061 self.pg_enable_capture(self.pg_interfaces)
3063 capture = self.pg2.get_capture(len(pkts))
3064 self.verify_capture_out(capture, nat_ip1)
3066 def create_routes_and_neigbors(self):
3067 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3068 [VppRoutePath(self.pg7.remote_ip4,
3069 self.pg7.sw_if_index)])
3070 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3071 [VppRoutePath(self.pg8.remote_ip4,
3072 self.pg8.sw_if_index)])
3076 n1 = VppNeighbor(self,
3077 self.pg7.sw_if_index,
3078 self.pg7.remote_mac,
3079 self.pg7.remote_ip4,
3081 n2 = VppNeighbor(self,
3082 self.pg8.sw_if_index,
3083 self.pg8.remote_mac,
3084 self.pg8.remote_ip4,
3089 def test_dynamic_ipless_interfaces(self):
3090 """ NAT44 interfaces without configured IP address """
3091 self.create_routes_and_neigbors()
3092 self.nat44_add_address(self.nat_addr)
3093 flags = self.config_flags.NAT_IS_INSIDE
3094 self.vapi.nat44_interface_add_del_feature(
3095 sw_if_index=self.pg7.sw_if_index,
3096 flags=flags, is_add=1)
3097 self.vapi.nat44_interface_add_del_feature(
3098 sw_if_index=self.pg8.sw_if_index,
3102 pkts = self.create_stream_in(self.pg7, self.pg8)
3103 self.pg7.add_stream(pkts)
3104 self.pg_enable_capture(self.pg_interfaces)
3106 capture = self.pg8.get_capture(len(pkts))
3107 self.verify_capture_out(capture)
3110 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3111 self.pg8.add_stream(pkts)
3112 self.pg_enable_capture(self.pg_interfaces)
3114 capture = self.pg7.get_capture(len(pkts))
3115 self.verify_capture_in(capture, self.pg7)
3117 def test_static_ipless_interfaces(self):
3118 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3120 self.create_routes_and_neigbors()
3121 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3122 flags = self.config_flags.NAT_IS_INSIDE
3123 self.vapi.nat44_interface_add_del_feature(
3124 sw_if_index=self.pg7.sw_if_index,
3125 flags=flags, is_add=1)
3126 self.vapi.nat44_interface_add_del_feature(
3127 sw_if_index=self.pg8.sw_if_index,
3131 pkts = self.create_stream_out(self.pg8)
3132 self.pg8.add_stream(pkts)
3133 self.pg_enable_capture(self.pg_interfaces)
3135 capture = self.pg7.get_capture(len(pkts))
3136 self.verify_capture_in(capture, self.pg7)
3139 pkts = self.create_stream_in(self.pg7, self.pg8)
3140 self.pg7.add_stream(pkts)
3141 self.pg_enable_capture(self.pg_interfaces)
3143 capture = self.pg8.get_capture(len(pkts))
3144 self.verify_capture_out(capture, self.nat_addr, True)
3146 def test_static_with_port_ipless_interfaces(self):
3147 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3149 self.tcp_port_out = 30606
3150 self.udp_port_out = 30607
3151 self.icmp_id_out = 30608
3153 self.create_routes_and_neigbors()
3154 self.nat44_add_address(self.nat_addr)
3155 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3156 self.tcp_port_in, self.tcp_port_out,
3157 proto=IP_PROTOS.tcp)
3158 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3159 self.udp_port_in, self.udp_port_out,
3160 proto=IP_PROTOS.udp)
3161 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3162 self.icmp_id_in, self.icmp_id_out,
3163 proto=IP_PROTOS.icmp)
3164 flags = self.config_flags.NAT_IS_INSIDE
3165 self.vapi.nat44_interface_add_del_feature(
3166 sw_if_index=self.pg7.sw_if_index,
3167 flags=flags, is_add=1)
3168 self.vapi.nat44_interface_add_del_feature(
3169 sw_if_index=self.pg8.sw_if_index,
3173 pkts = self.create_stream_out(self.pg8)
3174 self.pg8.add_stream(pkts)
3175 self.pg_enable_capture(self.pg_interfaces)
3177 capture = self.pg7.get_capture(len(pkts))
3178 self.verify_capture_in(capture, self.pg7)
3181 pkts = self.create_stream_in(self.pg7, self.pg8)
3182 self.pg7.add_stream(pkts)
3183 self.pg_enable_capture(self.pg_interfaces)
3185 capture = self.pg8.get_capture(len(pkts))
3186 self.verify_capture_out(capture)
3188 def test_static_unknown_proto(self):
3189 """ 1:1 NAT translate packet with unknown protocol """
3190 nat_ip = "10.0.0.10"
3191 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3192 flags = self.config_flags.NAT_IS_INSIDE
3193 self.vapi.nat44_interface_add_del_feature(
3194 sw_if_index=self.pg0.sw_if_index,
3195 flags=flags, is_add=1)
3196 self.vapi.nat44_interface_add_del_feature(
3197 sw_if_index=self.pg1.sw_if_index,
3201 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3202 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3204 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3205 TCP(sport=1234, dport=1234))
3206 self.pg0.add_stream(p)
3207 self.pg_enable_capture(self.pg_interfaces)
3209 p = self.pg1.get_capture(1)
3212 self.assertEqual(packet[IP].src, nat_ip)
3213 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3214 self.assertEqual(packet.haslayer(GRE), 1)
3215 self.assert_packet_checksums_valid(packet)
3217 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3221 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3222 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3224 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3225 TCP(sport=1234, dport=1234))
3226 self.pg1.add_stream(p)
3227 self.pg_enable_capture(self.pg_interfaces)
3229 p = self.pg0.get_capture(1)
3232 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3233 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3234 self.assertEqual(packet.haslayer(GRE), 1)
3235 self.assert_packet_checksums_valid(packet)
3237 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3240 def test_hairpinning_static_unknown_proto(self):
3241 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3243 host = self.pg0.remote_hosts[0]
3244 server = self.pg0.remote_hosts[1]
3246 host_nat_ip = "10.0.0.10"
3247 server_nat_ip = "10.0.0.11"
3249 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3250 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3251 flags = self.config_flags.NAT_IS_INSIDE
3252 self.vapi.nat44_interface_add_del_feature(
3253 sw_if_index=self.pg0.sw_if_index,
3254 flags=flags, is_add=1)
3255 self.vapi.nat44_interface_add_del_feature(
3256 sw_if_index=self.pg1.sw_if_index,
3260 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3261 IP(src=host.ip4, dst=server_nat_ip) /
3263 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3264 TCP(sport=1234, dport=1234))
3265 self.pg0.add_stream(p)
3266 self.pg_enable_capture(self.pg_interfaces)
3268 p = self.pg0.get_capture(1)
3271 self.assertEqual(packet[IP].src, host_nat_ip)
3272 self.assertEqual(packet[IP].dst, server.ip4)
3273 self.assertEqual(packet.haslayer(GRE), 1)
3274 self.assert_packet_checksums_valid(packet)
3276 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3280 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3281 IP(src=server.ip4, dst=host_nat_ip) /
3283 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3284 TCP(sport=1234, dport=1234))
3285 self.pg0.add_stream(p)
3286 self.pg_enable_capture(self.pg_interfaces)
3288 p = self.pg0.get_capture(1)
3291 self.assertEqual(packet[IP].src, server_nat_ip)
3292 self.assertEqual(packet[IP].dst, host.ip4)
3293 self.assertEqual(packet.haslayer(GRE), 1)
3294 self.assert_packet_checksums_valid(packet)
3296 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3299 def test_output_feature(self):
3300 """ NAT44 interface output feature (in2out postrouting) """
3301 self.nat44_add_address(self.nat_addr)
3302 flags = self.config_flags.NAT_IS_INSIDE
3303 self.vapi.nat44_interface_add_del_output_feature(
3304 is_add=1, flags=flags,
3305 sw_if_index=self.pg0.sw_if_index)
3306 self.vapi.nat44_interface_add_del_output_feature(
3307 is_add=1, flags=flags,
3308 sw_if_index=self.pg1.sw_if_index)
3309 self.vapi.nat44_interface_add_del_output_feature(
3311 sw_if_index=self.pg3.sw_if_index)
3314 pkts = self.create_stream_in(self.pg0, self.pg3)
3315 self.pg0.add_stream(pkts)
3316 self.pg_enable_capture(self.pg_interfaces)
3318 capture = self.pg3.get_capture(len(pkts))
3319 self.verify_capture_out(capture)
3322 pkts = self.create_stream_out(self.pg3)
3323 self.pg3.add_stream(pkts)
3324 self.pg_enable_capture(self.pg_interfaces)
3326 capture = self.pg0.get_capture(len(pkts))
3327 self.verify_capture_in(capture, self.pg0)
3329 # from non-NAT interface to NAT inside interface
3330 pkts = self.create_stream_in(self.pg2, self.pg0)
3331 self.pg2.add_stream(pkts)
3332 self.pg_enable_capture(self.pg_interfaces)
3334 capture = self.pg0.get_capture(len(pkts))
3335 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3337 def test_output_feature_vrf_aware(self):
3338 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3339 nat_ip_vrf10 = "10.0.0.10"
3340 nat_ip_vrf20 = "10.0.0.20"
3342 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3343 [VppRoutePath(self.pg3.remote_ip4,
3344 self.pg3.sw_if_index)],
3346 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3347 [VppRoutePath(self.pg3.remote_ip4,
3348 self.pg3.sw_if_index)],
3353 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3354 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3355 flags = self.config_flags.NAT_IS_INSIDE
3356 self.vapi.nat44_interface_add_del_output_feature(
3357 is_add=1, flags=flags,
3358 sw_if_index=self.pg4.sw_if_index)
3359 self.vapi.nat44_interface_add_del_output_feature(
3360 is_add=1, flags=flags,
3361 sw_if_index=self.pg6.sw_if_index)
3362 self.vapi.nat44_interface_add_del_output_feature(
3364 sw_if_index=self.pg3.sw_if_index)
3367 pkts = self.create_stream_in(self.pg4, self.pg3)
3368 self.pg4.add_stream(pkts)
3369 self.pg_enable_capture(self.pg_interfaces)
3371 capture = self.pg3.get_capture(len(pkts))
3372 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3375 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3376 self.pg3.add_stream(pkts)
3377 self.pg_enable_capture(self.pg_interfaces)
3379 capture = self.pg4.get_capture(len(pkts))
3380 self.verify_capture_in(capture, self.pg4)
3383 pkts = self.create_stream_in(self.pg6, self.pg3)
3384 self.pg6.add_stream(pkts)
3385 self.pg_enable_capture(self.pg_interfaces)
3387 capture = self.pg3.get_capture(len(pkts))
3388 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3391 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3392 self.pg3.add_stream(pkts)
3393 self.pg_enable_capture(self.pg_interfaces)
3395 capture = self.pg6.get_capture(len(pkts))
3396 self.verify_capture_in(capture, self.pg6)
3398 def test_output_feature_hairpinning(self):
3399 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3400 host = self.pg0.remote_hosts[0]
3401 server = self.pg0.remote_hosts[1]
3404 server_in_port = 5678
3405 server_out_port = 8765
3407 self.nat44_add_address(self.nat_addr)
3408 flags = self.config_flags.NAT_IS_INSIDE
3409 self.vapi.nat44_interface_add_del_output_feature(
3410 is_add=1, flags=flags,
3411 sw_if_index=self.pg0.sw_if_index)
3412 self.vapi.nat44_interface_add_del_output_feature(
3414 sw_if_index=self.pg1.sw_if_index)
3416 # add static mapping for server
3417 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3418 server_in_port, server_out_port,
3419 proto=IP_PROTOS.tcp)
3421 # send packet from host to server
3422 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3423 IP(src=host.ip4, dst=self.nat_addr) /
3424 TCP(sport=host_in_port, dport=server_out_port))
3425 self.pg0.add_stream(p)
3426 self.pg_enable_capture(self.pg_interfaces)
3428 capture = self.pg0.get_capture(1)
3433 self.assertEqual(ip.src, self.nat_addr)
3434 self.assertEqual(ip.dst, server.ip4)
3435 self.assertNotEqual(tcp.sport, host_in_port)
3436 self.assertEqual(tcp.dport, server_in_port)
3437 self.assert_packet_checksums_valid(p)
3438 host_out_port = tcp.sport
3440 self.logger.error(ppp("Unexpected or invalid packet:", p))
3443 # send reply from server to host
3444 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3445 IP(src=server.ip4, dst=self.nat_addr) /
3446 TCP(sport=server_in_port, dport=host_out_port))
3447 self.pg0.add_stream(p)
3448 self.pg_enable_capture(self.pg_interfaces)
3450 capture = self.pg0.get_capture(1)
3455 self.assertEqual(ip.src, self.nat_addr)
3456 self.assertEqual(ip.dst, host.ip4)
3457 self.assertEqual(tcp.sport, server_out_port)
3458 self.assertEqual(tcp.dport, host_in_port)
3459 self.assert_packet_checksums_valid(p)
3461 self.logger.error(ppp("Unexpected or invalid packet:", p))
3464 def test_one_armed_nat44(self):
3465 """ One armed NAT44 """
3466 remote_host = self.pg9.remote_hosts[0]
3467 local_host = self.pg9.remote_hosts[1]
3470 self.nat44_add_address(self.nat_addr)
3471 flags = self.config_flags.NAT_IS_INSIDE
3472 self.vapi.nat44_interface_add_del_feature(
3473 sw_if_index=self.pg9.sw_if_index,
3475 self.vapi.nat44_interface_add_del_feature(
3476 sw_if_index=self.pg9.sw_if_index,
3477 flags=flags, is_add=1)
3480 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3481 IP(src=local_host.ip4, dst=remote_host.ip4) /
3482 TCP(sport=12345, dport=80))
3483 self.pg9.add_stream(p)
3484 self.pg_enable_capture(self.pg_interfaces)
3486 capture = self.pg9.get_capture(1)
3491 self.assertEqual(ip.src, self.nat_addr)
3492 self.assertEqual(ip.dst, remote_host.ip4)
3493 self.assertNotEqual(tcp.sport, 12345)
3494 external_port = tcp.sport
3495 self.assertEqual(tcp.dport, 80)
3496 self.assert_packet_checksums_valid(p)
3498 self.logger.error(ppp("Unexpected or invalid packet:", p))
3502 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3503 IP(src=remote_host.ip4, dst=self.nat_addr) /
3504 TCP(sport=80, dport=external_port))
3505 self.pg9.add_stream(p)
3506 self.pg_enable_capture(self.pg_interfaces)
3508 capture = self.pg9.get_capture(1)
3513 self.assertEqual(ip.src, remote_host.ip4)
3514 self.assertEqual(ip.dst, local_host.ip4)
3515 self.assertEqual(tcp.sport, 80)
3516 self.assertEqual(tcp.dport, 12345)
3517 self.assert_packet_checksums_valid(p)
3519 self.logger.error(ppp("Unexpected or invalid packet:", p))
3522 err = self.statistics.get_err_counter(
3523 '/err/nat44-classify/next in2out')
3524 self.assertEqual(err, 1)
3525 err = self.statistics.get_err_counter(
3526 '/err/nat44-classify/next out2in')
3527 self.assertEqual(err, 1)
3529 def test_del_session(self):
3530 """ Delete NAT44 session """
3531 self.nat44_add_address(self.nat_addr)
3532 flags = self.config_flags.NAT_IS_INSIDE
3533 self.vapi.nat44_interface_add_del_feature(
3534 sw_if_index=self.pg0.sw_if_index,
3535 flags=flags, is_add=1)
3536 self.vapi.nat44_interface_add_del_feature(
3537 sw_if_index=self.pg1.sw_if_index,
3540 pkts = self.create_stream_in(self.pg0, self.pg1)
3541 self.pg0.add_stream(pkts)
3542 self.pg_enable_capture(self.pg_interfaces)
3544 self.pg1.get_capture(len(pkts))
3546 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3547 nsessions = len(sessions)
3549 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3550 port=sessions[0].inside_port,
3551 protocol=sessions[0].protocol,
3552 flags=self.config_flags.NAT_IS_INSIDE)
3553 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3554 port=sessions[1].outside_port,
3555 protocol=sessions[1].protocol)
3557 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3558 self.assertEqual(nsessions - len(sessions), 2)
3560 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3561 port=sessions[0].inside_port,
3562 protocol=sessions[0].protocol,
3563 flags=self.config_flags.NAT_IS_INSIDE)
3565 self.verify_no_nat44_user()
3567 def test_frag_in_order(self):
3568 """ NAT44 translate fragments arriving in order """
3570 self.nat44_add_address(self.nat_addr)
3571 flags = self.config_flags.NAT_IS_INSIDE
3572 self.vapi.nat44_interface_add_del_feature(
3573 sw_if_index=self.pg0.sw_if_index,
3574 flags=flags, is_add=1)
3575 self.vapi.nat44_interface_add_del_feature(
3576 sw_if_index=self.pg1.sw_if_index,
3579 self.frag_in_order(proto=IP_PROTOS.tcp)
3580 self.frag_in_order(proto=IP_PROTOS.udp)
3581 self.frag_in_order(proto=IP_PROTOS.icmp)
3583 def test_frag_forwarding(self):
3584 """ NAT44 forwarding fragment test """
3585 self.vapi.nat44_add_del_interface_addr(
3587 sw_if_index=self.pg1.sw_if_index)
3588 flags = self.config_flags.NAT_IS_INSIDE
3589 self.vapi.nat44_interface_add_del_feature(
3590 sw_if_index=self.pg0.sw_if_index,
3591 flags=flags, is_add=1)
3592 self.vapi.nat44_interface_add_del_feature(
3593 sw_if_index=self.pg1.sw_if_index,
3595 self.vapi.nat44_forwarding_enable_disable(enable=1)
3597 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3598 pkts = self.create_stream_frag(self.pg1,
3599 self.pg0.remote_ip4,
3603 proto=IP_PROTOS.udp)
3604 self.pg1.add_stream(pkts)
3605 self.pg_enable_capture(self.pg_interfaces)
3607 frags = self.pg0.get_capture(len(pkts))
3608 p = self.reass_frags_and_verify(frags,
3609 self.pg1.remote_ip4,
3610 self.pg0.remote_ip4)
3611 self.assertEqual(p[UDP].sport, 4789)
3612 self.assertEqual(p[UDP].dport, 4789)
3613 self.assertEqual(data, p[Raw].load)
3615 def test_reass_hairpinning(self):
3616 """ NAT44 fragments hairpinning """
3618 self.server = self.pg0.remote_hosts[1]
3619 self.host_in_port = random.randint(1025, 65535)
3620 self.server_in_port = random.randint(1025, 65535)
3621 self.server_out_port = random.randint(1025, 65535)
3623 self.nat44_add_address(self.nat_addr)
3624 flags = self.config_flags.NAT_IS_INSIDE
3625 self.vapi.nat44_interface_add_del_feature(
3626 sw_if_index=self.pg0.sw_if_index,
3627 flags=flags, is_add=1)
3628 self.vapi.nat44_interface_add_del_feature(
3629 sw_if_index=self.pg1.sw_if_index,
3631 # add static mapping for server
3632 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3633 self.server_in_port,
3634 self.server_out_port,
3635 proto=IP_PROTOS.tcp)
3636 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3637 self.server_in_port,
3638 self.server_out_port,
3639 proto=IP_PROTOS.udp)
3640 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3642 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3643 self.reass_hairpinning(proto=IP_PROTOS.udp)
3644 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3646 def test_frag_out_of_order(self):
3647 """ NAT44 translate fragments arriving out of order """
3649 self.nat44_add_address(self.nat_addr)
3650 flags = self.config_flags.NAT_IS_INSIDE
3651 self.vapi.nat44_interface_add_del_feature(
3652 sw_if_index=self.pg0.sw_if_index,
3653 flags=flags, is_add=1)
3654 self.vapi.nat44_interface_add_del_feature(
3655 sw_if_index=self.pg1.sw_if_index,
3658 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3659 self.frag_out_of_order(proto=IP_PROTOS.udp)
3660 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3662 def test_port_restricted(self):
3663 """ Port restricted NAT44 (MAP-E CE) """
3664 self.nat44_add_address(self.nat_addr)
3665 flags = self.config_flags.NAT_IS_INSIDE
3666 self.vapi.nat44_interface_add_del_feature(
3667 sw_if_index=self.pg0.sw_if_index,
3668 flags=flags, is_add=1)
3669 self.vapi.nat44_interface_add_del_feature(
3670 sw_if_index=self.pg1.sw_if_index,
3672 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3677 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3678 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3679 TCP(sport=4567, dport=22))
3680 self.pg0.add_stream(p)
3681 self.pg_enable_capture(self.pg_interfaces)
3683 capture = self.pg1.get_capture(1)
3688 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3689 self.assertEqual(ip.src, self.nat_addr)
3690 self.assertEqual(tcp.dport, 22)
3691 self.assertNotEqual(tcp.sport, 4567)
3692 self.assertEqual((tcp.sport >> 6) & 63, 10)
3693 self.assert_packet_checksums_valid(p)
3695 self.logger.error(ppp("Unexpected or invalid packet:", p))
3698 def test_port_range(self):
3699 """ External address port range """
3700 self.nat44_add_address(self.nat_addr)
3701 flags = self.config_flags.NAT_IS_INSIDE
3702 self.vapi.nat44_interface_add_del_feature(
3703 sw_if_index=self.pg0.sw_if_index,
3704 flags=flags, is_add=1)
3705 self.vapi.nat44_interface_add_del_feature(
3706 sw_if_index=self.pg1.sw_if_index,
3708 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3713 for port in range(0, 5):
3714 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3715 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3716 TCP(sport=1125 + port))
3718 self.pg0.add_stream(pkts)
3719 self.pg_enable_capture(self.pg_interfaces)
3721 capture = self.pg1.get_capture(3)
3724 self.assertGreaterEqual(tcp.sport, 1025)
3725 self.assertLessEqual(tcp.sport, 1027)
3727 def test_multiple_outside_vrf(self):
3728 """ Multiple outside VRF """
3732 self.pg1.unconfig_ip4()
3733 self.pg2.unconfig_ip4()
3734 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3735 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3736 self.pg1.set_table_ip4(vrf_id1)
3737 self.pg2.set_table_ip4(vrf_id2)
3738 self.pg1.config_ip4()
3739 self.pg2.config_ip4()
3740 self.pg1.resolve_arp()
3741 self.pg2.resolve_arp()
3743 self.nat44_add_address(self.nat_addr)
3744 flags = self.config_flags.NAT_IS_INSIDE
3745 self.vapi.nat44_interface_add_del_feature(
3746 sw_if_index=self.pg0.sw_if_index,
3747 flags=flags, is_add=1)
3748 self.vapi.nat44_interface_add_del_feature(
3749 sw_if_index=self.pg1.sw_if_index,
3751 self.vapi.nat44_interface_add_del_feature(
3752 sw_if_index=self.pg2.sw_if_index,
3757 pkts = self.create_stream_in(self.pg0, self.pg1)
3758 self.pg0.add_stream(pkts)
3759 self.pg_enable_capture(self.pg_interfaces)
3761 capture = self.pg1.get_capture(len(pkts))
3762 self.verify_capture_out(capture, self.nat_addr)
3764 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3765 self.pg1.add_stream(pkts)
3766 self.pg_enable_capture(self.pg_interfaces)
3768 capture = self.pg0.get_capture(len(pkts))
3769 self.verify_capture_in(capture, self.pg0)
3771 self.tcp_port_in = 60303
3772 self.udp_port_in = 60304
3773 self.icmp_id_in = 60305
3776 pkts = self.create_stream_in(self.pg0, self.pg2)
3777 self.pg0.add_stream(pkts)
3778 self.pg_enable_capture(self.pg_interfaces)
3780 capture = self.pg2.get_capture(len(pkts))
3781 self.verify_capture_out(capture, self.nat_addr)
3783 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3784 self.pg2.add_stream(pkts)
3785 self.pg_enable_capture(self.pg_interfaces)
3787 capture = self.pg0.get_capture(len(pkts))
3788 self.verify_capture_in(capture, self.pg0)
3791 self.nat44_add_address(self.nat_addr, is_add=0)
3792 self.pg1.unconfig_ip4()
3793 self.pg2.unconfig_ip4()
3794 self.pg1.set_table_ip4(0)
3795 self.pg2.set_table_ip4(0)
3796 self.pg1.config_ip4()
3797 self.pg2.config_ip4()
3798 self.pg1.resolve_arp()
3799 self.pg2.resolve_arp()
3801 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3802 def test_session_timeout(self):
3803 """ NAT44 session timeouts """
3804 self.nat44_add_address(self.nat_addr)
3805 flags = self.config_flags.NAT_IS_INSIDE
3806 self.vapi.nat44_interface_add_del_feature(
3807 sw_if_index=self.pg0.sw_if_index,
3808 flags=flags, is_add=1)
3809 self.vapi.nat44_interface_add_del_feature(
3810 sw_if_index=self.pg1.sw_if_index,
3812 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3813 tcp_transitory=240, icmp=60)
3817 for i in range(0, max_sessions):
3818 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3819 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3820 IP(src=src, dst=self.pg1.remote_ip4) /
3821 UDP(sport=1025, dport=53))
3823 self.pg0.add_stream(pkts)
3824 self.pg_enable_capture(self.pg_interfaces)
3826 self.pg1.get_capture(max_sessions)
3831 for i in range(0, max_sessions):
3832 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3833 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3834 IP(src=src, dst=self.pg1.remote_ip4) /
3835 UDP(sport=1026, dport=53))
3837 self.pg0.add_stream(pkts)
3838 self.pg_enable_capture(self.pg_interfaces)
3840 self.pg1.get_capture(max_sessions)
3843 users = self.vapi.nat44_user_dump()
3845 nsessions = nsessions + user.nsessions
3846 self.assertLess(nsessions, 2 * max_sessions)
3848 def test_mss_clamping(self):
3849 """ TCP MSS clamping """
3850 self.nat44_add_address(self.nat_addr)
3851 flags = self.config_flags.NAT_IS_INSIDE
3852 self.vapi.nat44_interface_add_del_feature(
3853 sw_if_index=self.pg0.sw_if_index,
3854 flags=flags, is_add=1)
3855 self.vapi.nat44_interface_add_del_feature(
3856 sw_if_index=self.pg1.sw_if_index,
3859 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3860 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3861 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3862 flags="S", options=[('MSS', 1400)]))
3864 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3865 self.pg0.add_stream(p)
3866 self.pg_enable_capture(self.pg_interfaces)
3868 capture = self.pg1.get_capture(1)
3869 # Negotiated MSS value greater than configured - changed
3870 self.verify_mss_value(capture[0], 1000)
3872 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3873 self.pg0.add_stream(p)
3874 self.pg_enable_capture(self.pg_interfaces)
3876 capture = self.pg1.get_capture(1)
3877 # MSS clamping disabled - negotiated MSS unchanged
3878 self.verify_mss_value(capture[0], 1400)
3880 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3881 self.pg0.add_stream(p)
3882 self.pg_enable_capture(self.pg_interfaces)
3884 capture = self.pg1.get_capture(1)
3885 # Negotiated MSS value smaller than configured - unchanged
3886 self.verify_mss_value(capture[0], 1400)
3888 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3889 def test_ha_send(self):
3890 """ Send HA session synchronization events (active) """
3891 self.nat44_add_address(self.nat_addr)
3892 flags = self.config_flags.NAT_IS_INSIDE
3893 self.vapi.nat44_interface_add_del_feature(
3894 sw_if_index=self.pg0.sw_if_index,
3895 flags=flags, is_add=1)
3896 self.vapi.nat44_interface_add_del_feature(
3897 sw_if_index=self.pg1.sw_if_index,
3899 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3902 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3903 port=12346, session_refresh_interval=10)
3904 bind_layers(UDP, HANATStateSync, sport=12345)
3907 pkts = self.create_stream_in(self.pg0, self.pg1)
3908 self.pg0.add_stream(pkts)
3909 self.pg_enable_capture(self.pg_interfaces)
3911 capture = self.pg1.get_capture(len(pkts))
3912 self.verify_capture_out(capture)
3913 # active send HA events
3914 self.vapi.nat_ha_flush()
3915 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3916 self.assertEqual(stats[0][0], 3)
3917 capture = self.pg3.get_capture(1)
3919 self.assert_packet_checksums_valid(p)
3923 hanat = p[HANATStateSync]
3925 self.logger.error(ppp("Invalid packet:", p))
3928 self.assertEqual(ip.src, self.pg3.local_ip4)
3929 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3930 self.assertEqual(udp.sport, 12345)
3931 self.assertEqual(udp.dport, 12346)
3932 self.assertEqual(hanat.version, 1)
3933 self.assertEqual(hanat.thread_index, 0)
3934 self.assertEqual(hanat.count, 3)
3935 seq = hanat.sequence_number
3936 for event in hanat.events:
3937 self.assertEqual(event.event_type, 1)
3938 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3939 self.assertEqual(event.out_addr, self.nat_addr)
3940 self.assertEqual(event.fib_index, 0)
3942 # ACK received events
3943 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3944 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3945 UDP(sport=12346, dport=12345) /
3946 HANATStateSync(sequence_number=seq, flags='ACK'))
3947 self.pg3.add_stream(ack)
3949 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3950 self.assertEqual(stats[0][0], 1)
3952 # delete one session
3953 self.pg_enable_capture(self.pg_interfaces)
3954 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3955 port=self.tcp_port_in,
3956 protocol=IP_PROTOS.tcp,
3957 flags=self.config_flags.NAT_IS_INSIDE)
3958 self.vapi.nat_ha_flush()
3959 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3960 self.assertEqual(stats[0][0], 1)
3961 capture = self.pg3.get_capture(1)
3964 hanat = p[HANATStateSync]
3966 self.logger.error(ppp("Invalid packet:", p))
3969 self.assertGreater(hanat.sequence_number, seq)
3971 # do not send ACK, active retry send HA event again
3972 self.pg_enable_capture(self.pg_interfaces)
3974 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3975 self.assertEqual(stats[0][0], 3)
3976 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3977 self.assertEqual(stats[0][0], 1)
3978 capture = self.pg3.get_capture(3)
3979 for packet in capture:
3980 self.assertEqual(packet, p)
3982 # session counters refresh
3983 pkts = self.create_stream_out(self.pg1)
3984 self.pg1.add_stream(pkts)
3985 self.pg_enable_capture(self.pg_interfaces)
3987 self.pg0.get_capture(2)
3988 self.vapi.nat_ha_flush()
3989 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3990 self.assertEqual(stats[0][0], 2)
3991 capture = self.pg3.get_capture(1)
3993 self.assert_packet_checksums_valid(p)
3997 hanat = p[HANATStateSync]
3999 self.logger.error(ppp("Invalid packet:", p))
4002 self.assertEqual(ip.src, self.pg3.local_ip4)
4003 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4004 self.assertEqual(udp.sport, 12345)
4005 self.assertEqual(udp.dport, 12346)
4006 self.assertEqual(hanat.version, 1)
4007 self.assertEqual(hanat.count, 2)
4008 seq = hanat.sequence_number
4009 for event in hanat.events:
4010 self.assertEqual(event.event_type, 3)
4011 self.assertEqual(event.out_addr, self.nat_addr)
4012 self.assertEqual(event.fib_index, 0)
4013 self.assertEqual(event.total_pkts, 2)
4014 self.assertGreater(event.total_bytes, 0)
4016 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4017 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4018 UDP(sport=12346, dport=12345) /
4019 HANATStateSync(sequence_number=seq, flags='ACK'))
4020 self.pg3.add_stream(ack)
4022 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4023 self.assertEqual(stats[0][0], 2)
4025 def test_ha_recv(self):
4026 """ Receive HA session synchronization events (passive) """
4027 self.nat44_add_address(self.nat_addr)
4028 flags = self.config_flags.NAT_IS_INSIDE
4029 self.vapi.nat44_interface_add_del_feature(
4030 sw_if_index=self.pg0.sw_if_index,
4031 flags=flags, is_add=1)
4032 self.vapi.nat44_interface_add_del_feature(
4033 sw_if_index=self.pg1.sw_if_index,
4035 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4038 bind_layers(UDP, HANATStateSync, sport=12345)
4040 self.tcp_port_out = random.randint(1025, 65535)
4041 self.udp_port_out = random.randint(1025, 65535)
4043 # send HA session add events to failover/passive
4044 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4045 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4046 UDP(sport=12346, dport=12345) /
4047 HANATStateSync(sequence_number=1, events=[
4048 Event(event_type='add', protocol='tcp',
4049 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4050 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4051 eh_addr=self.pg1.remote_ip4,
4052 ehn_addr=self.pg1.remote_ip4,
4053 eh_port=self.tcp_external_port,
4054 ehn_port=self.tcp_external_port, fib_index=0),
4055 Event(event_type='add', protocol='udp',
4056 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4057 in_port=self.udp_port_in, out_port=self.udp_port_out,
4058 eh_addr=self.pg1.remote_ip4,
4059 ehn_addr=self.pg1.remote_ip4,
4060 eh_port=self.udp_external_port,
4061 ehn_port=self.udp_external_port, fib_index=0)]))
4063 self.pg3.add_stream(p)
4064 self.pg_enable_capture(self.pg_interfaces)
4067 capture = self.pg3.get_capture(1)
4070 hanat = p[HANATStateSync]
4072 self.logger.error(ppp("Invalid packet:", p))
4075 self.assertEqual(hanat.sequence_number, 1)
4076 self.assertEqual(hanat.flags, 'ACK')
4077 self.assertEqual(hanat.version, 1)
4078 self.assertEqual(hanat.thread_index, 0)
4079 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4080 self.assertEqual(stats[0][0], 1)
4081 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4082 self.assertEqual(stats[0][0], 2)
4083 users = self.statistics.get_counter('/nat44/total-users')
4084 self.assertEqual(users[0][0], 1)
4085 sessions = self.statistics.get_counter('/nat44/total-sessions')
4086 self.assertEqual(sessions[0][0], 2)
4087 users = self.vapi.nat44_user_dump()
4088 self.assertEqual(len(users), 1)
4089 self.assertEqual(str(users[0].ip_address),
4090 self.pg0.remote_ip4)
4091 # there should be 2 sessions created by HA
4092 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4094 self.assertEqual(len(sessions), 2)
4095 for session in sessions:
4096 self.assertEqual(str(session.inside_ip_address),
4097 self.pg0.remote_ip4)
4098 self.assertEqual(str(session.outside_ip_address),
4100 self.assertIn(session.inside_port,
4101 [self.tcp_port_in, self.udp_port_in])
4102 self.assertIn(session.outside_port,
4103 [self.tcp_port_out, self.udp_port_out])
4104 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4106 # send HA session delete event to failover/passive
4107 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4108 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4109 UDP(sport=12346, dport=12345) /
4110 HANATStateSync(sequence_number=2, events=[
4111 Event(event_type='del', protocol='udp',
4112 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4113 in_port=self.udp_port_in, out_port=self.udp_port_out,
4114 eh_addr=self.pg1.remote_ip4,
4115 ehn_addr=self.pg1.remote_ip4,
4116 eh_port=self.udp_external_port,
4117 ehn_port=self.udp_external_port, fib_index=0)]))
4119 self.pg3.add_stream(p)
4120 self.pg_enable_capture(self.pg_interfaces)
4123 capture = self.pg3.get_capture(1)
4126 hanat = p[HANATStateSync]
4128 self.logger.error(ppp("Invalid packet:", p))
4131 self.assertEqual(hanat.sequence_number, 2)
4132 self.assertEqual(hanat.flags, 'ACK')
4133 self.assertEqual(hanat.version, 1)
4134 users = self.vapi.nat44_user_dump()
4135 self.assertEqual(len(users), 1)
4136 self.assertEqual(str(users[0].ip_address),
4137 self.pg0.remote_ip4)
4138 # now we should have only 1 session, 1 deleted by HA
4139 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4141 self.assertEqual(len(sessions), 1)
4142 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4143 self.assertEqual(stats[0][0], 1)
4145 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4146 self.assertEqual(stats, 2)
4148 # send HA session refresh event to failover/passive
4149 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4150 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4151 UDP(sport=12346, dport=12345) /
4152 HANATStateSync(sequence_number=3, events=[
4153 Event(event_type='refresh', protocol='tcp',
4154 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4155 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4156 eh_addr=self.pg1.remote_ip4,
4157 ehn_addr=self.pg1.remote_ip4,
4158 eh_port=self.tcp_external_port,
4159 ehn_port=self.tcp_external_port, fib_index=0,
4160 total_bytes=1024, total_pkts=2)]))
4161 self.pg3.add_stream(p)
4162 self.pg_enable_capture(self.pg_interfaces)
4165 capture = self.pg3.get_capture(1)
4168 hanat = p[HANATStateSync]
4170 self.logger.error(ppp("Invalid packet:", p))
4173 self.assertEqual(hanat.sequence_number, 3)
4174 self.assertEqual(hanat.flags, 'ACK')
4175 self.assertEqual(hanat.version, 1)
4176 users = self.vapi.nat44_user_dump()
4177 self.assertEqual(len(users), 1)
4178 self.assertEqual(str(users[0].ip_address),
4179 self.pg0.remote_ip4)
4180 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4182 self.assertEqual(len(sessions), 1)
4183 session = sessions[0]
4184 self.assertEqual(session.total_bytes, 1024)
4185 self.assertEqual(session.total_pkts, 2)
4186 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4187 self.assertEqual(stats[0][0], 1)
4189 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4190 self.assertEqual(stats, 3)
4192 # send packet to test session created by HA
4193 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4194 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4195 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4196 self.pg1.add_stream(p)
4197 self.pg_enable_capture(self.pg_interfaces)
4199 capture = self.pg0.get_capture(1)
4205 self.logger.error(ppp("Invalid packet:", p))
4208 self.assertEqual(ip.src, self.pg1.remote_ip4)
4209 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4210 self.assertEqual(tcp.sport, self.tcp_external_port)
4211 self.assertEqual(tcp.dport, self.tcp_port_in)
4214 super(TestNAT44, self).tearDown()
4216 self.vapi.cli("clear logging")
4218 def show_commands_at_teardown(self):
4219 self.logger.info(self.vapi.cli("show nat44 addresses"))
4220 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4221 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4222 self.logger.info(self.vapi.cli("show nat44 interface address"))
4223 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4224 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4225 self.logger.info(self.vapi.cli("show nat timeouts"))
4227 self.vapi.cli("show nat addr-port-assignment-alg"))
4228 self.logger.info(self.vapi.cli("show nat ha"))
4231 class TestNAT44EndpointDependent2(MethodHolder):
4232 """ Endpoint-Dependent session test cases """
4237 def setUpConstants(cls):
4238 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4239 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent",
4240 "translation", "hash", "buckets", "1",
4241 "icmp", "timeout", str(cls.icmp_timeout), "}"])
4244 def setUpClass(cls):
4245 super(TestNAT44EndpointDependent2, cls).setUpClass()
4247 translation_buckets = 1
4248 cls.max_translations = 10 * translation_buckets
4250 cls.create_pg_interfaces(range(2))
4251 cls.interfaces = list(cls.pg_interfaces[0:2])
4253 for i in cls.interfaces:
4258 cls.pg0.generate_remote_hosts(1)
4259 cls.pg0.configure_ipv4_neighbors()
4261 cls.pg1.generate_remote_hosts(1)
4262 cls.pg1.configure_ipv4_neighbors()
4265 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4268 def create_icmp_stream(self, in_if, out_if, count):
4270 Create ICMP packet stream for inside network
4272 :param in_if: Inside interface
4273 :param out_if: Outside interface
4274 :param count: Number of packets
4277 self.assertTrue(count > 0)
4278 icmp_id = random.randint(0, 65535 - (count - 1))
4281 for i in range(count):
4282 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4283 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4284 ICMP(id=icmp_id + i, type='echo-request'))
4288 def send_pkts(self, pkts, expected=None):
4289 self.pg0.add_stream(pkts)
4290 self.pg_enable_capture(self.pg_interfaces)
4292 return self.pg1.get_capture(
4293 len(pkts) if expected is None else expected)
4295 def test_session_cleanup(self):
4296 """ NAT44 session cleanup test """
4298 self.nat44_add_address(self.pg1.local_ip4)
4299 flags = self.config_flags.NAT_IS_INSIDE
4300 self.vapi.nat44_interface_add_del_feature(
4301 sw_if_index=self.pg0.sw_if_index,
4302 flags=flags, is_add=1)
4303 self.vapi.nat44_interface_add_del_feature(
4304 sw_if_index=self.pg1.sw_if_index,
4307 nat_config = self.vapi.nat_show_config()
4308 self.assertEqual(1, nat_config.endpoint_dependent)
4310 pkts = self.create_icmp_stream(self.pg0, self.pg1,
4311 self.max_translations + 2)
4315 self.send_pkts(pkts[0:self.max_translations])
4317 # false positive test
4318 self.send_pkts(pkts[self.max_translations:sz - 1], 0)
4320 sleep(self.icmp_timeout)
4323 self.send_pkts(pkts[self.max_translations + 1:sz])
4326 class TestNAT44EndpointDependent(MethodHolder):
4327 """ Endpoint-Dependent mapping and filtering test cases """
4330 def setUpConstants(cls):
4331 super(TestNAT44EndpointDependent, cls).setUpConstants()
4332 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4335 def setUpClass(cls):
4336 super(TestNAT44EndpointDependent, cls).setUpClass()
4337 cls.vapi.cli("set log class nat level debug")
4339 cls.tcp_port_in = 6303
4340 cls.tcp_port_out = 6303
4341 cls.udp_port_in = 6304
4342 cls.udp_port_out = 6304
4343 cls.icmp_id_in = 6305
4344 cls.icmp_id_out = 6305
4345 cls.nat_addr = '10.0.0.3'
4346 cls.ipfix_src_port = 4739
4347 cls.ipfix_domain_id = 1
4348 cls.tcp_external_port = 80
4350 cls.create_pg_interfaces(range(9))
4351 cls.interfaces = list(cls.pg_interfaces[0:3])
4353 for i in cls.interfaces:
4358 cls.pg0.generate_remote_hosts(3)
4359 cls.pg0.configure_ipv4_neighbors()
4363 cls.pg4.generate_remote_hosts(2)
4364 cls.pg4.config_ip4()
4365 cls.vapi.sw_interface_add_del_address(
4366 sw_if_index=cls.pg4.sw_if_index,
4367 prefix="10.0.0.1/24")
4370 cls.pg4.resolve_arp()
4371 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4372 cls.pg4.resolve_arp()
4374 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4375 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4377 cls.pg5._local_ip4 = "10.1.1.1"
4378 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4379 cls.pg5.set_table_ip4(1)
4380 cls.pg5.config_ip4()
4382 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4383 [VppRoutePath("0.0.0.0",
4384 cls.pg5.sw_if_index)],
4389 cls.pg6._local_ip4 = "10.1.2.1"
4390 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4391 cls.pg6.set_table_ip4(1)
4392 cls.pg6.config_ip4()
4395 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4396 [VppRoutePath("0.0.0.0",
4397 cls.pg6.sw_if_index)],
4400 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4401 [VppRoutePath("0.0.0.0",
4406 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4407 [VppRoutePath("0.0.0.0", 0xffffffff,
4411 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4412 [VppRoutePath(cls.pg1.local_ip4,
4413 cls.pg1.sw_if_index)],
4420 cls.pg5.resolve_arp()
4421 cls.pg6.resolve_arp()
4424 cls.pg7.config_ip4()
4425 cls.pg7.resolve_arp()
4426 cls.pg7.generate_remote_hosts(3)
4427 cls.pg7.configure_ipv4_neighbors()
4430 cls.pg8.config_ip4()
4431 cls.pg8.resolve_arp()
4434 super(TestNAT44EndpointDependent, cls).tearDownClass()
4438 def tearDownClass(cls):
4439 super(TestNAT44EndpointDependent, cls).tearDownClass()
4441 def test_frag_in_order(self):
4442 """ NAT44 translate fragments arriving in order """
4443 self.nat44_add_address(self.nat_addr)
4444 flags = self.config_flags.NAT_IS_INSIDE
4445 self.vapi.nat44_interface_add_del_feature(
4446 sw_if_index=self.pg0.sw_if_index,
4447 flags=flags, is_add=1)
4448 self.vapi.nat44_interface_add_del_feature(
4449 sw_if_index=self.pg1.sw_if_index,
4451 self.frag_in_order(proto=IP_PROTOS.tcp)
4452 self.frag_in_order(proto=IP_PROTOS.udp)
4453 self.frag_in_order(proto=IP_PROTOS.icmp)
4455 def test_frag_in_order_dont_translate(self):
4456 """ NAT44 don't translate fragments arriving in order """
4457 flags = self.config_flags.NAT_IS_INSIDE
4458 self.vapi.nat44_interface_add_del_feature(
4459 sw_if_index=self.pg0.sw_if_index,
4460 flags=flags, is_add=1)
4461 self.vapi.nat44_interface_add_del_feature(
4462 sw_if_index=self.pg1.sw_if_index,
4464 self.vapi.nat44_forwarding_enable_disable(enable=True)
4465 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4467 def test_frag_out_of_order(self):
4468 """ NAT44 translate fragments arriving out of order """
4469 self.nat44_add_address(self.nat_addr)
4470 flags = self.config_flags.NAT_IS_INSIDE
4471 self.vapi.nat44_interface_add_del_feature(
4472 sw_if_index=self.pg0.sw_if_index,
4473 flags=flags, is_add=1)
4474 self.vapi.nat44_interface_add_del_feature(
4475 sw_if_index=self.pg1.sw_if_index,
4477 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4478 self.frag_out_of_order(proto=IP_PROTOS.udp)
4479 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4481 def test_frag_out_of_order_dont_translate(self):
4482 """ NAT44 don't translate fragments arriving out of order """
4483 flags = self.config_flags.NAT_IS_INSIDE
4484 self.vapi.nat44_interface_add_del_feature(
4485 sw_if_index=self.pg0.sw_if_index,
4486 flags=flags, is_add=1)
4487 self.vapi.nat44_interface_add_del_feature(
4488 sw_if_index=self.pg1.sw_if_index,
4490 self.vapi.nat44_forwarding_enable_disable(enable=True)
4491 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4493 def test_frag_in_order_in_plus_out(self):
4494 """ in+out interface fragments in order """
4495 flags = self.config_flags.NAT_IS_INSIDE
4496 self.vapi.nat44_interface_add_del_feature(
4497 sw_if_index=self.pg0.sw_if_index,
4499 self.vapi.nat44_interface_add_del_feature(
4500 sw_if_index=self.pg0.sw_if_index,
4501 flags=flags, is_add=1)
4502 self.vapi.nat44_interface_add_del_feature(
4503 sw_if_index=self.pg1.sw_if_index,
4505 self.vapi.nat44_interface_add_del_feature(
4506 sw_if_index=self.pg1.sw_if_index,
4507 flags=flags, is_add=1)
4509 self.server = self.pg1.remote_hosts[0]
4511 self.server_in_addr = self.server.ip4
4512 self.server_out_addr = '11.11.11.11'
4513 self.server_in_port = random.randint(1025, 65535)
4514 self.server_out_port = random.randint(1025, 65535)
4516 self.nat44_add_address(self.server_out_addr)
4518 # add static mappings for server
4519 self.nat44_add_static_mapping(self.server_in_addr,
4520 self.server_out_addr,
4521 self.server_in_port,
4522 self.server_out_port,
4523 proto=IP_PROTOS.tcp)
4524 self.nat44_add_static_mapping(self.server_in_addr,
4525 self.server_out_addr,
4526 self.server_in_port,
4527 self.server_out_port,
4528 proto=IP_PROTOS.udp)
4529 self.nat44_add_static_mapping(self.server_in_addr,
4530 self.server_out_addr,
4531 proto=IP_PROTOS.icmp)
4533 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4534 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4535 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4537 def test_frag_out_of_order_in_plus_out(self):
4538 """ in+out interface fragments out of order """
4539 flags = self.config_flags.NAT_IS_INSIDE
4540 self.vapi.nat44_interface_add_del_feature(
4541 sw_if_index=self.pg0.sw_if_index,
4543 self.vapi.nat44_interface_add_del_feature(
4544 sw_if_index=self.pg0.sw_if_index,
4545 flags=flags, is_add=1)
4546 self.vapi.nat44_interface_add_del_feature(
4547 sw_if_index=self.pg1.sw_if_index,
4549 self.vapi.nat44_interface_add_del_feature(
4550 sw_if_index=self.pg1.sw_if_index,
4551 flags=flags, is_add=1)
4553 self.server = self.pg1.remote_hosts[0]
4555 self.server_in_addr = self.server.ip4
4556 self.server_out_addr = '11.11.11.11'
4557 self.server_in_port = random.randint(1025, 65535)
4558 self.server_out_port = random.randint(1025, 65535)
4560 self.nat44_add_address(self.server_out_addr)
4562 # add static mappings for server
4563 self.nat44_add_static_mapping(self.server_in_addr,
4564 self.server_out_addr,
4565 self.server_in_port,
4566 self.server_out_port,
4567 proto=IP_PROTOS.tcp)
4568 self.nat44_add_static_mapping(self.server_in_addr,
4569 self.server_out_addr,
4570 self.server_in_port,
4571 self.server_out_port,
4572 proto=IP_PROTOS.udp)
4573 self.nat44_add_static_mapping(self.server_in_addr,
4574 self.server_out_addr,
4575 proto=IP_PROTOS.icmp)
4577 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4578 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4579 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4581 def test_reass_hairpinning(self):
4582 """ NAT44 fragments hairpinning """
4583 self.server = self.pg0.remote_hosts[1]
4584 self.host_in_port = random.randint(1025, 65535)
4585 self.server_in_port = random.randint(1025, 65535)
4586 self.server_out_port = random.randint(1025, 65535)
4588 self.nat44_add_address(self.nat_addr)
4589 flags = self.config_flags.NAT_IS_INSIDE
4590 self.vapi.nat44_interface_add_del_feature(
4591 sw_if_index=self.pg0.sw_if_index,
4592 flags=flags, is_add=1)
4593 self.vapi.nat44_interface_add_del_feature(
4594 sw_if_index=self.pg1.sw_if_index,
4596 # add static mapping for server
4597 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4598 self.server_in_port,
4599 self.server_out_port,
4600 proto=IP_PROTOS.tcp)
4601 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4602 self.server_in_port,
4603 self.server_out_port,
4604 proto=IP_PROTOS.udp)
4605 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4607 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4608 self.reass_hairpinning(proto=IP_PROTOS.udp)
4609 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4611 def test_dynamic(self):
4612 """ NAT44 dynamic translation test """
4614 self.nat44_add_address(self.nat_addr)
4615 flags = self.config_flags.NAT_IS_INSIDE
4616 self.vapi.nat44_interface_add_del_feature(
4617 sw_if_index=self.pg0.sw_if_index,
4618 flags=flags, is_add=1)
4619 self.vapi.nat44_interface_add_del_feature(
4620 sw_if_index=self.pg1.sw_if_index,
4623 nat_config = self.vapi.nat_show_config()
4624 self.assertEqual(1, nat_config.endpoint_dependent)
4627 tcpn = self.statistics.get_err_counter(
4628 '/err/nat44-ed-in2out-slowpath/TCP packets')
4629 udpn = self.statistics.get_err_counter(
4630 '/err/nat44-ed-in2out-slowpath/UDP packets')
4631 icmpn = self.statistics.get_err_counter(
4632 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4633 totaln = self.statistics.get_err_counter(
4634 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4636 pkts = self.create_stream_in(self.pg0, self.pg1)
4637 self.pg0.add_stream(pkts)
4638 self.pg_enable_capture(self.pg_interfaces)
4640 capture = self.pg1.get_capture(len(pkts))
4641 self.verify_capture_out(capture)
4643 err = self.statistics.get_err_counter(
4644 '/err/nat44-ed-in2out-slowpath/TCP packets')
4645 self.assertEqual(err - tcpn, 2)
4646 err = self.statistics.get_err_counter(
4647 '/err/nat44-ed-in2out-slowpath/UDP packets')
4648 self.assertEqual(err - udpn, 1)
4649 err = self.statistics.get_err_counter(
4650 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4651 self.assertEqual(err - icmpn, 1)
4652 err = self.statistics.get_err_counter(
4653 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4654 self.assertEqual(err - totaln, 4)
4657 tcpn = self.statistics.get_err_counter(
4658 '/err/nat44-ed-out2in/TCP packets')
4659 udpn = self.statistics.get_err_counter(
4660 '/err/nat44-ed-out2in/UDP packets')
4661 icmpn = self.statistics.get_err_counter(
4662 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4663 totaln = self.statistics.get_err_counter(
4664 '/err/nat44-ed-out2in/good out2in packets processed')
4666 pkts = self.create_stream_out(self.pg1)
4667 self.pg1.add_stream(pkts)
4668 self.pg_enable_capture(self.pg_interfaces)
4670 capture = self.pg0.get_capture(len(pkts))
4671 self.verify_capture_in(capture, self.pg0)
4673 err = self.statistics.get_err_counter(
4674 '/err/nat44-ed-out2in/TCP packets')
4675 self.assertEqual(err - tcpn, 2)
4676 err = self.statistics.get_err_counter(
4677 '/err/nat44-ed-out2in/UDP packets')
4678 self.assertEqual(err - udpn, 1)
4679 err = self.statistics.get_err_counter(
4680 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4681 self.assertEqual(err - icmpn, 1)
4682 err = self.statistics.get_err_counter(
4683 '/err/nat44-ed-out2in/good out2in packets processed')
4684 self.assertEqual(err - totaln, 3)
4686 users = self.statistics.get_counter('/nat44/total-users')
4687 self.assertEqual(users[0][0], 1)
4688 sessions = self.statistics.get_counter('/nat44/total-sessions')
4689 self.assertEqual(sessions[0][0], 3)
4691 def test_dynamic_output_feature_vrf(self):
4692 """ NAT44 dynamic translation test: output-feature, VRF"""
4694 # other then default (0)
4697 self.nat44_add_address(self.nat_addr)
4698 flags = self.config_flags.NAT_IS_INSIDE
4699 self.vapi.nat44_interface_add_del_output_feature(
4700 sw_if_index=self.pg7.sw_if_index,
4701 flags=flags, is_add=1)
4702 self.vapi.nat44_interface_add_del_output_feature(
4703 sw_if_index=self.pg8.sw_if_index,
4707 self.vapi.ip_table_add_del(is_add=1,
4708 table={'table_id': new_vrf_id})
4710 self.pg7.unconfig_ip4()
4711 self.pg7.set_table_ip4(new_vrf_id)
4712 self.pg7.config_ip4()
4713 self.pg7.resolve_arp()
4715 self.pg8.unconfig_ip4()
4716 self.pg8.set_table_ip4(new_vrf_id)
4717 self.pg8.config_ip4()
4718 self.pg8.resolve_arp()
4720 nat_config = self.vapi.nat_show_config()
4721 self.assertEqual(1, nat_config.endpoint_dependent)
4724 tcpn = self.statistics.get_err_counter(
4725 '/err/nat44-ed-in2out-slowpath/TCP packets')
4726 udpn = self.statistics.get_err_counter(
4727 '/err/nat44-ed-in2out-slowpath/UDP packets')
4728 icmpn = self.statistics.get_err_counter(
4729 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4730 totaln = self.statistics.get_err_counter(
4731 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4733 pkts = self.create_stream_in(self.pg7, self.pg8)
4734 self.pg7.add_stream(pkts)
4735 self.pg_enable_capture(self.pg_interfaces)
4737 capture = self.pg8.get_capture(len(pkts))
4738 self.verify_capture_out(capture)
4740 err = self.statistics.get_err_counter(
4741 '/err/nat44-ed-in2out-slowpath/TCP packets')
4742 self.assertEqual(err - tcpn, 2)
4743 err = self.statistics.get_err_counter(
4744 '/err/nat44-ed-in2out-slowpath/UDP packets')
4745 self.assertEqual(err - udpn, 1)
4746 err = self.statistics.get_err_counter(
4747 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4748 self.assertEqual(err - icmpn, 1)
4749 err = self.statistics.get_err_counter(
4750 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4751 self.assertEqual(err - totaln, 4)
4754 tcpn = self.statistics.get_err_counter(
4755 '/err/nat44-ed-out2in/TCP packets')
4756 udpn = self.statistics.get_err_counter(
4757 '/err/nat44-ed-out2in/UDP packets')
4758 icmpn = self.statistics.get_err_counter(
4759 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4760 totaln = self.statistics.get_err_counter(
4761 '/err/nat44-ed-out2in/good out2in packets processed')
4763 pkts = self.create_stream_out(self.pg8)
4764 self.pg8.add_stream(pkts)
4765 self.pg_enable_capture(self.pg_interfaces)
4767 capture = self.pg7.get_capture(len(pkts))
4768 self.verify_capture_in(capture, self.pg7)
4770 err = self.statistics.get_err_counter(
4771 '/err/nat44-ed-out2in/TCP packets')
4772 self.assertEqual(err - tcpn, 2)
4773 err = self.statistics.get_err_counter(
4774 '/err/nat44-ed-out2in/UDP packets')
4775 self.assertEqual(err - udpn, 1)
4776 err = self.statistics.get_err_counter(
4777 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4778 self.assertEqual(err - icmpn, 1)
4779 err = self.statistics.get_err_counter(
4780 '/err/nat44-ed-out2in/good out2in packets processed')
4781 self.assertEqual(err - totaln, 3)
4783 users = self.statistics.get_counter('/nat44/total-users')
4784 self.assertEqual(users[0][0], 1)
4785 sessions = self.statistics.get_counter('/nat44/total-sessions')
4786 self.assertEqual(sessions[0][0], 3)
4789 self.pg7.unconfig_ip4()
4790 self.pg7.set_table_ip4(1)
4791 self.pg7.config_ip4()
4792 self.pg7.resolve_arp()
4794 self.pg8.unconfig_ip4()
4795 self.pg8.set_table_ip4(1)
4796 self.pg8.config_ip4()
4797 self.pg8.resolve_arp()
4799 self.vapi.ip_table_add_del(is_add=0,
4800 table={'table_id': new_vrf_id})
4802 def test_forwarding(self):
4803 """ NAT44 forwarding test """
4805 flags = self.config_flags.NAT_IS_INSIDE
4806 self.vapi.nat44_interface_add_del_feature(
4807 sw_if_index=self.pg0.sw_if_index,
4808 flags=flags, is_add=1)
4809 self.vapi.nat44_interface_add_del_feature(
4810 sw_if_index=self.pg1.sw_if_index,
4812 self.vapi.nat44_forwarding_enable_disable(enable=1)
4814 real_ip = self.pg0.remote_ip4
4815 alias_ip = self.nat_addr
4816 flags = self.config_flags.NAT_IS_ADDR_ONLY
4817 self.vapi.nat44_add_del_static_mapping(is_add=1,
4818 local_ip_address=real_ip,
4819 external_ip_address=alias_ip,
4820 external_sw_if_index=0xFFFFFFFF,
4824 # in2out - static mapping match
4826 pkts = self.create_stream_out(self.pg1)
4827 self.pg1.add_stream(pkts)
4828 self.pg_enable_capture(self.pg_interfaces)
4830 capture = self.pg0.get_capture(len(pkts))
4831 self.verify_capture_in(capture, self.pg0)
4833 pkts = self.create_stream_in(self.pg0, self.pg1)
4834 self.pg0.add_stream(pkts)
4835 self.pg_enable_capture(self.pg_interfaces)
4837 capture = self.pg1.get_capture(len(pkts))
4838 self.verify_capture_out(capture, same_port=True)
4840 # in2out - no static mapping match
4842 host0 = self.pg0.remote_hosts[0]
4843 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4845 pkts = self.create_stream_out(self.pg1,
4846 dst_ip=self.pg0.remote_ip4,
4847 use_inside_ports=True)
4848 self.pg1.add_stream(pkts)
4849 self.pg_enable_capture(self.pg_interfaces)
4851 capture = self.pg0.get_capture(len(pkts))
4852 self.verify_capture_in(capture, self.pg0)
4854 pkts = self.create_stream_in(self.pg0, self.pg1)
4855 self.pg0.add_stream(pkts)
4856 self.pg_enable_capture(self.pg_interfaces)
4858 capture = self.pg1.get_capture(len(pkts))
4859 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4862 self.pg0.remote_hosts[0] = host0
4864 user = self.pg0.remote_hosts[1]
4865 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4866 self.assertEqual(len(sessions), 3)
4867 self.assertTrue(sessions[0].flags &
4868 self.config_flags.NAT_IS_EXT_HOST_VALID)
4869 self.vapi.nat44_del_session(
4870 address=sessions[0].inside_ip_address,
4871 port=sessions[0].inside_port,
4872 protocol=sessions[0].protocol,
4873 flags=(self.config_flags.NAT_IS_INSIDE |
4874 self.config_flags.NAT_IS_EXT_HOST_VALID),
4875 ext_host_address=sessions[0].ext_host_address,
4876 ext_host_port=sessions[0].ext_host_port)
4877 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4878 self.assertEqual(len(sessions), 2)
4881 self.vapi.nat44_forwarding_enable_disable(enable=0)
4882 flags = self.config_flags.NAT_IS_ADDR_ONLY
4883 self.vapi.nat44_add_del_static_mapping(
4885 local_ip_address=real_ip,
4886 external_ip_address=alias_ip,
4887 external_sw_if_index=0xFFFFFFFF,
4890 def test_static_lb(self):
4891 """ NAT44 local service load balancing """
4892 external_addr_n = self.nat_addr
4895 server1 = self.pg0.remote_hosts[0]
4896 server2 = self.pg0.remote_hosts[1]
4898 locals = [{'addr': server1.ip4,
4902 {'addr': server2.ip4,
4907 self.nat44_add_address(self.nat_addr)
4908 self.vapi.nat44_add_del_lb_static_mapping(
4910 external_addr=external_addr_n,
4911 external_port=external_port,
4912 protocol=IP_PROTOS.tcp,
4913 local_num=len(locals),
4915 flags = self.config_flags.NAT_IS_INSIDE
4916 self.vapi.nat44_interface_add_del_feature(
4917 sw_if_index=self.pg0.sw_if_index,
4918 flags=flags, is_add=1)
4919 self.vapi.nat44_interface_add_del_feature(
4920 sw_if_index=self.pg1.sw_if_index,
4923 # from client to service
4924 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4925 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4926 TCP(sport=12345, dport=external_port))
4927 self.pg1.add_stream(p)
4928 self.pg_enable_capture(self.pg_interfaces)
4930 capture = self.pg0.get_capture(1)
4936 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4937 if ip.dst == server1.ip4:
4941 self.assertEqual(tcp.dport, local_port)
4942 self.assert_packet_checksums_valid(p)
4944 self.logger.error(ppp("Unexpected or invalid packet:", p))
4947 # from service back to client
4948 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4949 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4950 TCP(sport=local_port, dport=12345))
4951 self.pg0.add_stream(p)
4952 self.pg_enable_capture(self.pg_interfaces)
4954 capture = self.pg1.get_capture(1)
4959 self.assertEqual(ip.src, self.nat_addr)
4960 self.assertEqual(tcp.sport, external_port)
4961 self.assert_packet_checksums_valid(p)
4963 self.logger.error(ppp("Unexpected or invalid packet:", p))
4966 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4967 self.assertEqual(len(sessions), 1)
4968 self.assertTrue(sessions[0].flags &
4969 self.config_flags.NAT_IS_EXT_HOST_VALID)
4970 self.vapi.nat44_del_session(
4971 address=sessions[0].inside_ip_address,
4972 port=sessions[0].inside_port,
4973 protocol=sessions[0].protocol,
4974 flags=(self.config_flags.NAT_IS_INSIDE |
4975 self.config_flags.NAT_IS_EXT_HOST_VALID),
4976 ext_host_address=sessions[0].ext_host_address,
4977 ext_host_port=sessions[0].ext_host_port)
4978 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4979 self.assertEqual(len(sessions), 0)
4981 @unittest.skipUnless(running_extended_tests, "part of extended tests")
4982 def test_static_lb_multi_clients(self):
4983 """ NAT44 local service load balancing - multiple clients"""
4985 external_addr = self.nat_addr
4988 server1 = self.pg0.remote_hosts[0]
4989 server2 = self.pg0.remote_hosts[1]
4990 server3 = self.pg0.remote_hosts[2]
4992 locals = [{'addr': server1.ip4,
4996 {'addr': server2.ip4,
5001 self.nat44_add_address(self.nat_addr)
5002 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5003 external_addr=external_addr,
5004 external_port=external_port,
5005 protocol=IP_PROTOS.tcp,
5006 local_num=len(locals),
5008 flags = self.config_flags.NAT_IS_INSIDE
5009 self.vapi.nat44_interface_add_del_feature(
5010 sw_if_index=self.pg0.sw_if_index,
5011 flags=flags, is_add=1)
5012 self.vapi.nat44_interface_add_del_feature(
5013 sw_if_index=self.pg1.sw_if_index,
5018 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5020 for client in clients:
5021 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5022 IP(src=client, dst=self.nat_addr) /
5023 TCP(sport=12345, dport=external_port))
5025 self.pg1.add_stream(pkts)
5026 self.pg_enable_capture(self.pg_interfaces)
5028 capture = self.pg0.get_capture(len(pkts))
5030 if p[IP].dst == server1.ip4:
5034 self.assertGreater(server1_n, server2_n)
5037 'addr': server3.ip4,
5044 self.vapi.nat44_lb_static_mapping_add_del_local(
5046 external_addr=external_addr,
5047 external_port=external_port,
5049 protocol=IP_PROTOS.tcp)
5053 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5055 for client in clients:
5056 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5057 IP(src=client, dst=self.nat_addr) /
5058 TCP(sport=12346, dport=external_port))
5060 self.assertGreater(len(pkts), 0)
5061 self.pg1.add_stream(pkts)
5062 self.pg_enable_capture(self.pg_interfaces)
5064 capture = self.pg0.get_capture(len(pkts))
5066 if p[IP].dst == server1.ip4:
5068 elif p[IP].dst == server2.ip4:
5072 self.assertGreater(server1_n, 0)
5073 self.assertGreater(server2_n, 0)
5074 self.assertGreater(server3_n, 0)
5077 'addr': server2.ip4,
5083 # remove one back-end
5084 self.vapi.nat44_lb_static_mapping_add_del_local(
5086 external_addr=external_addr,
5087 external_port=external_port,
5089 protocol=IP_PROTOS.tcp)
5093 self.pg1.add_stream(pkts)
5094 self.pg_enable_capture(self.pg_interfaces)
5096 capture = self.pg0.get_capture(len(pkts))
5098 if p[IP].dst == server1.ip4:
5100 elif p[IP].dst == server2.ip4:
5104 self.assertGreater(server1_n, 0)
5105 self.assertEqual(server2_n, 0)
5106 self.assertGreater(server3_n, 0)
5108 def test_static_lb_2(self):
5109 """ NAT44 local service load balancing (asymmetrical rule) """
5110 external_addr = self.nat_addr
5113 server1 = self.pg0.remote_hosts[0]
5114 server2 = self.pg0.remote_hosts[1]
5116 locals = [{'addr': server1.ip4,
5120 {'addr': server2.ip4,
5125 self.vapi.nat44_forwarding_enable_disable(enable=1)
5126 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5127 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5128 external_addr=external_addr,
5129 external_port=external_port,
5130 protocol=IP_PROTOS.tcp,
5131 local_num=len(locals),
5133 flags = self.config_flags.NAT_IS_INSIDE
5134 self.vapi.nat44_interface_add_del_feature(
5135 sw_if_index=self.pg0.sw_if_index,
5136 flags=flags, is_add=1)
5137 self.vapi.nat44_interface_add_del_feature(
5138 sw_if_index=self.pg1.sw_if_index,
5141 # from client to service
5142 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5143 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5144 TCP(sport=12345, dport=external_port))
5145 self.pg1.add_stream(p)
5146 self.pg_enable_capture(self.pg_interfaces)
5148 capture = self.pg0.get_capture(1)
5154 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5155 if ip.dst == server1.ip4:
5159 self.assertEqual(tcp.dport, local_port)
5160 self.assert_packet_checksums_valid(p)
5162 self.logger.error(ppp("Unexpected or invalid packet:", p))
5165 # from service back to client
5166 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5167 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5168 TCP(sport=local_port, dport=12345))
5169 self.pg0.add_stream(p)
5170 self.pg_enable_capture(self.pg_interfaces)
5172 capture = self.pg1.get_capture(1)
5177 self.assertEqual(ip.src, self.nat_addr)
5178 self.assertEqual(tcp.sport, external_port)
5179 self.assert_packet_checksums_valid(p)
5181 self.logger.error(ppp("Unexpected or invalid packet:", p))
5184 # from client to server (no translation)
5185 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5186 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5187 TCP(sport=12346, dport=local_port))
5188 self.pg1.add_stream(p)
5189 self.pg_enable_capture(self.pg_interfaces)
5191 capture = self.pg0.get_capture(1)
5197 self.assertEqual(ip.dst, server1.ip4)
5198 self.assertEqual(tcp.dport, local_port)
5199 self.assert_packet_checksums_valid(p)
5201 self.logger.error(ppp("Unexpected or invalid packet:", p))
5204 # from service back to client (no translation)
5205 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5206 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5207 TCP(sport=local_port, dport=12346))
5208 self.pg0.add_stream(p)
5209 self.pg_enable_capture(self.pg_interfaces)
5211 capture = self.pg1.get_capture(1)
5216 self.assertEqual(ip.src, server1.ip4)
5217 self.assertEqual(tcp.sport, local_port)
5218 self.assert_packet_checksums_valid(p)
5220 self.logger.error(ppp("Unexpected or invalid packet:", p))
5223 def test_lb_affinity(self):
5224 """ NAT44 local service load balancing affinity """
5225 external_addr = self.nat_addr
5228 server1 = self.pg0.remote_hosts[0]
5229 server2 = self.pg0.remote_hosts[1]
5231 locals = [{'addr': server1.ip4,
5235 {'addr': server2.ip4,
5240 self.nat44_add_address(self.nat_addr)
5241 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5242 external_addr=external_addr,
5243 external_port=external_port,
5244 protocol=IP_PROTOS.tcp,
5246 local_num=len(locals),
5248 flags = self.config_flags.NAT_IS_INSIDE
5249 self.vapi.nat44_interface_add_del_feature(
5250 sw_if_index=self.pg0.sw_if_index,
5251 flags=flags, is_add=1)
5252 self.vapi.nat44_interface_add_del_feature(
5253 sw_if_index=self.pg1.sw_if_index,
5256 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5257 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5258 TCP(sport=1025, dport=external_port))
5259 self.pg1.add_stream(p)
5260 self.pg_enable_capture(self.pg_interfaces)
5262 capture = self.pg0.get_capture(1)
5263 backend = capture[0][IP].dst
5265 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5266 self.assertEqual(len(sessions), 1)
5267 self.assertTrue(sessions[0].flags &
5268 self.config_flags.NAT_IS_EXT_HOST_VALID)
5269 self.vapi.nat44_del_session(
5270 address=sessions[0].inside_ip_address,
5271 port=sessions[0].inside_port,
5272 protocol=sessions[0].protocol,
5273 flags=(self.config_flags.NAT_IS_INSIDE |
5274 self.config_flags.NAT_IS_EXT_HOST_VALID),
5275 ext_host_address=sessions[0].ext_host_address,
5276 ext_host_port=sessions[0].ext_host_port)
5279 for port in range(1030, 1100):
5280 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5281 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5282 TCP(sport=port, dport=external_port))
5284 self.pg1.add_stream(pkts)
5285 self.pg_enable_capture(self.pg_interfaces)
5287 capture = self.pg0.get_capture(len(pkts))
5289 self.assertEqual(p[IP].dst, backend)
5291 def test_unknown_proto(self):
5292 """ NAT44 translate packet with unknown protocol """
5293 self.nat44_add_address(self.nat_addr)
5294 flags = self.config_flags.NAT_IS_INSIDE
5295 self.vapi.nat44_interface_add_del_feature(
5296 sw_if_index=self.pg0.sw_if_index,
5297 flags=flags, is_add=1)
5298 self.vapi.nat44_interface_add_del_feature(
5299 sw_if_index=self.pg1.sw_if_index,
5303 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5304 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5305 TCP(sport=self.tcp_port_in, dport=20))
5306 self.pg0.add_stream(p)
5307 self.pg_enable_capture(self.pg_interfaces)
5309 p = self.pg1.get_capture(1)
5311 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5312 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5314 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5315 TCP(sport=1234, dport=1234))
5316 self.pg0.add_stream(p)
5317 self.pg_enable_capture(self.pg_interfaces)
5319 p = self.pg1.get_capture(1)
5322 self.assertEqual(packet[IP].src, self.nat_addr)
5323 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5324 self.assertEqual(packet.haslayer(GRE), 1)
5325 self.assert_packet_checksums_valid(packet)
5327 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5331 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5332 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5334 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5335 TCP(sport=1234, dport=1234))
5336 self.pg1.add_stream(p)
5337 self.pg_enable_capture(self.pg_interfaces)
5339 p = self.pg0.get_capture(1)
5342 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5343 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5344 self.assertEqual(packet.haslayer(GRE), 1)
5345 self.assert_packet_checksums_valid(packet)
5347 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5350 def test_hairpinning_unknown_proto(self):
5351 """ NAT44 translate packet with unknown protocol - hairpinning """
5352 host = self.pg0.remote_hosts[0]
5353 server = self.pg0.remote_hosts[1]
5355 server_out_port = 8765
5356 server_nat_ip = "10.0.0.11"
5358 self.nat44_add_address(self.nat_addr)
5359 flags = self.config_flags.NAT_IS_INSIDE
5360 self.vapi.nat44_interface_add_del_feature(
5361 sw_if_index=self.pg0.sw_if_index,
5362 flags=flags, is_add=1)
5363 self.vapi.nat44_interface_add_del_feature(
5364 sw_if_index=self.pg1.sw_if_index,
5367 # add static mapping for server
5368 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5371 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5372 IP(src=host.ip4, dst=server_nat_ip) /
5373 TCP(sport=host_in_port, dport=server_out_port))
5374 self.pg0.add_stream(p)
5375 self.pg_enable_capture(self.pg_interfaces)
5377 self.pg0.get_capture(1)
5379 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5380 IP(src=host.ip4, dst=server_nat_ip) /
5382 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5383 TCP(sport=1234, dport=1234))
5384 self.pg0.add_stream(p)
5385 self.pg_enable_capture(self.pg_interfaces)
5387 p = self.pg0.get_capture(1)
5390 self.assertEqual(packet[IP].src, self.nat_addr)
5391 self.assertEqual(packet[IP].dst, server.ip4)
5392 self.assertEqual(packet.haslayer(GRE), 1)
5393 self.assert_packet_checksums_valid(packet)
5395 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5399 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5400 IP(src=server.ip4, dst=self.nat_addr) /
5402 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5403 TCP(sport=1234, dport=1234))
5404 self.pg0.add_stream(p)
5405 self.pg_enable_capture(self.pg_interfaces)
5407 p = self.pg0.get_capture(1)
5410 self.assertEqual(packet[IP].src, server_nat_ip)
5411 self.assertEqual(packet[IP].dst, host.ip4)
5412 self.assertEqual(packet.haslayer(GRE), 1)
5413 self.assert_packet_checksums_valid(packet)
5415 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5418 def test_output_feature_and_service(self):
5419 """ NAT44 interface output feature and services """
5420 external_addr = '1.2.3.4'
5424 self.vapi.nat44_forwarding_enable_disable(enable=1)
5425 self.nat44_add_address(self.nat_addr)
5426 flags = self.config_flags.NAT_IS_ADDR_ONLY
5427 self.vapi.nat44_add_del_identity_mapping(
5428 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5429 flags=flags, is_add=1)
5430 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5431 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5432 local_port, external_port,
5433 proto=IP_PROTOS.tcp, flags=flags)
5434 flags = self.config_flags.NAT_IS_INSIDE
5435 self.vapi.nat44_interface_add_del_feature(
5436 sw_if_index=self.pg0.sw_if_index,
5438 self.vapi.nat44_interface_add_del_feature(
5439 sw_if_index=self.pg0.sw_if_index,
5440 flags=flags, is_add=1)
5441 self.vapi.nat44_interface_add_del_output_feature(
5443 sw_if_index=self.pg1.sw_if_index)
5445 # from client to service
5446 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5447 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5448 TCP(sport=12345, dport=external_port))
5449 self.pg1.add_stream(p)
5450 self.pg_enable_capture(self.pg_interfaces)
5452 capture = self.pg0.get_capture(1)
5457 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5458 self.assertEqual(tcp.dport, local_port)
5459 self.assert_packet_checksums_valid(p)
5461 self.logger.error(ppp("Unexpected or invalid packet:", p))
5464 # from service back to client
5465 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5466 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5467 TCP(sport=local_port, dport=12345))
5468 self.pg0.add_stream(p)
5469 self.pg_enable_capture(self.pg_interfaces)
5471 capture = self.pg1.get_capture(1)
5476 self.assertEqual(ip.src, external_addr)
5477 self.assertEqual(tcp.sport, external_port)
5478 self.assert_packet_checksums_valid(p)
5480 self.logger.error(ppp("Unexpected or invalid packet:", p))
5483 # from local network host to external network
5484 pkts = self.create_stream_in(self.pg0, self.pg1)
5485 self.pg0.add_stream(pkts)
5486 self.pg_enable_capture(self.pg_interfaces)
5488 capture = self.pg1.get_capture(len(pkts))
5489 self.verify_capture_out(capture)
5490 pkts = self.create_stream_in(self.pg0, self.pg1)
5491 self.pg0.add_stream(pkts)
5492 self.pg_enable_capture(self.pg_interfaces)
5494 capture = self.pg1.get_capture(len(pkts))
5495 self.verify_capture_out(capture)
5497 # from external network back to local network host
5498 pkts = self.create_stream_out(self.pg1)
5499 self.pg1.add_stream(pkts)
5500 self.pg_enable_capture(self.pg_interfaces)
5502 capture = self.pg0.get_capture(len(pkts))
5503 self.verify_capture_in(capture, self.pg0)
5505 def test_output_feature_and_service2(self):
5506 """ NAT44 interface output feature and service host direct access """
5507 self.vapi.nat44_forwarding_enable_disable(enable=1)
5508 self.nat44_add_address(self.nat_addr)
5509 self.vapi.nat44_interface_add_del_output_feature(
5511 sw_if_index=self.pg1.sw_if_index)
5513 # session initiated from service host - translate
5514 pkts = self.create_stream_in(self.pg0, self.pg1)
5515 self.pg0.add_stream(pkts)
5516 self.pg_enable_capture(self.pg_interfaces)
5518 capture = self.pg1.get_capture(len(pkts))
5519 self.verify_capture_out(capture)
5521 pkts = self.create_stream_out(self.pg1)
5522 self.pg1.add_stream(pkts)
5523 self.pg_enable_capture(self.pg_interfaces)
5525 capture = self.pg0.get_capture(len(pkts))
5526 self.verify_capture_in(capture, self.pg0)
5528 # session initiated from remote host - do not translate
5529 self.tcp_port_in = 60303
5530 self.udp_port_in = 60304
5531 self.icmp_id_in = 60305
5532 pkts = self.create_stream_out(self.pg1,
5533 self.pg0.remote_ip4,
5534 use_inside_ports=True)
5535 self.pg1.add_stream(pkts)
5536 self.pg_enable_capture(self.pg_interfaces)
5538 capture = self.pg0.get_capture(len(pkts))
5539 self.verify_capture_in(capture, self.pg0)
5541 pkts = self.create_stream_in(self.pg0, self.pg1)
5542 self.pg0.add_stream(pkts)
5543 self.pg_enable_capture(self.pg_interfaces)
5545 capture = self.pg1.get_capture(len(pkts))
5546 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5549 def test_output_feature_and_service3(self):
5550 """ NAT44 interface output feature and DST NAT """
5551 external_addr = '1.2.3.4'
5555 self.vapi.nat44_forwarding_enable_disable(enable=1)
5556 self.nat44_add_address(self.nat_addr)
5557 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5558 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5559 local_port, external_port,
5560 proto=IP_PROTOS.tcp, flags=flags)
5561 flags = self.config_flags.NAT_IS_INSIDE
5562 self.vapi.nat44_interface_add_del_feature(
5563 sw_if_index=self.pg0.sw_if_index,
5565 self.vapi.nat44_interface_add_del_feature(
5566 sw_if_index=self.pg0.sw_if_index,
5567 flags=flags, is_add=1)
5568 self.vapi.nat44_interface_add_del_output_feature(
5570 sw_if_index=self.pg1.sw_if_index)
5572 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5573 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5574 TCP(sport=12345, dport=external_port))
5575 self.pg0.add_stream(p)
5576 self.pg_enable_capture(self.pg_interfaces)
5578 capture = self.pg1.get_capture(1)
5583 self.assertEqual(ip.src, self.pg0.remote_ip4)
5584 self.assertEqual(tcp.sport, 12345)
5585 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5586 self.assertEqual(tcp.dport, local_port)
5587 self.assert_packet_checksums_valid(p)
5589 self.logger.error(ppp("Unexpected or invalid packet:", p))
5592 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5593 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5594 TCP(sport=local_port, dport=12345))
5595 self.pg1.add_stream(p)
5596 self.pg_enable_capture(self.pg_interfaces)
5598 capture = self.pg0.get_capture(1)
5603 self.assertEqual(ip.src, external_addr)
5604 self.assertEqual(tcp.sport, external_port)
5605 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5606 self.assertEqual(tcp.dport, 12345)
5607 self.assert_packet_checksums_valid(p)
5609 self.logger.error(ppp("Unexpected or invalid packet:", p))
5612 def test_next_src_nat(self):
5613 """ On way back forward packet to nat44-in2out node. """
5614 twice_nat_addr = '10.0.1.3'
5617 post_twice_nat_port = 0
5619 self.vapi.nat44_forwarding_enable_disable(enable=1)
5620 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5621 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5622 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5623 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5624 local_port, external_port,
5625 proto=IP_PROTOS.tcp, vrf_id=1,
5627 self.vapi.nat44_interface_add_del_feature(
5628 sw_if_index=self.pg6.sw_if_index,
5631 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5632 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5633 TCP(sport=12345, dport=external_port))
5634 self.pg6.add_stream(p)
5635 self.pg_enable_capture(self.pg_interfaces)
5637 capture = self.pg6.get_capture(1)
5642 self.assertEqual(ip.src, twice_nat_addr)
5643 self.assertNotEqual(tcp.sport, 12345)
5644 post_twice_nat_port = tcp.sport
5645 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5646 self.assertEqual(tcp.dport, local_port)
5647 self.assert_packet_checksums_valid(p)
5649 self.logger.error(ppp("Unexpected or invalid packet:", p))
5652 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5653 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5654 TCP(sport=local_port, dport=post_twice_nat_port))
5655 self.pg6.add_stream(p)
5656 self.pg_enable_capture(self.pg_interfaces)
5658 capture = self.pg6.get_capture(1)
5663 self.assertEqual(ip.src, self.pg1.remote_ip4)
5664 self.assertEqual(tcp.sport, external_port)
5665 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5666 self.assertEqual(tcp.dport, 12345)
5667 self.assert_packet_checksums_valid(p)
5669 self.logger.error(ppp("Unexpected or invalid packet:", p))
5672 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5674 twice_nat_addr = '10.0.1.3'
5682 port_in1 = port_in + 1
5683 port_in2 = port_in + 2
5688 server1 = self.pg0.remote_hosts[0]
5689 server2 = self.pg0.remote_hosts[1]
5701 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5704 self.nat44_add_address(self.nat_addr)
5705 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5709 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5711 flags |= self.config_flags.NAT_IS_TWICE_NAT
5714 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5716 proto=IP_PROTOS.tcp,
5719 locals = [{'addr': server1.ip4,
5723 {'addr': server2.ip4,
5727 out_addr = self.nat_addr
5729 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5730 external_addr=out_addr,
5731 external_port=port_out,
5732 protocol=IP_PROTOS.tcp,
5733 local_num=len(locals),
5735 flags = self.config_flags.NAT_IS_INSIDE
5736 self.vapi.nat44_interface_add_del_feature(
5737 sw_if_index=pg0.sw_if_index,
5738 flags=flags, is_add=1)
5739 self.vapi.nat44_interface_add_del_feature(
5740 sw_if_index=pg1.sw_if_index,
5747 assert client_id is not None
5749 client = self.pg0.remote_hosts[0]
5750 elif client_id == 2:
5751 client = self.pg0.remote_hosts[1]
5753 client = pg1.remote_hosts[0]
5754 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5755 IP(src=client.ip4, dst=self.nat_addr) /
5756 TCP(sport=eh_port_out, dport=port_out))
5758 self.pg_enable_capture(self.pg_interfaces)
5760 capture = pg0.get_capture(1)
5766 if ip.dst == server1.ip4:
5772 self.assertEqual(ip.dst, server.ip4)
5774 self.assertIn(tcp.dport, [port_in1, port_in2])
5776 self.assertEqual(tcp.dport, port_in)
5778 self.assertEqual(ip.src, twice_nat_addr)
5779 self.assertNotEqual(tcp.sport, eh_port_out)
5781 self.assertEqual(ip.src, client.ip4)
5782 self.assertEqual(tcp.sport, eh_port_out)
5784 eh_port_in = tcp.sport
5785 saved_port_in = tcp.dport
5786 self.assert_packet_checksums_valid(p)
5788 self.logger.error(ppp("Unexpected or invalid packet:", p))
5791 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5792 IP(src=server.ip4, dst=eh_addr_in) /
5793 TCP(sport=saved_port_in, dport=eh_port_in))
5795 self.pg_enable_capture(self.pg_interfaces)
5797 capture = pg1.get_capture(1)
5802 self.assertEqual(ip.dst, client.ip4)
5803 self.assertEqual(ip.src, self.nat_addr)
5804 self.assertEqual(tcp.dport, eh_port_out)
5805 self.assertEqual(tcp.sport, port_out)
5806 self.assert_packet_checksums_valid(p)
5808 self.logger.error(ppp("Unexpected or invalid packet:", p))
5812 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5813 self.assertEqual(len(sessions), 1)
5814 self.assertTrue(sessions[0].flags &
5815 self.config_flags.NAT_IS_EXT_HOST_VALID)
5816 self.assertTrue(sessions[0].flags &
5817 self.config_flags.NAT_IS_TWICE_NAT)
5818 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5819 self.vapi.nat44_del_session(
5820 address=sessions[0].inside_ip_address,
5821 port=sessions[0].inside_port,
5822 protocol=sessions[0].protocol,
5823 flags=(self.config_flags.NAT_IS_INSIDE |
5824 self.config_flags.NAT_IS_EXT_HOST_VALID),
5825 ext_host_address=sessions[0].ext_host_nat_address,
5826 ext_host_port=sessions[0].ext_host_nat_port)
5827 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5828 self.assertEqual(len(sessions), 0)
5830 def test_twice_nat(self):
5832 self.twice_nat_common()
5834 def test_self_twice_nat_positive(self):
5835 """ Self Twice NAT44 (positive test) """
5836 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5838 def test_self_twice_nat_negative(self):
5839 """ Self Twice NAT44 (negative test) """
5840 self.twice_nat_common(self_twice_nat=True)
5842 def test_twice_nat_lb(self):
5843 """ Twice NAT44 local service load balancing """
5844 self.twice_nat_common(lb=True)
5846 def test_self_twice_nat_lb_positive(self):
5847 """ Self Twice NAT44 local service load balancing (positive test) """
5848 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5851 def test_self_twice_nat_lb_negative(self):
5852 """ Self Twice NAT44 local service load balancing (negative test) """
5853 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5856 def test_twice_nat_interface_addr(self):
5857 """ Acquire twice NAT44 addresses from interface """
5858 flags = self.config_flags.NAT_IS_TWICE_NAT
5859 self.vapi.nat44_add_del_interface_addr(
5861 sw_if_index=self.pg3.sw_if_index,
5864 # no address in NAT pool
5865 adresses = self.vapi.nat44_address_dump()
5866 self.assertEqual(0, len(adresses))
5868 # configure interface address and check NAT address pool
5869 self.pg3.config_ip4()
5870 adresses = self.vapi.nat44_address_dump()
5871 self.assertEqual(1, len(adresses))
5872 self.assertEqual(str(adresses[0].ip_address),
5874 self.assertEqual(adresses[0].flags, flags)
5876 # remove interface address and check NAT address pool
5877 self.pg3.unconfig_ip4()
5878 adresses = self.vapi.nat44_address_dump()
5879 self.assertEqual(0, len(adresses))
5881 def test_tcp_close(self):
5882 """ Close TCP session from inside network - output feature """
5883 self.vapi.nat44_forwarding_enable_disable(enable=1)
5884 self.nat44_add_address(self.pg1.local_ip4)
5885 twice_nat_addr = '10.0.1.3'
5886 service_ip = '192.168.16.150'
5887 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5888 flags = self.config_flags.NAT_IS_INSIDE
5889 self.vapi.nat44_interface_add_del_feature(
5890 sw_if_index=self.pg0.sw_if_index,
5892 self.vapi.nat44_interface_add_del_feature(
5893 sw_if_index=self.pg0.sw_if_index,
5894 flags=flags, is_add=1)
5895 self.vapi.nat44_interface_add_del_output_feature(
5897 sw_if_index=self.pg1.sw_if_index)
5898 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5899 self.config_flags.NAT_IS_TWICE_NAT)
5900 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5904 proto=IP_PROTOS.tcp,
5906 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5907 start_sessnum = len(sessions)
5909 # SYN packet out->in
5910 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5911 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5912 TCP(sport=33898, dport=80, flags="S"))
5913 self.pg1.add_stream(p)
5914 self.pg_enable_capture(self.pg_interfaces)
5916 capture = self.pg0.get_capture(1)
5918 tcp_port = p[TCP].sport
5920 # SYN + ACK packet in->out
5921 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5922 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5923 TCP(sport=80, dport=tcp_port, flags="SA"))
5924 self.pg0.add_stream(p)
5925 self.pg_enable_capture(self.pg_interfaces)
5927 self.pg1.get_capture(1)
5929 # ACK packet out->in
5930 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5931 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5932 TCP(sport=33898, dport=80, flags="A"))
5933 self.pg1.add_stream(p)
5934 self.pg_enable_capture(self.pg_interfaces)
5936 self.pg0.get_capture(1)
5938 # FIN packet in -> out
5939 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5940 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5941 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5942 self.pg0.add_stream(p)
5943 self.pg_enable_capture(self.pg_interfaces)
5945 self.pg1.get_capture(1)
5947 # FIN+ACK packet out -> in
5948 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5949 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5950 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5951 self.pg1.add_stream(p)
5952 self.pg_enable_capture(self.pg_interfaces)
5954 self.pg0.get_capture(1)
5956 # ACK packet in -> out
5957 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5958 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5959 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5960 self.pg0.add_stream(p)
5961 self.pg_enable_capture(self.pg_interfaces)
5963 self.pg1.get_capture(1)
5965 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5967 self.assertEqual(len(sessions) - start_sessnum, 0)
5969 def test_tcp_session_close_in(self):
5970 """ Close TCP session from inside network """
5971 self.tcp_port_out = 10505
5972 self.nat44_add_address(self.nat_addr)
5973 flags = self.config_flags.NAT_IS_TWICE_NAT
5974 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5978 proto=IP_PROTOS.tcp,
5980 flags = self.config_flags.NAT_IS_INSIDE
5981 self.vapi.nat44_interface_add_del_feature(
5982 sw_if_index=self.pg0.sw_if_index,
5983 flags=flags, is_add=1)
5984 self.vapi.nat44_interface_add_del_feature(
5985 sw_if_index=self.pg1.sw_if_index,
5988 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5989 start_sessnum = len(sessions)
5991 self.initiate_tcp_session(self.pg0, self.pg1)
5993 # FIN packet in -> out
5994 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5995 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5996 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5997 flags="FA", seq=100, ack=300))
5998 self.pg0.add_stream(p)
5999 self.pg_enable_capture(self.pg_interfaces)
6001 self.pg1.get_capture(1)
6005 # ACK packet out -> in
6006 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6007 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6008 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6009 flags="A", seq=300, ack=101))
6012 # FIN packet out -> in
6013 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6014 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6015 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6016 flags="FA", seq=300, ack=101))
6019 self.pg1.add_stream(pkts)
6020 self.pg_enable_capture(self.pg_interfaces)
6022 self.pg0.get_capture(2)
6024 # ACK packet in -> out
6025 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6026 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6027 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6028 flags="A", seq=101, ack=301))
6029 self.pg0.add_stream(p)
6030 self.pg_enable_capture(self.pg_interfaces)
6032 self.pg1.get_capture(1)
6034 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6036 self.assertEqual(len(sessions) - start_sessnum, 0)
6038 def test_tcp_session_close_out(self):
6039 """ Close TCP session from outside network """
6040 self.tcp_port_out = 10505
6041 self.nat44_add_address(self.nat_addr)
6042 flags = self.config_flags.NAT_IS_TWICE_NAT
6043 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6047 proto=IP_PROTOS.tcp,
6049 flags = self.config_flags.NAT_IS_INSIDE
6050 self.vapi.nat44_interface_add_del_feature(
6051 sw_if_index=self.pg0.sw_if_index,
6052 flags=flags, is_add=1)
6053 self.vapi.nat44_interface_add_del_feature(
6054 sw_if_index=self.pg1.sw_if_index,
6057 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6058 start_sessnum = len(sessions)
6060 self.initiate_tcp_session(self.pg0, self.pg1)
6062 # FIN packet out -> in
6063 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6064 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6065 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6066 flags="FA", seq=100, ack=300))
6067 self.pg1.add_stream(p)
6068 self.pg_enable_capture(self.pg_interfaces)
6070 self.pg0.get_capture(1)
6072 # FIN+ACK packet in -> out
6073 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6074 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6075 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6076 flags="FA", seq=300, ack=101))
6078 self.pg0.add_stream(p)
6079 self.pg_enable_capture(self.pg_interfaces)
6081 self.pg1.get_capture(1)
6083 # ACK packet out -> in
6084 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6085 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6086 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6087 flags="A", seq=101, ack=301))
6088 self.pg1.add_stream(p)
6089 self.pg_enable_capture(self.pg_interfaces)
6091 self.pg0.get_capture(1)
6093 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6095 self.assertEqual(len(sessions) - start_sessnum, 0)
6097 def test_tcp_session_close_simultaneous(self):
6098 """ Close TCP session from inside network """
6099 self.tcp_port_out = 10505
6100 self.nat44_add_address(self.nat_addr)
6101 flags = self.config_flags.NAT_IS_TWICE_NAT
6102 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6106 proto=IP_PROTOS.tcp,
6108 flags = self.config_flags.NAT_IS_INSIDE
6109 self.vapi.nat44_interface_add_del_feature(
6110 sw_if_index=self.pg0.sw_if_index,
6111 flags=flags, is_add=1)
6112 self.vapi.nat44_interface_add_del_feature(
6113 sw_if_index=self.pg1.sw_if_index,
6116 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6117 start_sessnum = len(sessions)
6119 self.initiate_tcp_session(self.pg0, self.pg1)
6121 # FIN packet in -> out
6122 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6123 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6124 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6125 flags="FA", seq=100, ack=300))
6126 self.pg0.add_stream(p)
6127 self.pg_enable_capture(self.pg_interfaces)
6129 self.pg1.get_capture(1)
6131 # FIN packet out -> in
6132 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6133 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6134 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6135 flags="FA", seq=300, ack=100))
6136 self.pg1.add_stream(p)
6137 self.pg_enable_capture(self.pg_interfaces)
6139 self.pg0.get_capture(1)
6141 # ACK packet in -> out
6142 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6143 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6144 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6145 flags="A", seq=101, ack=301))
6146 self.pg0.add_stream(p)
6147 self.pg_enable_capture(self.pg_interfaces)
6149 self.pg1.get_capture(1)
6151 # ACK packet out -> in
6152 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6153 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6154 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6155 flags="A", seq=301, ack=101))
6156 self.pg1.add_stream(p)
6157 self.pg_enable_capture(self.pg_interfaces)
6159 self.pg0.get_capture(1)
6161 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6163 self.assertEqual(len(sessions) - start_sessnum, 0)
6165 def test_one_armed_nat44_static(self):
6166 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6167 remote_host = self.pg4.remote_hosts[0]
6168 local_host = self.pg4.remote_hosts[1]
6173 self.vapi.nat44_forwarding_enable_disable(enable=1)
6174 self.nat44_add_address(self.nat_addr, twice_nat=1)
6175 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6176 self.config_flags.NAT_IS_TWICE_NAT)
6177 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6178 local_port, external_port,
6179 proto=IP_PROTOS.tcp, flags=flags)
6180 flags = self.config_flags.NAT_IS_INSIDE
6181 self.vapi.nat44_interface_add_del_feature(
6182 sw_if_index=self.pg4.sw_if_index,
6184 self.vapi.nat44_interface_add_del_feature(
6185 sw_if_index=self.pg4.sw_if_index,
6186 flags=flags, is_add=1)
6188 # from client to service
6189 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6190 IP(src=remote_host.ip4, dst=self.nat_addr) /
6191 TCP(sport=12345, dport=external_port))
6192 self.pg4.add_stream(p)
6193 self.pg_enable_capture(self.pg_interfaces)
6195 capture = self.pg4.get_capture(1)
6200 self.assertEqual(ip.dst, local_host.ip4)
6201 self.assertEqual(ip.src, self.nat_addr)
6202 self.assertEqual(tcp.dport, local_port)
6203 self.assertNotEqual(tcp.sport, 12345)
6204 eh_port_in = tcp.sport
6205 self.assert_packet_checksums_valid(p)
6207 self.logger.error(ppp("Unexpected or invalid packet:", p))
6210 # from service back to client
6211 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6212 IP(src=local_host.ip4, dst=self.nat_addr) /
6213 TCP(sport=local_port, dport=eh_port_in))
6214 self.pg4.add_stream(p)
6215 self.pg_enable_capture(self.pg_interfaces)
6217 capture = self.pg4.get_capture(1)
6222 self.assertEqual(ip.src, self.nat_addr)
6223 self.assertEqual(ip.dst, remote_host.ip4)
6224 self.assertEqual(tcp.sport, external_port)
6225 self.assertEqual(tcp.dport, 12345)
6226 self.assert_packet_checksums_valid(p)
6228 self.logger.error(ppp("Unexpected or invalid packet:", p))
6231 def test_static_with_port_out2(self):
6232 """ 1:1 NAPT asymmetrical rule """
6237 self.vapi.nat44_forwarding_enable_disable(enable=1)
6238 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6239 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6240 local_port, external_port,
6241 proto=IP_PROTOS.tcp, flags=flags)
6242 flags = self.config_flags.NAT_IS_INSIDE
6243 self.vapi.nat44_interface_add_del_feature(
6244 sw_if_index=self.pg0.sw_if_index,
6245 flags=flags, is_add=1)
6246 self.vapi.nat44_interface_add_del_feature(
6247 sw_if_index=self.pg1.sw_if_index,
6250 # from client to service
6251 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6252 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6253 TCP(sport=12345, dport=external_port))
6254 self.pg1.add_stream(p)
6255 self.pg_enable_capture(self.pg_interfaces)
6257 capture = self.pg0.get_capture(1)
6262 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6263 self.assertEqual(tcp.dport, local_port)
6264 self.assert_packet_checksums_valid(p)
6266 self.logger.error(ppp("Unexpected or invalid packet:", p))
6270 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6271 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6272 ICMP(type=11) / capture[0][IP])
6273 self.pg0.add_stream(p)
6274 self.pg_enable_capture(self.pg_interfaces)
6276 capture = self.pg1.get_capture(1)
6279 self.assertEqual(p[IP].src, self.nat_addr)
6281 self.assertEqual(inner.dst, self.nat_addr)
6282 self.assertEqual(inner[TCPerror].dport, external_port)
6284 self.logger.error(ppp("Unexpected or invalid packet:", p))
6287 # from service back to client
6288 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6289 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6290 TCP(sport=local_port, dport=12345))
6291 self.pg0.add_stream(p)
6292 self.pg_enable_capture(self.pg_interfaces)
6294 capture = self.pg1.get_capture(1)
6299 self.assertEqual(ip.src, self.nat_addr)
6300 self.assertEqual(tcp.sport, external_port)
6301 self.assert_packet_checksums_valid(p)
6303 self.logger.error(ppp("Unexpected or invalid packet:", p))
6307 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6308 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6309 ICMP(type=11) / capture[0][IP])
6310 self.pg1.add_stream(p)
6311 self.pg_enable_capture(self.pg_interfaces)
6313 capture = self.pg0.get_capture(1)
6316 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6318 self.assertEqual(inner.src, self.pg0.remote_ip4)
6319 self.assertEqual(inner[TCPerror].sport, local_port)
6321 self.logger.error(ppp("Unexpected or invalid packet:", p))
6324 # from client to server (no translation)
6325 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6326 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6327 TCP(sport=12346, dport=local_port))
6328 self.pg1.add_stream(p)
6329 self.pg_enable_capture(self.pg_interfaces)
6331 capture = self.pg0.get_capture(1)
6336 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6337 self.assertEqual(tcp.dport, local_port)
6338 self.assert_packet_checksums_valid(p)
6340 self.logger.error(ppp("Unexpected or invalid packet:", p))
6343 # from service back to client (no translation)
6344 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6345 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6346 TCP(sport=local_port, dport=12346))
6347 self.pg0.add_stream(p)
6348 self.pg_enable_capture(self.pg_interfaces)
6350 capture = self.pg1.get_capture(1)
6355 self.assertEqual(ip.src, self.pg0.remote_ip4)
6356 self.assertEqual(tcp.sport, local_port)
6357 self.assert_packet_checksums_valid(p)
6359 self.logger.error(ppp("Unexpected or invalid packet:", p))
6362 def test_output_feature(self):
6363 """ NAT44 interface output feature (in2out postrouting) """
6364 self.vapi.nat44_forwarding_enable_disable(enable=1)
6365 self.nat44_add_address(self.nat_addr)
6366 self.vapi.nat44_interface_add_del_feature(
6367 sw_if_index=self.pg0.sw_if_index,
6369 self.vapi.nat44_interface_add_del_output_feature(
6371 sw_if_index=self.pg1.sw_if_index)
6374 pkts = self.create_stream_in(self.pg0, self.pg1)
6375 self.pg0.add_stream(pkts)
6376 self.pg_enable_capture(self.pg_interfaces)
6378 capture = self.pg1.get_capture(len(pkts))
6379 self.verify_capture_out(capture)
6382 pkts = self.create_stream_out(self.pg1)
6383 self.pg1.add_stream(pkts)
6384 self.pg_enable_capture(self.pg_interfaces)
6386 capture = self.pg0.get_capture(len(pkts))
6387 self.verify_capture_in(capture, self.pg0)
6389 def test_multiple_vrf(self):
6390 """ Multiple VRF setup """
6391 external_addr = '1.2.3.4'
6396 self.vapi.nat44_forwarding_enable_disable(enable=1)
6397 self.nat44_add_address(self.nat_addr)
6398 flags = self.config_flags.NAT_IS_INSIDE
6399 self.vapi.nat44_interface_add_del_feature(
6400 sw_if_index=self.pg0.sw_if_index,
6402 self.vapi.nat44_interface_add_del_feature(
6403 sw_if_index=self.pg0.sw_if_index,
6404 flags=flags, is_add=1)
6405 self.vapi.nat44_interface_add_del_output_feature(
6407 sw_if_index=self.pg1.sw_if_index)
6408 self.vapi.nat44_interface_add_del_feature(
6409 sw_if_index=self.pg5.sw_if_index,
6411 self.vapi.nat44_interface_add_del_feature(
6412 sw_if_index=self.pg5.sw_if_index,
6413 flags=flags, is_add=1)
6414 self.vapi.nat44_interface_add_del_feature(
6415 sw_if_index=self.pg6.sw_if_index,
6417 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6418 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6419 local_port, external_port, vrf_id=1,
6420 proto=IP_PROTOS.tcp, flags=flags)
6421 self.nat44_add_static_mapping(
6422 self.pg0.remote_ip4,
6423 external_sw_if_index=self.pg0.sw_if_index,
6424 local_port=local_port,
6426 external_port=external_port,
6427 proto=IP_PROTOS.tcp,
6431 # from client to service (both VRF1)
6432 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6433 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6434 TCP(sport=12345, dport=external_port))
6435 self.pg6.add_stream(p)
6436 self.pg_enable_capture(self.pg_interfaces)
6438 capture = self.pg5.get_capture(1)
6443 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6444 self.assertEqual(tcp.dport, local_port)
6445 self.assert_packet_checksums_valid(p)
6447 self.logger.error(ppp("Unexpected or invalid packet:", p))
6450 # from service back to client (both VRF1)
6451 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6452 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6453 TCP(sport=local_port, dport=12345))
6454 self.pg5.add_stream(p)
6455 self.pg_enable_capture(self.pg_interfaces)
6457 capture = self.pg6.get_capture(1)
6462 self.assertEqual(ip.src, external_addr)
6463 self.assertEqual(tcp.sport, external_port)
6464 self.assert_packet_checksums_valid(p)
6466 self.logger.error(ppp("Unexpected or invalid packet:", p))
6469 # dynamic NAT from VRF1 to VRF0 (output-feature)
6470 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6471 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6472 TCP(sport=2345, dport=22))
6473 self.pg5.add_stream(p)
6474 self.pg_enable_capture(self.pg_interfaces)
6476 capture = self.pg1.get_capture(1)
6481 self.assertEqual(ip.src, self.nat_addr)
6482 self.assertNotEqual(tcp.sport, 2345)
6483 self.assert_packet_checksums_valid(p)
6486 self.logger.error(ppp("Unexpected or invalid packet:", p))
6489 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6490 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6491 TCP(sport=22, dport=port))
6492 self.pg1.add_stream(p)
6493 self.pg_enable_capture(self.pg_interfaces)
6495 capture = self.pg5.get_capture(1)
6500 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6501 self.assertEqual(tcp.dport, 2345)
6502 self.assert_packet_checksums_valid(p)
6504 self.logger.error(ppp("Unexpected or invalid packet:", p))
6507 # from client VRF1 to service VRF0
6508 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6509 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6510 TCP(sport=12346, dport=external_port))
6511 self.pg6.add_stream(p)
6512 self.pg_enable_capture(self.pg_interfaces)
6514 capture = self.pg0.get_capture(1)
6519 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6520 self.assertEqual(tcp.dport, local_port)
6521 self.assert_packet_checksums_valid(p)
6523 self.logger.error(ppp("Unexpected or invalid packet:", p))
6526 # from service VRF0 back to client VRF1
6527 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6528 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6529 TCP(sport=local_port, dport=12346))
6530 self.pg0.add_stream(p)
6531 self.pg_enable_capture(self.pg_interfaces)
6533 capture = self.pg6.get_capture(1)
6538 self.assertEqual(ip.src, self.pg0.local_ip4)
6539 self.assertEqual(tcp.sport, external_port)
6540 self.assert_packet_checksums_valid(p)
6542 self.logger.error(ppp("Unexpected or invalid packet:", p))
6545 # from client VRF0 to service VRF1
6546 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6547 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6548 TCP(sport=12347, dport=external_port))
6549 self.pg0.add_stream(p)
6550 self.pg_enable_capture(self.pg_interfaces)
6552 capture = self.pg5.get_capture(1)
6557 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6558 self.assertEqual(tcp.dport, local_port)
6559 self.assert_packet_checksums_valid(p)
6561 self.logger.error(ppp("Unexpected or invalid packet:", p))
6564 # from service VRF1 back to client VRF0
6565 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6566 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6567 TCP(sport=local_port, dport=12347))
6568 self.pg5.add_stream(p)
6569 self.pg_enable_capture(self.pg_interfaces)
6571 capture = self.pg0.get_capture(1)
6576 self.assertEqual(ip.src, external_addr)
6577 self.assertEqual(tcp.sport, external_port)
6578 self.assert_packet_checksums_valid(p)
6580 self.logger.error(ppp("Unexpected or invalid packet:", p))
6583 # from client to server (both VRF1, no translation)
6584 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6585 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6586 TCP(sport=12348, dport=local_port))
6587 self.pg6.add_stream(p)
6588 self.pg_enable_capture(self.pg_interfaces)
6590 capture = self.pg5.get_capture(1)
6595 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6596 self.assertEqual(tcp.dport, local_port)
6597 self.assert_packet_checksums_valid(p)
6599 self.logger.error(ppp("Unexpected or invalid packet:", p))
6602 # from server back to client (both VRF1, no translation)
6603 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6604 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6605 TCP(sport=local_port, dport=12348))
6606 self.pg5.add_stream(p)
6607 self.pg_enable_capture(self.pg_interfaces)
6609 capture = self.pg6.get_capture(1)
6614 self.assertEqual(ip.src, self.pg5.remote_ip4)
6615 self.assertEqual(tcp.sport, local_port)
6616 self.assert_packet_checksums_valid(p)
6618 self.logger.error(ppp("Unexpected or invalid packet:", p))
6621 # from client VRF1 to server VRF0 (no translation)
6622 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6623 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6624 TCP(sport=local_port, dport=12349))
6625 self.pg0.add_stream(p)
6626 self.pg_enable_capture(self.pg_interfaces)
6628 capture = self.pg6.get_capture(1)
6633 self.assertEqual(ip.src, self.pg0.remote_ip4)
6634 self.assertEqual(tcp.sport, local_port)
6635 self.assert_packet_checksums_valid(p)
6637 self.logger.error(ppp("Unexpected or invalid packet:", p))
6640 # from server VRF0 back to client VRF1 (no translation)
6641 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6642 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6643 TCP(sport=local_port, dport=12349))
6644 self.pg0.add_stream(p)
6645 self.pg_enable_capture(self.pg_interfaces)
6647 capture = self.pg6.get_capture(1)
6652 self.assertEqual(ip.src, self.pg0.remote_ip4)
6653 self.assertEqual(tcp.sport, local_port)
6654 self.assert_packet_checksums_valid(p)
6656 self.logger.error(ppp("Unexpected or invalid packet:", p))
6659 # from client VRF0 to server VRF1 (no translation)
6660 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6661 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6662 TCP(sport=12344, dport=local_port))
6663 self.pg0.add_stream(p)
6664 self.pg_enable_capture(self.pg_interfaces)
6666 capture = self.pg5.get_capture(1)
6671 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6672 self.assertEqual(tcp.dport, local_port)
6673 self.assert_packet_checksums_valid(p)
6675 self.logger.error(ppp("Unexpected or invalid packet:", p))
6678 # from server VRF1 back to client VRF0 (no translation)
6679 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6680 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6681 TCP(sport=local_port, dport=12344))
6682 self.pg5.add_stream(p)
6683 self.pg_enable_capture(self.pg_interfaces)
6685 capture = self.pg0.get_capture(1)
6690 self.assertEqual(ip.src, self.pg5.remote_ip4)
6691 self.assertEqual(tcp.sport, local_port)
6692 self.assert_packet_checksums_valid(p)
6694 self.logger.error(ppp("Unexpected or invalid packet:", p))
6697 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6698 def test_session_timeout(self):
6699 """ NAT44 session timeouts """
6700 self.nat44_add_address(self.nat_addr)
6701 flags = self.config_flags.NAT_IS_INSIDE
6702 self.vapi.nat44_interface_add_del_feature(
6703 sw_if_index=self.pg0.sw_if_index,
6704 flags=flags, is_add=1)
6705 self.vapi.nat44_interface_add_del_feature(
6706 sw_if_index=self.pg1.sw_if_index,
6708 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6709 tcp_transitory=240, icmp=5)
6713 for i in range(0, max_sessions):
6714 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6715 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6716 IP(src=src, dst=self.pg1.remote_ip4) /
6717 ICMP(id=1025, type='echo-request'))
6719 self.pg0.add_stream(pkts)
6720 self.pg_enable_capture(self.pg_interfaces)
6722 self.pg1.get_capture(max_sessions)
6727 for i in range(0, max_sessions):
6728 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6729 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6730 IP(src=src, dst=self.pg1.remote_ip4) /
6731 ICMP(id=1026, type='echo-request'))
6733 self.pg0.add_stream(pkts)
6734 self.pg_enable_capture(self.pg_interfaces)
6736 self.pg1.get_capture(max_sessions)
6739 users = self.vapi.nat44_user_dump()
6741 nsessions = nsessions + user.nsessions
6742 self.assertLess(nsessions, 2 * max_sessions)
6744 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6745 def test_session_rst_timeout(self):
6746 """ NAT44 session RST timeouts """
6747 self.nat44_add_address(self.nat_addr)
6748 flags = self.config_flags.NAT_IS_INSIDE
6749 self.vapi.nat44_interface_add_del_feature(
6750 sw_if_index=self.pg0.sw_if_index,
6751 flags=flags, is_add=1)
6752 self.vapi.nat44_interface_add_del_feature(
6753 sw_if_index=self.pg1.sw_if_index,
6755 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6756 tcp_transitory=5, icmp=60)
6758 self.initiate_tcp_session(self.pg0, self.pg1)
6759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6760 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6761 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6763 self.pg0.add_stream(p)
6764 self.pg_enable_capture(self.pg_interfaces)
6766 self.pg1.get_capture(1)
6770 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6771 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6772 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
6774 self.pg0.add_stream(p)
6775 self.pg_enable_capture(self.pg_interfaces)
6777 self.pg1.get_capture(1)
6780 users = self.vapi.nat44_user_dump()
6781 self.assertEqual(len(users), 1)
6782 self.assertEqual(str(users[0].ip_address),
6783 self.pg0.remote_ip4)
6784 self.assertEqual(users[0].nsessions, 1)
6786 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6787 def test_session_limit_per_user(self):
6788 """ Maximum sessions per user limit """
6789 self.nat44_add_address(self.nat_addr)
6790 flags = self.config_flags.NAT_IS_INSIDE
6791 self.vapi.nat44_interface_add_del_feature(
6792 sw_if_index=self.pg0.sw_if_index,
6793 flags=flags, is_add=1)
6794 self.vapi.nat44_interface_add_del_feature(
6795 sw_if_index=self.pg1.sw_if_index,
6797 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
6798 src_address=self.pg2.local_ip4,
6800 template_interval=10)
6801 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
6802 tcp_transitory=240, icmp=60)
6804 # get maximum number of translations per user
6805 nat44_config = self.vapi.nat_show_config()
6808 for port in range(0, nat44_config.max_translations_per_user):
6809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6810 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6811 UDP(sport=1025 + port, dport=1025 + port))
6814 self.pg0.add_stream(pkts)
6815 self.pg_enable_capture(self.pg_interfaces)
6817 capture = self.pg1.get_capture(len(pkts))
6819 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
6820 src_port=self.ipfix_src_port,
6823 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6824 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6825 UDP(sport=3001, dport=3002))
6826 self.pg0.add_stream(p)
6827 self.pg_enable_capture(self.pg_interfaces)
6829 capture = self.pg1.assert_nothing_captured()
6831 # verify IPFIX logging
6832 self.vapi.ipfix_flush()
6834 capture = self.pg2.get_capture(10)
6835 ipfix = IPFIXDecoder()
6836 # first load template
6838 self.assertTrue(p.haslayer(IPFIX))
6839 if p.haslayer(Template):
6840 ipfix.add_template(p.getlayer(Template))
6841 # verify events in data set
6843 if p.haslayer(Data):
6844 data = ipfix.decode_data_set(p.getlayer(Set))
6845 self.verify_ipfix_max_entries_per_user(
6847 nat44_config.max_translations_per_user,
6848 self.pg0.remote_ip4)
6851 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6852 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6853 UDP(sport=3001, dport=3002))
6854 self.pg0.add_stream(p)
6855 self.pg_enable_capture(self.pg_interfaces)
6857 self.pg1.get_capture(1)
6859 def test_syslog_sess(self):
6860 """ Test syslog session creation and deletion """
6861 self.vapi.syslog_set_filter(
6862 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
6863 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
6864 self.nat44_add_address(self.nat_addr)
6865 flags = self.config_flags.NAT_IS_INSIDE
6866 self.vapi.nat44_interface_add_del_feature(
6867 sw_if_index=self.pg0.sw_if_index,
6868 flags=flags, is_add=1)
6869 self.vapi.nat44_interface_add_del_feature(
6870 sw_if_index=self.pg1.sw_if_index,
6873 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6874 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6875 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6876 self.pg0.add_stream(p)
6877 self.pg_enable_capture(self.pg_interfaces)
6879 capture = self.pg1.get_capture(1)
6880 self.tcp_port_out = capture[0][TCP].sport
6881 capture = self.pg2.get_capture(1)
6882 self.verify_syslog_sess(capture[0][Raw].load)
6884 self.pg_enable_capture(self.pg_interfaces)
6886 self.nat44_add_address(self.nat_addr, is_add=0)
6887 capture = self.pg2.get_capture(1)
6888 self.verify_syslog_sess(capture[0][Raw].load, False)
6891 super(TestNAT44EndpointDependent, self).tearDown()
6892 if not self.vpp_dead:
6894 self.vapi.cli("clear logging")
6896 def show_commands_at_teardown(self):
6897 self.logger.info(self.vapi.cli("show nat44 addresses"))
6898 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6899 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6900 self.logger.info(self.vapi.cli("show nat44 interface address"))
6901 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
6902 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
6903 self.logger.info(self.vapi.cli("show nat timeouts"))
6906 class TestNAT44Out2InDPO(MethodHolder):
6907 """ NAT44 Test Cases using out2in DPO """
6910 def setUpConstants(cls):
6911 super(TestNAT44Out2InDPO, cls).setUpConstants()
6912 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6915 def setUpClass(cls):
6916 super(TestNAT44Out2InDPO, cls).setUpClass()
6917 cls.vapi.cli("set log class nat level debug")
6920 cls.tcp_port_in = 6303
6921 cls.tcp_port_out = 6303
6922 cls.udp_port_in = 6304
6923 cls.udp_port_out = 6304
6924 cls.icmp_id_in = 6305
6925 cls.icmp_id_out = 6305
6926 cls.nat_addr = '10.0.0.3'
6927 cls.dst_ip4 = '192.168.70.1'
6929 cls.create_pg_interfaces(range(2))
6932 cls.pg0.config_ip4()
6933 cls.pg0.resolve_arp()
6936 cls.pg1.config_ip6()
6937 cls.pg1.resolve_ndp()
6939 r1 = VppIpRoute(cls, "::", 0,
6940 [VppRoutePath(cls.pg1.remote_ip6,
6941 cls.pg1.sw_if_index)],
6946 super(TestNAT44Out2InDPO, cls).tearDownClass()
6950 def tearDownClass(cls):
6951 super(TestNAT44Out2InDPO, cls).tearDownClass()
6953 def configure_xlat(self):
6954 self.dst_ip6_pfx = '1:2:3::'
6955 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6957 self.dst_ip6_pfx_len = 96
6958 self.src_ip6_pfx = '4:5:6::'
6959 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6961 self.src_ip6_pfx_len = 96
6962 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6963 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6964 '\x00\x00\x00\x00', 0)
6966 @unittest.skip('Temporary disabled')
6967 def test_464xlat_ce(self):
6968 """ Test 464XLAT CE with NAT44 """
6970 nat_config = self.vapi.nat_show_config()
6971 self.assertEqual(1, nat_config.out2in_dpo)
6973 self.configure_xlat()
6975 flags = self.config_flags.NAT_IS_INSIDE
6976 self.vapi.nat44_interface_add_del_feature(
6977 sw_if_index=self.pg0.sw_if_index,
6978 flags=flags, is_add=1)
6979 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
6980 last_ip_address=self.nat_addr_n,
6981 vrf_id=0xFFFFFFFF, is_add=1)
6983 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6984 self.dst_ip6_pfx_len)
6985 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6986 self.src_ip6_pfx_len)
6989 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6990 self.pg0.add_stream(pkts)
6991 self.pg_enable_capture(self.pg_interfaces)
6993 capture = self.pg1.get_capture(len(pkts))
6994 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6997 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6999 self.pg1.add_stream(pkts)
7000 self.pg_enable_capture(self.pg_interfaces)
7002 capture = self.pg0.get_capture(len(pkts))
7003 self.verify_capture_in(capture, self.pg0)
7005 self.vapi.nat44_interface_add_del_feature(
7006 sw_if_index=self.pg0.sw_if_index,
7008 self.vapi.nat44_add_del_address_range(
7009 first_ip_address=self.nat_addr_n,
7010 last_ip_address=self.nat_addr_n,
7013 @unittest.skip('Temporary disabled')
7014 def test_464xlat_ce_no_nat(self):
7015 """ Test 464XLAT CE without NAT44 """
7017 self.configure_xlat()
7019 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7020 self.dst_ip6_pfx_len)
7021 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7022 self.src_ip6_pfx_len)
7024 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7025 self.pg0.add_stream(pkts)
7026 self.pg_enable_capture(self.pg_interfaces)
7028 capture = self.pg1.get_capture(len(pkts))
7029 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7030 nat_ip=out_dst_ip6, same_port=True)
7032 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7033 self.pg1.add_stream(pkts)
7034 self.pg_enable_capture(self.pg_interfaces)
7036 capture = self.pg0.get_capture(len(pkts))
7037 self.verify_capture_in(capture, self.pg0)
7040 class TestDeterministicNAT(MethodHolder):
7041 """ Deterministic NAT Test Cases """
7044 def setUpConstants(cls):
7045 super(TestDeterministicNAT, cls).setUpConstants()
7046 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7049 def setUpClass(cls):
7050 super(TestDeterministicNAT, cls).setUpClass()
7051 cls.vapi.cli("set log class nat level debug")
7054 cls.tcp_port_in = 6303
7055 cls.tcp_external_port = 6303
7056 cls.udp_port_in = 6304
7057 cls.udp_external_port = 6304
7058 cls.icmp_id_in = 6305
7059 cls.nat_addr = '10.0.0.3'
7061 cls.create_pg_interfaces(range(3))
7062 cls.interfaces = list(cls.pg_interfaces)
7064 for i in cls.interfaces:
7069 cls.pg0.generate_remote_hosts(2)
7070 cls.pg0.configure_ipv4_neighbors()
7073 super(TestDeterministicNAT, cls).tearDownClass()
7077 def tearDownClass(cls):
7078 super(TestDeterministicNAT, cls).tearDownClass()
7080 def create_stream_in(self, in_if, out_if, ttl=64):
7082 Create packet stream for inside network
7084 :param in_if: Inside interface
7085 :param out_if: Outside interface
7086 :param ttl: TTL of generated packets
7090 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7091 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7092 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7096 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7097 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7098 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7102 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7103 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7104 ICMP(id=self.icmp_id_in, type='echo-request'))
7109 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7111 Create packet stream for outside network
7113 :param out_if: Outside interface
7114 :param dst_ip: Destination IP address (Default use global NAT address)
7115 :param ttl: TTL of generated packets
7118 dst_ip = self.nat_addr
7121 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7122 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7123 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7127 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7128 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7129 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7133 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7134 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7135 ICMP(id=self.icmp_external_id, type='echo-reply'))
7140 def verify_capture_out(self, capture, nat_ip=None):
7142 Verify captured packets on outside network
7144 :param capture: Captured packets
7145 :param nat_ip: Translated IP address (Default use global NAT address)
7146 :param same_port: Source port number is not translated (Default False)
7149 nat_ip = self.nat_addr
7150 for packet in capture:
7152 self.assertEqual(packet[IP].src, nat_ip)
7153 if packet.haslayer(TCP):
7154 self.tcp_port_out = packet[TCP].sport
7155 elif packet.haslayer(UDP):
7156 self.udp_port_out = packet[UDP].sport
7158 self.icmp_external_id = packet[ICMP].id
7160 self.logger.error(ppp("Unexpected or invalid packet "
7161 "(outside network):", packet))
7164 def test_deterministic_mode(self):
7165 """ NAT plugin run deterministic mode """
7166 in_addr = '172.16.255.0'
7167 out_addr = '172.17.255.50'
7168 in_addr_t = '172.16.255.20'
7172 nat_config = self.vapi.nat_show_config()
7173 self.assertEqual(1, nat_config.deterministic)
7175 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7176 in_plen=in_plen, out_addr=out_addr,
7179 rep1 = self.vapi.nat_det_forward(in_addr_t)
7180 self.assertEqual(str(rep1.out_addr), out_addr)
7181 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7183 self.assertEqual(str(rep2.in_addr), in_addr_t)
7185 deterministic_mappings = self.vapi.nat_det_map_dump()
7186 self.assertEqual(len(deterministic_mappings), 1)
7187 dsm = deterministic_mappings[0]
7188 self.assertEqual(in_addr, str(dsm.in_addr))
7189 self.assertEqual(in_plen, dsm.in_plen)
7190 self.assertEqual(out_addr, str(dsm.out_addr))
7191 self.assertEqual(out_plen, dsm.out_plen)
7193 self.clear_nat_det()
7194 deterministic_mappings = self.vapi.nat_det_map_dump()
7195 self.assertEqual(len(deterministic_mappings), 0)
7197 def test_set_timeouts(self):
7198 """ Set deterministic NAT timeouts """
7199 timeouts_before = self.vapi.nat_get_timeouts()
7201 self.vapi.nat_set_timeouts(
7202 udp=timeouts_before.udp + 10,
7203 tcp_established=timeouts_before.tcp_established + 10,
7204 tcp_transitory=timeouts_before.tcp_transitory + 10,
7205 icmp=timeouts_before.icmp + 10)
7207 timeouts_after = self.vapi.nat_get_timeouts()
7209 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7210 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7211 self.assertNotEqual(timeouts_before.tcp_established,
7212 timeouts_after.tcp_established)
7213 self.assertNotEqual(timeouts_before.tcp_transitory,
7214 timeouts_after.tcp_transitory)
7216 def test_det_in(self):
7217 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7219 nat_ip = "10.0.0.10"
7221 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7223 out_addr=socket.inet_aton(nat_ip),
7226 flags = self.config_flags.NAT_IS_INSIDE
7227 self.vapi.nat44_interface_add_del_feature(
7228 sw_if_index=self.pg0.sw_if_index,
7229 flags=flags, is_add=1)
7230 self.vapi.nat44_interface_add_del_feature(
7231 sw_if_index=self.pg1.sw_if_index,
7235 pkts = self.create_stream_in(self.pg0, self.pg1)
7236 self.pg0.add_stream(pkts)
7237 self.pg_enable_capture(self.pg_interfaces)
7239 capture = self.pg1.get_capture(len(pkts))
7240 self.verify_capture_out(capture, nat_ip)
7243 pkts = self.create_stream_out(self.pg1, nat_ip)
7244 self.pg1.add_stream(pkts)
7245 self.pg_enable_capture(self.pg_interfaces)
7247 capture = self.pg0.get_capture(len(pkts))
7248 self.verify_capture_in(capture, self.pg0)
7251 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7252 self.assertEqual(len(sessions), 3)
7256 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7257 self.assertEqual(s.in_port, self.tcp_port_in)
7258 self.assertEqual(s.out_port, self.tcp_port_out)
7259 self.assertEqual(s.ext_port, self.tcp_external_port)
7263 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7264 self.assertEqual(s.in_port, self.udp_port_in)
7265 self.assertEqual(s.out_port, self.udp_port_out)
7266 self.assertEqual(s.ext_port, self.udp_external_port)
7270 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7271 self.assertEqual(s.in_port, self.icmp_id_in)
7272 self.assertEqual(s.out_port, self.icmp_external_id)
7274 def test_multiple_users(self):
7275 """ Deterministic NAT multiple users """
7277 nat_ip = "10.0.0.10"
7279 external_port = 6303
7281 host0 = self.pg0.remote_hosts[0]
7282 host1 = self.pg0.remote_hosts[1]
7284 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7285 out_addr=socket.inet_aton(nat_ip),
7287 flags = self.config_flags.NAT_IS_INSIDE
7288 self.vapi.nat44_interface_add_del_feature(
7289 sw_if_index=self.pg0.sw_if_index,
7290 flags=flags, is_add=1)
7291 self.vapi.nat44_interface_add_del_feature(
7292 sw_if_index=self.pg1.sw_if_index,
7296 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7297 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7298 TCP(sport=port_in, dport=external_port))
7299 self.pg0.add_stream(p)
7300 self.pg_enable_capture(self.pg_interfaces)
7302 capture = self.pg1.get_capture(1)
7307 self.assertEqual(ip.src, nat_ip)
7308 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7309 self.assertEqual(tcp.dport, external_port)
7310 port_out0 = tcp.sport
7312 self.logger.error(ppp("Unexpected or invalid packet:", p))
7316 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7317 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7318 TCP(sport=port_in, dport=external_port))
7319 self.pg0.add_stream(p)
7320 self.pg_enable_capture(self.pg_interfaces)
7322 capture = self.pg1.get_capture(1)
7327 self.assertEqual(ip.src, nat_ip)
7328 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7329 self.assertEqual(tcp.dport, external_port)
7330 port_out1 = tcp.sport
7332 self.logger.error(ppp("Unexpected or invalid packet:", p))
7335 dms = self.vapi.nat_det_map_dump()
7336 self.assertEqual(1, len(dms))
7337 self.assertEqual(2, dms[0].ses_num)
7340 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7341 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7342 TCP(sport=external_port, dport=port_out0))
7343 self.pg1.add_stream(p)
7344 self.pg_enable_capture(self.pg_interfaces)
7346 capture = self.pg0.get_capture(1)
7351 self.assertEqual(ip.src, self.pg1.remote_ip4)
7352 self.assertEqual(ip.dst, host0.ip4)
7353 self.assertEqual(tcp.dport, port_in)
7354 self.assertEqual(tcp.sport, external_port)
7356 self.logger.error(ppp("Unexpected or invalid packet:", p))
7360 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7361 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7362 TCP(sport=external_port, dport=port_out1))
7363 self.pg1.add_stream(p)
7364 self.pg_enable_capture(self.pg_interfaces)
7366 capture = self.pg0.get_capture(1)
7371 self.assertEqual(ip.src, self.pg1.remote_ip4)
7372 self.assertEqual(ip.dst, host1.ip4)
7373 self.assertEqual(tcp.dport, port_in)
7374 self.assertEqual(tcp.sport, external_port)
7376 self.logger.error(ppp("Unexpected or invalid packet", p))
7379 # session close api test
7380 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7382 self.pg1.remote_ip4,
7384 dms = self.vapi.nat_det_map_dump()
7385 self.assertEqual(dms[0].ses_num, 1)
7387 self.vapi.nat_det_close_session_in(host0.ip4,
7389 self.pg1.remote_ip4,
7391 dms = self.vapi.nat_det_map_dump()
7392 self.assertEqual(dms[0].ses_num, 0)
7394 def test_tcp_session_close_detection_in(self):
7395 """ Deterministic NAT TCP session close from inside network """
7396 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7398 out_addr=socket.inet_aton(self.nat_addr),
7400 flags = self.config_flags.NAT_IS_INSIDE
7401 self.vapi.nat44_interface_add_del_feature(
7402 sw_if_index=self.pg0.sw_if_index,
7403 flags=flags, is_add=1)
7404 self.vapi.nat44_interface_add_del_feature(
7405 sw_if_index=self.pg1.sw_if_index,
7408 self.initiate_tcp_session(self.pg0, self.pg1)
7410 # close the session from inside
7412 # FIN packet in -> out
7413 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7414 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7415 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7417 self.pg0.add_stream(p)
7418 self.pg_enable_capture(self.pg_interfaces)
7420 self.pg1.get_capture(1)
7424 # ACK packet out -> in
7425 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7426 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7427 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7431 # FIN packet out -> in
7432 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7433 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7434 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7438 self.pg1.add_stream(pkts)
7439 self.pg_enable_capture(self.pg_interfaces)
7441 self.pg0.get_capture(2)
7443 # ACK packet in -> out
7444 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7445 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7446 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7448 self.pg0.add_stream(p)
7449 self.pg_enable_capture(self.pg_interfaces)
7451 self.pg1.get_capture(1)
7453 # Check if deterministic NAT44 closed the session
7454 dms = self.vapi.nat_det_map_dump()
7455 self.assertEqual(0, dms[0].ses_num)
7457 self.logger.error("TCP session termination failed")
7460 def test_tcp_session_close_detection_out(self):
7461 """ Deterministic NAT TCP session close from outside network """
7462 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7464 out_addr=socket.inet_aton(self.nat_addr),
7466 flags = self.config_flags.NAT_IS_INSIDE
7467 self.vapi.nat44_interface_add_del_feature(
7468 sw_if_index=self.pg0.sw_if_index,
7469 flags=flags, is_add=1)
7470 self.vapi.nat44_interface_add_del_feature(
7471 sw_if_index=self.pg1.sw_if_index,
7474 self.initiate_tcp_session(self.pg0, self.pg1)
7476 # close the session from outside
7478 # FIN packet out -> in
7479 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7480 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7481 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7483 self.pg1.add_stream(p)
7484 self.pg_enable_capture(self.pg_interfaces)
7486 self.pg0.get_capture(1)
7490 # ACK packet in -> out
7491 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7492 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7493 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7497 # ACK packet in -> out
7498 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7499 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7500 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7504 self.pg0.add_stream(pkts)
7505 self.pg_enable_capture(self.pg_interfaces)
7507 self.pg1.get_capture(2)
7509 # ACK packet out -> in
7510 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7511 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7512 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7514 self.pg1.add_stream(p)
7515 self.pg_enable_capture(self.pg_interfaces)
7517 self.pg0.get_capture(1)
7519 # Check if deterministic NAT44 closed the session
7520 dms = self.vapi.nat_det_map_dump()
7521 self.assertEqual(0, dms[0].ses_num)
7523 self.logger.error("TCP session termination failed")
7526 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7527 def test_session_timeout(self):
7528 """ Deterministic NAT session timeouts """
7529 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7531 out_addr=socket.inet_aton(self.nat_addr),
7533 flags = self.config_flags.NAT_IS_INSIDE
7534 self.vapi.nat44_interface_add_del_feature(
7535 sw_if_index=self.pg0.sw_if_index,
7536 flags=flags, is_add=1)
7537 self.vapi.nat44_interface_add_del_feature(
7538 sw_if_index=self.pg1.sw_if_index,
7541 self.initiate_tcp_session(self.pg0, self.pg1)
7542 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7544 pkts = self.create_stream_in(self.pg0, self.pg1)
7545 self.pg0.add_stream(pkts)
7546 self.pg_enable_capture(self.pg_interfaces)
7548 capture = self.pg1.get_capture(len(pkts))
7551 dms = self.vapi.nat_det_map_dump()
7552 self.assertEqual(0, dms[0].ses_num)
7554 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7555 def test_session_limit_per_user(self):
7556 """ Deterministic NAT maximum sessions per user limit """
7557 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7559 out_addr=socket.inet_aton(self.nat_addr),
7561 flags = self.config_flags.NAT_IS_INSIDE
7562 self.vapi.nat44_interface_add_del_feature(
7563 sw_if_index=self.pg0.sw_if_index,
7564 flags=flags, is_add=1)
7565 self.vapi.nat44_interface_add_del_feature(
7566 sw_if_index=self.pg1.sw_if_index,
7568 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7569 src_address=self.pg2.local_ip4,
7571 template_interval=10)
7572 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7576 for port in range(1025, 2025):
7577 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7578 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7579 UDP(sport=port, dport=port))
7582 self.pg0.add_stream(pkts)
7583 self.pg_enable_capture(self.pg_interfaces)
7585 capture = self.pg1.get_capture(len(pkts))
7587 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7588 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7589 UDP(sport=3001, dport=3002))
7590 self.pg0.add_stream(p)
7591 self.pg_enable_capture(self.pg_interfaces)
7593 capture = self.pg1.assert_nothing_captured()
7595 # verify ICMP error packet
7596 capture = self.pg0.get_capture(1)
7598 self.assertTrue(p.haslayer(ICMP))
7600 self.assertEqual(icmp.type, 3)
7601 self.assertEqual(icmp.code, 1)
7602 self.assertTrue(icmp.haslayer(IPerror))
7603 inner_ip = icmp[IPerror]
7604 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7605 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7607 dms = self.vapi.nat_det_map_dump()
7609 self.assertEqual(1000, dms[0].ses_num)
7611 # verify IPFIX logging
7612 self.vapi.ipfix_flush()
7614 capture = self.pg2.get_capture(2)
7615 ipfix = IPFIXDecoder()
7616 # first load template
7618 self.assertTrue(p.haslayer(IPFIX))
7619 if p.haslayer(Template):
7620 ipfix.add_template(p.getlayer(Template))
7621 # verify events in data set
7623 if p.haslayer(Data):
7624 data = ipfix.decode_data_set(p.getlayer(Set))
7625 self.verify_ipfix_max_entries_per_user(data,
7627 self.pg0.remote_ip4)
7629 def clear_nat_det(self):
7631 Clear deterministic NAT configuration.
7633 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7635 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7636 tcp_transitory=240, icmp=60)
7637 deterministic_mappings = self.vapi.nat_det_map_dump()
7638 for dsm in deterministic_mappings:
7639 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7640 in_plen=dsm.in_plen,
7641 out_addr=dsm.out_addr,
7642 out_plen=dsm.out_plen)
7644 interfaces = self.vapi.nat44_interface_dump()
7645 for intf in interfaces:
7646 self.vapi.nat44_interface_add_del_feature(
7647 sw_if_index=intf.sw_if_index,
7651 super(TestDeterministicNAT, self).tearDown()
7652 if not self.vpp_dead:
7653 self.clear_nat_det()
7655 def show_commands_at_teardown(self):
7656 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7657 self.logger.info(self.vapi.cli("show nat timeouts"))
7659 self.vapi.cli("show nat44 deterministic mappings"))
7661 self.vapi.cli("show nat44 deterministic sessions"))
7664 class TestNAT64(MethodHolder):
7665 """ NAT64 Test Cases """
7668 def setUpConstants(cls):
7669 super(TestNAT64, cls).setUpConstants()
7670 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7671 "nat64 st hash buckets 256", "}"])
7674 def setUpClass(cls):
7675 super(TestNAT64, cls).setUpClass()
7678 cls.tcp_port_in = 6303
7679 cls.tcp_port_out = 6303
7680 cls.udp_port_in = 6304
7681 cls.udp_port_out = 6304
7682 cls.icmp_id_in = 6305
7683 cls.icmp_id_out = 6305
7684 cls.tcp_external_port = 80
7685 cls.nat_addr = '10.0.0.3'
7686 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7688 cls.vrf1_nat_addr = '10.0.10.3'
7689 cls.ipfix_src_port = 4739
7690 cls.ipfix_domain_id = 1
7692 cls.create_pg_interfaces(range(6))
7693 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7694 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7695 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7697 cls.vapi.ip_table_add_del(is_add=1,
7698 table={'table_id': cls.vrf1_id,
7701 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7703 cls.pg0.generate_remote_hosts(2)
7705 for i in cls.ip6_interfaces:
7708 i.configure_ipv6_neighbors()
7710 for i in cls.ip4_interfaces:
7716 cls.pg3.config_ip4()
7717 cls.pg3.resolve_arp()
7718 cls.pg3.config_ip6()
7719 cls.pg3.configure_ipv6_neighbors()
7722 cls.pg5.config_ip6()
7725 super(TestNAT64, cls).tearDownClass()
7729 def tearDownClass(cls):
7730 super(TestNAT64, cls).tearDownClass()
7732 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7733 """ NAT64 inside interface handles Neighbor Advertisement """
7735 flags = self.config_flags.NAT_IS_INSIDE
7736 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7737 sw_if_index=self.pg5.sw_if_index)
7740 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7741 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7742 ICMPv6EchoRequest())
7744 self.pg5.add_stream(pkts)
7745 self.pg_enable_capture(self.pg_interfaces)
7748 # Wait for Neighbor Solicitation
7749 capture = self.pg5.get_capture(len(pkts))
7752 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7753 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7754 tgt = packet[ICMPv6ND_NS].tgt
7756 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7759 # Send Neighbor Advertisement
7760 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7761 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7762 ICMPv6ND_NA(tgt=tgt) /
7763 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7765 self.pg5.add_stream(pkts)
7766 self.pg_enable_capture(self.pg_interfaces)
7769 # Try to send ping again
7771 self.pg5.add_stream(pkts)
7772 self.pg_enable_capture(self.pg_interfaces)
7775 # Wait for ping reply
7776 capture = self.pg5.get_capture(len(pkts))
7779 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7780 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7781 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7783 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7786 def test_pool(self):
7787 """ Add/delete address to NAT64 pool """
7788 nat_addr = '1.2.3.4'
7790 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7792 vrf_id=0xFFFFFFFF, is_add=1)
7794 addresses = self.vapi.nat64_pool_addr_dump()
7795 self.assertEqual(len(addresses), 1)
7796 self.assertEqual(str(addresses[0].address), nat_addr)
7798 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7800 vrf_id=0xFFFFFFFF, is_add=0)
7802 addresses = self.vapi.nat64_pool_addr_dump()
7803 self.assertEqual(len(addresses), 0)
7805 def test_interface(self):
7806 """ Enable/disable NAT64 feature on the interface """
7807 flags = self.config_flags.NAT_IS_INSIDE
7808 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7809 sw_if_index=self.pg0.sw_if_index)
7810 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7811 sw_if_index=self.pg1.sw_if_index)
7813 interfaces = self.vapi.nat64_interface_dump()
7814 self.assertEqual(len(interfaces), 2)
7817 for intf in interfaces:
7818 if intf.sw_if_index == self.pg0.sw_if_index:
7819 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7821 elif intf.sw_if_index == self.pg1.sw_if_index:
7822 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7824 self.assertTrue(pg0_found)
7825 self.assertTrue(pg1_found)
7827 features = self.vapi.cli("show interface features pg0")
7828 self.assertIn('nat64-in2out', features)
7829 features = self.vapi.cli("show interface features pg1")
7830 self.assertIn('nat64-out2in', features)
7832 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7833 sw_if_index=self.pg0.sw_if_index)
7834 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7835 sw_if_index=self.pg1.sw_if_index)
7837 interfaces = self.vapi.nat64_interface_dump()
7838 self.assertEqual(len(interfaces), 0)
7840 def test_static_bib(self):
7841 """ Add/delete static BIB entry """
7842 in_addr = '2001:db8:85a3::8a2e:370:7334'
7843 out_addr = '10.1.1.3'
7846 proto = IP_PROTOS.tcp
7848 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7849 i_port=in_port, o_port=out_port,
7850 proto=proto, vrf_id=0, is_add=1)
7851 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7854 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7856 self.assertEqual(str(bibe.i_addr), in_addr)
7857 self.assertEqual(str(bibe.o_addr), out_addr)
7858 self.assertEqual(bibe.i_port, in_port)
7859 self.assertEqual(bibe.o_port, out_port)
7860 self.assertEqual(static_bib_num, 1)
7861 bibs = self.statistics.get_counter('/nat64/total-bibs')
7862 self.assertEqual(bibs[0][0], 1)
7864 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7865 i_port=in_port, o_port=out_port,
7866 proto=proto, vrf_id=0, is_add=0)
7867 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7870 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7872 self.assertEqual(static_bib_num, 0)
7873 bibs = self.statistics.get_counter('/nat64/total-bibs')
7874 self.assertEqual(bibs[0][0], 0)
7876 def test_set_timeouts(self):
7877 """ Set NAT64 timeouts """
7878 # verify default values
7879 timeouts = self.vapi.nat_get_timeouts()
7880 self.assertEqual(timeouts.udp, 300)
7881 self.assertEqual(timeouts.icmp, 60)
7882 self.assertEqual(timeouts.tcp_transitory, 240)
7883 self.assertEqual(timeouts.tcp_established, 7440)
7885 # set and verify custom values
7886 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7887 tcp_transitory=250, icmp=30)
7888 timeouts = self.vapi.nat_get_timeouts()
7889 self.assertEqual(timeouts.udp, 200)
7890 self.assertEqual(timeouts.icmp, 30)
7891 self.assertEqual(timeouts.tcp_transitory, 250)
7892 self.assertEqual(timeouts.tcp_established, 7450)
7894 def test_dynamic(self):
7895 """ NAT64 dynamic translation test """
7896 self.tcp_port_in = 6303
7897 self.udp_port_in = 6304
7898 self.icmp_id_in = 6305
7900 ses_num_start = self.nat64_get_ses_num()
7902 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7903 end_addr=self.nat_addr,
7906 flags = self.config_flags.NAT_IS_INSIDE
7907 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7908 sw_if_index=self.pg0.sw_if_index)
7909 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7910 sw_if_index=self.pg1.sw_if_index)
7913 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7914 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7915 icmpn = self.statistics.get_err_counter(
7916 '/err/nat64-in2out/ICMP packets')
7917 totaln = self.statistics.get_err_counter(
7918 '/err/nat64-in2out/good in2out packets processed')
7920 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7921 self.pg0.add_stream(pkts)
7922 self.pg_enable_capture(self.pg_interfaces)
7924 capture = self.pg1.get_capture(len(pkts))
7925 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7926 dst_ip=self.pg1.remote_ip4)
7928 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
7929 self.assertEqual(err - tcpn, 1)
7930 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
7931 self.assertEqual(err - udpn, 1)
7932 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
7933 self.assertEqual(err - icmpn, 1)
7934 err = self.statistics.get_err_counter(
7935 '/err/nat64-in2out/good in2out packets processed')
7936 self.assertEqual(err - totaln, 3)
7939 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7940 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7941 icmpn = self.statistics.get_err_counter(
7942 '/err/nat64-out2in/ICMP packets')
7943 totaln = self.statistics.get_err_counter(
7944 '/err/nat64-out2in/good out2in packets processed')
7946 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7947 self.pg1.add_stream(pkts)
7948 self.pg_enable_capture(self.pg_interfaces)
7950 capture = self.pg0.get_capture(len(pkts))
7951 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7952 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7954 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
7955 self.assertEqual(err - tcpn, 2)
7956 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
7957 self.assertEqual(err - udpn, 1)
7958 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
7959 self.assertEqual(err - icmpn, 1)
7960 err = self.statistics.get_err_counter(
7961 '/err/nat64-out2in/good out2in packets processed')
7962 self.assertEqual(err - totaln, 4)
7964 bibs = self.statistics.get_counter('/nat64/total-bibs')
7965 self.assertEqual(bibs[0][0], 3)
7966 sessions = self.statistics.get_counter('/nat64/total-sessions')
7967 self.assertEqual(sessions[0][0], 3)
7970 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7971 self.pg0.add_stream(pkts)
7972 self.pg_enable_capture(self.pg_interfaces)
7974 capture = self.pg1.get_capture(len(pkts))
7975 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7976 dst_ip=self.pg1.remote_ip4)
7979 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7980 self.pg1.add_stream(pkts)
7981 self.pg_enable_capture(self.pg_interfaces)
7983 capture = self.pg0.get_capture(len(pkts))
7984 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7986 ses_num_end = self.nat64_get_ses_num()
7988 self.assertEqual(ses_num_end - ses_num_start, 3)
7990 # tenant with specific VRF
7991 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7992 end_addr=self.vrf1_nat_addr,
7993 vrf_id=self.vrf1_id, is_add=1)
7994 flags = self.config_flags.NAT_IS_INSIDE
7995 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7996 sw_if_index=self.pg2.sw_if_index)
7998 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7999 self.pg2.add_stream(pkts)
8000 self.pg_enable_capture(self.pg_interfaces)
8002 capture = self.pg1.get_capture(len(pkts))
8003 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8004 dst_ip=self.pg1.remote_ip4)
8006 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8007 self.pg1.add_stream(pkts)
8008 self.pg_enable_capture(self.pg_interfaces)
8010 capture = self.pg2.get_capture(len(pkts))
8011 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8013 def test_static(self):
8014 """ NAT64 static translation test """
8015 self.tcp_port_in = 60303
8016 self.udp_port_in = 60304
8017 self.icmp_id_in = 60305
8018 self.tcp_port_out = 60303
8019 self.udp_port_out = 60304
8020 self.icmp_id_out = 60305
8022 ses_num_start = self.nat64_get_ses_num()
8024 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8025 end_addr=self.nat_addr,
8028 flags = self.config_flags.NAT_IS_INSIDE
8029 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8030 sw_if_index=self.pg0.sw_if_index)
8031 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8032 sw_if_index=self.pg1.sw_if_index)
8034 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8035 o_addr=self.nat_addr,
8036 i_port=self.tcp_port_in,
8037 o_port=self.tcp_port_out,
8038 proto=IP_PROTOS.tcp, vrf_id=0,
8040 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8041 o_addr=self.nat_addr,
8042 i_port=self.udp_port_in,
8043 o_port=self.udp_port_out,
8044 proto=IP_PROTOS.udp, vrf_id=0,
8046 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6n,
8047 o_addr=self.nat_addr,
8048 i_port=self.icmp_id_in,
8049 o_port=self.icmp_id_out,
8050 proto=IP_PROTOS.icmp, vrf_id=0,
8054 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8055 self.pg0.add_stream(pkts)
8056 self.pg_enable_capture(self.pg_interfaces)
8058 capture = self.pg1.get_capture(len(pkts))
8059 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8060 dst_ip=self.pg1.remote_ip4, same_port=True)
8063 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8064 self.pg1.add_stream(pkts)
8065 self.pg_enable_capture(self.pg_interfaces)
8067 capture = self.pg0.get_capture(len(pkts))
8068 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8069 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8071 ses_num_end = self.nat64_get_ses_num()
8073 self.assertEqual(ses_num_end - ses_num_start, 3)
8075 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8076 def test_session_timeout(self):
8077 """ NAT64 session timeout """
8078 self.icmp_id_in = 1234
8079 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8080 end_addr=self.nat_addr,
8083 flags = self.config_flags.NAT_IS_INSIDE
8084 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8085 sw_if_index=self.pg0.sw_if_index)
8086 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8087 sw_if_index=self.pg1.sw_if_index)
8088 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8092 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8093 self.pg0.add_stream(pkts)
8094 self.pg_enable_capture(self.pg_interfaces)
8096 capture = self.pg1.get_capture(len(pkts))
8098 ses_num_before_timeout = self.nat64_get_ses_num()
8102 # ICMP and TCP session after timeout
8103 ses_num_after_timeout = self.nat64_get_ses_num()
8104 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8106 def test_icmp_error(self):
8107 """ NAT64 ICMP Error message translation """
8108 self.tcp_port_in = 6303
8109 self.udp_port_in = 6304
8110 self.icmp_id_in = 6305
8112 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8113 end_addr=self.nat_addr,
8116 flags = self.config_flags.NAT_IS_INSIDE
8117 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8118 sw_if_index=self.pg0.sw_if_index)
8119 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8120 sw_if_index=self.pg1.sw_if_index)
8122 # send some packets to create sessions
8123 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8124 self.pg0.add_stream(pkts)
8125 self.pg_enable_capture(self.pg_interfaces)
8127 capture_ip4 = self.pg1.get_capture(len(pkts))
8128 self.verify_capture_out(capture_ip4,
8129 nat_ip=self.nat_addr,
8130 dst_ip=self.pg1.remote_ip4)
8132 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8133 self.pg1.add_stream(pkts)
8134 self.pg_enable_capture(self.pg_interfaces)
8136 capture_ip6 = self.pg0.get_capture(len(pkts))
8137 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8138 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8139 self.pg0.remote_ip6)
8142 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8143 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8144 ICMPv6DestUnreach(code=1) /
8145 packet[IPv6] for packet in capture_ip6]
8146 self.pg0.add_stream(pkts)
8147 self.pg_enable_capture(self.pg_interfaces)
8149 capture = self.pg1.get_capture(len(pkts))
8150 for packet in capture:
8152 self.assertEqual(packet[IP].src, self.nat_addr)
8153 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8154 self.assertEqual(packet[ICMP].type, 3)
8155 self.assertEqual(packet[ICMP].code, 13)
8156 inner = packet[IPerror]
8157 self.assertEqual(inner.src, self.pg1.remote_ip4)
8158 self.assertEqual(inner.dst, self.nat_addr)
8159 self.assert_packet_checksums_valid(packet)
8160 if inner.haslayer(TCPerror):
8161 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8162 elif inner.haslayer(UDPerror):
8163 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8165 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8167 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8171 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8172 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8173 ICMP(type=3, code=13) /
8174 packet[IP] for packet in capture_ip4]
8175 self.pg1.add_stream(pkts)
8176 self.pg_enable_capture(self.pg_interfaces)
8178 capture = self.pg0.get_capture(len(pkts))
8179 for packet in capture:
8181 self.assertEqual(packet[IPv6].src, ip.src)
8182 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8183 icmp = packet[ICMPv6DestUnreach]
8184 self.assertEqual(icmp.code, 1)
8185 inner = icmp[IPerror6]
8186 self.assertEqual(inner.src, self.pg0.remote_ip6)
8187 self.assertEqual(inner.dst, ip.src)
8188 self.assert_icmpv6_checksum_valid(packet)
8189 if inner.haslayer(TCPerror):
8190 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8191 elif inner.haslayer(UDPerror):
8192 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8194 self.assertEqual(inner[ICMPv6EchoRequest].id,
8197 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8200 def test_hairpinning(self):
8201 """ NAT64 hairpinning """
8203 client = self.pg0.remote_hosts[0]
8204 server = self.pg0.remote_hosts[1]
8205 server_tcp_in_port = 22
8206 server_tcp_out_port = 4022
8207 server_udp_in_port = 23
8208 server_udp_out_port = 4023
8209 client_tcp_in_port = 1234
8210 client_udp_in_port = 1235
8211 client_tcp_out_port = 0
8212 client_udp_out_port = 0
8213 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8214 nat_addr_ip6 = ip.src
8216 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8217 end_addr=self.nat_addr,
8220 flags = self.config_flags.NAT_IS_INSIDE
8221 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8222 sw_if_index=self.pg0.sw_if_index)
8223 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8224 sw_if_index=self.pg1.sw_if_index)
8226 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8227 o_addr=self.nat_addr,
8228 i_port=server_tcp_in_port,
8229 o_port=server_tcp_out_port,
8230 proto=IP_PROTOS.tcp, vrf_id=0,
8232 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8233 o_addr=self.nat_addr,
8234 i_port=server_udp_in_port,
8235 o_port=server_udp_out_port,
8236 proto=IP_PROTOS.udp, vrf_id=0,
8241 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8242 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8243 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8245 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8246 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8247 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8249 self.pg0.add_stream(pkts)
8250 self.pg_enable_capture(self.pg_interfaces)
8252 capture = self.pg0.get_capture(len(pkts))
8253 for packet in capture:
8255 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8256 self.assertEqual(packet[IPv6].dst, server.ip6)
8257 self.assert_packet_checksums_valid(packet)
8258 if packet.haslayer(TCP):
8259 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8260 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8261 client_tcp_out_port = packet[TCP].sport
8263 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8264 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8265 client_udp_out_port = packet[UDP].sport
8267 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8272 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8273 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8274 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8276 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8277 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8278 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8280 self.pg0.add_stream(pkts)
8281 self.pg_enable_capture(self.pg_interfaces)
8283 capture = self.pg0.get_capture(len(pkts))
8284 for packet in capture:
8286 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8287 self.assertEqual(packet[IPv6].dst, client.ip6)
8288 self.assert_packet_checksums_valid(packet)
8289 if packet.haslayer(TCP):
8290 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8291 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8293 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8294 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8296 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8301 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8302 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8303 ICMPv6DestUnreach(code=1) /
8304 packet[IPv6] for packet in capture]
8305 self.pg0.add_stream(pkts)
8306 self.pg_enable_capture(self.pg_interfaces)
8308 capture = self.pg0.get_capture(len(pkts))
8309 for packet in capture:
8311 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8312 self.assertEqual(packet[IPv6].dst, server.ip6)
8313 icmp = packet[ICMPv6DestUnreach]
8314 self.assertEqual(icmp.code, 1)
8315 inner = icmp[IPerror6]
8316 self.assertEqual(inner.src, server.ip6)
8317 self.assertEqual(inner.dst, nat_addr_ip6)
8318 self.assert_packet_checksums_valid(packet)
8319 if inner.haslayer(TCPerror):
8320 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8321 self.assertEqual(inner[TCPerror].dport,
8322 client_tcp_out_port)
8324 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8325 self.assertEqual(inner[UDPerror].dport,
8326 client_udp_out_port)
8328 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8331 def test_prefix(self):
8332 """ NAT64 Network-Specific Prefix """
8334 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8335 end_addr=self.nat_addr,
8338 flags = self.config_flags.NAT_IS_INSIDE
8339 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8340 sw_if_index=self.pg0.sw_if_index)
8341 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8342 sw_if_index=self.pg1.sw_if_index)
8343 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8344 end_addr=self.vrf1_nat_addr,
8345 vrf_id=self.vrf1_id, is_add=1)
8346 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8347 sw_if_index=self.pg2.sw_if_index)
8350 global_pref64 = "2001:db8::"
8351 global_pref64_len = 32
8352 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8353 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8356 prefix = self.vapi.nat64_prefix_dump()
8357 self.assertEqual(len(prefix), 1)
8358 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8359 self.assertEqual(prefix[0].vrf_id, 0)
8361 # Add tenant specific prefix
8362 vrf1_pref64 = "2001:db8:122:300::"
8363 vrf1_pref64_len = 56
8364 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8365 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8366 vrf_id=self.vrf1_id, is_add=1)
8368 prefix = self.vapi.nat64_prefix_dump()
8369 self.assertEqual(len(prefix), 2)
8372 pkts = self.create_stream_in_ip6(self.pg0,
8375 plen=global_pref64_len)
8376 self.pg0.add_stream(pkts)
8377 self.pg_enable_capture(self.pg_interfaces)
8379 capture = self.pg1.get_capture(len(pkts))
8380 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8381 dst_ip=self.pg1.remote_ip4)
8383 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8384 self.pg1.add_stream(pkts)
8385 self.pg_enable_capture(self.pg_interfaces)
8387 capture = self.pg0.get_capture(len(pkts))
8388 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8391 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8393 # Tenant specific prefix
8394 pkts = self.create_stream_in_ip6(self.pg2,
8397 plen=vrf1_pref64_len)
8398 self.pg2.add_stream(pkts)
8399 self.pg_enable_capture(self.pg_interfaces)
8401 capture = self.pg1.get_capture(len(pkts))
8402 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8403 dst_ip=self.pg1.remote_ip4)
8405 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8406 self.pg1.add_stream(pkts)
8407 self.pg_enable_capture(self.pg_interfaces)
8409 capture = self.pg2.get_capture(len(pkts))
8410 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8413 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8415 def test_unknown_proto(self):
8416 """ NAT64 translate packet with unknown protocol """
8418 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8419 end_addr=self.nat_addr,
8422 flags = self.config_flags.NAT_IS_INSIDE
8423 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8424 sw_if_index=self.pg0.sw_if_index)
8425 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8426 sw_if_index=self.pg1.sw_if_index)
8427 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8430 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8431 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8432 TCP(sport=self.tcp_port_in, dport=20))
8433 self.pg0.add_stream(p)
8434 self.pg_enable_capture(self.pg_interfaces)
8436 p = self.pg1.get_capture(1)
8438 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8439 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8441 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8442 TCP(sport=1234, dport=1234))
8443 self.pg0.add_stream(p)
8444 self.pg_enable_capture(self.pg_interfaces)
8446 p = self.pg1.get_capture(1)
8449 self.assertEqual(packet[IP].src, self.nat_addr)
8450 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8451 self.assertEqual(packet.haslayer(GRE), 1)
8452 self.assert_packet_checksums_valid(packet)
8454 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8458 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8459 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8461 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8462 TCP(sport=1234, dport=1234))
8463 self.pg1.add_stream(p)
8464 self.pg_enable_capture(self.pg_interfaces)
8466 p = self.pg0.get_capture(1)
8469 self.assertEqual(packet[IPv6].src, remote_ip6)
8470 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8471 self.assertEqual(packet[IPv6].nh, 47)
8473 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8476 def test_hairpinning_unknown_proto(self):
8477 """ NAT64 translate packet with unknown protocol - hairpinning """
8479 client = self.pg0.remote_hosts[0]
8480 server = self.pg0.remote_hosts[1]
8481 server_tcp_in_port = 22
8482 server_tcp_out_port = 4022
8483 client_tcp_in_port = 1234
8484 client_tcp_out_port = 1235
8485 server_nat_ip = "10.0.0.100"
8486 client_nat_ip = "10.0.0.110"
8487 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8488 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8490 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8491 end_addr=client_nat_ip,
8494 flags = self.config_flags.NAT_IS_INSIDE
8495 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8496 sw_if_index=self.pg0.sw_if_index)
8497 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8498 sw_if_index=self.pg1.sw_if_index)
8500 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8501 o_addr=server_nat_ip,
8502 i_port=server_tcp_in_port,
8503 o_port=server_tcp_out_port,
8504 proto=IP_PROTOS.tcp, vrf_id=0,
8507 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8508 o_addr=server_nat_ip, i_port=0,
8510 proto=IP_PROTOS.gre, vrf_id=0,
8513 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8514 o_addr=client_nat_ip,
8515 i_port=client_tcp_in_port,
8516 o_port=client_tcp_out_port,
8517 proto=IP_PROTOS.tcp, vrf_id=0,
8521 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8522 IPv6(src=client.ip6, dst=server_nat_ip6) /
8523 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8524 self.pg0.add_stream(p)
8525 self.pg_enable_capture(self.pg_interfaces)
8527 p = self.pg0.get_capture(1)
8529 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8530 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8532 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8533 TCP(sport=1234, dport=1234))
8534 self.pg0.add_stream(p)
8535 self.pg_enable_capture(self.pg_interfaces)
8537 p = self.pg0.get_capture(1)
8540 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8541 self.assertEqual(packet[IPv6].dst, server.ip6)
8542 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8544 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8548 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8549 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8551 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8552 TCP(sport=1234, dport=1234))
8553 self.pg0.add_stream(p)
8554 self.pg_enable_capture(self.pg_interfaces)
8556 p = self.pg0.get_capture(1)
8559 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8560 self.assertEqual(packet[IPv6].dst, client.ip6)
8561 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8563 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8566 def test_one_armed_nat64(self):
8567 """ One armed NAT64 """
8569 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8573 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8574 end_addr=self.nat_addr,
8577 flags = self.config_flags.NAT_IS_INSIDE
8578 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8579 sw_if_index=self.pg3.sw_if_index)
8580 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8581 sw_if_index=self.pg3.sw_if_index)
8584 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8585 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8586 TCP(sport=12345, dport=80))
8587 self.pg3.add_stream(p)
8588 self.pg_enable_capture(self.pg_interfaces)
8590 capture = self.pg3.get_capture(1)
8595 self.assertEqual(ip.src, self.nat_addr)
8596 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8597 self.assertNotEqual(tcp.sport, 12345)
8598 external_port = tcp.sport
8599 self.assertEqual(tcp.dport, 80)
8600 self.assert_packet_checksums_valid(p)
8602 self.logger.error(ppp("Unexpected or invalid packet:", p))
8606 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8607 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8608 TCP(sport=80, dport=external_port))
8609 self.pg3.add_stream(p)
8610 self.pg_enable_capture(self.pg_interfaces)
8612 capture = self.pg3.get_capture(1)
8617 self.assertEqual(ip.src, remote_host_ip6)
8618 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8619 self.assertEqual(tcp.sport, 80)
8620 self.assertEqual(tcp.dport, 12345)
8621 self.assert_packet_checksums_valid(p)
8623 self.logger.error(ppp("Unexpected or invalid packet:", p))
8626 def test_frag_in_order(self):
8627 """ NAT64 translate fragments arriving in order """
8628 self.tcp_port_in = random.randint(1025, 65535)
8630 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8631 end_addr=self.nat_addr,
8634 flags = self.config_flags.NAT_IS_INSIDE
8635 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8636 sw_if_index=self.pg0.sw_if_index)
8637 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8638 sw_if_index=self.pg1.sw_if_index)
8642 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8643 self.tcp_port_in, 20, data)
8644 self.pg0.add_stream(pkts)
8645 self.pg_enable_capture(self.pg_interfaces)
8647 frags = self.pg1.get_capture(len(pkts))
8648 p = self.reass_frags_and_verify(frags,
8650 self.pg1.remote_ip4)
8651 self.assertEqual(p[TCP].dport, 20)
8652 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8653 self.tcp_port_out = p[TCP].sport
8654 self.assertEqual(data, p[Raw].load)
8657 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8658 pkts = self.create_stream_frag(self.pg1,
8663 self.pg1.add_stream(pkts)
8664 self.pg_enable_capture(self.pg_interfaces)
8666 frags = self.pg0.get_capture(len(pkts))
8667 self.logger.debug(ppc("Captured:", frags))
8668 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8669 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8670 self.assertEqual(p[TCP].sport, 20)
8671 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8672 self.assertEqual(data, p[Raw].load)
8674 def test_reass_hairpinning(self):
8675 """ NAT64 fragments hairpinning """
8677 server = self.pg0.remote_hosts[1]
8678 server_in_port = random.randint(1025, 65535)
8679 server_out_port = random.randint(1025, 65535)
8680 client_in_port = random.randint(1025, 65535)
8681 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8682 nat_addr_ip6 = ip.src
8684 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8685 end_addr=self.nat_addr,
8688 flags = self.config_flags.NAT_IS_INSIDE
8689 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8690 sw_if_index=self.pg0.sw_if_index)
8691 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8692 sw_if_index=self.pg1.sw_if_index)
8694 # add static BIB entry for server
8695 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8696 o_addr=self.nat_addr,
8697 i_port=server_in_port,
8698 o_port=server_out_port,
8699 proto=IP_PROTOS.tcp, vrf_id=0,
8702 # send packet from host to server
8703 pkts = self.create_stream_frag_ip6(self.pg0,
8708 self.pg0.add_stream(pkts)
8709 self.pg_enable_capture(self.pg_interfaces)
8711 frags = self.pg0.get_capture(len(pkts))
8712 self.logger.debug(ppc("Captured:", frags))
8713 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8714 self.assertNotEqual(p[TCP].sport, client_in_port)
8715 self.assertEqual(p[TCP].dport, server_in_port)
8716 self.assertEqual(data, p[Raw].load)
8718 def test_frag_out_of_order(self):
8719 """ NAT64 translate fragments arriving out of order """
8720 self.tcp_port_in = random.randint(1025, 65535)
8722 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8723 end_addr=self.nat_addr,
8726 flags = self.config_flags.NAT_IS_INSIDE
8727 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8728 sw_if_index=self.pg0.sw_if_index)
8729 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8730 sw_if_index=self.pg1.sw_if_index)
8734 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8735 self.tcp_port_in, 20, data)
8737 self.pg0.add_stream(pkts)
8738 self.pg_enable_capture(self.pg_interfaces)
8740 frags = self.pg1.get_capture(len(pkts))
8741 p = self.reass_frags_and_verify(frags,
8743 self.pg1.remote_ip4)
8744 self.assertEqual(p[TCP].dport, 20)
8745 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8746 self.tcp_port_out = p[TCP].sport
8747 self.assertEqual(data, p[Raw].load)
8750 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8751 pkts = self.create_stream_frag(self.pg1,
8757 self.pg1.add_stream(pkts)
8758 self.pg_enable_capture(self.pg_interfaces)
8760 frags = self.pg0.get_capture(len(pkts))
8761 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8762 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8763 self.assertEqual(p[TCP].sport, 20)
8764 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8765 self.assertEqual(data, p[Raw].load)
8767 def test_interface_addr(self):
8768 """ Acquire NAT64 pool addresses from interface """
8769 self.vapi.nat64_add_del_interface_addr(
8771 sw_if_index=self.pg4.sw_if_index)
8773 # no address in NAT64 pool
8774 addresses = self.vapi.nat44_address_dump()
8775 self.assertEqual(0, len(addresses))
8777 # configure interface address and check NAT64 address pool
8778 self.pg4.config_ip4()
8779 addresses = self.vapi.nat64_pool_addr_dump()
8780 self.assertEqual(len(addresses), 1)
8782 self.assertEqual(str(addresses[0].address),
8785 # remove interface address and check NAT64 address pool
8786 self.pg4.unconfig_ip4()
8787 addresses = self.vapi.nat64_pool_addr_dump()
8788 self.assertEqual(0, len(addresses))
8790 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8791 def test_ipfix_max_bibs_sessions(self):
8792 """ IPFIX logging maximum session and BIB entries exceeded """
8795 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8799 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8800 end_addr=self.nat_addr,
8803 flags = self.config_flags.NAT_IS_INSIDE
8804 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8805 sw_if_index=self.pg0.sw_if_index)
8806 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8807 sw_if_index=self.pg1.sw_if_index)
8811 for i in range(0, max_bibs):
8812 src = "fd01:aa::%x" % (i)
8813 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8814 IPv6(src=src, dst=remote_host_ip6) /
8815 TCP(sport=12345, dport=80))
8817 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8818 IPv6(src=src, dst=remote_host_ip6) /
8819 TCP(sport=12345, dport=22))
8821 self.pg0.add_stream(pkts)
8822 self.pg_enable_capture(self.pg_interfaces)
8824 self.pg1.get_capture(max_sessions)
8826 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8827 src_address=self.pg3.local_ip4,
8829 template_interval=10)
8830 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8831 src_port=self.ipfix_src_port,
8834 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8835 IPv6(src=src, dst=remote_host_ip6) /
8836 TCP(sport=12345, dport=25))
8837 self.pg0.add_stream(p)
8838 self.pg_enable_capture(self.pg_interfaces)
8840 self.pg1.assert_nothing_captured()
8842 self.vapi.ipfix_flush()
8843 capture = self.pg3.get_capture(9)
8844 ipfix = IPFIXDecoder()
8845 # first load template
8847 self.assertTrue(p.haslayer(IPFIX))
8848 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8849 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8850 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8851 self.assertEqual(p[UDP].dport, 4739)
8852 self.assertEqual(p[IPFIX].observationDomainID,
8853 self.ipfix_domain_id)
8854 if p.haslayer(Template):
8855 ipfix.add_template(p.getlayer(Template))
8856 # verify events in data set
8858 if p.haslayer(Data):
8859 data = ipfix.decode_data_set(p.getlayer(Set))
8860 self.verify_ipfix_max_sessions(data, max_sessions)
8862 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8863 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8864 TCP(sport=12345, dport=80))
8865 self.pg0.add_stream(p)
8866 self.pg_enable_capture(self.pg_interfaces)
8868 self.pg1.assert_nothing_captured()
8870 self.vapi.ipfix_flush()
8871 capture = self.pg3.get_capture(1)
8872 # verify events in data set
8874 self.assertTrue(p.haslayer(IPFIX))
8875 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8876 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8877 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8878 self.assertEqual(p[UDP].dport, 4739)
8879 self.assertEqual(p[IPFIX].observationDomainID,
8880 self.ipfix_domain_id)
8881 if p.haslayer(Data):
8882 data = ipfix.decode_data_set(p.getlayer(Set))
8883 self.verify_ipfix_max_bibs(data, max_bibs)
8885 def test_ipfix_bib_ses(self):
8886 """ IPFIX logging NAT64 BIB/session create and delete events """
8887 self.tcp_port_in = random.randint(1025, 65535)
8888 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8892 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8893 end_addr=self.nat_addr,
8896 flags = self.config_flags.NAT_IS_INSIDE
8897 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8898 sw_if_index=self.pg0.sw_if_index)
8899 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8900 sw_if_index=self.pg1.sw_if_index)
8901 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8902 src_address=self.pg3.local_ip4,
8904 template_interval=10)
8905 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8906 src_port=self.ipfix_src_port,
8910 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8911 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8912 TCP(sport=self.tcp_port_in, dport=25))
8913 self.pg0.add_stream(p)
8914 self.pg_enable_capture(self.pg_interfaces)
8916 p = self.pg1.get_capture(1)
8917 self.tcp_port_out = p[0][TCP].sport
8918 self.vapi.ipfix_flush()
8919 capture = self.pg3.get_capture(10)
8920 ipfix = IPFIXDecoder()
8921 # first load template
8923 self.assertTrue(p.haslayer(IPFIX))
8924 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8925 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8926 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8927 self.assertEqual(p[UDP].dport, 4739)
8928 self.assertEqual(p[IPFIX].observationDomainID,
8929 self.ipfix_domain_id)
8930 if p.haslayer(Template):
8931 ipfix.add_template(p.getlayer(Template))
8932 # verify events in data set
8934 if p.haslayer(Data):
8935 data = ipfix.decode_data_set(p.getlayer(Set))
8936 if scapy.compat.orb(data[0][230]) == 10:
8937 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
8938 elif scapy.compat.orb(data[0][230]) == 6:
8939 self.verify_ipfix_nat64_ses(data,
8941 self.pg0.remote_ip6n,
8942 self.pg1.remote_ip4,
8945 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8948 self.pg_enable_capture(self.pg_interfaces)
8949 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8950 end_addr=self.nat_addr,
8953 self.vapi.ipfix_flush()
8954 capture = self.pg3.get_capture(2)
8955 # verify events in data set
8957 self.assertTrue(p.haslayer(IPFIX))
8958 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8959 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8960 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8961 self.assertEqual(p[UDP].dport, 4739)
8962 self.assertEqual(p[IPFIX].observationDomainID,
8963 self.ipfix_domain_id)
8964 if p.haslayer(Data):
8965 data = ipfix.decode_data_set(p.getlayer(Set))
8966 if scapy.compat.orb(data[0][230]) == 11:
8967 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8968 elif scapy.compat.orb(data[0][230]) == 7:
8969 self.verify_ipfix_nat64_ses(data,
8971 self.pg0.remote_ip6n,
8972 self.pg1.remote_ip4,
8975 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8977 def test_syslog_sess(self):
8978 """ Test syslog session creation and deletion """
8979 self.tcp_port_in = random.randint(1025, 65535)
8980 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8984 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8985 end_addr=self.nat_addr,
8988 flags = self.config_flags.NAT_IS_INSIDE
8989 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8990 sw_if_index=self.pg0.sw_if_index)
8991 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8992 sw_if_index=self.pg1.sw_if_index)
8993 self.vapi.syslog_set_filter(
8994 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8995 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
8997 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8998 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8999 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9000 self.pg0.add_stream(p)
9001 self.pg_enable_capture(self.pg_interfaces)
9003 p = self.pg1.get_capture(1)
9004 self.tcp_port_out = p[0][TCP].sport
9005 capture = self.pg3.get_capture(1)
9006 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9008 self.pg_enable_capture(self.pg_interfaces)
9010 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9011 end_addr=self.nat_addr,
9014 capture = self.pg3.get_capture(1)
9015 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9017 def nat64_get_ses_num(self):
9019 Return number of active NAT64 sessions.
9021 st = self.vapi.nat64_st_dump(proto=255)
9024 def clear_nat64(self):
9026 Clear NAT64 configuration.
9028 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9029 src_port=self.ipfix_src_port,
9031 self.ipfix_src_port = 4739
9032 self.ipfix_domain_id = 1
9034 self.vapi.syslog_set_filter(
9035 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9037 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9038 tcp_transitory=240, icmp=60)
9040 interfaces = self.vapi.nat64_interface_dump()
9041 for intf in interfaces:
9042 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9043 sw_if_index=intf.sw_if_index)
9045 bib = self.vapi.nat64_bib_dump(proto=255)
9047 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9048 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9056 adresses = self.vapi.nat64_pool_addr_dump()
9057 for addr in adresses:
9058 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9059 end_addr=addr.address,
9063 prefixes = self.vapi.nat64_prefix_dump()
9064 for prefix in prefixes:
9065 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9066 vrf_id=prefix.vrf_id, is_add=0)
9068 bibs = self.statistics.get_counter('/nat64/total-bibs')
9069 self.assertEqual(bibs[0][0], 0)
9070 sessions = self.statistics.get_counter('/nat64/total-sessions')
9071 self.assertEqual(sessions[0][0], 0)
9074 super(TestNAT64, self).tearDown()
9075 if not self.vpp_dead:
9078 def show_commands_at_teardown(self):
9079 self.logger.info(self.vapi.cli("show nat64 pool"))
9080 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9081 self.logger.info(self.vapi.cli("show nat64 prefix"))
9082 self.logger.info(self.vapi.cli("show nat64 bib all"))
9083 self.logger.info(self.vapi.cli("show nat64 session table all"))
9086 class TestDSlite(MethodHolder):
9087 """ DS-Lite Test Cases """
9090 def setUpClass(cls):
9091 super(TestDSlite, cls).setUpClass()
9094 cls.nat_addr = '10.0.0.3'
9096 cls.create_pg_interfaces(range(3))
9098 cls.pg0.config_ip4()
9099 cls.pg0.resolve_arp()
9101 cls.pg1.config_ip6()
9102 cls.pg1.generate_remote_hosts(2)
9103 cls.pg1.configure_ipv6_neighbors()
9105 cls.pg2.config_ip4()
9106 cls.pg2.resolve_arp()
9109 super(TestDSlite, cls).tearDownClass()
9113 def tearDownClass(cls):
9114 super(TestDSlite, cls).tearDownClass()
9116 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
9118 message = data.decode('utf-8')
9120 message = SyslogMessage.parse(message)
9121 except ParseError as e:
9122 self.logger.error(e)
9124 self.assertEqual(message.severity, SyslogSeverity.info)
9125 self.assertEqual(message.appname, 'NAT')
9126 self.assertEqual(message.msgid, 'APMADD')
9127 sd_params = message.sd.get('napmap')
9128 self.assertTrue(sd_params is not None)
9129 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
9130 self.assertEqual(sd_params.get('ISADDR'), isaddr)
9131 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
9132 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
9133 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
9134 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
9135 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
9136 self.assertTrue(sd_params.get('SSUBIX') is not None)
9137 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
9139 def test_dslite(self):
9140 """ Test DS-Lite """
9141 nat_config = self.vapi.nat_show_config()
9142 self.assertEqual(0, nat_config.dslite_ce)
9144 self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
9145 end_addr=self.nat_addr,
9147 aftr_ip4 = '192.0.0.1'
9148 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9149 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9150 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
9153 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9154 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
9155 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9156 UDP(sport=20000, dport=10000))
9157 self.pg1.add_stream(p)
9158 self.pg_enable_capture(self.pg_interfaces)
9160 capture = self.pg0.get_capture(1)
9161 capture = capture[0]
9162 self.assertFalse(capture.haslayer(IPv6))
9163 self.assertEqual(capture[IP].src, self.nat_addr)
9164 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9165 self.assertNotEqual(capture[UDP].sport, 20000)
9166 self.assertEqual(capture[UDP].dport, 10000)
9167 self.assert_packet_checksums_valid(capture)
9168 out_port = capture[UDP].sport
9169 capture = self.pg2.get_capture(1)
9170 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
9171 20000, self.nat_addr, out_port,
9172 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
9174 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9175 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9176 UDP(sport=10000, dport=out_port))
9177 self.pg0.add_stream(p)
9178 self.pg_enable_capture(self.pg_interfaces)
9180 capture = self.pg1.get_capture(1)
9181 capture = capture[0]
9182 self.assertEqual(capture[IPv6].src, aftr_ip6)
9183 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9184 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9185 self.assertEqual(capture[IP].dst, '192.168.1.1')
9186 self.assertEqual(capture[UDP].sport, 10000)
9187 self.assertEqual(capture[UDP].dport, 20000)
9188 self.assert_packet_checksums_valid(capture)
9191 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9192 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9193 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9194 TCP(sport=20001, dport=10001))
9195 self.pg1.add_stream(p)
9196 self.pg_enable_capture(self.pg_interfaces)
9198 capture = self.pg0.get_capture(1)
9199 capture = capture[0]
9200 self.assertFalse(capture.haslayer(IPv6))
9201 self.assertEqual(capture[IP].src, self.nat_addr)
9202 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9203 self.assertNotEqual(capture[TCP].sport, 20001)
9204 self.assertEqual(capture[TCP].dport, 10001)
9205 self.assert_packet_checksums_valid(capture)
9206 out_port = capture[TCP].sport
9208 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9209 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9210 TCP(sport=10001, dport=out_port))
9211 self.pg0.add_stream(p)
9212 self.pg_enable_capture(self.pg_interfaces)
9214 capture = self.pg1.get_capture(1)
9215 capture = capture[0]
9216 self.assertEqual(capture[IPv6].src, aftr_ip6)
9217 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9218 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9219 self.assertEqual(capture[IP].dst, '192.168.1.1')
9220 self.assertEqual(capture[TCP].sport, 10001)
9221 self.assertEqual(capture[TCP].dport, 20001)
9222 self.assert_packet_checksums_valid(capture)
9225 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9226 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
9227 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
9228 ICMP(id=4000, type='echo-request'))
9229 self.pg1.add_stream(p)
9230 self.pg_enable_capture(self.pg_interfaces)
9232 capture = self.pg0.get_capture(1)
9233 capture = capture[0]
9234 self.assertFalse(capture.haslayer(IPv6))
9235 self.assertEqual(capture[IP].src, self.nat_addr)
9236 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9237 self.assertNotEqual(capture[ICMP].id, 4000)
9238 self.assert_packet_checksums_valid(capture)
9239 out_id = capture[ICMP].id
9241 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9242 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
9243 ICMP(id=out_id, type='echo-reply'))
9244 self.pg0.add_stream(p)
9245 self.pg_enable_capture(self.pg_interfaces)
9247 capture = self.pg1.get_capture(1)
9248 capture = capture[0]
9249 self.assertEqual(capture[IPv6].src, aftr_ip6)
9250 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9251 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9252 self.assertEqual(capture[IP].dst, '192.168.1.1')
9253 self.assertEqual(capture[ICMP].id, 4000)
9254 self.assert_packet_checksums_valid(capture)
9256 # ping DS-Lite AFTR tunnel endpoint address
9257 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9258 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
9259 ICMPv6EchoRequest())
9260 self.pg1.add_stream(p)
9261 self.pg_enable_capture(self.pg_interfaces)
9263 capture = self.pg1.get_capture(1)
9264 capture = capture[0]
9265 self.assertEqual(capture[IPv6].src, aftr_ip6)
9266 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
9267 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9269 b4s = self.statistics.get_counter('/dslite/total-b4s')
9270 self.assertEqual(b4s[0][0], 2)
9271 sessions = self.statistics.get_counter('/dslite/total-sessions')
9272 self.assertEqual(sessions[0][0], 3)
9275 super(TestDSlite, self).tearDown()
9277 def show_commands_at_teardown(self):
9278 self.logger.info(self.vapi.cli("show dslite pool"))
9280 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9281 self.logger.info(self.vapi.cli("show dslite sessions"))
9284 class TestDSliteCE(MethodHolder):
9285 """ DS-Lite CE Test Cases """
9288 def setUpConstants(cls):
9289 super(TestDSliteCE, cls).setUpConstants()
9290 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
9293 def setUpClass(cls):
9294 super(TestDSliteCE, cls).setUpClass()
9297 cls.create_pg_interfaces(range(2))
9299 cls.pg0.config_ip4()
9300 cls.pg0.resolve_arp()
9302 cls.pg1.config_ip6()
9303 cls.pg1.generate_remote_hosts(1)
9304 cls.pg1.configure_ipv6_neighbors()
9307 super(TestDSliteCE, cls).tearDownClass()
9311 def tearDownClass(cls):
9312 super(TestDSliteCE, cls).tearDownClass()
9314 def test_dslite_ce(self):
9315 """ Test DS-Lite CE """
9317 nat_config = self.vapi.nat_show_config()
9318 self.assertEqual(1, nat_config.dslite_ce)
9320 b4_ip4 = '192.0.0.2'
9321 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
9322 self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)
9324 aftr_ip4 = '192.0.0.1'
9325 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
9326 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
9327 self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
9329 r1 = VppIpRoute(self, aftr_ip6, 128,
9330 [VppRoutePath(self.pg1.remote_ip6,
9331 self.pg1.sw_if_index)])
9335 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9336 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
9337 UDP(sport=10000, dport=20000))
9338 self.pg0.add_stream(p)
9339 self.pg_enable_capture(self.pg_interfaces)
9341 capture = self.pg1.get_capture(1)
9342 capture = capture[0]
9343 self.assertEqual(capture[IPv6].src, b4_ip6)
9344 self.assertEqual(capture[IPv6].dst, aftr_ip6)
9345 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
9346 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
9347 self.assertEqual(capture[UDP].sport, 10000)
9348 self.assertEqual(capture[UDP].dport, 20000)
9349 self.assert_packet_checksums_valid(capture)
9352 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9353 IPv6(dst=b4_ip6, src=aftr_ip6) /
9354 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
9355 UDP(sport=20000, dport=10000))
9356 self.pg1.add_stream(p)
9357 self.pg_enable_capture(self.pg_interfaces)
9359 capture = self.pg0.get_capture(1)
9360 capture = capture[0]
9361 self.assertFalse(capture.haslayer(IPv6))
9362 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
9363 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
9364 self.assertEqual(capture[UDP].sport, 20000)
9365 self.assertEqual(capture[UDP].dport, 10000)
9366 self.assert_packet_checksums_valid(capture)
9368 # ping DS-Lite B4 tunnel endpoint address
9369 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9370 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
9371 ICMPv6EchoRequest())
9372 self.pg1.add_stream(p)
9373 self.pg_enable_capture(self.pg_interfaces)
9375 capture = self.pg1.get_capture(1)
9376 capture = capture[0]
9377 self.assertEqual(capture[IPv6].src, b4_ip6)
9378 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
9379 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
9382 super(TestDSliteCE, self).tearDown()
9384 def show_commands_at_teardown(self):
9386 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
9388 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
9391 class TestNAT66(MethodHolder):
9392 """ NAT66 Test Cases """
9395 def setUpClass(cls):
9396 super(TestNAT66, cls).setUpClass()
9399 cls.nat_addr = 'fd01:ff::2'
9401 cls.create_pg_interfaces(range(2))
9402 cls.interfaces = list(cls.pg_interfaces)
9404 for i in cls.interfaces:
9407 i.configure_ipv6_neighbors()
9410 super(TestNAT66, cls).tearDownClass()
9414 def tearDownClass(cls):
9415 super(TestNAT66, cls).tearDownClass()
9417 def test_static(self):
9418 """ 1:1 NAT66 test """
9419 flags = self.config_flags.NAT_IS_INSIDE
9420 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9421 sw_if_index=self.pg0.sw_if_index)
9422 self.vapi.nat66_add_del_interface(is_add=1,
9423 sw_if_index=self.pg1.sw_if_index)
9424 self.vapi.nat66_add_del_static_mapping(
9425 local_ip_address=self.pg0.remote_ip6n,
9426 external_ip_address=self.nat_addr,
9431 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9432 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9435 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9436 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9439 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9440 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9441 ICMPv6EchoRequest())
9443 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9444 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9445 GRE() / IP() / TCP())
9447 self.pg0.add_stream(pkts)
9448 self.pg_enable_capture(self.pg_interfaces)
9450 capture = self.pg1.get_capture(len(pkts))
9452 for packet in capture:
9454 self.assertEqual(packet[IPv6].src, self.nat_addr)
9455 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9456 self.assert_packet_checksums_valid(packet)
9458 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9463 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9464 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9467 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9468 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9471 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9472 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9475 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9476 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9477 GRE() / IP() / TCP())
9479 self.pg1.add_stream(pkts)
9480 self.pg_enable_capture(self.pg_interfaces)
9482 capture = self.pg0.get_capture(len(pkts))
9483 for packet in capture:
9485 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9486 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9487 self.assert_packet_checksums_valid(packet)
9489 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9492 sm = self.vapi.nat66_static_mapping_dump()
9493 self.assertEqual(len(sm), 1)
9494 self.assertEqual(sm[0].total_pkts, 8)
9496 def test_check_no_translate(self):
9497 """ NAT66 translate only when egress interface is outside interface """
9498 flags = self.config_flags.NAT_IS_INSIDE
9499 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9500 sw_if_index=self.pg0.sw_if_index)
9501 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9502 sw_if_index=self.pg1.sw_if_index)
9503 self.vapi.nat66_add_del_static_mapping(
9504 local_ip_address=self.pg0.remote_ip6n,
9505 external_ip_address=self.nat_addr,
9509 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9510 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9512 self.pg0.add_stream([p])
9513 self.pg_enable_capture(self.pg_interfaces)
9515 capture = self.pg1.get_capture(1)
9518 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9519 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9521 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9524 def clear_nat66(self):
9526 Clear NAT66 configuration.
9528 interfaces = self.vapi.nat66_interface_dump()
9529 for intf in interfaces:
9530 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9531 sw_if_index=intf.sw_if_index)
9533 static_mappings = self.vapi.nat66_static_mapping_dump()
9534 for sm in static_mappings:
9535 self.vapi.nat66_add_del_static_mapping(
9536 local_ip_address=sm.local_ip_address,
9537 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9541 super(TestNAT66, self).tearDown()
9544 def show_commands_at_teardown(self):
9545 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9546 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9549 if __name__ == '__main__':
9550 unittest.main(testRunner=VppTestRunner)