12 from framework import VppTestCase, VppTestRunner, running_extended_tests
13 from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
14 from scapy.all import bind_layers, Packet, ByteEnumField, ShortField, \
15 IPField, IntField, LongField, XByteField, FlagsField, FieldLenField, \
17 from scapy.data import IP_PROTOS
18 from scapy.layers.inet import IP, TCP, UDP, ICMP
19 from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
20 from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
21 from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
22 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
23 from scapy.layers.l2 import Ether, ARP, GRE
24 from scapy.packet import Raw
25 from syslog_rfc5424_parser import SyslogMessage, ParseError
26 from syslog_rfc5424_parser.constants import SyslogSeverity
27 from util import ip4_range
28 from util import ppc, ppp
29 from vpp_acl import AclRule, VppAcl, VppAclInterface
30 from vpp_ip_route import VppIpRoute, VppRoutePath
31 from vpp_neighbor import VppNeighbor
32 from vpp_papi import VppEnum
35 # NAT HA protocol event data
38 fields_desc = [ByteEnumField("event_type", None,
39 {1: "add", 2: "del", 3: "refresh"}),
40 ByteEnumField("protocol", None,
41 {0: "other", 1: "udp", 2: "tcp", 3: "icmp"}),
42 ShortField("flags", 0),
43 IPField("in_addr", None),
44 IPField("out_addr", None),
45 ShortField("in_port", None),
46 ShortField("out_port", None),
47 IPField("eh_addr", None),
48 IPField("ehn_addr", None),
49 ShortField("eh_port", None),
50 ShortField("ehn_port", None),
51 IntField("fib_index", None),
52 IntField("total_pkts", 0),
53 LongField("total_bytes", 0)]
55 def extract_padding(self, s):
59 # NAT HA protocol header
60 class HANATStateSync(Packet):
61 name = "HA NAT state sync"
62 fields_desc = [XByteField("version", 1),
63 FlagsField("flags", 0, 8, ['ACK']),
64 FieldLenField("count", None, count_of="events"),
65 IntField("sequence_number", 1),
66 IntField("thread_index", 0),
67 PacketListField("events", [], Event,
68 count_from=lambda pkt: pkt.count)]
71 class MethodHolder(VppTestCase):
72 """ NAT create capture and verify method holder """
75 def config_flags(self):
76 return VppEnum.vl_api_nat_config_flags_t
79 def SYSLOG_SEVERITY(self):
80 return VppEnum.vl_api_syslog_severity_t
82 def clear_nat44(self):
84 Clear NAT44 configuration.
86 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
87 if self.pg7.has_ip4_config:
88 self.pg7.unconfig_ip4()
90 self.vapi.nat44_forwarding_enable_disable(enable=0)
92 interfaces = self.vapi.nat44_interface_addr_dump()
93 for intf in interfaces:
94 self.vapi.nat44_add_del_interface_addr(
96 sw_if_index=intf.sw_if_index,
99 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
100 src_port=self.ipfix_src_port,
102 self.ipfix_src_port = 4739
103 self.ipfix_domain_id = 1
105 self.vapi.syslog_set_filter(
106 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
108 self.vapi.nat_ha_set_listener(ip_address='0.0.0.0', port=0,
110 self.vapi.nat_ha_set_failover(ip_address='0.0.0.0', port=0,
111 session_refresh_interval=10)
113 interfaces = self.vapi.nat44_interface_dump()
114 for intf in interfaces:
115 if intf.flags & self.config_flags.NAT_IS_INSIDE and \
116 intf.flags & self.config_flags.NAT_IS_OUTSIDE:
117 self.vapi.nat44_interface_add_del_feature(
118 sw_if_index=intf.sw_if_index)
119 self.vapi.nat44_interface_add_del_feature(
120 sw_if_index=intf.sw_if_index,
123 interfaces = self.vapi.nat44_interface_output_feature_dump()
124 for intf in interfaces:
125 self.vapi.nat44_interface_add_del_output_feature(
128 sw_if_index=intf.sw_if_index)
129 static_mappings = self.vapi.nat44_static_mapping_dump()
130 for sm in static_mappings:
131 self.vapi.nat44_add_del_static_mapping(
133 local_ip_address=sm.local_ip_address,
134 external_ip_address=sm.external_ip_address,
135 external_sw_if_index=sm.external_sw_if_index,
136 local_port=sm.local_port,
137 external_port=sm.external_port,
139 protocol=sm.protocol,
140 flags=sm.flags, tag=sm.tag)
142 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
143 for lb_sm in lb_static_mappings:
144 self.vapi.nat44_add_del_lb_static_mapping(
147 external_addr=lb_sm.external_addr,
148 external_port=lb_sm.external_port,
149 protocol=lb_sm.protocol,
150 local_num=0, locals=[],
153 identity_mappings = self.vapi.nat44_identity_mapping_dump()
154 for id_m in identity_mappings:
155 self.vapi.nat44_add_del_identity_mapping(
156 ip_address=id_m.ip_address,
157 sw_if_index=id_m.sw_if_index,
161 protocol=id_m.protocol)
163 addresses = self.vapi.nat44_address_dump()
164 for addr in addresses:
165 self.vapi.nat44_add_del_address_range(
166 first_ip_address=addr.ip_address,
167 last_ip_address=addr.ip_address,
168 vrf_id=0xFFFFFFFF, flags=addr.flags)
170 self.verify_no_nat44_user()
171 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
172 tcp_transitory=240, icmp=60)
173 self.vapi.nat_set_addr_and_port_alloc_alg()
174 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
176 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
177 local_port=0, external_port=0, vrf_id=0,
178 is_add=1, external_sw_if_index=0xFFFFFFFF,
179 proto=0, tag="", flags=0):
181 Add/delete NAT44 static mapping
183 :param local_ip: Local IP address
184 :param external_ip: External IP address
185 :param local_port: Local port number (Optional)
186 :param external_port: External port number (Optional)
187 :param vrf_id: VRF ID (Default 0)
188 :param is_add: 1 if add, 0 if delete (Default add)
189 :param external_sw_if_index: External interface instead of IP address
190 :param proto: IP protocol (Mandatory if port specified)
191 :param tag: Opaque string tag
192 :param flags: NAT configuration flags
195 if not (local_port and external_port):
196 flags |= self.config_flags.NAT_IS_ADDR_ONLY
198 self.vapi.nat44_add_del_static_mapping(
200 local_ip_address=local_ip,
201 external_ip_address=external_ip,
202 external_sw_if_index=external_sw_if_index,
203 local_port=local_port,
204 external_port=external_port,
205 vrf_id=vrf_id, protocol=proto,
209 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
211 Add/delete NAT44 address
213 :param ip: IP address
214 :param is_add: 1 if add, 0 if delete (Default add)
215 :param twice_nat: twice NAT address for external hosts
217 flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
218 self.vapi.nat44_add_del_address_range(first_ip_address=ip,
224 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
226 Create packet stream for inside network
228 :param in_if: Inside interface
229 :param out_if: Outside interface
230 :param dst_ip: Destination address
231 :param ttl: TTL of generated packets
234 dst_ip = out_if.remote_ip4
238 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
239 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
240 TCP(sport=self.tcp_port_in, dport=20))
244 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
245 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
246 UDP(sport=self.udp_port_in, dport=20))
250 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
251 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
252 ICMP(id=self.icmp_id_in, type='echo-request'))
257 def compose_ip6(self, ip4, pref, plen):
259 Compose IPv4-embedded IPv6 addresses
261 :param ip4: IPv4 address
262 :param pref: IPv6 prefix
263 :param plen: IPv6 prefix length
264 :returns: IPv4-embedded IPv6 addresses
266 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
267 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
282 pref_n[10] = ip4_n[3]
286 pref_n[10] = ip4_n[2]
287 pref_n[11] = ip4_n[3]
290 pref_n[10] = ip4_n[1]
291 pref_n[11] = ip4_n[2]
292 pref_n[12] = ip4_n[3]
294 pref_n[12] = ip4_n[0]
295 pref_n[13] = ip4_n[1]
296 pref_n[14] = ip4_n[2]
297 pref_n[15] = ip4_n[3]
298 packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
299 return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
301 def extract_ip4(self, ip6, plen):
303 Extract IPv4 address embedded in IPv6 addresses
305 :param ip6: IPv6 address
306 :param plen: IPv6 prefix length
307 :returns: extracted IPv4 address
309 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
341 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
343 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
345 Create IPv6 packet stream for inside network
347 :param in_if: Inside interface
348 :param out_if: Outside interface
349 :param ttl: Hop Limit of generated packets
350 :param pref: NAT64 prefix
351 :param plen: NAT64 prefix length
355 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
357 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
360 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
361 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
362 TCP(sport=self.tcp_port_in, dport=20))
366 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
367 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
368 UDP(sport=self.udp_port_in, dport=20))
372 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
373 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
374 ICMPv6EchoRequest(id=self.icmp_id_in))
379 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
380 use_inside_ports=False):
382 Create packet stream for outside network
384 :param out_if: Outside interface
385 :param dst_ip: Destination IP address (Default use global NAT address)
386 :param ttl: TTL of generated packets
387 :param use_inside_ports: Use inside NAT ports as destination ports
388 instead of outside ports
391 dst_ip = self.nat_addr
392 if not use_inside_ports:
393 tcp_port = self.tcp_port_out
394 udp_port = self.udp_port_out
395 icmp_id = self.icmp_id_out
397 tcp_port = self.tcp_port_in
398 udp_port = self.udp_port_in
399 icmp_id = self.icmp_id_in
402 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
403 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
404 TCP(dport=tcp_port, sport=20))
408 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
409 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
410 UDP(dport=udp_port, sport=20))
414 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
415 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
416 ICMP(id=icmp_id, type='echo-reply'))
421 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
423 Create packet stream for outside network
425 :param out_if: Outside interface
426 :param dst_ip: Destination IP address (Default use global NAT address)
427 :param hl: HL of generated packets
431 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
432 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
433 TCP(dport=self.tcp_port_out, sport=20))
437 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
438 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
439 UDP(dport=self.udp_port_out, sport=20))
443 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
444 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
445 ICMPv6EchoReply(id=self.icmp_id_out))
450 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
451 dst_ip=None, is_ip6=False):
453 Verify captured packets on outside network
455 :param capture: Captured packets
456 :param nat_ip: Translated IP address (Default use global NAT address)
457 :param same_port: Source port number is not translated (Default False)
458 :param dst_ip: Destination IP address (Default do not verify)
459 :param is_ip6: If L3 protocol is IPv6 (Default False)
463 ICMP46 = ICMPv6EchoRequest
468 nat_ip = self.nat_addr
469 for packet in capture:
472 self.assert_packet_checksums_valid(packet)
473 self.assertEqual(packet[IP46].src, nat_ip)
474 if dst_ip is not None:
475 self.assertEqual(packet[IP46].dst, dst_ip)
476 if packet.haslayer(TCP):
478 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
481 packet[TCP].sport, self.tcp_port_in)
482 self.tcp_port_out = packet[TCP].sport
483 self.assert_packet_checksums_valid(packet)
484 elif packet.haslayer(UDP):
486 self.assertEqual(packet[UDP].sport, self.udp_port_in)
489 packet[UDP].sport, self.udp_port_in)
490 self.udp_port_out = packet[UDP].sport
493 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
495 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
496 self.icmp_id_out = packet[ICMP46].id
497 self.assert_packet_checksums_valid(packet)
499 self.logger.error(ppp("Unexpected or invalid packet "
500 "(outside network):", packet))
503 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
506 Verify captured packets on outside network
508 :param capture: Captured packets
509 :param nat_ip: Translated IP address
510 :param same_port: Source port number is not translated (Default False)
511 :param dst_ip: Destination IP address (Default do not verify)
513 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
516 def verify_capture_in(self, capture, in_if):
518 Verify captured packets on inside network
520 :param capture: Captured packets
521 :param in_if: Inside interface
523 for packet in capture:
525 self.assert_packet_checksums_valid(packet)
526 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
527 if packet.haslayer(TCP):
528 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
529 elif packet.haslayer(UDP):
530 self.assertEqual(packet[UDP].dport, self.udp_port_in)
532 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
534 self.logger.error(ppp("Unexpected or invalid packet "
535 "(inside network):", packet))
538 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
540 Verify captured IPv6 packets on inside network
542 :param capture: Captured packets
543 :param src_ip: Source IP
544 :param dst_ip: Destination IP address
546 for packet in capture:
548 self.assertEqual(packet[IPv6].src, src_ip)
549 self.assertEqual(packet[IPv6].dst, dst_ip)
550 self.assert_packet_checksums_valid(packet)
551 if packet.haslayer(TCP):
552 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
553 elif packet.haslayer(UDP):
554 self.assertEqual(packet[UDP].dport, self.udp_port_in)
556 self.assertEqual(packet[ICMPv6EchoReply].id,
559 self.logger.error(ppp("Unexpected or invalid packet "
560 "(inside network):", packet))
563 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
565 Verify captured packet that don't have to be translated
567 :param capture: Captured packets
568 :param ingress_if: Ingress interface
569 :param egress_if: Egress interface
571 for packet in capture:
573 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
574 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
575 if packet.haslayer(TCP):
576 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
577 elif packet.haslayer(UDP):
578 self.assertEqual(packet[UDP].sport, self.udp_port_in)
580 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
582 self.logger.error(ppp("Unexpected or invalid packet "
583 "(inside network):", packet))
586 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
589 Verify captured packets with ICMP errors on outside network
591 :param capture: Captured packets
592 :param src_ip: Translated IP address or IP address of VPP
593 (Default use global NAT address)
594 :param icmp_type: Type of error ICMP packet
595 we are expecting (Default 11)
598 src_ip = self.nat_addr
599 for packet in capture:
601 self.assertEqual(packet[IP].src, src_ip)
602 self.assertEqual(packet.haslayer(ICMP), 1)
604 self.assertEqual(icmp.type, icmp_type)
605 self.assertTrue(icmp.haslayer(IPerror))
606 inner_ip = icmp[IPerror]
607 if inner_ip.haslayer(TCPerror):
608 self.assertEqual(inner_ip[TCPerror].dport,
610 elif inner_ip.haslayer(UDPerror):
611 self.assertEqual(inner_ip[UDPerror].dport,
614 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
616 self.logger.error(ppp("Unexpected or invalid packet "
617 "(outside network):", packet))
620 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
622 Verify captured packets with ICMP errors on inside network
624 :param capture: Captured packets
625 :param in_if: Inside interface
626 :param icmp_type: Type of error ICMP packet
627 we are expecting (Default 11)
629 for packet in capture:
631 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
632 self.assertEqual(packet.haslayer(ICMP), 1)
634 self.assertEqual(icmp.type, icmp_type)
635 self.assertTrue(icmp.haslayer(IPerror))
636 inner_ip = icmp[IPerror]
637 if inner_ip.haslayer(TCPerror):
638 self.assertEqual(inner_ip[TCPerror].sport,
640 elif inner_ip.haslayer(UDPerror):
641 self.assertEqual(inner_ip[UDPerror].sport,
644 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
646 self.logger.error(ppp("Unexpected or invalid packet "
647 "(inside network):", packet))
650 def create_stream_frag(self, src_if, dst, sport, dport, data,
651 proto=IP_PROTOS.tcp, echo_reply=False):
653 Create fragmented packet stream
655 :param src_if: Source interface
656 :param dst: Destination IPv4 address
657 :param sport: Source port
658 :param dport: Destination port
659 :param data: Payload data
660 :param proto: protocol (TCP, UDP, ICMP)
661 :param echo_reply: use echo_reply if protocol is ICMP
664 if proto == IP_PROTOS.tcp:
665 p = (IP(src=src_if.remote_ip4, dst=dst) /
666 TCP(sport=sport, dport=dport) /
668 p = p.__class__(scapy.compat.raw(p))
669 chksum = p[TCP].chksum
670 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
671 elif proto == IP_PROTOS.udp:
672 proto_header = UDP(sport=sport, dport=dport)
673 elif proto == IP_PROTOS.icmp:
675 proto_header = ICMP(id=sport, type='echo-request')
677 proto_header = ICMP(id=sport, type='echo-reply')
679 raise Exception("Unsupported protocol")
680 id = random.randint(0, 65535)
682 if proto == IP_PROTOS.tcp:
685 raw = Raw(data[0:16])
686 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
687 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
691 if proto == IP_PROTOS.tcp:
692 raw = Raw(data[4:20])
694 raw = Raw(data[16:32])
695 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
696 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
700 if proto == IP_PROTOS.tcp:
704 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
705 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
711 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
712 pref=None, plen=0, frag_size=128):
714 Create fragmented packet stream
716 :param src_if: Source interface
717 :param dst: Destination IPv4 address
718 :param sport: Source TCP port
719 :param dport: Destination TCP port
720 :param data: Payload data
721 :param pref: NAT64 prefix
722 :param plen: NAT64 prefix length
723 :param fragsize: size of fragments
727 dst_ip6 = ''.join(['64:ff9b::', dst])
729 dst_ip6 = self.compose_ip6(dst, pref, plen)
731 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
732 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
733 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
734 TCP(sport=sport, dport=dport) /
737 return fragment6(p, frag_size)
739 def reass_frags_and_verify(self, frags, src, dst):
741 Reassemble and verify fragmented packet
743 :param frags: Captured fragments
744 :param src: Source IPv4 address to verify
745 :param dst: Destination IPv4 address to verify
747 :returns: Reassembled IPv4 packet
751 self.assertEqual(p[IP].src, src)
752 self.assertEqual(p[IP].dst, dst)
753 self.assert_ip_checksum_valid(p)
754 buffer.seek(p[IP].frag * 8)
755 buffer.write(bytes(p[IP].payload))
756 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
757 proto=frags[0][IP].proto)
758 if ip.proto == IP_PROTOS.tcp:
759 p = (ip / TCP(buffer.getvalue()))
760 self.logger.debug(ppp("Reassembled:", p))
761 self.assert_tcp_checksum_valid(p)
762 elif ip.proto == IP_PROTOS.udp:
763 p = (ip / UDP(buffer.getvalue()[:8]) /
764 Raw(buffer.getvalue()[8:]))
765 elif ip.proto == IP_PROTOS.icmp:
766 p = (ip / ICMP(buffer.getvalue()))
769 def reass_frags_and_verify_ip6(self, frags, src, dst):
771 Reassemble and verify fragmented packet
773 :param frags: Captured fragments
774 :param src: Source IPv6 address to verify
775 :param dst: Destination IPv6 address to verify
777 :returns: Reassembled IPv6 packet
781 self.assertEqual(p[IPv6].src, src)
782 self.assertEqual(p[IPv6].dst, dst)
783 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
784 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
785 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
786 nh=frags[0][IPv6ExtHdrFragment].nh)
787 if ip.nh == IP_PROTOS.tcp:
788 p = (ip / TCP(buffer.getvalue()))
789 elif ip.nh == IP_PROTOS.udp:
790 p = (ip / UDP(buffer.getvalue()))
791 self.logger.debug(ppp("Reassembled:", p))
792 self.assert_packet_checksums_valid(p)
795 def initiate_tcp_session(self, in_if, out_if):
797 Initiates TCP session
799 :param in_if: Inside interface
800 :param out_if: Outside interface
804 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
805 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
806 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
809 self.pg_enable_capture(self.pg_interfaces)
811 capture = out_if.get_capture(1)
813 self.tcp_port_out = p[TCP].sport
815 # SYN + ACK packet out->in
816 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
817 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
818 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
821 self.pg_enable_capture(self.pg_interfaces)
826 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
827 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
828 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
831 self.pg_enable_capture(self.pg_interfaces)
833 out_if.get_capture(1)
836 self.logger.error("TCP 3 way handshake failed")
839 def verify_ipfix_nat44_ses(self, data):
841 Verify IPFIX NAT44 session create/delete event
843 :param data: Decoded IPFIX data records
845 nat44_ses_create_num = 0
846 nat44_ses_delete_num = 0
847 self.assertEqual(6, len(data))
850 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
851 if scapy.compat.orb(record[230]) == 4:
852 nat44_ses_create_num += 1
854 nat44_ses_delete_num += 1
856 self.assertEqual(self.pg0.remote_ip4,
857 str(ipaddress.IPv4Address(record[8])))
858 # postNATSourceIPv4Address
859 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
862 self.assertEqual(struct.pack("!I", 0), record[234])
863 # protocolIdentifier/sourceTransportPort
864 # /postNAPTSourceTransportPort
865 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
866 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
867 self.assertEqual(struct.pack("!H", self.icmp_id_out),
869 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
870 self.assertEqual(struct.pack("!H", self.tcp_port_in),
872 self.assertEqual(struct.pack("!H", self.tcp_port_out),
874 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
875 self.assertEqual(struct.pack("!H", self.udp_port_in),
877 self.assertEqual(struct.pack("!H", self.udp_port_out),
880 self.fail("Invalid protocol")
881 self.assertEqual(3, nat44_ses_create_num)
882 self.assertEqual(3, nat44_ses_delete_num)
884 def verify_ipfix_addr_exhausted(self, data):
886 Verify IPFIX NAT addresses event
888 :param data: Decoded IPFIX data records
890 self.assertEqual(1, len(data))
893 self.assertEqual(scapy.compat.orb(record[230]), 3)
895 self.assertEqual(struct.pack("!I", 0), record[283])
897 def verify_ipfix_max_sessions(self, data, limit):
899 Verify IPFIX maximum session entries exceeded event
901 :param data: Decoded IPFIX data records
902 :param limit: Number of maximum session entries that can be created.
904 self.assertEqual(1, len(data))
907 self.assertEqual(scapy.compat.orb(record[230]), 13)
908 # natQuotaExceededEvent
909 self.assertEqual(struct.pack("I", 1), record[466])
911 self.assertEqual(struct.pack("I", limit), record[471])
913 def verify_ipfix_max_bibs(self, data, limit):
915 Verify IPFIX maximum BIB entries exceeded event
917 :param data: Decoded IPFIX data records
918 :param limit: Number of maximum BIB entries that can be created.
920 self.assertEqual(1, len(data))
923 self.assertEqual(scapy.compat.orb(record[230]), 13)
924 # natQuotaExceededEvent
925 self.assertEqual(struct.pack("I", 2), record[466])
927 self.assertEqual(struct.pack("I", limit), record[472])
929 def verify_ipfix_bib(self, data, is_create, src_addr):
931 Verify IPFIX NAT64 BIB create and delete events
933 :param data: Decoded IPFIX data records
934 :param is_create: Create event if nonzero value otherwise delete event
935 :param src_addr: IPv6 source address
937 self.assertEqual(1, len(data))
941 self.assertEqual(scapy.compat.orb(record[230]), 10)
943 self.assertEqual(scapy.compat.orb(record[230]), 11)
945 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
946 # postNATSourceIPv4Address
947 self.assertEqual(self.nat_addr_n, record[225])
949 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
951 self.assertEqual(struct.pack("!I", 0), record[234])
952 # sourceTransportPort
953 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
954 # postNAPTSourceTransportPort
955 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
957 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
960 Verify IPFIX NAT64 session create and delete events
962 :param data: Decoded IPFIX data records
963 :param is_create: Create event if nonzero value otherwise delete event
964 :param src_addr: IPv6 source address
965 :param dst_addr: IPv4 destination address
966 :param dst_port: destination TCP port
968 self.assertEqual(1, len(data))
972 self.assertEqual(scapy.compat.orb(record[230]), 6)
974 self.assertEqual(scapy.compat.orb(record[230]), 7)
976 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
977 # destinationIPv6Address
978 self.assertEqual(socket.inet_pton(socket.AF_INET6,
979 self.compose_ip6(dst_addr,
983 # postNATSourceIPv4Address
984 self.assertEqual(self.nat_addr_n, record[225])
985 # postNATDestinationIPv4Address
986 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
989 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
991 self.assertEqual(struct.pack("!I", 0), record[234])
992 # sourceTransportPort
993 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
994 # postNAPTSourceTransportPort
995 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
996 # destinationTransportPort
997 self.assertEqual(struct.pack("!H", dst_port), record[11])
998 # postNAPTDestinationTransportPort
999 self.assertEqual(struct.pack("!H", dst_port), record[228])
1001 def verify_no_nat44_user(self):
1002 """ Verify that there is no NAT44 user """
1003 users = self.vapi.nat44_user_dump()
1004 self.assertEqual(len(users), 0)
1005 users = self.statistics.get_counter('/nat44/total-users')
1006 self.assertEqual(users[0][0], 0)
1007 sessions = self.statistics.get_counter('/nat44/total-sessions')
1008 self.assertEqual(sessions[0][0], 0)
1010 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1012 Verify IPFIX maximum entries per user exceeded event
1014 :param data: Decoded IPFIX data records
1015 :param limit: Number of maximum entries per user
1016 :param src_addr: IPv4 source address
1018 self.assertEqual(1, len(data))
1021 self.assertEqual(scapy.compat.orb(record[230]), 13)
1022 # natQuotaExceededEvent
1023 self.assertEqual(struct.pack("I", 3), record[466])
1025 self.assertEqual(struct.pack("I", limit), record[473])
1027 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1029 def verify_syslog_apmap(self, data, is_add=True):
1030 message = data.decode('utf-8')
1032 message = SyslogMessage.parse(message)
1033 except ParseError as e:
1034 self.logger.error(e)
1037 self.assertEqual(message.severity, SyslogSeverity.info)
1038 self.assertEqual(message.appname, 'NAT')
1039 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1040 sd_params = message.sd.get('napmap')
1041 self.assertTrue(sd_params is not None)
1042 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1043 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1044 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1045 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1046 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1047 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1048 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1049 self.assertTrue(sd_params.get('SSUBIX') is not None)
1050 self.assertEqual(sd_params.get('SVLAN'), '0')
1052 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1053 message = data.decode('utf-8')
1055 message = SyslogMessage.parse(message)
1056 except ParseError as e:
1057 self.logger.error(e)
1060 self.assertEqual(message.severity, SyslogSeverity.info)
1061 self.assertEqual(message.appname, 'NAT')
1062 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1063 sd_params = message.sd.get('nsess')
1064 self.assertTrue(sd_params is not None)
1066 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1067 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1069 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1070 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1071 self.assertTrue(sd_params.get('SSUBIX') is not None)
1072 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1073 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1074 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1075 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1076 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1077 self.assertEqual(sd_params.get('SVLAN'), '0')
1078 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1079 self.assertEqual(sd_params.get('XDPORT'),
1080 "%d" % self.tcp_external_port)
1082 def verify_mss_value(self, pkt, mss):
1084 Verify TCP MSS value
1089 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1090 raise TypeError("Not a TCP/IP packet")
1092 for option in pkt[TCP].options:
1093 if option[0] == 'MSS':
1094 self.assertEqual(option[1], mss)
1095 self.assert_tcp_checksum_valid(pkt)
1098 def proto2layer(proto):
1099 if proto == IP_PROTOS.tcp:
1101 elif proto == IP_PROTOS.udp:
1103 elif proto == IP_PROTOS.icmp:
1106 raise Exception("Unsupported protocol")
1108 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1109 layer = self.proto2layer(proto)
1111 if proto == IP_PROTOS.tcp:
1112 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1114 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1115 self.port_in = random.randint(1025, 65535)
1118 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1119 self.port_in, 20, data, proto)
1120 self.pg0.add_stream(pkts)
1121 self.pg_enable_capture(self.pg_interfaces)
1123 frags = self.pg1.get_capture(len(pkts))
1124 if not dont_translate:
1125 p = self.reass_frags_and_verify(frags,
1127 self.pg1.remote_ip4)
1129 p = self.reass_frags_and_verify(frags,
1130 self.pg0.remote_ip4,
1131 self.pg1.remote_ip4)
1132 if proto != IP_PROTOS.icmp:
1133 if not dont_translate:
1134 self.assertEqual(p[layer].dport, 20)
1135 self.assertNotEqual(p[layer].sport, self.port_in)
1137 self.assertEqual(p[layer].sport, self.port_in)
1139 if not dont_translate:
1140 self.assertNotEqual(p[layer].id, self.port_in)
1142 self.assertEqual(p[layer].id, self.port_in)
1143 self.assertEqual(data, p[Raw].load)
1146 if not dont_translate:
1147 dst_addr = self.nat_addr
1149 dst_addr = self.pg0.remote_ip4
1150 if proto != IP_PROTOS.icmp:
1152 dport = p[layer].sport
1156 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
1157 proto, echo_reply=True)
1158 self.pg1.add_stream(pkts)
1159 self.pg_enable_capture(self.pg_interfaces)
1161 frags = self.pg0.get_capture(len(pkts))
1162 p = self.reass_frags_and_verify(frags,
1163 self.pg1.remote_ip4,
1164 self.pg0.remote_ip4)
1165 if proto != IP_PROTOS.icmp:
1166 self.assertEqual(p[layer].sport, 20)
1167 self.assertEqual(p[layer].dport, self.port_in)
1169 self.assertEqual(p[layer].id, self.port_in)
1170 self.assertEqual(data, p[Raw].load)
1172 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1173 layer = self.proto2layer(proto)
1175 if proto == IP_PROTOS.tcp:
1176 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1178 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1179 self.port_in = random.randint(1025, 65535)
1183 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1184 self.port_in, self.server_out_port,
1186 self.pg0.add_stream(pkts)
1187 self.pg_enable_capture(self.pg_interfaces)
1189 frags = self.pg1.get_capture(len(pkts))
1190 p = self.reass_frags_and_verify(frags,
1191 self.pg0.remote_ip4,
1192 self.server_in_addr)
1193 if proto != IP_PROTOS.icmp:
1194 self.assertEqual(p[layer].sport, self.port_in)
1195 self.assertEqual(p[layer].dport, self.server_in_port)
1197 self.assertEqual(p[layer].id, self.port_in)
1198 self.assertEqual(data, p[Raw].load)
1201 if proto != IP_PROTOS.icmp:
1202 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1203 self.server_in_port,
1204 p[layer].sport, data, proto)
1206 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1207 p[layer].id, 0, data, proto,
1209 self.pg1.add_stream(pkts)
1210 self.pg_enable_capture(self.pg_interfaces)
1212 frags = self.pg0.get_capture(len(pkts))
1213 p = self.reass_frags_and_verify(frags,
1214 self.server_out_addr,
1215 self.pg0.remote_ip4)
1216 if proto != IP_PROTOS.icmp:
1217 self.assertEqual(p[layer].sport, self.server_out_port)
1218 self.assertEqual(p[layer].dport, self.port_in)
1220 self.assertEqual(p[layer].id, self.port_in)
1221 self.assertEqual(data, p[Raw].load)
1223 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1224 layer = self.proto2layer(proto)
1226 if proto == IP_PROTOS.tcp:
1227 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1229 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1231 # send packet from host to server
1232 pkts = self.create_stream_frag(self.pg0,
1235 self.server_out_port,
1238 self.pg0.add_stream(pkts)
1239 self.pg_enable_capture(self.pg_interfaces)
1241 frags = self.pg0.get_capture(len(pkts))
1242 p = self.reass_frags_and_verify(frags,
1245 if proto != IP_PROTOS.icmp:
1246 self.assertNotEqual(p[layer].sport, self.host_in_port)
1247 self.assertEqual(p[layer].dport, self.server_in_port)
1249 self.assertNotEqual(p[layer].id, self.host_in_port)
1250 self.assertEqual(data, p[Raw].load)
1252 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1253 layer = self.proto2layer(proto)
1255 if proto == IP_PROTOS.tcp:
1256 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1258 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1259 self.port_in = random.randint(1025, 65535)
1263 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1264 self.port_in, 20, data, proto)
1266 self.pg0.add_stream(pkts)
1267 self.pg_enable_capture(self.pg_interfaces)
1269 frags = self.pg1.get_capture(len(pkts))
1270 if not dont_translate:
1271 p = self.reass_frags_and_verify(frags,
1273 self.pg1.remote_ip4)
1275 p = self.reass_frags_and_verify(frags,
1276 self.pg0.remote_ip4,
1277 self.pg1.remote_ip4)
1278 if proto != IP_PROTOS.icmp:
1279 if not dont_translate:
1280 self.assertEqual(p[layer].dport, 20)
1281 self.assertNotEqual(p[layer].sport, self.port_in)
1283 self.assertEqual(p[layer].sport, self.port_in)
1285 if not dont_translate:
1286 self.assertNotEqual(p[layer].id, self.port_in)
1288 self.assertEqual(p[layer].id, self.port_in)
1289 self.assertEqual(data, p[Raw].load)
1292 if not dont_translate:
1293 dst_addr = self.nat_addr
1295 dst_addr = self.pg0.remote_ip4
1296 if proto != IP_PROTOS.icmp:
1298 dport = p[layer].sport
1302 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1303 data, proto, echo_reply=True)
1305 self.pg1.add_stream(pkts)
1306 self.pg_enable_capture(self.pg_interfaces)
1308 frags = self.pg0.get_capture(len(pkts))
1309 p = self.reass_frags_and_verify(frags,
1310 self.pg1.remote_ip4,
1311 self.pg0.remote_ip4)
1312 if proto != IP_PROTOS.icmp:
1313 self.assertEqual(p[layer].sport, 20)
1314 self.assertEqual(p[layer].dport, self.port_in)
1316 self.assertEqual(p[layer].id, self.port_in)
1317 self.assertEqual(data, p[Raw].load)
1319 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1320 layer = self.proto2layer(proto)
1322 if proto == IP_PROTOS.tcp:
1323 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1325 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1326 self.port_in = random.randint(1025, 65535)
1330 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1331 self.port_in, self.server_out_port,
1334 self.pg0.add_stream(pkts)
1335 self.pg_enable_capture(self.pg_interfaces)
1337 frags = self.pg1.get_capture(len(pkts))
1338 p = self.reass_frags_and_verify(frags,
1339 self.pg0.remote_ip4,
1340 self.server_in_addr)
1341 if proto != IP_PROTOS.icmp:
1342 self.assertEqual(p[layer].dport, self.server_in_port)
1343 self.assertEqual(p[layer].sport, self.port_in)
1344 self.assertEqual(p[layer].dport, self.server_in_port)
1346 self.assertEqual(p[layer].id, self.port_in)
1347 self.assertEqual(data, p[Raw].load)
1350 if proto != IP_PROTOS.icmp:
1351 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1352 self.server_in_port,
1353 p[layer].sport, data, proto)
1355 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1356 p[layer].id, 0, data, proto,
1359 self.pg1.add_stream(pkts)
1360 self.pg_enable_capture(self.pg_interfaces)
1362 frags = self.pg0.get_capture(len(pkts))
1363 p = self.reass_frags_and_verify(frags,
1364 self.server_out_addr,
1365 self.pg0.remote_ip4)
1366 if proto != IP_PROTOS.icmp:
1367 self.assertEqual(p[layer].sport, self.server_out_port)
1368 self.assertEqual(p[layer].dport, self.port_in)
1370 self.assertEqual(p[layer].id, self.port_in)
1371 self.assertEqual(data, p[Raw].load)
1374 class TestNAT44(MethodHolder):
1375 """ NAT44 Test Cases """
1378 def setUpClass(cls):
1379 super(TestNAT44, cls).setUpClass()
1380 cls.vapi.cli("set log class nat level debug")
1382 cls.tcp_port_in = 6303
1383 cls.tcp_port_out = 6303
1384 cls.udp_port_in = 6304
1385 cls.udp_port_out = 6304
1386 cls.icmp_id_in = 6305
1387 cls.icmp_id_out = 6305
1388 cls.nat_addr = '10.0.0.3'
1389 cls.ipfix_src_port = 4739
1390 cls.ipfix_domain_id = 1
1391 cls.tcp_external_port = 80
1392 cls.udp_external_port = 69
1394 cls.create_pg_interfaces(range(10))
1395 cls.interfaces = list(cls.pg_interfaces[0:4])
1397 for i in cls.interfaces:
1402 cls.pg0.generate_remote_hosts(3)
1403 cls.pg0.configure_ipv4_neighbors()
1405 cls.pg1.generate_remote_hosts(1)
1406 cls.pg1.configure_ipv4_neighbors()
1408 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1409 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1410 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1412 cls.pg4._local_ip4 = "172.16.255.1"
1413 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1414 cls.pg4.set_table_ip4(10)
1415 cls.pg5._local_ip4 = "172.17.255.3"
1416 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1417 cls.pg5.set_table_ip4(10)
1418 cls.pg6._local_ip4 = "172.16.255.1"
1419 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1420 cls.pg6.set_table_ip4(20)
1421 for i in cls.overlapping_interfaces:
1429 cls.pg9.generate_remote_hosts(2)
1430 cls.pg9.config_ip4()
1431 cls.vapi.sw_interface_add_del_address(
1432 sw_if_index=cls.pg9.sw_if_index,
1433 prefix="10.0.0.1/24")
1436 cls.pg9.resolve_arp()
1437 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1438 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1439 cls.pg9.resolve_arp()
1442 def tearDownClass(cls):
1443 super(TestNAT44, cls).tearDownClass()
1445 def test_clear_sessions(self):
1446 """ NAT44 session clearing test """
1448 self.nat44_add_address(self.nat_addr)
1449 flags = self.config_flags.NAT_IS_INSIDE
1450 self.vapi.nat44_interface_add_del_feature(
1451 sw_if_index=self.pg0.sw_if_index,
1452 flags=flags, is_add=1)
1453 self.vapi.nat44_interface_add_del_feature(
1454 sw_if_index=self.pg1.sw_if_index,
1457 nat_config = self.vapi.nat_show_config()
1458 self.assertEqual(0, nat_config.endpoint_dependent)
1460 pkts = self.create_stream_in(self.pg0, self.pg1)
1461 self.pg0.add_stream(pkts)
1462 self.pg_enable_capture(self.pg_interfaces)
1464 capture = self.pg1.get_capture(len(pkts))
1465 self.verify_capture_out(capture)
1467 sessions = self.statistics.get_counter('/nat44/total-sessions')
1468 self.assertTrue(sessions[0][0] > 0)
1469 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1471 self.vapi.cli("clear nat44 sessions")
1473 sessions = self.statistics.get_counter('/nat44/total-sessions')
1474 self.assertEqual(sessions[0][0], 0)
1475 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1477 def test_dynamic(self):
1478 """ NAT44 dynamic translation test """
1479 self.nat44_add_address(self.nat_addr)
1480 flags = self.config_flags.NAT_IS_INSIDE
1481 self.vapi.nat44_interface_add_del_feature(
1482 sw_if_index=self.pg0.sw_if_index,
1483 flags=flags, is_add=1)
1484 self.vapi.nat44_interface_add_del_feature(
1485 sw_if_index=self.pg1.sw_if_index,
1489 tcpn = self.statistics.get_err_counter(
1490 '/err/nat44-in2out-slowpath/TCP packets')
1491 udpn = self.statistics.get_err_counter(
1492 '/err/nat44-in2out-slowpath/UDP packets')
1493 icmpn = self.statistics.get_err_counter(
1494 '/err/nat44-in2out-slowpath/ICMP packets')
1495 totaln = self.statistics.get_err_counter(
1496 '/err/nat44-in2out-slowpath/good in2out packets processed')
1498 pkts = self.create_stream_in(self.pg0, self.pg1)
1499 self.pg0.add_stream(pkts)
1500 self.pg_enable_capture(self.pg_interfaces)
1502 capture = self.pg1.get_capture(len(pkts))
1503 self.verify_capture_out(capture)
1505 err = self.statistics.get_err_counter(
1506 '/err/nat44-in2out-slowpath/TCP packets')
1507 self.assertEqual(err - tcpn, 2)
1508 err = self.statistics.get_err_counter(
1509 '/err/nat44-in2out-slowpath/UDP packets')
1510 self.assertEqual(err - udpn, 1)
1511 err = self.statistics.get_err_counter(
1512 '/err/nat44-in2out-slowpath/ICMP packets')
1513 self.assertEqual(err - icmpn, 1)
1514 err = self.statistics.get_err_counter(
1515 '/err/nat44-in2out-slowpath/good in2out packets processed')
1516 self.assertEqual(err - totaln, 4)
1519 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1520 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1521 icmpn = self.statistics.get_err_counter(
1522 '/err/nat44-out2in/ICMP packets')
1523 totaln = self.statistics.get_err_counter(
1524 '/err/nat44-out2in/good out2in packets processed')
1526 pkts = self.create_stream_out(self.pg1)
1527 self.pg1.add_stream(pkts)
1528 self.pg_enable_capture(self.pg_interfaces)
1530 capture = self.pg0.get_capture(len(pkts))
1531 self.verify_capture_in(capture, self.pg0)
1533 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1534 self.assertEqual(err - tcpn, 2)
1535 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1536 self.assertEqual(err - udpn, 1)
1537 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1538 self.assertEqual(err - icmpn, 1)
1539 err = self.statistics.get_err_counter(
1540 '/err/nat44-out2in/good out2in packets processed')
1541 self.assertEqual(err - totaln, 4)
1543 users = self.statistics.get_counter('/nat44/total-users')
1544 self.assertEqual(users[0][0], 1)
1545 sessions = self.statistics.get_counter('/nat44/total-sessions')
1546 self.assertEqual(sessions[0][0], 3)
1548 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1549 """ NAT44 handling of client packets with TTL=1 """
1551 self.nat44_add_address(self.nat_addr)
1552 flags = self.config_flags.NAT_IS_INSIDE
1553 self.vapi.nat44_interface_add_del_feature(
1554 sw_if_index=self.pg0.sw_if_index,
1555 flags=flags, is_add=1)
1556 self.vapi.nat44_interface_add_del_feature(
1557 sw_if_index=self.pg1.sw_if_index,
1560 # Client side - generate traffic
1561 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1562 self.pg0.add_stream(pkts)
1563 self.pg_enable_capture(self.pg_interfaces)
1566 # Client side - verify ICMP type 11 packets
1567 capture = self.pg0.get_capture(len(pkts))
1568 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1570 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1571 """ NAT44 handling of server packets with TTL=1 """
1573 self.nat44_add_address(self.nat_addr)
1574 flags = self.config_flags.NAT_IS_INSIDE
1575 self.vapi.nat44_interface_add_del_feature(
1576 sw_if_index=self.pg0.sw_if_index,
1577 flags=flags, is_add=1)
1578 self.vapi.nat44_interface_add_del_feature(
1579 sw_if_index=self.pg1.sw_if_index,
1582 # Client side - create sessions
1583 pkts = self.create_stream_in(self.pg0, self.pg1)
1584 self.pg0.add_stream(pkts)
1585 self.pg_enable_capture(self.pg_interfaces)
1588 # Server side - generate traffic
1589 capture = self.pg1.get_capture(len(pkts))
1590 self.verify_capture_out(capture)
1591 pkts = self.create_stream_out(self.pg1, ttl=1)
1592 self.pg1.add_stream(pkts)
1593 self.pg_enable_capture(self.pg_interfaces)
1596 # Server side - verify ICMP type 11 packets
1597 capture = self.pg1.get_capture(len(pkts))
1598 self.verify_capture_out_with_icmp_errors(capture,
1599 src_ip=self.pg1.local_ip4)
1601 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1602 """ NAT44 handling of error responses to client packets with TTL=2 """
1604 self.nat44_add_address(self.nat_addr)
1605 flags = self.config_flags.NAT_IS_INSIDE
1606 self.vapi.nat44_interface_add_del_feature(
1607 sw_if_index=self.pg0.sw_if_index,
1608 flags=flags, is_add=1)
1609 self.vapi.nat44_interface_add_del_feature(
1610 sw_if_index=self.pg1.sw_if_index,
1613 # Client side - generate traffic
1614 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1615 self.pg0.add_stream(pkts)
1616 self.pg_enable_capture(self.pg_interfaces)
1619 # Server side - simulate ICMP type 11 response
1620 capture = self.pg1.get_capture(len(pkts))
1621 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1622 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1623 ICMP(type=11) / packet[IP] for packet in capture]
1624 self.pg1.add_stream(pkts)
1625 self.pg_enable_capture(self.pg_interfaces)
1628 # Client side - verify ICMP type 11 packets
1629 capture = self.pg0.get_capture(len(pkts))
1630 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1632 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1633 """ NAT44 handling of error responses to server packets with TTL=2 """
1635 self.nat44_add_address(self.nat_addr)
1636 flags = self.config_flags.NAT_IS_INSIDE
1637 self.vapi.nat44_interface_add_del_feature(
1638 sw_if_index=self.pg0.sw_if_index,
1639 flags=flags, is_add=1)
1640 self.vapi.nat44_interface_add_del_feature(
1641 sw_if_index=self.pg1.sw_if_index,
1644 # Client side - create sessions
1645 pkts = self.create_stream_in(self.pg0, self.pg1)
1646 self.pg0.add_stream(pkts)
1647 self.pg_enable_capture(self.pg_interfaces)
1650 # Server side - generate traffic
1651 capture = self.pg1.get_capture(len(pkts))
1652 self.verify_capture_out(capture)
1653 pkts = self.create_stream_out(self.pg1, ttl=2)
1654 self.pg1.add_stream(pkts)
1655 self.pg_enable_capture(self.pg_interfaces)
1658 # Client side - simulate ICMP type 11 response
1659 capture = self.pg0.get_capture(len(pkts))
1660 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1661 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1662 ICMP(type=11) / packet[IP] for packet in capture]
1663 self.pg0.add_stream(pkts)
1664 self.pg_enable_capture(self.pg_interfaces)
1667 # Server side - verify ICMP type 11 packets
1668 capture = self.pg1.get_capture(len(pkts))
1669 self.verify_capture_out_with_icmp_errors(capture)
1671 def test_ping_out_interface_from_outside(self):
1672 """ Ping NAT44 out interface from outside network """
1674 self.nat44_add_address(self.nat_addr)
1675 flags = self.config_flags.NAT_IS_INSIDE
1676 self.vapi.nat44_interface_add_del_feature(
1677 sw_if_index=self.pg0.sw_if_index,
1678 flags=flags, is_add=1)
1679 self.vapi.nat44_interface_add_del_feature(
1680 sw_if_index=self.pg1.sw_if_index,
1683 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1684 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1685 ICMP(id=self.icmp_id_out, type='echo-request'))
1687 self.pg1.add_stream(pkts)
1688 self.pg_enable_capture(self.pg_interfaces)
1690 capture = self.pg1.get_capture(len(pkts))
1693 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1694 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1695 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1696 self.assertEqual(packet[ICMP].type, 0) # echo reply
1698 self.logger.error(ppp("Unexpected or invalid packet "
1699 "(outside network):", packet))
1702 def test_ping_internal_host_from_outside(self):
1703 """ Ping internal host from outside network """
1705 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1706 flags = self.config_flags.NAT_IS_INSIDE
1707 self.vapi.nat44_interface_add_del_feature(
1708 sw_if_index=self.pg0.sw_if_index,
1709 flags=flags, is_add=1)
1710 self.vapi.nat44_interface_add_del_feature(
1711 sw_if_index=self.pg1.sw_if_index,
1715 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1716 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1717 ICMP(id=self.icmp_id_out, type='echo-request'))
1718 self.pg1.add_stream(pkt)
1719 self.pg_enable_capture(self.pg_interfaces)
1721 capture = self.pg0.get_capture(1)
1722 self.verify_capture_in(capture, self.pg0)
1723 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1726 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1727 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1728 ICMP(id=self.icmp_id_in, type='echo-reply'))
1729 self.pg0.add_stream(pkt)
1730 self.pg_enable_capture(self.pg_interfaces)
1732 capture = self.pg1.get_capture(1)
1733 self.verify_capture_out(capture, same_port=True)
1734 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1736 def test_forwarding(self):
1737 """ NAT44 forwarding test """
1739 flags = self.config_flags.NAT_IS_INSIDE
1740 self.vapi.nat44_interface_add_del_feature(
1741 sw_if_index=self.pg0.sw_if_index,
1742 flags=flags, is_add=1)
1743 self.vapi.nat44_interface_add_del_feature(
1744 sw_if_index=self.pg1.sw_if_index,
1746 self.vapi.nat44_forwarding_enable_disable(enable=1)
1748 real_ip = self.pg0.remote_ip4
1749 alias_ip = self.nat_addr
1750 flags = self.config_flags.NAT_IS_ADDR_ONLY
1751 self.vapi.nat44_add_del_static_mapping(is_add=1,
1752 local_ip_address=real_ip,
1753 external_ip_address=alias_ip,
1754 external_sw_if_index=0xFFFFFFFF,
1758 # static mapping match
1760 pkts = self.create_stream_out(self.pg1)
1761 self.pg1.add_stream(pkts)
1762 self.pg_enable_capture(self.pg_interfaces)
1764 capture = self.pg0.get_capture(len(pkts))
1765 self.verify_capture_in(capture, self.pg0)
1767 pkts = self.create_stream_in(self.pg0, self.pg1)
1768 self.pg0.add_stream(pkts)
1769 self.pg_enable_capture(self.pg_interfaces)
1771 capture = self.pg1.get_capture(len(pkts))
1772 self.verify_capture_out(capture, same_port=True)
1774 # no static mapping match
1776 host0 = self.pg0.remote_hosts[0]
1777 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1779 pkts = self.create_stream_out(self.pg1,
1780 dst_ip=self.pg0.remote_ip4,
1781 use_inside_ports=True)
1782 self.pg1.add_stream(pkts)
1783 self.pg_enable_capture(self.pg_interfaces)
1785 capture = self.pg0.get_capture(len(pkts))
1786 self.verify_capture_in(capture, self.pg0)
1788 pkts = self.create_stream_in(self.pg0, self.pg1)
1789 self.pg0.add_stream(pkts)
1790 self.pg_enable_capture(self.pg_interfaces)
1792 capture = self.pg1.get_capture(len(pkts))
1793 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1796 self.pg0.remote_hosts[0] = host0
1799 self.vapi.nat44_forwarding_enable_disable(enable=0)
1800 flags = self.config_flags.NAT_IS_ADDR_ONLY
1801 self.vapi.nat44_add_del_static_mapping(
1803 local_ip_address=real_ip,
1804 external_ip_address=alias_ip,
1805 external_sw_if_index=0xFFFFFFFF,
1808 def test_static_in(self):
1809 """ 1:1 NAT initialized from inside network """
1811 nat_ip = "10.0.0.10"
1812 self.tcp_port_out = 6303
1813 self.udp_port_out = 6304
1814 self.icmp_id_out = 6305
1816 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1817 flags = self.config_flags.NAT_IS_INSIDE
1818 self.vapi.nat44_interface_add_del_feature(
1819 sw_if_index=self.pg0.sw_if_index,
1820 flags=flags, is_add=1)
1821 self.vapi.nat44_interface_add_del_feature(
1822 sw_if_index=self.pg1.sw_if_index,
1824 sm = self.vapi.nat44_static_mapping_dump()
1825 self.assertEqual(len(sm), 1)
1826 self.assertEqual(sm[0].tag, '')
1827 self.assertEqual(sm[0].protocol, 0)
1828 self.assertEqual(sm[0].local_port, 0)
1829 self.assertEqual(sm[0].external_port, 0)
1832 pkts = self.create_stream_in(self.pg0, self.pg1)
1833 self.pg0.add_stream(pkts)
1834 self.pg_enable_capture(self.pg_interfaces)
1836 capture = self.pg1.get_capture(len(pkts))
1837 self.verify_capture_out(capture, nat_ip, True)
1840 pkts = self.create_stream_out(self.pg1, nat_ip)
1841 self.pg1.add_stream(pkts)
1842 self.pg_enable_capture(self.pg_interfaces)
1844 capture = self.pg0.get_capture(len(pkts))
1845 self.verify_capture_in(capture, self.pg0)
1847 def test_static_out(self):
1848 """ 1:1 NAT initialized from outside network """
1850 nat_ip = "10.0.0.20"
1851 self.tcp_port_out = 6303
1852 self.udp_port_out = 6304
1853 self.icmp_id_out = 6305
1856 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1857 flags = self.config_flags.NAT_IS_INSIDE
1858 self.vapi.nat44_interface_add_del_feature(
1859 sw_if_index=self.pg0.sw_if_index,
1860 flags=flags, is_add=1)
1861 self.vapi.nat44_interface_add_del_feature(
1862 sw_if_index=self.pg1.sw_if_index,
1864 sm = self.vapi.nat44_static_mapping_dump()
1865 self.assertEqual(len(sm), 1)
1866 self.assertEqual(sm[0].tag, tag)
1869 pkts = self.create_stream_out(self.pg1, nat_ip)
1870 self.pg1.add_stream(pkts)
1871 self.pg_enable_capture(self.pg_interfaces)
1873 capture = self.pg0.get_capture(len(pkts))
1874 self.verify_capture_in(capture, self.pg0)
1877 pkts = self.create_stream_in(self.pg0, self.pg1)
1878 self.pg0.add_stream(pkts)
1879 self.pg_enable_capture(self.pg_interfaces)
1881 capture = self.pg1.get_capture(len(pkts))
1882 self.verify_capture_out(capture, nat_ip, True)
1884 def test_static_with_port_in(self):
1885 """ 1:1 NAPT initialized from inside network """
1887 self.tcp_port_out = 3606
1888 self.udp_port_out = 3607
1889 self.icmp_id_out = 3608
1891 self.nat44_add_address(self.nat_addr)
1892 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1893 self.tcp_port_in, self.tcp_port_out,
1894 proto=IP_PROTOS.tcp)
1895 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1896 self.udp_port_in, self.udp_port_out,
1897 proto=IP_PROTOS.udp)
1898 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1899 self.icmp_id_in, self.icmp_id_out,
1900 proto=IP_PROTOS.icmp)
1901 flags = self.config_flags.NAT_IS_INSIDE
1902 self.vapi.nat44_interface_add_del_feature(
1903 sw_if_index=self.pg0.sw_if_index,
1904 flags=flags, is_add=1)
1905 self.vapi.nat44_interface_add_del_feature(
1906 sw_if_index=self.pg1.sw_if_index,
1910 pkts = self.create_stream_in(self.pg0, self.pg1)
1911 self.pg0.add_stream(pkts)
1912 self.pg_enable_capture(self.pg_interfaces)
1914 capture = self.pg1.get_capture(len(pkts))
1915 self.verify_capture_out(capture)
1918 pkts = self.create_stream_out(self.pg1)
1919 self.pg1.add_stream(pkts)
1920 self.pg_enable_capture(self.pg_interfaces)
1922 capture = self.pg0.get_capture(len(pkts))
1923 self.verify_capture_in(capture, self.pg0)
1925 def test_static_with_port_out(self):
1926 """ 1:1 NAPT initialized from outside network """
1928 self.tcp_port_out = 30606
1929 self.udp_port_out = 30607
1930 self.icmp_id_out = 30608
1932 self.nat44_add_address(self.nat_addr)
1933 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1934 self.tcp_port_in, self.tcp_port_out,
1935 proto=IP_PROTOS.tcp)
1936 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1937 self.udp_port_in, self.udp_port_out,
1938 proto=IP_PROTOS.udp)
1939 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1940 self.icmp_id_in, self.icmp_id_out,
1941 proto=IP_PROTOS.icmp)
1942 flags = self.config_flags.NAT_IS_INSIDE
1943 self.vapi.nat44_interface_add_del_feature(
1944 sw_if_index=self.pg0.sw_if_index,
1945 flags=flags, is_add=1)
1946 self.vapi.nat44_interface_add_del_feature(
1947 sw_if_index=self.pg1.sw_if_index,
1951 pkts = self.create_stream_out(self.pg1)
1952 self.pg1.add_stream(pkts)
1953 self.pg_enable_capture(self.pg_interfaces)
1955 capture = self.pg0.get_capture(len(pkts))
1956 self.verify_capture_in(capture, self.pg0)
1959 pkts = self.create_stream_in(self.pg0, self.pg1)
1960 self.pg0.add_stream(pkts)
1961 self.pg_enable_capture(self.pg_interfaces)
1963 capture = self.pg1.get_capture(len(pkts))
1964 self.verify_capture_out(capture)
1966 def test_static_vrf_aware(self):
1967 """ 1:1 NAT VRF awareness """
1969 nat_ip1 = "10.0.0.30"
1970 nat_ip2 = "10.0.0.40"
1971 self.tcp_port_out = 6303
1972 self.udp_port_out = 6304
1973 self.icmp_id_out = 6305
1975 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1977 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1979 flags = self.config_flags.NAT_IS_INSIDE
1980 self.vapi.nat44_interface_add_del_feature(
1981 sw_if_index=self.pg3.sw_if_index,
1983 self.vapi.nat44_interface_add_del_feature(
1984 sw_if_index=self.pg0.sw_if_index,
1985 flags=flags, is_add=1)
1986 self.vapi.nat44_interface_add_del_feature(
1987 sw_if_index=self.pg4.sw_if_index,
1988 flags=flags, is_add=1)
1990 # inside interface VRF match NAT44 static mapping VRF
1991 pkts = self.create_stream_in(self.pg4, self.pg3)
1992 self.pg4.add_stream(pkts)
1993 self.pg_enable_capture(self.pg_interfaces)
1995 capture = self.pg3.get_capture(len(pkts))
1996 self.verify_capture_out(capture, nat_ip1, True)
1998 # inside interface VRF don't match NAT44 static mapping VRF (packets
2000 pkts = self.create_stream_in(self.pg0, self.pg3)
2001 self.pg0.add_stream(pkts)
2002 self.pg_enable_capture(self.pg_interfaces)
2004 self.pg3.assert_nothing_captured()
2006 def test_dynamic_to_static(self):
2007 """ Switch from dynamic translation to 1:1NAT """
2008 nat_ip = "10.0.0.10"
2009 self.tcp_port_out = 6303
2010 self.udp_port_out = 6304
2011 self.icmp_id_out = 6305
2013 self.nat44_add_address(self.nat_addr)
2014 flags = self.config_flags.NAT_IS_INSIDE
2015 self.vapi.nat44_interface_add_del_feature(
2016 sw_if_index=self.pg0.sw_if_index,
2017 flags=flags, is_add=1)
2018 self.vapi.nat44_interface_add_del_feature(
2019 sw_if_index=self.pg1.sw_if_index,
2023 pkts = self.create_stream_in(self.pg0, self.pg1)
2024 self.pg0.add_stream(pkts)
2025 self.pg_enable_capture(self.pg_interfaces)
2027 capture = self.pg1.get_capture(len(pkts))
2028 self.verify_capture_out(capture)
2031 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2032 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2033 self.assertEqual(len(sessions), 0)
2034 pkts = self.create_stream_in(self.pg0, self.pg1)
2035 self.pg0.add_stream(pkts)
2036 self.pg_enable_capture(self.pg_interfaces)
2038 capture = self.pg1.get_capture(len(pkts))
2039 self.verify_capture_out(capture, nat_ip, True)
2041 def test_identity_nat(self):
2042 """ Identity NAT """
2043 flags = self.config_flags.NAT_IS_ADDR_ONLY
2044 self.vapi.nat44_add_del_identity_mapping(
2045 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2046 flags=flags, is_add=1)
2047 flags = self.config_flags.NAT_IS_INSIDE
2048 self.vapi.nat44_interface_add_del_feature(
2049 sw_if_index=self.pg0.sw_if_index,
2050 flags=flags, is_add=1)
2051 self.vapi.nat44_interface_add_del_feature(
2052 sw_if_index=self.pg1.sw_if_index,
2055 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2056 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2057 TCP(sport=12345, dport=56789))
2058 self.pg1.add_stream(p)
2059 self.pg_enable_capture(self.pg_interfaces)
2061 capture = self.pg0.get_capture(1)
2066 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2067 self.assertEqual(ip.src, self.pg1.remote_ip4)
2068 self.assertEqual(tcp.dport, 56789)
2069 self.assertEqual(tcp.sport, 12345)
2070 self.assert_packet_checksums_valid(p)
2072 self.logger.error(ppp("Unexpected or invalid packet:", p))
2075 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2076 self.assertEqual(len(sessions), 0)
2077 flags = self.config_flags.NAT_IS_ADDR_ONLY
2078 self.vapi.nat44_add_del_identity_mapping(
2079 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2080 flags=flags, vrf_id=1, is_add=1)
2081 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2082 self.assertEqual(len(identity_mappings), 2)
2084 def test_multiple_inside_interfaces(self):
2085 """ NAT44 multiple non-overlapping address space inside interfaces """
2087 self.nat44_add_address(self.nat_addr)
2088 flags = self.config_flags.NAT_IS_INSIDE
2089 self.vapi.nat44_interface_add_del_feature(
2090 sw_if_index=self.pg0.sw_if_index,
2091 flags=flags, is_add=1)
2092 self.vapi.nat44_interface_add_del_feature(
2093 sw_if_index=self.pg1.sw_if_index,
2094 flags=flags, is_add=1)
2095 self.vapi.nat44_interface_add_del_feature(
2096 sw_if_index=self.pg3.sw_if_index,
2099 # between two NAT44 inside interfaces (no translation)
2100 pkts = self.create_stream_in(self.pg0, self.pg1)
2101 self.pg0.add_stream(pkts)
2102 self.pg_enable_capture(self.pg_interfaces)
2104 capture = self.pg1.get_capture(len(pkts))
2105 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2107 # from NAT44 inside to interface without NAT44 feature (no translation)
2108 pkts = self.create_stream_in(self.pg0, self.pg2)
2109 self.pg0.add_stream(pkts)
2110 self.pg_enable_capture(self.pg_interfaces)
2112 capture = self.pg2.get_capture(len(pkts))
2113 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2115 # in2out 1st interface
2116 pkts = self.create_stream_in(self.pg0, self.pg3)
2117 self.pg0.add_stream(pkts)
2118 self.pg_enable_capture(self.pg_interfaces)
2120 capture = self.pg3.get_capture(len(pkts))
2121 self.verify_capture_out(capture)
2123 # out2in 1st interface
2124 pkts = self.create_stream_out(self.pg3)
2125 self.pg3.add_stream(pkts)
2126 self.pg_enable_capture(self.pg_interfaces)
2128 capture = self.pg0.get_capture(len(pkts))
2129 self.verify_capture_in(capture, self.pg0)
2131 # in2out 2nd interface
2132 pkts = self.create_stream_in(self.pg1, self.pg3)
2133 self.pg1.add_stream(pkts)
2134 self.pg_enable_capture(self.pg_interfaces)
2136 capture = self.pg3.get_capture(len(pkts))
2137 self.verify_capture_out(capture)
2139 # out2in 2nd interface
2140 pkts = self.create_stream_out(self.pg3)
2141 self.pg3.add_stream(pkts)
2142 self.pg_enable_capture(self.pg_interfaces)
2144 capture = self.pg1.get_capture(len(pkts))
2145 self.verify_capture_in(capture, self.pg1)
2147 def test_inside_overlapping_interfaces(self):
2148 """ NAT44 multiple inside interfaces with overlapping address space """
2150 static_nat_ip = "10.0.0.10"
2151 self.nat44_add_address(self.nat_addr)
2152 flags = self.config_flags.NAT_IS_INSIDE
2153 self.vapi.nat44_interface_add_del_feature(
2154 sw_if_index=self.pg3.sw_if_index,
2156 self.vapi.nat44_interface_add_del_feature(
2157 sw_if_index=self.pg4.sw_if_index,
2158 flags=flags, is_add=1)
2159 self.vapi.nat44_interface_add_del_feature(
2160 sw_if_index=self.pg5.sw_if_index,
2161 flags=flags, is_add=1)
2162 self.vapi.nat44_interface_add_del_feature(
2163 sw_if_index=self.pg6.sw_if_index,
2164 flags=flags, is_add=1)
2165 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2168 # between NAT44 inside interfaces with same VRF (no translation)
2169 pkts = self.create_stream_in(self.pg4, self.pg5)
2170 self.pg4.add_stream(pkts)
2171 self.pg_enable_capture(self.pg_interfaces)
2173 capture = self.pg5.get_capture(len(pkts))
2174 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2176 # between NAT44 inside interfaces with different VRF (hairpinning)
2177 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2178 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2179 TCP(sport=1234, dport=5678))
2180 self.pg4.add_stream(p)
2181 self.pg_enable_capture(self.pg_interfaces)
2183 capture = self.pg6.get_capture(1)
2188 self.assertEqual(ip.src, self.nat_addr)
2189 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2190 self.assertNotEqual(tcp.sport, 1234)
2191 self.assertEqual(tcp.dport, 5678)
2193 self.logger.error(ppp("Unexpected or invalid packet:", p))
2196 # in2out 1st interface
2197 pkts = self.create_stream_in(self.pg4, self.pg3)
2198 self.pg4.add_stream(pkts)
2199 self.pg_enable_capture(self.pg_interfaces)
2201 capture = self.pg3.get_capture(len(pkts))
2202 self.verify_capture_out(capture)
2204 # out2in 1st interface
2205 pkts = self.create_stream_out(self.pg3)
2206 self.pg3.add_stream(pkts)
2207 self.pg_enable_capture(self.pg_interfaces)
2209 capture = self.pg4.get_capture(len(pkts))
2210 self.verify_capture_in(capture, self.pg4)
2212 # in2out 2nd interface
2213 pkts = self.create_stream_in(self.pg5, self.pg3)
2214 self.pg5.add_stream(pkts)
2215 self.pg_enable_capture(self.pg_interfaces)
2217 capture = self.pg3.get_capture(len(pkts))
2218 self.verify_capture_out(capture)
2220 # out2in 2nd interface
2221 pkts = self.create_stream_out(self.pg3)
2222 self.pg3.add_stream(pkts)
2223 self.pg_enable_capture(self.pg_interfaces)
2225 capture = self.pg5.get_capture(len(pkts))
2226 self.verify_capture_in(capture, self.pg5)
2229 addresses = self.vapi.nat44_address_dump()
2230 self.assertEqual(len(addresses), 1)
2231 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2232 self.assertEqual(len(sessions), 3)
2233 for session in sessions:
2234 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2235 self.assertEqual(str(session.inside_ip_address),
2236 self.pg5.remote_ip4)
2237 self.assertEqual(session.outside_ip_address,
2238 addresses[0].ip_address)
2239 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2240 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2241 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2242 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2243 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2244 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2245 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2246 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2247 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2249 # in2out 3rd interface
2250 pkts = self.create_stream_in(self.pg6, self.pg3)
2251 self.pg6.add_stream(pkts)
2252 self.pg_enable_capture(self.pg_interfaces)
2254 capture = self.pg3.get_capture(len(pkts))
2255 self.verify_capture_out(capture, static_nat_ip, True)
2257 # out2in 3rd interface
2258 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2259 self.pg3.add_stream(pkts)
2260 self.pg_enable_capture(self.pg_interfaces)
2262 capture = self.pg6.get_capture(len(pkts))
2263 self.verify_capture_in(capture, self.pg6)
2265 # general user and session dump verifications
2266 users = self.vapi.nat44_user_dump()
2267 self.assertGreaterEqual(len(users), 3)
2268 addresses = self.vapi.nat44_address_dump()
2269 self.assertEqual(len(addresses), 1)
2271 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2273 for session in sessions:
2274 self.assertEqual(user.ip_address, session.inside_ip_address)
2275 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2276 self.assertTrue(session.protocol in
2277 [IP_PROTOS.tcp, IP_PROTOS.udp,
2279 self.assertFalse(session.flags &
2280 self.config_flags.NAT_IS_EXT_HOST_VALID)
2283 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2284 self.assertGreaterEqual(len(sessions), 4)
2285 for session in sessions:
2286 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2287 self.assertEqual(str(session.inside_ip_address),
2288 self.pg4.remote_ip4)
2289 self.assertEqual(session.outside_ip_address,
2290 addresses[0].ip_address)
2293 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2294 self.assertGreaterEqual(len(sessions), 3)
2295 for session in sessions:
2296 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2297 self.assertEqual(str(session.inside_ip_address),
2298 self.pg6.remote_ip4)
2299 self.assertEqual(str(session.outside_ip_address),
2301 self.assertTrue(session.inside_port in
2302 [self.tcp_port_in, self.udp_port_in,
2305 def test_hairpinning(self):
2306 """ NAT44 hairpinning - 1:1 NAPT """
2308 host = self.pg0.remote_hosts[0]
2309 server = self.pg0.remote_hosts[1]
2312 server_in_port = 5678
2313 server_out_port = 8765
2315 self.nat44_add_address(self.nat_addr)
2316 flags = self.config_flags.NAT_IS_INSIDE
2317 self.vapi.nat44_interface_add_del_feature(
2318 sw_if_index=self.pg0.sw_if_index,
2319 flags=flags, is_add=1)
2320 self.vapi.nat44_interface_add_del_feature(
2321 sw_if_index=self.pg1.sw_if_index,
2324 # add static mapping for server
2325 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2326 server_in_port, server_out_port,
2327 proto=IP_PROTOS.tcp)
2329 # send packet from host to server
2330 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2331 IP(src=host.ip4, dst=self.nat_addr) /
2332 TCP(sport=host_in_port, dport=server_out_port))
2333 self.pg0.add_stream(p)
2334 self.pg_enable_capture(self.pg_interfaces)
2336 capture = self.pg0.get_capture(1)
2341 self.assertEqual(ip.src, self.nat_addr)
2342 self.assertEqual(ip.dst, server.ip4)
2343 self.assertNotEqual(tcp.sport, host_in_port)
2344 self.assertEqual(tcp.dport, server_in_port)
2345 self.assert_packet_checksums_valid(p)
2346 host_out_port = tcp.sport
2348 self.logger.error(ppp("Unexpected or invalid packet:", p))
2351 # send reply from server to host
2352 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2353 IP(src=server.ip4, dst=self.nat_addr) /
2354 TCP(sport=server_in_port, dport=host_out_port))
2355 self.pg0.add_stream(p)
2356 self.pg_enable_capture(self.pg_interfaces)
2358 capture = self.pg0.get_capture(1)
2363 self.assertEqual(ip.src, self.nat_addr)
2364 self.assertEqual(ip.dst, host.ip4)
2365 self.assertEqual(tcp.sport, server_out_port)
2366 self.assertEqual(tcp.dport, host_in_port)
2367 self.assert_packet_checksums_valid(p)
2369 self.logger.error(ppp("Unexpected or invalid packet:", p))
2372 def test_hairpinning2(self):
2373 """ NAT44 hairpinning - 1:1 NAT"""
2375 server1_nat_ip = "10.0.0.10"
2376 server2_nat_ip = "10.0.0.11"
2377 host = self.pg0.remote_hosts[0]
2378 server1 = self.pg0.remote_hosts[1]
2379 server2 = self.pg0.remote_hosts[2]
2380 server_tcp_port = 22
2381 server_udp_port = 20
2383 self.nat44_add_address(self.nat_addr)
2384 flags = self.config_flags.NAT_IS_INSIDE
2385 self.vapi.nat44_interface_add_del_feature(
2386 sw_if_index=self.pg0.sw_if_index,
2387 flags=flags, is_add=1)
2388 self.vapi.nat44_interface_add_del_feature(
2389 sw_if_index=self.pg1.sw_if_index,
2392 # add static mapping for servers
2393 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2394 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2398 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2399 IP(src=host.ip4, dst=server1_nat_ip) /
2400 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2402 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2403 IP(src=host.ip4, dst=server1_nat_ip) /
2404 UDP(sport=self.udp_port_in, dport=server_udp_port))
2406 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2407 IP(src=host.ip4, dst=server1_nat_ip) /
2408 ICMP(id=self.icmp_id_in, type='echo-request'))
2410 self.pg0.add_stream(pkts)
2411 self.pg_enable_capture(self.pg_interfaces)
2413 capture = self.pg0.get_capture(len(pkts))
2414 for packet in capture:
2416 self.assertEqual(packet[IP].src, self.nat_addr)
2417 self.assertEqual(packet[IP].dst, server1.ip4)
2418 if packet.haslayer(TCP):
2419 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2420 self.assertEqual(packet[TCP].dport, server_tcp_port)
2421 self.tcp_port_out = packet[TCP].sport
2422 self.assert_packet_checksums_valid(packet)
2423 elif packet.haslayer(UDP):
2424 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2425 self.assertEqual(packet[UDP].dport, server_udp_port)
2426 self.udp_port_out = packet[UDP].sport
2428 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2429 self.icmp_id_out = packet[ICMP].id
2431 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2437 IP(src=server1.ip4, dst=self.nat_addr) /
2438 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2441 IP(src=server1.ip4, dst=self.nat_addr) /
2442 UDP(sport=server_udp_port, dport=self.udp_port_out))
2444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2445 IP(src=server1.ip4, dst=self.nat_addr) /
2446 ICMP(id=self.icmp_id_out, type='echo-reply'))
2448 self.pg0.add_stream(pkts)
2449 self.pg_enable_capture(self.pg_interfaces)
2451 capture = self.pg0.get_capture(len(pkts))
2452 for packet in capture:
2454 self.assertEqual(packet[IP].src, server1_nat_ip)
2455 self.assertEqual(packet[IP].dst, host.ip4)
2456 if packet.haslayer(TCP):
2457 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2458 self.assertEqual(packet[TCP].sport, server_tcp_port)
2459 self.assert_packet_checksums_valid(packet)
2460 elif packet.haslayer(UDP):
2461 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2462 self.assertEqual(packet[UDP].sport, server_udp_port)
2464 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2466 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2469 # server2 to server1
2471 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2472 IP(src=server2.ip4, dst=server1_nat_ip) /
2473 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2475 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2476 IP(src=server2.ip4, dst=server1_nat_ip) /
2477 UDP(sport=self.udp_port_in, dport=server_udp_port))
2479 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2480 IP(src=server2.ip4, dst=server1_nat_ip) /
2481 ICMP(id=self.icmp_id_in, type='echo-request'))
2483 self.pg0.add_stream(pkts)
2484 self.pg_enable_capture(self.pg_interfaces)
2486 capture = self.pg0.get_capture(len(pkts))
2487 for packet in capture:
2489 self.assertEqual(packet[IP].src, server2_nat_ip)
2490 self.assertEqual(packet[IP].dst, server1.ip4)
2491 if packet.haslayer(TCP):
2492 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2493 self.assertEqual(packet[TCP].dport, server_tcp_port)
2494 self.tcp_port_out = packet[TCP].sport
2495 self.assert_packet_checksums_valid(packet)
2496 elif packet.haslayer(UDP):
2497 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2498 self.assertEqual(packet[UDP].dport, server_udp_port)
2499 self.udp_port_out = packet[UDP].sport
2501 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2502 self.icmp_id_out = packet[ICMP].id
2504 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2507 # server1 to server2
2509 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2510 IP(src=server1.ip4, dst=server2_nat_ip) /
2511 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2513 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2514 IP(src=server1.ip4, dst=server2_nat_ip) /
2515 UDP(sport=server_udp_port, dport=self.udp_port_out))
2517 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2518 IP(src=server1.ip4, dst=server2_nat_ip) /
2519 ICMP(id=self.icmp_id_out, type='echo-reply'))
2521 self.pg0.add_stream(pkts)
2522 self.pg_enable_capture(self.pg_interfaces)
2524 capture = self.pg0.get_capture(len(pkts))
2525 for packet in capture:
2527 self.assertEqual(packet[IP].src, server1_nat_ip)
2528 self.assertEqual(packet[IP].dst, server2.ip4)
2529 if packet.haslayer(TCP):
2530 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2531 self.assertEqual(packet[TCP].sport, server_tcp_port)
2532 self.assert_packet_checksums_valid(packet)
2533 elif packet.haslayer(UDP):
2534 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2535 self.assertEqual(packet[UDP].sport, server_udp_port)
2537 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2539 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2542 def test_interface_addr(self):
2543 """ Acquire NAT44 addresses from interface """
2544 self.vapi.nat44_add_del_interface_addr(
2546 sw_if_index=self.pg7.sw_if_index)
2548 # no address in NAT pool
2549 addresses = self.vapi.nat44_address_dump()
2550 self.assertEqual(0, len(addresses))
2552 # configure interface address and check NAT address pool
2553 self.pg7.config_ip4()
2554 addresses = self.vapi.nat44_address_dump()
2555 self.assertEqual(1, len(addresses))
2556 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2558 # remove interface address and check NAT address pool
2559 self.pg7.unconfig_ip4()
2560 addresses = self.vapi.nat44_address_dump()
2561 self.assertEqual(0, len(addresses))
2563 def test_interface_addr_static_mapping(self):
2564 """ Static mapping with addresses from interface """
2567 self.vapi.nat44_add_del_interface_addr(
2569 sw_if_index=self.pg7.sw_if_index)
2570 self.nat44_add_static_mapping(
2572 external_sw_if_index=self.pg7.sw_if_index,
2575 # static mappings with external interface
2576 static_mappings = self.vapi.nat44_static_mapping_dump()
2577 self.assertEqual(1, len(static_mappings))
2578 self.assertEqual(self.pg7.sw_if_index,
2579 static_mappings[0].external_sw_if_index)
2580 self.assertEqual(static_mappings[0].tag, tag)
2582 # configure interface address and check static mappings
2583 self.pg7.config_ip4()
2584 static_mappings = self.vapi.nat44_static_mapping_dump()
2585 self.assertEqual(2, len(static_mappings))
2587 for sm in static_mappings:
2588 if sm.external_sw_if_index == 0xFFFFFFFF:
2589 self.assertEqual(str(sm.external_ip_address),
2591 self.assertEqual(sm.tag, tag)
2593 self.assertTrue(resolved)
2595 # remove interface address and check static mappings
2596 self.pg7.unconfig_ip4()
2597 static_mappings = self.vapi.nat44_static_mapping_dump()
2598 self.assertEqual(1, len(static_mappings))
2599 self.assertEqual(self.pg7.sw_if_index,
2600 static_mappings[0].external_sw_if_index)
2601 self.assertEqual(static_mappings[0].tag, tag)
2603 # configure interface address again and check static mappings
2604 self.pg7.config_ip4()
2605 static_mappings = self.vapi.nat44_static_mapping_dump()
2606 self.assertEqual(2, len(static_mappings))
2608 for sm in static_mappings:
2609 if sm.external_sw_if_index == 0xFFFFFFFF:
2610 self.assertEqual(str(sm.external_ip_address),
2612 self.assertEqual(sm.tag, tag)
2614 self.assertTrue(resolved)
2616 # remove static mapping
2617 self.nat44_add_static_mapping(
2619 external_sw_if_index=self.pg7.sw_if_index,
2622 static_mappings = self.vapi.nat44_static_mapping_dump()
2623 self.assertEqual(0, len(static_mappings))
2625 def test_interface_addr_identity_nat(self):
2626 """ Identity NAT with addresses from interface """
2629 self.vapi.nat44_add_del_interface_addr(
2631 sw_if_index=self.pg7.sw_if_index)
2632 self.vapi.nat44_add_del_identity_mapping(
2634 sw_if_index=self.pg7.sw_if_index,
2636 protocol=IP_PROTOS.tcp,
2639 # identity mappings with external interface
2640 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2641 self.assertEqual(1, len(identity_mappings))
2642 self.assertEqual(self.pg7.sw_if_index,
2643 identity_mappings[0].sw_if_index)
2645 # configure interface address and check identity mappings
2646 self.pg7.config_ip4()
2647 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2649 self.assertEqual(2, len(identity_mappings))
2650 for sm in identity_mappings:
2651 if sm.sw_if_index == 0xFFFFFFFF:
2652 self.assertEqual(str(identity_mappings[0].ip_address),
2654 self.assertEqual(port, identity_mappings[0].port)
2655 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2657 self.assertTrue(resolved)
2659 # remove interface address and check identity mappings
2660 self.pg7.unconfig_ip4()
2661 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2662 self.assertEqual(1, len(identity_mappings))
2663 self.assertEqual(self.pg7.sw_if_index,
2664 identity_mappings[0].sw_if_index)
2666 def test_ipfix_nat44_sess(self):
2667 """ IPFIX logging NAT44 session created/deleted """
2668 self.ipfix_domain_id = 10
2669 self.ipfix_src_port = 20202
2670 collector_port = 30303
2671 bind_layers(UDP, IPFIX, dport=30303)
2672 self.nat44_add_address(self.nat_addr)
2673 flags = self.config_flags.NAT_IS_INSIDE
2674 self.vapi.nat44_interface_add_del_feature(
2675 sw_if_index=self.pg0.sw_if_index,
2676 flags=flags, is_add=1)
2677 self.vapi.nat44_interface_add_del_feature(
2678 sw_if_index=self.pg1.sw_if_index,
2680 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2681 src_address=self.pg3.local_ip4,
2683 template_interval=10,
2684 collector_port=collector_port)
2685 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2686 src_port=self.ipfix_src_port,
2689 pkts = self.create_stream_in(self.pg0, self.pg1)
2690 self.pg0.add_stream(pkts)
2691 self.pg_enable_capture(self.pg_interfaces)
2693 capture = self.pg1.get_capture(len(pkts))
2694 self.verify_capture_out(capture)
2695 self.nat44_add_address(self.nat_addr, is_add=0)
2696 self.vapi.ipfix_flush()
2697 capture = self.pg3.get_capture(7)
2698 ipfix = IPFIXDecoder()
2699 # first load template
2701 self.assertTrue(p.haslayer(IPFIX))
2702 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2703 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2704 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2705 self.assertEqual(p[UDP].dport, collector_port)
2706 self.assertEqual(p[IPFIX].observationDomainID,
2707 self.ipfix_domain_id)
2708 if p.haslayer(Template):
2709 ipfix.add_template(p.getlayer(Template))
2710 # verify events in data set
2712 if p.haslayer(Data):
2713 data = ipfix.decode_data_set(p.getlayer(Set))
2714 self.verify_ipfix_nat44_ses(data)
2716 def test_ipfix_addr_exhausted(self):
2717 """ IPFIX logging NAT addresses exhausted """
2718 flags = self.config_flags.NAT_IS_INSIDE
2719 self.vapi.nat44_interface_add_del_feature(
2720 sw_if_index=self.pg0.sw_if_index,
2721 flags=flags, is_add=1)
2722 self.vapi.nat44_interface_add_del_feature(
2723 sw_if_index=self.pg1.sw_if_index,
2725 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2726 src_address=self.pg3.local_ip4,
2728 template_interval=10)
2729 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2730 src_port=self.ipfix_src_port,
2733 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2734 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2736 self.pg0.add_stream(p)
2737 self.pg_enable_capture(self.pg_interfaces)
2739 self.pg1.assert_nothing_captured()
2741 self.vapi.ipfix_flush()
2742 capture = self.pg3.get_capture(7)
2743 ipfix = IPFIXDecoder()
2744 # first load template
2746 self.assertTrue(p.haslayer(IPFIX))
2747 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2748 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2749 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2750 self.assertEqual(p[UDP].dport, 4739)
2751 self.assertEqual(p[IPFIX].observationDomainID,
2752 self.ipfix_domain_id)
2753 if p.haslayer(Template):
2754 ipfix.add_template(p.getlayer(Template))
2755 # verify events in data set
2757 if p.haslayer(Data):
2758 data = ipfix.decode_data_set(p.getlayer(Set))
2759 self.verify_ipfix_addr_exhausted(data)
2761 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2762 def test_ipfix_max_sessions(self):
2763 """ IPFIX logging maximum session entries exceeded """
2764 self.nat44_add_address(self.nat_addr)
2765 flags = self.config_flags.NAT_IS_INSIDE
2766 self.vapi.nat44_interface_add_del_feature(
2767 sw_if_index=self.pg0.sw_if_index,
2768 flags=flags, is_add=1)
2769 self.vapi.nat44_interface_add_del_feature(
2770 sw_if_index=self.pg1.sw_if_index,
2773 nat44_config = self.vapi.nat_show_config()
2774 max_sessions = 10 * nat44_config.translation_buckets
2777 for i in range(0, max_sessions):
2778 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2779 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2780 IP(src=src, dst=self.pg1.remote_ip4) /
2783 self.pg0.add_stream(pkts)
2784 self.pg_enable_capture(self.pg_interfaces)
2787 self.pg1.get_capture(max_sessions)
2788 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2789 src_address=self.pg3.local_ip4,
2791 template_interval=10)
2792 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2793 src_port=self.ipfix_src_port,
2796 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2797 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2799 self.pg0.add_stream(p)
2800 self.pg_enable_capture(self.pg_interfaces)
2802 self.pg1.assert_nothing_captured()
2804 self.vapi.ipfix_flush()
2805 capture = self.pg3.get_capture(7)
2806 ipfix = IPFIXDecoder()
2807 # first load template
2809 self.assertTrue(p.haslayer(IPFIX))
2810 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2811 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2812 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2813 self.assertEqual(p[UDP].dport, 4739)
2814 self.assertEqual(p[IPFIX].observationDomainID,
2815 self.ipfix_domain_id)
2816 if p.haslayer(Template):
2817 ipfix.add_template(p.getlayer(Template))
2818 # verify events in data set
2820 if p.haslayer(Data):
2821 data = ipfix.decode_data_set(p.getlayer(Set))
2822 self.verify_ipfix_max_sessions(data, max_sessions)
2824 def test_syslog_apmap(self):
2825 """ Test syslog address and port mapping creation and deletion """
2826 self.vapi.syslog_set_filter(
2827 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2828 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2829 self.nat44_add_address(self.nat_addr)
2830 flags = self.config_flags.NAT_IS_INSIDE
2831 self.vapi.nat44_interface_add_del_feature(
2832 sw_if_index=self.pg0.sw_if_index,
2833 flags=flags, is_add=1)
2834 self.vapi.nat44_interface_add_del_feature(
2835 sw_if_index=self.pg1.sw_if_index,
2838 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2839 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2840 TCP(sport=self.tcp_port_in, dport=20))
2841 self.pg0.add_stream(p)
2842 self.pg_enable_capture(self.pg_interfaces)
2844 capture = self.pg1.get_capture(1)
2845 self.tcp_port_out = capture[0][TCP].sport
2846 capture = self.pg3.get_capture(1)
2847 self.verify_syslog_apmap(capture[0][Raw].load)
2849 self.pg_enable_capture(self.pg_interfaces)
2851 self.nat44_add_address(self.nat_addr, is_add=0)
2852 capture = self.pg3.get_capture(1)
2853 self.verify_syslog_apmap(capture[0][Raw].load, False)
2855 def test_pool_addr_fib(self):
2856 """ NAT44 add pool addresses to FIB """
2857 static_addr = '10.0.0.10'
2858 self.nat44_add_address(self.nat_addr)
2859 flags = self.config_flags.NAT_IS_INSIDE
2860 self.vapi.nat44_interface_add_del_feature(
2861 sw_if_index=self.pg0.sw_if_index,
2862 flags=flags, is_add=1)
2863 self.vapi.nat44_interface_add_del_feature(
2864 sw_if_index=self.pg1.sw_if_index,
2866 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2869 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2870 ARP(op=ARP.who_has, pdst=self.nat_addr,
2871 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2872 self.pg1.add_stream(p)
2873 self.pg_enable_capture(self.pg_interfaces)
2875 capture = self.pg1.get_capture(1)
2876 self.assertTrue(capture[0].haslayer(ARP))
2877 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2880 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2881 ARP(op=ARP.who_has, pdst=static_addr,
2882 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2883 self.pg1.add_stream(p)
2884 self.pg_enable_capture(self.pg_interfaces)
2886 capture = self.pg1.get_capture(1)
2887 self.assertTrue(capture[0].haslayer(ARP))
2888 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2890 # send ARP to non-NAT44 interface
2891 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2892 ARP(op=ARP.who_has, pdst=self.nat_addr,
2893 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2894 self.pg2.add_stream(p)
2895 self.pg_enable_capture(self.pg_interfaces)
2897 self.pg1.assert_nothing_captured()
2899 # remove addresses and verify
2900 self.nat44_add_address(self.nat_addr, is_add=0)
2901 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2904 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2905 ARP(op=ARP.who_has, pdst=self.nat_addr,
2906 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2907 self.pg1.add_stream(p)
2908 self.pg_enable_capture(self.pg_interfaces)
2910 self.pg1.assert_nothing_captured()
2912 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2913 ARP(op=ARP.who_has, pdst=static_addr,
2914 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2915 self.pg1.add_stream(p)
2916 self.pg_enable_capture(self.pg_interfaces)
2918 self.pg1.assert_nothing_captured()
2920 def test_vrf_mode(self):
2921 """ NAT44 tenant VRF aware address pool mode """
2925 nat_ip1 = "10.0.0.10"
2926 nat_ip2 = "10.0.0.11"
2928 self.pg0.unconfig_ip4()
2929 self.pg1.unconfig_ip4()
2930 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2931 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2932 self.pg0.set_table_ip4(vrf_id1)
2933 self.pg1.set_table_ip4(vrf_id2)
2934 self.pg0.config_ip4()
2935 self.pg1.config_ip4()
2936 self.pg0.resolve_arp()
2937 self.pg1.resolve_arp()
2939 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2940 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2941 flags = self.config_flags.NAT_IS_INSIDE
2942 self.vapi.nat44_interface_add_del_feature(
2943 sw_if_index=self.pg0.sw_if_index,
2944 flags=flags, is_add=1)
2945 self.vapi.nat44_interface_add_del_feature(
2946 sw_if_index=self.pg1.sw_if_index,
2947 flags=flags, is_add=1)
2948 self.vapi.nat44_interface_add_del_feature(
2949 sw_if_index=self.pg2.sw_if_index,
2954 pkts = self.create_stream_in(self.pg0, self.pg2)
2955 self.pg0.add_stream(pkts)
2956 self.pg_enable_capture(self.pg_interfaces)
2958 capture = self.pg2.get_capture(len(pkts))
2959 self.verify_capture_out(capture, nat_ip1)
2962 pkts = self.create_stream_in(self.pg1, self.pg2)
2963 self.pg1.add_stream(pkts)
2964 self.pg_enable_capture(self.pg_interfaces)
2966 capture = self.pg2.get_capture(len(pkts))
2967 self.verify_capture_out(capture, nat_ip2)
2970 self.pg0.unconfig_ip4()
2971 self.pg1.unconfig_ip4()
2972 self.pg0.set_table_ip4(0)
2973 self.pg1.set_table_ip4(0)
2974 self.pg0.config_ip4()
2975 self.pg1.config_ip4()
2976 self.pg0.resolve_arp()
2977 self.pg1.resolve_arp()
2978 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2979 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2981 def test_vrf_feature_independent(self):
2982 """ NAT44 tenant VRF independent address pool mode """
2984 nat_ip1 = "10.0.0.10"
2985 nat_ip2 = "10.0.0.11"
2987 self.nat44_add_address(nat_ip1)
2988 self.nat44_add_address(nat_ip2, vrf_id=99)
2989 flags = self.config_flags.NAT_IS_INSIDE
2990 self.vapi.nat44_interface_add_del_feature(
2991 sw_if_index=self.pg0.sw_if_index,
2992 flags=flags, is_add=1)
2993 self.vapi.nat44_interface_add_del_feature(
2994 sw_if_index=self.pg1.sw_if_index,
2995 flags=flags, is_add=1)
2996 self.vapi.nat44_interface_add_del_feature(
2997 sw_if_index=self.pg2.sw_if_index,
3001 pkts = self.create_stream_in(self.pg0, self.pg2)
3002 self.pg0.add_stream(pkts)
3003 self.pg_enable_capture(self.pg_interfaces)
3005 capture = self.pg2.get_capture(len(pkts))
3006 self.verify_capture_out(capture, nat_ip1)
3009 pkts = self.create_stream_in(self.pg1, self.pg2)
3010 self.pg1.add_stream(pkts)
3011 self.pg_enable_capture(self.pg_interfaces)
3013 capture = self.pg2.get_capture(len(pkts))
3014 self.verify_capture_out(capture, nat_ip1)
3016 def create_routes_and_neigbors(self):
3017 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3018 [VppRoutePath(self.pg7.remote_ip4,
3019 self.pg7.sw_if_index)])
3020 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3021 [VppRoutePath(self.pg8.remote_ip4,
3022 self.pg8.sw_if_index)])
3026 n1 = VppNeighbor(self,
3027 self.pg7.sw_if_index,
3028 self.pg7.remote_mac,
3029 self.pg7.remote_ip4,
3031 n2 = VppNeighbor(self,
3032 self.pg8.sw_if_index,
3033 self.pg8.remote_mac,
3034 self.pg8.remote_ip4,
3039 def test_dynamic_ipless_interfaces(self):
3040 """ NAT44 interfaces without configured IP address """
3041 self.create_routes_and_neigbors()
3042 self.nat44_add_address(self.nat_addr)
3043 flags = self.config_flags.NAT_IS_INSIDE
3044 self.vapi.nat44_interface_add_del_feature(
3045 sw_if_index=self.pg7.sw_if_index,
3046 flags=flags, is_add=1)
3047 self.vapi.nat44_interface_add_del_feature(
3048 sw_if_index=self.pg8.sw_if_index,
3052 pkts = self.create_stream_in(self.pg7, self.pg8)
3053 self.pg7.add_stream(pkts)
3054 self.pg_enable_capture(self.pg_interfaces)
3056 capture = self.pg8.get_capture(len(pkts))
3057 self.verify_capture_out(capture)
3060 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3061 self.pg8.add_stream(pkts)
3062 self.pg_enable_capture(self.pg_interfaces)
3064 capture = self.pg7.get_capture(len(pkts))
3065 self.verify_capture_in(capture, self.pg7)
3067 def test_static_ipless_interfaces(self):
3068 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3070 self.create_routes_and_neigbors()
3071 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3072 flags = self.config_flags.NAT_IS_INSIDE
3073 self.vapi.nat44_interface_add_del_feature(
3074 sw_if_index=self.pg7.sw_if_index,
3075 flags=flags, is_add=1)
3076 self.vapi.nat44_interface_add_del_feature(
3077 sw_if_index=self.pg8.sw_if_index,
3081 pkts = self.create_stream_out(self.pg8)
3082 self.pg8.add_stream(pkts)
3083 self.pg_enable_capture(self.pg_interfaces)
3085 capture = self.pg7.get_capture(len(pkts))
3086 self.verify_capture_in(capture, self.pg7)
3089 pkts = self.create_stream_in(self.pg7, self.pg8)
3090 self.pg7.add_stream(pkts)
3091 self.pg_enable_capture(self.pg_interfaces)
3093 capture = self.pg8.get_capture(len(pkts))
3094 self.verify_capture_out(capture, self.nat_addr, True)
3096 def test_static_with_port_ipless_interfaces(self):
3097 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3099 self.tcp_port_out = 30606
3100 self.udp_port_out = 30607
3101 self.icmp_id_out = 30608
3103 self.create_routes_and_neigbors()
3104 self.nat44_add_address(self.nat_addr)
3105 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3106 self.tcp_port_in, self.tcp_port_out,
3107 proto=IP_PROTOS.tcp)
3108 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3109 self.udp_port_in, self.udp_port_out,
3110 proto=IP_PROTOS.udp)
3111 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3112 self.icmp_id_in, self.icmp_id_out,
3113 proto=IP_PROTOS.icmp)
3114 flags = self.config_flags.NAT_IS_INSIDE
3115 self.vapi.nat44_interface_add_del_feature(
3116 sw_if_index=self.pg7.sw_if_index,
3117 flags=flags, is_add=1)
3118 self.vapi.nat44_interface_add_del_feature(
3119 sw_if_index=self.pg8.sw_if_index,
3123 pkts = self.create_stream_out(self.pg8)
3124 self.pg8.add_stream(pkts)
3125 self.pg_enable_capture(self.pg_interfaces)
3127 capture = self.pg7.get_capture(len(pkts))
3128 self.verify_capture_in(capture, self.pg7)
3131 pkts = self.create_stream_in(self.pg7, self.pg8)
3132 self.pg7.add_stream(pkts)
3133 self.pg_enable_capture(self.pg_interfaces)
3135 capture = self.pg8.get_capture(len(pkts))
3136 self.verify_capture_out(capture)
3138 def test_static_unknown_proto(self):
3139 """ 1:1 NAT translate packet with unknown protocol """
3140 nat_ip = "10.0.0.10"
3141 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3142 flags = self.config_flags.NAT_IS_INSIDE
3143 self.vapi.nat44_interface_add_del_feature(
3144 sw_if_index=self.pg0.sw_if_index,
3145 flags=flags, is_add=1)
3146 self.vapi.nat44_interface_add_del_feature(
3147 sw_if_index=self.pg1.sw_if_index,
3151 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3152 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3154 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3155 TCP(sport=1234, dport=1234))
3156 self.pg0.add_stream(p)
3157 self.pg_enable_capture(self.pg_interfaces)
3159 p = self.pg1.get_capture(1)
3162 self.assertEqual(packet[IP].src, nat_ip)
3163 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3164 self.assertEqual(packet.haslayer(GRE), 1)
3165 self.assert_packet_checksums_valid(packet)
3167 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3171 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3172 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3174 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3175 TCP(sport=1234, dport=1234))
3176 self.pg1.add_stream(p)
3177 self.pg_enable_capture(self.pg_interfaces)
3179 p = self.pg0.get_capture(1)
3182 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3183 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3184 self.assertEqual(packet.haslayer(GRE), 1)
3185 self.assert_packet_checksums_valid(packet)
3187 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3190 def test_hairpinning_static_unknown_proto(self):
3191 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3193 host = self.pg0.remote_hosts[0]
3194 server = self.pg0.remote_hosts[1]
3196 host_nat_ip = "10.0.0.10"
3197 server_nat_ip = "10.0.0.11"
3199 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3200 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3201 flags = self.config_flags.NAT_IS_INSIDE
3202 self.vapi.nat44_interface_add_del_feature(
3203 sw_if_index=self.pg0.sw_if_index,
3204 flags=flags, is_add=1)
3205 self.vapi.nat44_interface_add_del_feature(
3206 sw_if_index=self.pg1.sw_if_index,
3210 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3211 IP(src=host.ip4, dst=server_nat_ip) /
3213 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3214 TCP(sport=1234, dport=1234))
3215 self.pg0.add_stream(p)
3216 self.pg_enable_capture(self.pg_interfaces)
3218 p = self.pg0.get_capture(1)
3221 self.assertEqual(packet[IP].src, host_nat_ip)
3222 self.assertEqual(packet[IP].dst, server.ip4)
3223 self.assertEqual(packet.haslayer(GRE), 1)
3224 self.assert_packet_checksums_valid(packet)
3226 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3230 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3231 IP(src=server.ip4, dst=host_nat_ip) /
3233 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3234 TCP(sport=1234, dport=1234))
3235 self.pg0.add_stream(p)
3236 self.pg_enable_capture(self.pg_interfaces)
3238 p = self.pg0.get_capture(1)
3241 self.assertEqual(packet[IP].src, server_nat_ip)
3242 self.assertEqual(packet[IP].dst, host.ip4)
3243 self.assertEqual(packet.haslayer(GRE), 1)
3244 self.assert_packet_checksums_valid(packet)
3246 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3249 def test_output_feature(self):
3250 """ NAT44 interface output feature (in2out postrouting) """
3251 self.nat44_add_address(self.nat_addr)
3252 flags = self.config_flags.NAT_IS_INSIDE
3253 self.vapi.nat44_interface_add_del_output_feature(
3254 is_add=1, flags=flags,
3255 sw_if_index=self.pg0.sw_if_index)
3256 self.vapi.nat44_interface_add_del_output_feature(
3257 is_add=1, flags=flags,
3258 sw_if_index=self.pg1.sw_if_index)
3259 self.vapi.nat44_interface_add_del_output_feature(
3261 sw_if_index=self.pg3.sw_if_index)
3264 pkts = self.create_stream_in(self.pg0, self.pg3)
3265 self.pg0.add_stream(pkts)
3266 self.pg_enable_capture(self.pg_interfaces)
3268 capture = self.pg3.get_capture(len(pkts))
3269 self.verify_capture_out(capture)
3272 pkts = self.create_stream_out(self.pg3)
3273 self.pg3.add_stream(pkts)
3274 self.pg_enable_capture(self.pg_interfaces)
3276 capture = self.pg0.get_capture(len(pkts))
3277 self.verify_capture_in(capture, self.pg0)
3279 # from non-NAT interface to NAT inside interface
3280 pkts = self.create_stream_in(self.pg2, self.pg0)
3281 self.pg2.add_stream(pkts)
3282 self.pg_enable_capture(self.pg_interfaces)
3284 capture = self.pg0.get_capture(len(pkts))
3285 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3287 def test_output_feature_vrf_aware(self):
3288 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3289 nat_ip_vrf10 = "10.0.0.10"
3290 nat_ip_vrf20 = "10.0.0.20"
3292 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3293 [VppRoutePath(self.pg3.remote_ip4,
3294 self.pg3.sw_if_index)],
3296 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3297 [VppRoutePath(self.pg3.remote_ip4,
3298 self.pg3.sw_if_index)],
3303 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3304 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3305 flags = self.config_flags.NAT_IS_INSIDE
3306 self.vapi.nat44_interface_add_del_output_feature(
3307 is_add=1, flags=flags,
3308 sw_if_index=self.pg4.sw_if_index)
3309 self.vapi.nat44_interface_add_del_output_feature(
3310 is_add=1, flags=flags,
3311 sw_if_index=self.pg6.sw_if_index)
3312 self.vapi.nat44_interface_add_del_output_feature(
3314 sw_if_index=self.pg3.sw_if_index)
3317 pkts = self.create_stream_in(self.pg4, self.pg3)
3318 self.pg4.add_stream(pkts)
3319 self.pg_enable_capture(self.pg_interfaces)
3321 capture = self.pg3.get_capture(len(pkts))
3322 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3325 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3326 self.pg3.add_stream(pkts)
3327 self.pg_enable_capture(self.pg_interfaces)
3329 capture = self.pg4.get_capture(len(pkts))
3330 self.verify_capture_in(capture, self.pg4)
3333 pkts = self.create_stream_in(self.pg6, self.pg3)
3334 self.pg6.add_stream(pkts)
3335 self.pg_enable_capture(self.pg_interfaces)
3337 capture = self.pg3.get_capture(len(pkts))
3338 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3341 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3342 self.pg3.add_stream(pkts)
3343 self.pg_enable_capture(self.pg_interfaces)
3345 capture = self.pg6.get_capture(len(pkts))
3346 self.verify_capture_in(capture, self.pg6)
3348 def test_output_feature_hairpinning(self):
3349 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3350 host = self.pg0.remote_hosts[0]
3351 server = self.pg0.remote_hosts[1]
3354 server_in_port = 5678
3355 server_out_port = 8765
3357 self.nat44_add_address(self.nat_addr)
3358 flags = self.config_flags.NAT_IS_INSIDE
3359 self.vapi.nat44_interface_add_del_output_feature(
3360 is_add=1, flags=flags,
3361 sw_if_index=self.pg0.sw_if_index)
3362 self.vapi.nat44_interface_add_del_output_feature(
3364 sw_if_index=self.pg1.sw_if_index)
3366 # add static mapping for server
3367 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3368 server_in_port, server_out_port,
3369 proto=IP_PROTOS.tcp)
3371 # send packet from host to server
3372 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3373 IP(src=host.ip4, dst=self.nat_addr) /
3374 TCP(sport=host_in_port, dport=server_out_port))
3375 self.pg0.add_stream(p)
3376 self.pg_enable_capture(self.pg_interfaces)
3378 capture = self.pg0.get_capture(1)
3383 self.assertEqual(ip.src, self.nat_addr)
3384 self.assertEqual(ip.dst, server.ip4)
3385 self.assertNotEqual(tcp.sport, host_in_port)
3386 self.assertEqual(tcp.dport, server_in_port)
3387 self.assert_packet_checksums_valid(p)
3388 host_out_port = tcp.sport
3390 self.logger.error(ppp("Unexpected or invalid packet:", p))
3393 # send reply from server to host
3394 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3395 IP(src=server.ip4, dst=self.nat_addr) /
3396 TCP(sport=server_in_port, dport=host_out_port))
3397 self.pg0.add_stream(p)
3398 self.pg_enable_capture(self.pg_interfaces)
3400 capture = self.pg0.get_capture(1)
3405 self.assertEqual(ip.src, self.nat_addr)
3406 self.assertEqual(ip.dst, host.ip4)
3407 self.assertEqual(tcp.sport, server_out_port)
3408 self.assertEqual(tcp.dport, host_in_port)
3409 self.assert_packet_checksums_valid(p)
3411 self.logger.error(ppp("Unexpected or invalid packet:", p))
3414 def test_one_armed_nat44(self):
3415 """ One armed NAT44 """
3416 remote_host = self.pg9.remote_hosts[0]
3417 local_host = self.pg9.remote_hosts[1]
3420 self.nat44_add_address(self.nat_addr)
3421 flags = self.config_flags.NAT_IS_INSIDE
3422 self.vapi.nat44_interface_add_del_feature(
3423 sw_if_index=self.pg9.sw_if_index,
3425 self.vapi.nat44_interface_add_del_feature(
3426 sw_if_index=self.pg9.sw_if_index,
3427 flags=flags, is_add=1)
3430 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3431 IP(src=local_host.ip4, dst=remote_host.ip4) /
3432 TCP(sport=12345, dport=80))
3433 self.pg9.add_stream(p)
3434 self.pg_enable_capture(self.pg_interfaces)
3436 capture = self.pg9.get_capture(1)
3441 self.assertEqual(ip.src, self.nat_addr)
3442 self.assertEqual(ip.dst, remote_host.ip4)
3443 self.assertNotEqual(tcp.sport, 12345)
3444 external_port = tcp.sport
3445 self.assertEqual(tcp.dport, 80)
3446 self.assert_packet_checksums_valid(p)
3448 self.logger.error(ppp("Unexpected or invalid packet:", p))
3452 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3453 IP(src=remote_host.ip4, dst=self.nat_addr) /
3454 TCP(sport=80, dport=external_port))
3455 self.pg9.add_stream(p)
3456 self.pg_enable_capture(self.pg_interfaces)
3458 capture = self.pg9.get_capture(1)
3463 self.assertEqual(ip.src, remote_host.ip4)
3464 self.assertEqual(ip.dst, local_host.ip4)
3465 self.assertEqual(tcp.sport, 80)
3466 self.assertEqual(tcp.dport, 12345)
3467 self.assert_packet_checksums_valid(p)
3469 self.logger.error(ppp("Unexpected or invalid packet:", p))
3472 err = self.statistics.get_err_counter(
3473 '/err/nat44-classify/next in2out')
3474 self.assertEqual(err, 1)
3475 err = self.statistics.get_err_counter(
3476 '/err/nat44-classify/next out2in')
3477 self.assertEqual(err, 1)
3479 def test_del_session(self):
3480 """ Delete NAT44 session """
3481 self.nat44_add_address(self.nat_addr)
3482 flags = self.config_flags.NAT_IS_INSIDE
3483 self.vapi.nat44_interface_add_del_feature(
3484 sw_if_index=self.pg0.sw_if_index,
3485 flags=flags, is_add=1)
3486 self.vapi.nat44_interface_add_del_feature(
3487 sw_if_index=self.pg1.sw_if_index,
3490 pkts = self.create_stream_in(self.pg0, self.pg1)
3491 self.pg0.add_stream(pkts)
3492 self.pg_enable_capture(self.pg_interfaces)
3494 self.pg1.get_capture(len(pkts))
3496 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3497 nsessions = len(sessions)
3499 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3500 port=sessions[0].inside_port,
3501 protocol=sessions[0].protocol,
3502 flags=self.config_flags.NAT_IS_INSIDE)
3503 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3504 port=sessions[1].outside_port,
3505 protocol=sessions[1].protocol)
3507 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3508 self.assertEqual(nsessions - len(sessions), 2)
3510 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3511 port=sessions[0].inside_port,
3512 protocol=sessions[0].protocol,
3513 flags=self.config_flags.NAT_IS_INSIDE)
3515 self.verify_no_nat44_user()
3517 def test_frag_in_order(self):
3518 """ NAT44 translate fragments arriving in order """
3520 self.nat44_add_address(self.nat_addr)
3521 flags = self.config_flags.NAT_IS_INSIDE
3522 self.vapi.nat44_interface_add_del_feature(
3523 sw_if_index=self.pg0.sw_if_index,
3524 flags=flags, is_add=1)
3525 self.vapi.nat44_interface_add_del_feature(
3526 sw_if_index=self.pg1.sw_if_index,
3529 self.frag_in_order(proto=IP_PROTOS.tcp)
3530 self.frag_in_order(proto=IP_PROTOS.udp)
3531 self.frag_in_order(proto=IP_PROTOS.icmp)
3533 def test_frag_forwarding(self):
3534 """ NAT44 forwarding fragment test """
3535 self.vapi.nat44_add_del_interface_addr(
3537 sw_if_index=self.pg1.sw_if_index)
3538 flags = self.config_flags.NAT_IS_INSIDE
3539 self.vapi.nat44_interface_add_del_feature(
3540 sw_if_index=self.pg0.sw_if_index,
3541 flags=flags, is_add=1)
3542 self.vapi.nat44_interface_add_del_feature(
3543 sw_if_index=self.pg1.sw_if_index,
3545 self.vapi.nat44_forwarding_enable_disable(enable=1)
3547 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3548 pkts = self.create_stream_frag(self.pg1,
3549 self.pg0.remote_ip4,
3553 proto=IP_PROTOS.udp)
3554 self.pg1.add_stream(pkts)
3555 self.pg_enable_capture(self.pg_interfaces)
3557 frags = self.pg0.get_capture(len(pkts))
3558 p = self.reass_frags_and_verify(frags,
3559 self.pg1.remote_ip4,
3560 self.pg0.remote_ip4)
3561 self.assertEqual(p[UDP].sport, 4789)
3562 self.assertEqual(p[UDP].dport, 4789)
3563 self.assertEqual(data, p[Raw].load)
3565 def test_reass_hairpinning(self):
3566 """ NAT44 fragments hairpinning """
3568 self.server = self.pg0.remote_hosts[1]
3569 self.host_in_port = random.randint(1025, 65535)
3570 self.server_in_port = random.randint(1025, 65535)
3571 self.server_out_port = random.randint(1025, 65535)
3573 self.nat44_add_address(self.nat_addr)
3574 flags = self.config_flags.NAT_IS_INSIDE
3575 self.vapi.nat44_interface_add_del_feature(
3576 sw_if_index=self.pg0.sw_if_index,
3577 flags=flags, is_add=1)
3578 self.vapi.nat44_interface_add_del_feature(
3579 sw_if_index=self.pg1.sw_if_index,
3581 # add static mapping for server
3582 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3583 self.server_in_port,
3584 self.server_out_port,
3585 proto=IP_PROTOS.tcp)
3586 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3587 self.server_in_port,
3588 self.server_out_port,
3589 proto=IP_PROTOS.udp)
3590 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3592 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3593 self.reass_hairpinning(proto=IP_PROTOS.udp)
3594 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3596 def test_frag_out_of_order(self):
3597 """ NAT44 translate fragments arriving out of order """
3599 self.nat44_add_address(self.nat_addr)
3600 flags = self.config_flags.NAT_IS_INSIDE
3601 self.vapi.nat44_interface_add_del_feature(
3602 sw_if_index=self.pg0.sw_if_index,
3603 flags=flags, is_add=1)
3604 self.vapi.nat44_interface_add_del_feature(
3605 sw_if_index=self.pg1.sw_if_index,
3608 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3609 self.frag_out_of_order(proto=IP_PROTOS.udp)
3610 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3612 def test_port_restricted(self):
3613 """ Port restricted NAT44 (MAP-E CE) """
3614 self.nat44_add_address(self.nat_addr)
3615 flags = self.config_flags.NAT_IS_INSIDE
3616 self.vapi.nat44_interface_add_del_feature(
3617 sw_if_index=self.pg0.sw_if_index,
3618 flags=flags, is_add=1)
3619 self.vapi.nat44_interface_add_del_feature(
3620 sw_if_index=self.pg1.sw_if_index,
3622 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3627 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3628 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3629 TCP(sport=4567, dport=22))
3630 self.pg0.add_stream(p)
3631 self.pg_enable_capture(self.pg_interfaces)
3633 capture = self.pg1.get_capture(1)
3638 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3639 self.assertEqual(ip.src, self.nat_addr)
3640 self.assertEqual(tcp.dport, 22)
3641 self.assertNotEqual(tcp.sport, 4567)
3642 self.assertEqual((tcp.sport >> 6) & 63, 10)
3643 self.assert_packet_checksums_valid(p)
3645 self.logger.error(ppp("Unexpected or invalid packet:", p))
3648 def test_port_range(self):
3649 """ External address port range """
3650 self.nat44_add_address(self.nat_addr)
3651 flags = self.config_flags.NAT_IS_INSIDE
3652 self.vapi.nat44_interface_add_del_feature(
3653 sw_if_index=self.pg0.sw_if_index,
3654 flags=flags, is_add=1)
3655 self.vapi.nat44_interface_add_del_feature(
3656 sw_if_index=self.pg1.sw_if_index,
3658 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3663 for port in range(0, 5):
3664 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3665 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3666 TCP(sport=1125 + port))
3668 self.pg0.add_stream(pkts)
3669 self.pg_enable_capture(self.pg_interfaces)
3671 capture = self.pg1.get_capture(3)
3674 self.assertGreaterEqual(tcp.sport, 1025)
3675 self.assertLessEqual(tcp.sport, 1027)
3677 def test_multiple_outside_vrf(self):
3678 """ Multiple outside VRF """
3682 self.pg1.unconfig_ip4()
3683 self.pg2.unconfig_ip4()
3684 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3685 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3686 self.pg1.set_table_ip4(vrf_id1)
3687 self.pg2.set_table_ip4(vrf_id2)
3688 self.pg1.config_ip4()
3689 self.pg2.config_ip4()
3690 self.pg1.resolve_arp()
3691 self.pg2.resolve_arp()
3693 self.nat44_add_address(self.nat_addr)
3694 flags = self.config_flags.NAT_IS_INSIDE
3695 self.vapi.nat44_interface_add_del_feature(
3696 sw_if_index=self.pg0.sw_if_index,
3697 flags=flags, is_add=1)
3698 self.vapi.nat44_interface_add_del_feature(
3699 sw_if_index=self.pg1.sw_if_index,
3701 self.vapi.nat44_interface_add_del_feature(
3702 sw_if_index=self.pg2.sw_if_index,
3707 pkts = self.create_stream_in(self.pg0, self.pg1)
3708 self.pg0.add_stream(pkts)
3709 self.pg_enable_capture(self.pg_interfaces)
3711 capture = self.pg1.get_capture(len(pkts))
3712 self.verify_capture_out(capture, self.nat_addr)
3714 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3715 self.pg1.add_stream(pkts)
3716 self.pg_enable_capture(self.pg_interfaces)
3718 capture = self.pg0.get_capture(len(pkts))
3719 self.verify_capture_in(capture, self.pg0)
3721 self.tcp_port_in = 60303
3722 self.udp_port_in = 60304
3723 self.icmp_id_in = 60305
3726 pkts = self.create_stream_in(self.pg0, self.pg2)
3727 self.pg0.add_stream(pkts)
3728 self.pg_enable_capture(self.pg_interfaces)
3730 capture = self.pg2.get_capture(len(pkts))
3731 self.verify_capture_out(capture, self.nat_addr)
3733 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3734 self.pg2.add_stream(pkts)
3735 self.pg_enable_capture(self.pg_interfaces)
3737 capture = self.pg0.get_capture(len(pkts))
3738 self.verify_capture_in(capture, self.pg0)
3741 self.nat44_add_address(self.nat_addr, is_add=0)
3742 self.pg1.unconfig_ip4()
3743 self.pg2.unconfig_ip4()
3744 self.pg1.set_table_ip4(0)
3745 self.pg2.set_table_ip4(0)
3746 self.pg1.config_ip4()
3747 self.pg2.config_ip4()
3748 self.pg1.resolve_arp()
3749 self.pg2.resolve_arp()
3751 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3752 def test_session_timeout(self):
3753 """ NAT44 session timeouts """
3754 self.nat44_add_address(self.nat_addr)
3755 flags = self.config_flags.NAT_IS_INSIDE
3756 self.vapi.nat44_interface_add_del_feature(
3757 sw_if_index=self.pg0.sw_if_index,
3758 flags=flags, is_add=1)
3759 self.vapi.nat44_interface_add_del_feature(
3760 sw_if_index=self.pg1.sw_if_index,
3762 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3763 tcp_transitory=240, icmp=60)
3767 for i in range(0, max_sessions):
3768 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3769 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3770 IP(src=src, dst=self.pg1.remote_ip4) /
3771 UDP(sport=1025, dport=53))
3773 self.pg0.add_stream(pkts)
3774 self.pg_enable_capture(self.pg_interfaces)
3776 self.pg1.get_capture(max_sessions)
3781 for i in range(0, max_sessions):
3782 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3783 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3784 IP(src=src, dst=self.pg1.remote_ip4) /
3785 UDP(sport=1026, dport=53))
3787 self.pg0.add_stream(pkts)
3788 self.pg_enable_capture(self.pg_interfaces)
3790 self.pg1.get_capture(max_sessions)
3793 users = self.vapi.nat44_user_dump()
3795 nsessions = nsessions + user.nsessions
3796 self.assertLess(nsessions, 2 * max_sessions)
3798 def test_mss_clamping(self):
3799 """ TCP MSS clamping """
3800 self.nat44_add_address(self.nat_addr)
3801 flags = self.config_flags.NAT_IS_INSIDE
3802 self.vapi.nat44_interface_add_del_feature(
3803 sw_if_index=self.pg0.sw_if_index,
3804 flags=flags, is_add=1)
3805 self.vapi.nat44_interface_add_del_feature(
3806 sw_if_index=self.pg1.sw_if_index,
3809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3810 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3811 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3812 flags="S", options=[('MSS', 1400)]))
3814 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3815 self.pg0.add_stream(p)
3816 self.pg_enable_capture(self.pg_interfaces)
3818 capture = self.pg1.get_capture(1)
3819 # Negotiated MSS value greater than configured - changed
3820 self.verify_mss_value(capture[0], 1000)
3822 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3823 self.pg0.add_stream(p)
3824 self.pg_enable_capture(self.pg_interfaces)
3826 capture = self.pg1.get_capture(1)
3827 # MSS clamping disabled - negotiated MSS unchanged
3828 self.verify_mss_value(capture[0], 1400)
3830 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3831 self.pg0.add_stream(p)
3832 self.pg_enable_capture(self.pg_interfaces)
3834 capture = self.pg1.get_capture(1)
3835 # Negotiated MSS value smaller than configured - unchanged
3836 self.verify_mss_value(capture[0], 1400)
3838 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3839 def test_ha_send(self):
3840 """ Send HA session synchronization events (active) """
3841 self.nat44_add_address(self.nat_addr)
3842 flags = self.config_flags.NAT_IS_INSIDE
3843 self.vapi.nat44_interface_add_del_feature(
3844 sw_if_index=self.pg0.sw_if_index,
3845 flags=flags, is_add=1)
3846 self.vapi.nat44_interface_add_del_feature(
3847 sw_if_index=self.pg1.sw_if_index,
3849 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3852 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3853 port=12346, session_refresh_interval=10)
3854 bind_layers(UDP, HANATStateSync, sport=12345)
3857 pkts = self.create_stream_in(self.pg0, self.pg1)
3858 self.pg0.add_stream(pkts)
3859 self.pg_enable_capture(self.pg_interfaces)
3861 capture = self.pg1.get_capture(len(pkts))
3862 self.verify_capture_out(capture)
3863 # active send HA events
3864 self.vapi.nat_ha_flush()
3865 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3866 self.assertEqual(stats[0][0], 3)
3867 capture = self.pg3.get_capture(1)
3869 self.assert_packet_checksums_valid(p)
3873 hanat = p[HANATStateSync]
3875 self.logger.error(ppp("Invalid packet:", p))
3878 self.assertEqual(ip.src, self.pg3.local_ip4)
3879 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3880 self.assertEqual(udp.sport, 12345)
3881 self.assertEqual(udp.dport, 12346)
3882 self.assertEqual(hanat.version, 1)
3883 self.assertEqual(hanat.thread_index, 0)
3884 self.assertEqual(hanat.count, 3)
3885 seq = hanat.sequence_number
3886 for event in hanat.events:
3887 self.assertEqual(event.event_type, 1)
3888 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3889 self.assertEqual(event.out_addr, self.nat_addr)
3890 self.assertEqual(event.fib_index, 0)
3892 # ACK received events
3893 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3894 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3895 UDP(sport=12346, dport=12345) /
3896 HANATStateSync(sequence_number=seq, flags='ACK'))
3897 self.pg3.add_stream(ack)
3899 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3900 self.assertEqual(stats[0][0], 1)
3902 # delete one session
3903 self.pg_enable_capture(self.pg_interfaces)
3904 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3905 port=self.tcp_port_in,
3906 protocol=IP_PROTOS.tcp,
3907 flags=self.config_flags.NAT_IS_INSIDE)
3908 self.vapi.nat_ha_flush()
3909 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3910 self.assertEqual(stats[0][0], 1)
3911 capture = self.pg3.get_capture(1)
3914 hanat = p[HANATStateSync]
3916 self.logger.error(ppp("Invalid packet:", p))
3919 self.assertGreater(hanat.sequence_number, seq)
3921 # do not send ACK, active retry send HA event again
3922 self.pg_enable_capture(self.pg_interfaces)
3924 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3925 self.assertEqual(stats[0][0], 3)
3926 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3927 self.assertEqual(stats[0][0], 1)
3928 capture = self.pg3.get_capture(3)
3929 for packet in capture:
3930 self.assertEqual(packet, p)
3932 # session counters refresh
3933 pkts = self.create_stream_out(self.pg1)
3934 self.pg1.add_stream(pkts)
3935 self.pg_enable_capture(self.pg_interfaces)
3937 self.pg0.get_capture(2)
3938 self.vapi.nat_ha_flush()
3939 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3940 self.assertEqual(stats[0][0], 2)
3941 capture = self.pg3.get_capture(1)
3943 self.assert_packet_checksums_valid(p)
3947 hanat = p[HANATStateSync]
3949 self.logger.error(ppp("Invalid packet:", p))
3952 self.assertEqual(ip.src, self.pg3.local_ip4)
3953 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3954 self.assertEqual(udp.sport, 12345)
3955 self.assertEqual(udp.dport, 12346)
3956 self.assertEqual(hanat.version, 1)
3957 self.assertEqual(hanat.count, 2)
3958 seq = hanat.sequence_number
3959 for event in hanat.events:
3960 self.assertEqual(event.event_type, 3)
3961 self.assertEqual(event.out_addr, self.nat_addr)
3962 self.assertEqual(event.fib_index, 0)
3963 self.assertEqual(event.total_pkts, 2)
3964 self.assertGreater(event.total_bytes, 0)
3966 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3967 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3968 UDP(sport=12346, dport=12345) /
3969 HANATStateSync(sequence_number=seq, flags='ACK'))
3970 self.pg3.add_stream(ack)
3972 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3973 self.assertEqual(stats[0][0], 2)
3975 def test_ha_recv(self):
3976 """ Receive HA session synchronization events (passive) """
3977 self.nat44_add_address(self.nat_addr)
3978 flags = self.config_flags.NAT_IS_INSIDE
3979 self.vapi.nat44_interface_add_del_feature(
3980 sw_if_index=self.pg0.sw_if_index,
3981 flags=flags, is_add=1)
3982 self.vapi.nat44_interface_add_del_feature(
3983 sw_if_index=self.pg1.sw_if_index,
3985 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3988 bind_layers(UDP, HANATStateSync, sport=12345)
3990 self.tcp_port_out = random.randint(1025, 65535)
3991 self.udp_port_out = random.randint(1025, 65535)
3993 # send HA session add events to failover/passive
3994 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3995 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3996 UDP(sport=12346, dport=12345) /
3997 HANATStateSync(sequence_number=1, events=[
3998 Event(event_type='add', protocol='tcp',
3999 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4000 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4001 eh_addr=self.pg1.remote_ip4,
4002 ehn_addr=self.pg1.remote_ip4,
4003 eh_port=self.tcp_external_port,
4004 ehn_port=self.tcp_external_port, fib_index=0),
4005 Event(event_type='add', protocol='udp',
4006 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4007 in_port=self.udp_port_in, out_port=self.udp_port_out,
4008 eh_addr=self.pg1.remote_ip4,
4009 ehn_addr=self.pg1.remote_ip4,
4010 eh_port=self.udp_external_port,
4011 ehn_port=self.udp_external_port, fib_index=0)]))
4013 self.pg3.add_stream(p)
4014 self.pg_enable_capture(self.pg_interfaces)
4017 capture = self.pg3.get_capture(1)
4020 hanat = p[HANATStateSync]
4022 self.logger.error(ppp("Invalid packet:", p))
4025 self.assertEqual(hanat.sequence_number, 1)
4026 self.assertEqual(hanat.flags, 'ACK')
4027 self.assertEqual(hanat.version, 1)
4028 self.assertEqual(hanat.thread_index, 0)
4029 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4030 self.assertEqual(stats[0][0], 1)
4031 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4032 self.assertEqual(stats[0][0], 2)
4033 users = self.statistics.get_counter('/nat44/total-users')
4034 self.assertEqual(users[0][0], 1)
4035 sessions = self.statistics.get_counter('/nat44/total-sessions')
4036 self.assertEqual(sessions[0][0], 2)
4037 users = self.vapi.nat44_user_dump()
4038 self.assertEqual(len(users), 1)
4039 self.assertEqual(str(users[0].ip_address),
4040 self.pg0.remote_ip4)
4041 # there should be 2 sessions created by HA
4042 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4044 self.assertEqual(len(sessions), 2)
4045 for session in sessions:
4046 self.assertEqual(str(session.inside_ip_address),
4047 self.pg0.remote_ip4)
4048 self.assertEqual(str(session.outside_ip_address),
4050 self.assertIn(session.inside_port,
4051 [self.tcp_port_in, self.udp_port_in])
4052 self.assertIn(session.outside_port,
4053 [self.tcp_port_out, self.udp_port_out])
4054 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4056 # send HA session delete event to failover/passive
4057 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4058 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4059 UDP(sport=12346, dport=12345) /
4060 HANATStateSync(sequence_number=2, events=[
4061 Event(event_type='del', protocol='udp',
4062 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4063 in_port=self.udp_port_in, out_port=self.udp_port_out,
4064 eh_addr=self.pg1.remote_ip4,
4065 ehn_addr=self.pg1.remote_ip4,
4066 eh_port=self.udp_external_port,
4067 ehn_port=self.udp_external_port, fib_index=0)]))
4069 self.pg3.add_stream(p)
4070 self.pg_enable_capture(self.pg_interfaces)
4073 capture = self.pg3.get_capture(1)
4076 hanat = p[HANATStateSync]
4078 self.logger.error(ppp("Invalid packet:", p))
4081 self.assertEqual(hanat.sequence_number, 2)
4082 self.assertEqual(hanat.flags, 'ACK')
4083 self.assertEqual(hanat.version, 1)
4084 users = self.vapi.nat44_user_dump()
4085 self.assertEqual(len(users), 1)
4086 self.assertEqual(str(users[0].ip_address),
4087 self.pg0.remote_ip4)
4088 # now we should have only 1 session, 1 deleted by HA
4089 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4091 self.assertEqual(len(sessions), 1)
4092 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4093 self.assertEqual(stats[0][0], 1)
4095 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4096 self.assertEqual(stats, 2)
4098 # send HA session refresh event to failover/passive
4099 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4100 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4101 UDP(sport=12346, dport=12345) /
4102 HANATStateSync(sequence_number=3, events=[
4103 Event(event_type='refresh', protocol='tcp',
4104 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4105 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4106 eh_addr=self.pg1.remote_ip4,
4107 ehn_addr=self.pg1.remote_ip4,
4108 eh_port=self.tcp_external_port,
4109 ehn_port=self.tcp_external_port, fib_index=0,
4110 total_bytes=1024, total_pkts=2)]))
4111 self.pg3.add_stream(p)
4112 self.pg_enable_capture(self.pg_interfaces)
4115 capture = self.pg3.get_capture(1)
4118 hanat = p[HANATStateSync]
4120 self.logger.error(ppp("Invalid packet:", p))
4123 self.assertEqual(hanat.sequence_number, 3)
4124 self.assertEqual(hanat.flags, 'ACK')
4125 self.assertEqual(hanat.version, 1)
4126 users = self.vapi.nat44_user_dump()
4127 self.assertEqual(len(users), 1)
4128 self.assertEqual(str(users[0].ip_address),
4129 self.pg0.remote_ip4)
4130 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4132 self.assertEqual(len(sessions), 1)
4133 session = sessions[0]
4134 self.assertEqual(session.total_bytes, 1024)
4135 self.assertEqual(session.total_pkts, 2)
4136 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4137 self.assertEqual(stats[0][0], 1)
4139 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4140 self.assertEqual(stats, 3)
4142 # send packet to test session created by HA
4143 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4144 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4145 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4146 self.pg1.add_stream(p)
4147 self.pg_enable_capture(self.pg_interfaces)
4149 capture = self.pg0.get_capture(1)
4155 self.logger.error(ppp("Invalid packet:", p))
4158 self.assertEqual(ip.src, self.pg1.remote_ip4)
4159 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4160 self.assertEqual(tcp.sport, self.tcp_external_port)
4161 self.assertEqual(tcp.dport, self.tcp_port_in)
4164 super(TestNAT44, self).tearDown()
4166 self.vapi.cli("clear logging")
4168 def show_commands_at_teardown(self):
4169 self.logger.info(self.vapi.cli("show nat44 addresses"))
4170 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4171 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4172 self.logger.info(self.vapi.cli("show nat44 interface address"))
4173 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4174 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4175 self.logger.info(self.vapi.cli("show nat timeouts"))
4177 self.vapi.cli("show nat addr-port-assignment-alg"))
4178 self.logger.info(self.vapi.cli("show nat ha"))
4181 class TestNAT44EndpointDependent2(MethodHolder):
4182 """ Endpoint-Dependent mapping and filtering test cases """
4185 def setUpConstants(cls):
4186 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4187 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4190 def tearDownClass(cls):
4191 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4194 super(TestNAT44EndpointDependent2, self).tearDown()
4197 def create_and_add_ip4_table(cls, i, table_id):
4198 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4199 i.set_table_ip4(table_id)
4202 def setUpClass(cls):
4203 super(TestNAT44EndpointDependent2, cls).setUpClass()
4205 cls.create_pg_interfaces(range(3))
4206 cls.interfaces = list(cls.pg_interfaces)
4208 cls.create_and_add_ip4_table(cls.pg1, 10)
4210 for i in cls.interfaces:
4215 i.generate_remote_hosts(1)
4216 i.configure_ipv4_neighbors()
4219 super(TestNAT44EndpointDependent2, self).setUp()
4221 nat_config = self.vapi.nat_show_config()
4222 self.assertEqual(1, nat_config.endpoint_dependent)
4224 def nat_add_inside_interface(self, i):
4225 self.vapi.nat44_interface_add_del_feature(
4226 flags=self.config_flags.NAT_IS_INSIDE,
4227 sw_if_index=i.sw_if_index, is_add=1)
4229 def nat_add_outside_interface(self, i):
4230 self.vapi.nat44_interface_add_del_feature(
4231 flags=self.config_flags.NAT_IS_OUTSIDE,
4232 sw_if_index=i.sw_if_index, is_add=1)
4234 def nat_add_interface_address(self, i):
4235 self.nat_addr = i.local_ip4
4236 self.vapi.nat44_add_del_interface_addr(
4237 sw_if_index=i.sw_if_index, is_add=1)
4239 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4240 self.nat_addr = address
4241 self.nat44_add_address(address, vrf_id=vrf_id)
4243 def cli(self, command):
4244 result = self.vapi.cli(command)
4245 self.logger.info(result)
4248 def show_configuration(self):
4249 self.cli("show interface")
4250 self.cli("show interface address")
4251 self.cli("show nat44 addresses")
4252 self.cli("show nat44 interfaces")
4254 def create_tcp_stream(self, in_if, out_if, count):
4256 Create tcp packet stream
4258 :param in_if: Inside interface
4259 :param out_if: Outside interface
4260 :param count: count of packets to generate
4265 for i in range(count):
4266 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4267 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4268 TCP(sport=port + i, dport=20))
4273 def test_session_limit_per_vrf(self):
4276 inside_vrf10 = self.pg1
4281 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4282 # non existing vrf_id makes process core dump
4283 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4285 self.nat_add_inside_interface(inside)
4286 self.nat_add_inside_interface(inside_vrf10)
4287 self.nat_add_outside_interface(outside)
4290 self.nat_add_interface_address(outside)
4292 # BUG: causing core dump - when bad vrf_id is specified
4293 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4295 self.show_configuration()
4297 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4298 inside_vrf10.add_stream(stream)
4300 self.pg_enable_capture(self.pg_interfaces)
4303 capture = outside.get_capture(limit)
4305 stream = self.create_tcp_stream(inside, outside, limit * 2)
4306 inside.add_stream(stream)
4308 self.pg_enable_capture(self.pg_interfaces)
4311 capture = outside.get_capture(len(stream))
4314 class TestNAT44EndpointDependent(MethodHolder):
4315 """ Endpoint-Dependent mapping and filtering test cases """
4318 def setUpConstants(cls):
4319 super(TestNAT44EndpointDependent, cls).setUpConstants()
4320 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4323 def setUpClass(cls):
4324 super(TestNAT44EndpointDependent, cls).setUpClass()
4325 cls.vapi.cli("set log class nat level debug")
4327 cls.tcp_port_in = 6303
4328 cls.tcp_port_out = 6303
4329 cls.udp_port_in = 6304
4330 cls.udp_port_out = 6304
4331 cls.icmp_id_in = 6305
4332 cls.icmp_id_out = 6305
4333 cls.nat_addr = '10.0.0.3'
4334 cls.ipfix_src_port = 4739
4335 cls.ipfix_domain_id = 1
4336 cls.tcp_external_port = 80
4338 cls.create_pg_interfaces(range(9))
4339 cls.interfaces = list(cls.pg_interfaces[0:3])
4341 for i in cls.interfaces:
4346 cls.pg0.generate_remote_hosts(3)
4347 cls.pg0.configure_ipv4_neighbors()
4351 cls.pg4.generate_remote_hosts(2)
4352 cls.pg4.config_ip4()
4353 cls.vapi.sw_interface_add_del_address(
4354 sw_if_index=cls.pg4.sw_if_index,
4355 prefix="10.0.0.1/24")
4358 cls.pg4.resolve_arp()
4359 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4360 cls.pg4.resolve_arp()
4362 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4363 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4365 cls.pg5._local_ip4 = "10.1.1.1"
4366 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4367 cls.pg5.set_table_ip4(1)
4368 cls.pg5.config_ip4()
4370 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4371 [VppRoutePath("0.0.0.0",
4372 cls.pg5.sw_if_index)],
4377 cls.pg6._local_ip4 = "10.1.2.1"
4378 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4379 cls.pg6.set_table_ip4(1)
4380 cls.pg6.config_ip4()
4383 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4384 [VppRoutePath("0.0.0.0",
4385 cls.pg6.sw_if_index)],
4388 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4389 [VppRoutePath("0.0.0.0",
4394 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4395 [VppRoutePath("0.0.0.0", 0xffffffff,
4399 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4400 [VppRoutePath(cls.pg1.local_ip4,
4401 cls.pg1.sw_if_index)],
4408 cls.pg5.resolve_arp()
4409 cls.pg6.resolve_arp()
4412 cls.pg7.config_ip4()
4413 cls.pg7.resolve_arp()
4414 cls.pg7.generate_remote_hosts(3)
4415 cls.pg7.configure_ipv4_neighbors()
4418 cls.pg8.config_ip4()
4419 cls.pg8.resolve_arp()
4422 super(TestNAT44EndpointDependent, self).setUp()
4423 self.vapi.nat_set_timeouts(
4424 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4427 def tearDownClass(cls):
4428 super(TestNAT44EndpointDependent, cls).tearDownClass()
4430 def test_frag_in_order(self):
4431 """ NAT44 translate fragments arriving in order """
4432 self.nat44_add_address(self.nat_addr)
4433 flags = self.config_flags.NAT_IS_INSIDE
4434 self.vapi.nat44_interface_add_del_feature(
4435 sw_if_index=self.pg0.sw_if_index,
4436 flags=flags, is_add=1)
4437 self.vapi.nat44_interface_add_del_feature(
4438 sw_if_index=self.pg1.sw_if_index,
4440 self.frag_in_order(proto=IP_PROTOS.tcp)
4441 self.frag_in_order(proto=IP_PROTOS.udp)
4442 self.frag_in_order(proto=IP_PROTOS.icmp)
4444 def test_frag_in_order_dont_translate(self):
4445 """ NAT44 don't translate fragments arriving in order """
4446 flags = self.config_flags.NAT_IS_INSIDE
4447 self.vapi.nat44_interface_add_del_feature(
4448 sw_if_index=self.pg0.sw_if_index,
4449 flags=flags, is_add=1)
4450 self.vapi.nat44_interface_add_del_feature(
4451 sw_if_index=self.pg1.sw_if_index,
4453 self.vapi.nat44_forwarding_enable_disable(enable=True)
4454 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4456 def test_frag_out_of_order(self):
4457 """ NAT44 translate fragments arriving out of order """
4458 self.nat44_add_address(self.nat_addr)
4459 flags = self.config_flags.NAT_IS_INSIDE
4460 self.vapi.nat44_interface_add_del_feature(
4461 sw_if_index=self.pg0.sw_if_index,
4462 flags=flags, is_add=1)
4463 self.vapi.nat44_interface_add_del_feature(
4464 sw_if_index=self.pg1.sw_if_index,
4466 self.frag_out_of_order(proto=IP_PROTOS.tcp)
4467 self.frag_out_of_order(proto=IP_PROTOS.udp)
4468 self.frag_out_of_order(proto=IP_PROTOS.icmp)
4470 def test_frag_out_of_order_dont_translate(self):
4471 """ NAT44 don't translate fragments arriving out of order """
4472 flags = self.config_flags.NAT_IS_INSIDE
4473 self.vapi.nat44_interface_add_del_feature(
4474 sw_if_index=self.pg0.sw_if_index,
4475 flags=flags, is_add=1)
4476 self.vapi.nat44_interface_add_del_feature(
4477 sw_if_index=self.pg1.sw_if_index,
4479 self.vapi.nat44_forwarding_enable_disable(enable=True)
4480 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4482 def test_frag_in_order_in_plus_out(self):
4483 """ in+out interface fragments in order """
4484 flags = self.config_flags.NAT_IS_INSIDE
4485 self.vapi.nat44_interface_add_del_feature(
4486 sw_if_index=self.pg0.sw_if_index,
4488 self.vapi.nat44_interface_add_del_feature(
4489 sw_if_index=self.pg0.sw_if_index,
4490 flags=flags, is_add=1)
4491 self.vapi.nat44_interface_add_del_feature(
4492 sw_if_index=self.pg1.sw_if_index,
4494 self.vapi.nat44_interface_add_del_feature(
4495 sw_if_index=self.pg1.sw_if_index,
4496 flags=flags, is_add=1)
4498 self.server = self.pg1.remote_hosts[0]
4500 self.server_in_addr = self.server.ip4
4501 self.server_out_addr = '11.11.11.11'
4502 self.server_in_port = random.randint(1025, 65535)
4503 self.server_out_port = random.randint(1025, 65535)
4505 self.nat44_add_address(self.server_out_addr)
4507 # add static mappings for server
4508 self.nat44_add_static_mapping(self.server_in_addr,
4509 self.server_out_addr,
4510 self.server_in_port,
4511 self.server_out_port,
4512 proto=IP_PROTOS.tcp)
4513 self.nat44_add_static_mapping(self.server_in_addr,
4514 self.server_out_addr,
4515 self.server_in_port,
4516 self.server_out_port,
4517 proto=IP_PROTOS.udp)
4518 self.nat44_add_static_mapping(self.server_in_addr,
4519 self.server_out_addr,
4520 proto=IP_PROTOS.icmp)
4522 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4523 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4524 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4526 def test_frag_out_of_order_in_plus_out(self):
4527 """ in+out interface fragments out of order """
4528 flags = self.config_flags.NAT_IS_INSIDE
4529 self.vapi.nat44_interface_add_del_feature(
4530 sw_if_index=self.pg0.sw_if_index,
4532 self.vapi.nat44_interface_add_del_feature(
4533 sw_if_index=self.pg0.sw_if_index,
4534 flags=flags, is_add=1)
4535 self.vapi.nat44_interface_add_del_feature(
4536 sw_if_index=self.pg1.sw_if_index,
4538 self.vapi.nat44_interface_add_del_feature(
4539 sw_if_index=self.pg1.sw_if_index,
4540 flags=flags, is_add=1)
4542 self.server = self.pg1.remote_hosts[0]
4544 self.server_in_addr = self.server.ip4
4545 self.server_out_addr = '11.11.11.11'
4546 self.server_in_port = random.randint(1025, 65535)
4547 self.server_out_port = random.randint(1025, 65535)
4549 self.nat44_add_address(self.server_out_addr)
4551 # add static mappings for server
4552 self.nat44_add_static_mapping(self.server_in_addr,
4553 self.server_out_addr,
4554 self.server_in_port,
4555 self.server_out_port,
4556 proto=IP_PROTOS.tcp)
4557 self.nat44_add_static_mapping(self.server_in_addr,
4558 self.server_out_addr,
4559 self.server_in_port,
4560 self.server_out_port,
4561 proto=IP_PROTOS.udp)
4562 self.nat44_add_static_mapping(self.server_in_addr,
4563 self.server_out_addr,
4564 proto=IP_PROTOS.icmp)
4566 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4567 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4568 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4570 def test_reass_hairpinning(self):
4571 """ NAT44 fragments hairpinning """
4572 self.server = self.pg0.remote_hosts[1]
4573 self.host_in_port = random.randint(1025, 65535)
4574 self.server_in_port = random.randint(1025, 65535)
4575 self.server_out_port = random.randint(1025, 65535)
4577 self.nat44_add_address(self.nat_addr)
4578 flags = self.config_flags.NAT_IS_INSIDE
4579 self.vapi.nat44_interface_add_del_feature(
4580 sw_if_index=self.pg0.sw_if_index,
4581 flags=flags, is_add=1)
4582 self.vapi.nat44_interface_add_del_feature(
4583 sw_if_index=self.pg1.sw_if_index,
4585 # add static mapping for server
4586 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4587 self.server_in_port,
4588 self.server_out_port,
4589 proto=IP_PROTOS.tcp)
4590 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4591 self.server_in_port,
4592 self.server_out_port,
4593 proto=IP_PROTOS.udp)
4594 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4596 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4597 self.reass_hairpinning(proto=IP_PROTOS.udp)
4598 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4600 def test_clear_sessions(self):
4601 """ NAT44 ED session clearing test """
4603 self.nat44_add_address(self.nat_addr)
4604 flags = self.config_flags.NAT_IS_INSIDE
4605 self.vapi.nat44_interface_add_del_feature(
4606 sw_if_index=self.pg0.sw_if_index,
4607 flags=flags, is_add=1)
4608 self.vapi.nat44_interface_add_del_feature(
4609 sw_if_index=self.pg1.sw_if_index,
4612 nat_config = self.vapi.nat_show_config()
4613 self.assertEqual(1, nat_config.endpoint_dependent)
4615 pkts = self.create_stream_in(self.pg0, self.pg1)
4616 self.pg0.add_stream(pkts)
4617 self.pg_enable_capture(self.pg_interfaces)
4619 capture = self.pg1.get_capture(len(pkts))
4620 self.verify_capture_out(capture)
4622 sessions = self.statistics.get_counter('/nat44/total-sessions')
4623 self.assertTrue(sessions[0][0] > 0)
4624 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4626 # just for testing purposes
4627 self.logger.info(self.vapi.cli("show nat44 summary"))
4629 self.vapi.cli("clear nat44 sessions")
4631 self.logger.info(self.vapi.cli("show nat44 summary"))
4633 sessions = self.statistics.get_counter('/nat44/total-sessions')
4634 self.assertEqual(sessions[0][0], 0)
4635 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4637 def test_dynamic(self):
4638 """ NAT44 dynamic translation test """
4640 self.nat44_add_address(self.nat_addr)
4641 flags = self.config_flags.NAT_IS_INSIDE
4642 self.vapi.nat44_interface_add_del_feature(
4643 sw_if_index=self.pg0.sw_if_index,
4644 flags=flags, is_add=1)
4645 self.vapi.nat44_interface_add_del_feature(
4646 sw_if_index=self.pg1.sw_if_index,
4649 nat_config = self.vapi.nat_show_config()
4650 self.assertEqual(1, nat_config.endpoint_dependent)
4653 tcpn = self.statistics.get_err_counter(
4654 '/err/nat44-ed-in2out-slowpath/TCP packets')
4655 udpn = self.statistics.get_err_counter(
4656 '/err/nat44-ed-in2out-slowpath/UDP packets')
4657 icmpn = self.statistics.get_err_counter(
4658 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4659 totaln = self.statistics.get_err_counter(
4660 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4662 pkts = self.create_stream_in(self.pg0, self.pg1)
4663 self.pg0.add_stream(pkts)
4664 self.pg_enable_capture(self.pg_interfaces)
4666 capture = self.pg1.get_capture(len(pkts))
4667 self.verify_capture_out(capture)
4669 err = self.statistics.get_err_counter(
4670 '/err/nat44-ed-in2out-slowpath/TCP packets')
4671 self.assertEqual(err - tcpn, 2)
4672 err = self.statistics.get_err_counter(
4673 '/err/nat44-ed-in2out-slowpath/UDP packets')
4674 self.assertEqual(err - udpn, 1)
4675 err = self.statistics.get_err_counter(
4676 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4677 self.assertEqual(err - icmpn, 1)
4678 err = self.statistics.get_err_counter(
4679 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4680 self.assertEqual(err - totaln, 4)
4683 tcpn = self.statistics.get_err_counter(
4684 '/err/nat44-ed-out2in/TCP packets')
4685 udpn = self.statistics.get_err_counter(
4686 '/err/nat44-ed-out2in/UDP packets')
4687 icmpn = self.statistics.get_err_counter(
4688 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4689 totaln = self.statistics.get_err_counter(
4690 '/err/nat44-ed-out2in/good out2in packets processed')
4692 pkts = self.create_stream_out(self.pg1)
4693 self.pg1.add_stream(pkts)
4694 self.pg_enable_capture(self.pg_interfaces)
4696 capture = self.pg0.get_capture(len(pkts))
4697 self.verify_capture_in(capture, self.pg0)
4699 err = self.statistics.get_err_counter(
4700 '/err/nat44-ed-out2in/TCP packets')
4701 self.assertEqual(err - tcpn, 2)
4702 err = self.statistics.get_err_counter(
4703 '/err/nat44-ed-out2in/UDP packets')
4704 self.assertEqual(err - udpn, 1)
4705 err = self.statistics.get_err_counter(
4706 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4707 self.assertEqual(err - icmpn, 1)
4708 err = self.statistics.get_err_counter(
4709 '/err/nat44-ed-out2in/good out2in packets processed')
4710 self.assertEqual(err - totaln, 3)
4712 sessions = self.statistics.get_counter('/nat44/total-sessions')
4713 self.assertEqual(sessions[0][0], 3)
4715 def test_dynamic_out_of_ports(self):
4716 """ NAT44 dynamic translation test: out of ports """
4718 flags = self.config_flags.NAT_IS_INSIDE
4719 self.vapi.nat44_interface_add_del_feature(
4720 sw_if_index=self.pg0.sw_if_index,
4721 flags=flags, is_add=1)
4722 self.vapi.nat44_interface_add_del_feature(
4723 sw_if_index=self.pg1.sw_if_index,
4726 nat_config = self.vapi.nat_show_config()
4727 self.assertEqual(1, nat_config.endpoint_dependent)
4729 # in2out and no NAT addresses added
4730 err_old = self.statistics.get_err_counter(
4731 '/err/nat44-ed-in2out-slowpath/out of ports')
4733 pkts = self.create_stream_in(self.pg0, self.pg1)
4734 self.pg0.add_stream(pkts)
4735 self.pg_enable_capture(self.pg_interfaces)
4737 self.pg1.get_capture(0, timeout=1)
4739 err_new = self.statistics.get_err_counter(
4740 '/err/nat44-ed-in2out-slowpath/out of ports')
4742 self.assertEqual(err_new - err_old, len(pkts))
4744 # in2out after NAT addresses added
4745 self.nat44_add_address(self.nat_addr)
4747 err_old = self.statistics.get_err_counter(
4748 '/err/nat44-ed-in2out-slowpath/out of ports')
4750 pkts = self.create_stream_in(self.pg0, self.pg1)
4751 self.pg0.add_stream(pkts)
4752 self.pg_enable_capture(self.pg_interfaces)
4754 capture = self.pg1.get_capture(len(pkts))
4755 self.verify_capture_out(capture)
4757 err_new = self.statistics.get_err_counter(
4758 '/err/nat44-ed-in2out-slowpath/out of ports')
4760 self.assertEqual(err_new, err_old)
4762 def test_dynamic_output_feature_vrf(self):
4763 """ NAT44 dynamic translation test: output-feature, VRF"""
4765 # other then default (0)
4768 self.nat44_add_address(self.nat_addr)
4769 flags = self.config_flags.NAT_IS_INSIDE
4770 self.vapi.nat44_interface_add_del_output_feature(
4771 sw_if_index=self.pg7.sw_if_index,
4772 flags=flags, is_add=1)
4773 self.vapi.nat44_interface_add_del_output_feature(
4774 sw_if_index=self.pg8.sw_if_index,
4778 self.vapi.ip_table_add_del(is_add=1,
4779 table={'table_id': new_vrf_id})
4781 self.pg7.unconfig_ip4()
4782 self.pg7.set_table_ip4(new_vrf_id)
4783 self.pg7.config_ip4()
4784 self.pg7.resolve_arp()
4786 self.pg8.unconfig_ip4()
4787 self.pg8.set_table_ip4(new_vrf_id)
4788 self.pg8.config_ip4()
4789 self.pg8.resolve_arp()
4791 nat_config = self.vapi.nat_show_config()
4792 self.assertEqual(1, nat_config.endpoint_dependent)
4795 tcpn = self.statistics.get_err_counter(
4796 '/err/nat44-ed-in2out-slowpath/TCP packets')
4797 udpn = self.statistics.get_err_counter(
4798 '/err/nat44-ed-in2out-slowpath/UDP packets')
4799 icmpn = self.statistics.get_err_counter(
4800 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4801 totaln = self.statistics.get_err_counter(
4802 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4804 pkts = self.create_stream_in(self.pg7, self.pg8)
4805 self.pg7.add_stream(pkts)
4806 self.pg_enable_capture(self.pg_interfaces)
4808 capture = self.pg8.get_capture(len(pkts))
4809 self.verify_capture_out(capture)
4811 err = self.statistics.get_err_counter(
4812 '/err/nat44-ed-in2out-slowpath/TCP packets')
4813 self.assertEqual(err - tcpn, 2)
4814 err = self.statistics.get_err_counter(
4815 '/err/nat44-ed-in2out-slowpath/UDP packets')
4816 self.assertEqual(err - udpn, 1)
4817 err = self.statistics.get_err_counter(
4818 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4819 self.assertEqual(err - icmpn, 1)
4820 err = self.statistics.get_err_counter(
4821 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4822 self.assertEqual(err - totaln, 4)
4825 tcpn = self.statistics.get_err_counter(
4826 '/err/nat44-ed-out2in/TCP packets')
4827 udpn = self.statistics.get_err_counter(
4828 '/err/nat44-ed-out2in/UDP packets')
4829 icmpn = self.statistics.get_err_counter(
4830 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4831 totaln = self.statistics.get_err_counter(
4832 '/err/nat44-ed-out2in/good out2in packets processed')
4834 pkts = self.create_stream_out(self.pg8)
4835 self.pg8.add_stream(pkts)
4836 self.pg_enable_capture(self.pg_interfaces)
4838 capture = self.pg7.get_capture(len(pkts))
4839 self.verify_capture_in(capture, self.pg7)
4841 err = self.statistics.get_err_counter(
4842 '/err/nat44-ed-out2in/TCP packets')
4843 self.assertEqual(err - tcpn, 2)
4844 err = self.statistics.get_err_counter(
4845 '/err/nat44-ed-out2in/UDP packets')
4846 self.assertEqual(err - udpn, 1)
4847 err = self.statistics.get_err_counter(
4848 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4849 self.assertEqual(err - icmpn, 1)
4850 err = self.statistics.get_err_counter(
4851 '/err/nat44-ed-out2in/good out2in packets processed')
4852 self.assertEqual(err - totaln, 3)
4854 sessions = self.statistics.get_counter('/nat44/total-sessions')
4855 self.assertEqual(sessions[0][0], 3)
4858 self.pg7.unconfig_ip4()
4859 self.pg7.set_table_ip4(1)
4860 self.pg7.config_ip4()
4861 self.pg7.resolve_arp()
4863 self.pg8.unconfig_ip4()
4864 self.pg8.set_table_ip4(1)
4865 self.pg8.config_ip4()
4866 self.pg8.resolve_arp()
4868 self.vapi.ip_table_add_del(is_add=0,
4869 table={'table_id': new_vrf_id})
4871 def test_forwarding(self):
4872 """ NAT44 forwarding test """
4874 flags = self.config_flags.NAT_IS_INSIDE
4875 self.vapi.nat44_interface_add_del_feature(
4876 sw_if_index=self.pg0.sw_if_index,
4877 flags=flags, is_add=1)
4878 self.vapi.nat44_interface_add_del_feature(
4879 sw_if_index=self.pg1.sw_if_index,
4881 self.vapi.nat44_forwarding_enable_disable(enable=1)
4883 real_ip = self.pg0.remote_ip4
4884 alias_ip = self.nat_addr
4885 flags = self.config_flags.NAT_IS_ADDR_ONLY
4886 self.vapi.nat44_add_del_static_mapping(is_add=1,
4887 local_ip_address=real_ip,
4888 external_ip_address=alias_ip,
4889 external_sw_if_index=0xFFFFFFFF,
4893 # in2out - static mapping match
4895 pkts = self.create_stream_out(self.pg1)
4896 self.pg1.add_stream(pkts)
4897 self.pg_enable_capture(self.pg_interfaces)
4899 capture = self.pg0.get_capture(len(pkts))
4900 self.verify_capture_in(capture, self.pg0)
4902 pkts = self.create_stream_in(self.pg0, self.pg1)
4903 self.pg0.add_stream(pkts)
4904 self.pg_enable_capture(self.pg_interfaces)
4906 capture = self.pg1.get_capture(len(pkts))
4907 self.verify_capture_out(capture, same_port=True)
4909 # in2out - no static mapping match
4911 host0 = self.pg0.remote_hosts[0]
4912 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4914 pkts = self.create_stream_out(self.pg1,
4915 dst_ip=self.pg0.remote_ip4,
4916 use_inside_ports=True)
4917 self.pg1.add_stream(pkts)
4918 self.pg_enable_capture(self.pg_interfaces)
4920 capture = self.pg0.get_capture(len(pkts))
4921 self.verify_capture_in(capture, self.pg0)
4923 pkts = self.create_stream_in(self.pg0, self.pg1)
4924 self.pg0.add_stream(pkts)
4925 self.pg_enable_capture(self.pg_interfaces)
4927 capture = self.pg1.get_capture(len(pkts))
4928 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4931 self.pg0.remote_hosts[0] = host0
4933 user = self.pg0.remote_hosts[1]
4934 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4935 self.assertEqual(len(sessions), 3)
4936 self.assertTrue(sessions[0].flags &
4937 self.config_flags.NAT_IS_EXT_HOST_VALID)
4938 self.vapi.nat44_del_session(
4939 address=sessions[0].inside_ip_address,
4940 port=sessions[0].inside_port,
4941 protocol=sessions[0].protocol,
4942 flags=(self.config_flags.NAT_IS_INSIDE |
4943 self.config_flags.NAT_IS_EXT_HOST_VALID),
4944 ext_host_address=sessions[0].ext_host_address,
4945 ext_host_port=sessions[0].ext_host_port)
4946 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4947 self.assertEqual(len(sessions), 2)
4950 self.vapi.nat44_forwarding_enable_disable(enable=0)
4951 flags = self.config_flags.NAT_IS_ADDR_ONLY
4952 self.vapi.nat44_add_del_static_mapping(
4954 local_ip_address=real_ip,
4955 external_ip_address=alias_ip,
4956 external_sw_if_index=0xFFFFFFFF,
4959 def test_static_lb(self):
4960 """ NAT44 local service load balancing """
4961 external_addr_n = self.nat_addr
4964 server1 = self.pg0.remote_hosts[0]
4965 server2 = self.pg0.remote_hosts[1]
4967 locals = [{'addr': server1.ip4,
4971 {'addr': server2.ip4,
4976 self.nat44_add_address(self.nat_addr)
4977 self.vapi.nat44_add_del_lb_static_mapping(
4979 external_addr=external_addr_n,
4980 external_port=external_port,
4981 protocol=IP_PROTOS.tcp,
4982 local_num=len(locals),
4984 flags = self.config_flags.NAT_IS_INSIDE
4985 self.vapi.nat44_interface_add_del_feature(
4986 sw_if_index=self.pg0.sw_if_index,
4987 flags=flags, is_add=1)
4988 self.vapi.nat44_interface_add_del_feature(
4989 sw_if_index=self.pg1.sw_if_index,
4992 # from client to service
4993 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4994 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4995 TCP(sport=12345, dport=external_port))
4996 self.pg1.add_stream(p)
4997 self.pg_enable_capture(self.pg_interfaces)
4999 capture = self.pg0.get_capture(1)
5005 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5006 if ip.dst == server1.ip4:
5010 self.assertEqual(tcp.dport, local_port)
5011 self.assert_packet_checksums_valid(p)
5013 self.logger.error(ppp("Unexpected or invalid packet:", p))
5016 # from service back to client
5017 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5018 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5019 TCP(sport=local_port, dport=12345))
5020 self.pg0.add_stream(p)
5021 self.pg_enable_capture(self.pg_interfaces)
5023 capture = self.pg1.get_capture(1)
5028 self.assertEqual(ip.src, self.nat_addr)
5029 self.assertEqual(tcp.sport, external_port)
5030 self.assert_packet_checksums_valid(p)
5032 self.logger.error(ppp("Unexpected or invalid packet:", p))
5035 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5036 self.assertEqual(len(sessions), 1)
5037 self.assertTrue(sessions[0].flags &
5038 self.config_flags.NAT_IS_EXT_HOST_VALID)
5039 self.vapi.nat44_del_session(
5040 address=sessions[0].inside_ip_address,
5041 port=sessions[0].inside_port,
5042 protocol=sessions[0].protocol,
5043 flags=(self.config_flags.NAT_IS_INSIDE |
5044 self.config_flags.NAT_IS_EXT_HOST_VALID),
5045 ext_host_address=sessions[0].ext_host_address,
5046 ext_host_port=sessions[0].ext_host_port)
5047 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5048 self.assertEqual(len(sessions), 0)
5050 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5051 def test_static_lb_multi_clients(self):
5052 """ NAT44 local service load balancing - multiple clients"""
5054 external_addr = self.nat_addr
5057 server1 = self.pg0.remote_hosts[0]
5058 server2 = self.pg0.remote_hosts[1]
5059 server3 = self.pg0.remote_hosts[2]
5061 locals = [{'addr': server1.ip4,
5065 {'addr': server2.ip4,
5070 self.nat44_add_address(self.nat_addr)
5071 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5072 external_addr=external_addr,
5073 external_port=external_port,
5074 protocol=IP_PROTOS.tcp,
5075 local_num=len(locals),
5077 flags = self.config_flags.NAT_IS_INSIDE
5078 self.vapi.nat44_interface_add_del_feature(
5079 sw_if_index=self.pg0.sw_if_index,
5080 flags=flags, is_add=1)
5081 self.vapi.nat44_interface_add_del_feature(
5082 sw_if_index=self.pg1.sw_if_index,
5087 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5089 for client in clients:
5090 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5091 IP(src=client, dst=self.nat_addr) /
5092 TCP(sport=12345, dport=external_port))
5094 self.pg1.add_stream(pkts)
5095 self.pg_enable_capture(self.pg_interfaces)
5097 capture = self.pg0.get_capture(len(pkts))
5099 if p[IP].dst == server1.ip4:
5103 self.assertGreater(server1_n, server2_n)
5106 'addr': server3.ip4,
5113 self.vapi.nat44_lb_static_mapping_add_del_local(
5115 external_addr=external_addr,
5116 external_port=external_port,
5118 protocol=IP_PROTOS.tcp)
5122 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5124 for client in clients:
5125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5126 IP(src=client, dst=self.nat_addr) /
5127 TCP(sport=12346, dport=external_port))
5129 self.assertGreater(len(pkts), 0)
5130 self.pg1.add_stream(pkts)
5131 self.pg_enable_capture(self.pg_interfaces)
5133 capture = self.pg0.get_capture(len(pkts))
5135 if p[IP].dst == server1.ip4:
5137 elif p[IP].dst == server2.ip4:
5141 self.assertGreater(server1_n, 0)
5142 self.assertGreater(server2_n, 0)
5143 self.assertGreater(server3_n, 0)
5146 'addr': server2.ip4,
5152 # remove one back-end
5153 self.vapi.nat44_lb_static_mapping_add_del_local(
5155 external_addr=external_addr,
5156 external_port=external_port,
5158 protocol=IP_PROTOS.tcp)
5162 self.pg1.add_stream(pkts)
5163 self.pg_enable_capture(self.pg_interfaces)
5165 capture = self.pg0.get_capture(len(pkts))
5167 if p[IP].dst == server1.ip4:
5169 elif p[IP].dst == server2.ip4:
5173 self.assertGreater(server1_n, 0)
5174 self.assertEqual(server2_n, 0)
5175 self.assertGreater(server3_n, 0)
5177 def test_static_lb_2(self):
5178 """ NAT44 local service load balancing (asymmetrical rule) """
5179 external_addr = self.nat_addr
5182 server1 = self.pg0.remote_hosts[0]
5183 server2 = self.pg0.remote_hosts[1]
5185 locals = [{'addr': server1.ip4,
5189 {'addr': server2.ip4,
5194 self.vapi.nat44_forwarding_enable_disable(enable=1)
5195 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5196 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5197 external_addr=external_addr,
5198 external_port=external_port,
5199 protocol=IP_PROTOS.tcp,
5200 local_num=len(locals),
5202 flags = self.config_flags.NAT_IS_INSIDE
5203 self.vapi.nat44_interface_add_del_feature(
5204 sw_if_index=self.pg0.sw_if_index,
5205 flags=flags, is_add=1)
5206 self.vapi.nat44_interface_add_del_feature(
5207 sw_if_index=self.pg1.sw_if_index,
5210 # from client to service
5211 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5212 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5213 TCP(sport=12345, dport=external_port))
5214 self.pg1.add_stream(p)
5215 self.pg_enable_capture(self.pg_interfaces)
5217 capture = self.pg0.get_capture(1)
5223 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5224 if ip.dst == server1.ip4:
5228 self.assertEqual(tcp.dport, local_port)
5229 self.assert_packet_checksums_valid(p)
5231 self.logger.error(ppp("Unexpected or invalid packet:", p))
5234 # from service back to client
5235 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5236 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5237 TCP(sport=local_port, dport=12345))
5238 self.pg0.add_stream(p)
5239 self.pg_enable_capture(self.pg_interfaces)
5241 capture = self.pg1.get_capture(1)
5246 self.assertEqual(ip.src, self.nat_addr)
5247 self.assertEqual(tcp.sport, external_port)
5248 self.assert_packet_checksums_valid(p)
5250 self.logger.error(ppp("Unexpected or invalid packet:", p))
5253 # from client to server (no translation)
5254 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5255 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5256 TCP(sport=12346, dport=local_port))
5257 self.pg1.add_stream(p)
5258 self.pg_enable_capture(self.pg_interfaces)
5260 capture = self.pg0.get_capture(1)
5266 self.assertEqual(ip.dst, server1.ip4)
5267 self.assertEqual(tcp.dport, local_port)
5268 self.assert_packet_checksums_valid(p)
5270 self.logger.error(ppp("Unexpected or invalid packet:", p))
5273 # from service back to client (no translation)
5274 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5275 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5276 TCP(sport=local_port, dport=12346))
5277 self.pg0.add_stream(p)
5278 self.pg_enable_capture(self.pg_interfaces)
5280 capture = self.pg1.get_capture(1)
5285 self.assertEqual(ip.src, server1.ip4)
5286 self.assertEqual(tcp.sport, local_port)
5287 self.assert_packet_checksums_valid(p)
5289 self.logger.error(ppp("Unexpected or invalid packet:", p))
5292 def test_lb_affinity(self):
5293 """ NAT44 local service load balancing affinity """
5294 external_addr = self.nat_addr
5297 server1 = self.pg0.remote_hosts[0]
5298 server2 = self.pg0.remote_hosts[1]
5300 locals = [{'addr': server1.ip4,
5304 {'addr': server2.ip4,
5309 self.nat44_add_address(self.nat_addr)
5310 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5311 external_addr=external_addr,
5312 external_port=external_port,
5313 protocol=IP_PROTOS.tcp,
5315 local_num=len(locals),
5317 flags = self.config_flags.NAT_IS_INSIDE
5318 self.vapi.nat44_interface_add_del_feature(
5319 sw_if_index=self.pg0.sw_if_index,
5320 flags=flags, is_add=1)
5321 self.vapi.nat44_interface_add_del_feature(
5322 sw_if_index=self.pg1.sw_if_index,
5325 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5326 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5327 TCP(sport=1025, dport=external_port))
5328 self.pg1.add_stream(p)
5329 self.pg_enable_capture(self.pg_interfaces)
5331 capture = self.pg0.get_capture(1)
5332 backend = capture[0][IP].dst
5334 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5335 self.assertEqual(len(sessions), 1)
5336 self.assertTrue(sessions[0].flags &
5337 self.config_flags.NAT_IS_EXT_HOST_VALID)
5338 self.vapi.nat44_del_session(
5339 address=sessions[0].inside_ip_address,
5340 port=sessions[0].inside_port,
5341 protocol=sessions[0].protocol,
5342 flags=(self.config_flags.NAT_IS_INSIDE |
5343 self.config_flags.NAT_IS_EXT_HOST_VALID),
5344 ext_host_address=sessions[0].ext_host_address,
5345 ext_host_port=sessions[0].ext_host_port)
5348 for port in range(1030, 1100):
5349 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5350 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5351 TCP(sport=port, dport=external_port))
5353 self.pg1.add_stream(pkts)
5354 self.pg_enable_capture(self.pg_interfaces)
5356 capture = self.pg0.get_capture(len(pkts))
5358 self.assertEqual(p[IP].dst, backend)
5360 def test_unknown_proto(self):
5361 """ NAT44 translate packet with unknown protocol """
5362 self.nat44_add_address(self.nat_addr)
5363 flags = self.config_flags.NAT_IS_INSIDE
5364 self.vapi.nat44_interface_add_del_feature(
5365 sw_if_index=self.pg0.sw_if_index,
5366 flags=flags, is_add=1)
5367 self.vapi.nat44_interface_add_del_feature(
5368 sw_if_index=self.pg1.sw_if_index,
5372 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5373 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5374 TCP(sport=self.tcp_port_in, dport=20))
5375 self.pg0.add_stream(p)
5376 self.pg_enable_capture(self.pg_interfaces)
5378 p = self.pg1.get_capture(1)
5380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5381 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5383 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5384 TCP(sport=1234, dport=1234))
5385 self.pg0.add_stream(p)
5386 self.pg_enable_capture(self.pg_interfaces)
5388 p = self.pg1.get_capture(1)
5391 self.assertEqual(packet[IP].src, self.nat_addr)
5392 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5393 self.assertEqual(packet.haslayer(GRE), 1)
5394 self.assert_packet_checksums_valid(packet)
5396 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5400 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5401 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5403 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5404 TCP(sport=1234, dport=1234))
5405 self.pg1.add_stream(p)
5406 self.pg_enable_capture(self.pg_interfaces)
5408 p = self.pg0.get_capture(1)
5411 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5412 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5413 self.assertEqual(packet.haslayer(GRE), 1)
5414 self.assert_packet_checksums_valid(packet)
5416 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5419 def test_hairpinning_unknown_proto(self):
5420 """ NAT44 translate packet with unknown protocol - hairpinning """
5421 host = self.pg0.remote_hosts[0]
5422 server = self.pg0.remote_hosts[1]
5424 server_out_port = 8765
5425 server_nat_ip = "10.0.0.11"
5427 self.nat44_add_address(self.nat_addr)
5428 flags = self.config_flags.NAT_IS_INSIDE
5429 self.vapi.nat44_interface_add_del_feature(
5430 sw_if_index=self.pg0.sw_if_index,
5431 flags=flags, is_add=1)
5432 self.vapi.nat44_interface_add_del_feature(
5433 sw_if_index=self.pg1.sw_if_index,
5436 # add static mapping for server
5437 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5440 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5441 IP(src=host.ip4, dst=server_nat_ip) /
5442 TCP(sport=host_in_port, dport=server_out_port))
5443 self.pg0.add_stream(p)
5444 self.pg_enable_capture(self.pg_interfaces)
5446 self.pg0.get_capture(1)
5448 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5449 IP(src=host.ip4, dst=server_nat_ip) /
5451 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5452 TCP(sport=1234, dport=1234))
5453 self.pg0.add_stream(p)
5454 self.pg_enable_capture(self.pg_interfaces)
5456 p = self.pg0.get_capture(1)
5459 self.assertEqual(packet[IP].src, self.nat_addr)
5460 self.assertEqual(packet[IP].dst, server.ip4)
5461 self.assertEqual(packet.haslayer(GRE), 1)
5462 self.assert_packet_checksums_valid(packet)
5464 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5468 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5469 IP(src=server.ip4, dst=self.nat_addr) /
5471 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5472 TCP(sport=1234, dport=1234))
5473 self.pg0.add_stream(p)
5474 self.pg_enable_capture(self.pg_interfaces)
5476 p = self.pg0.get_capture(1)
5479 self.assertEqual(packet[IP].src, server_nat_ip)
5480 self.assertEqual(packet[IP].dst, host.ip4)
5481 self.assertEqual(packet.haslayer(GRE), 1)
5482 self.assert_packet_checksums_valid(packet)
5484 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5487 def test_output_feature_and_service(self):
5488 """ NAT44 interface output feature and services """
5489 external_addr = '1.2.3.4'
5493 self.vapi.nat44_forwarding_enable_disable(enable=1)
5494 self.nat44_add_address(self.nat_addr)
5495 flags = self.config_flags.NAT_IS_ADDR_ONLY
5496 self.vapi.nat44_add_del_identity_mapping(
5497 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5498 flags=flags, is_add=1)
5499 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5500 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5501 local_port, external_port,
5502 proto=IP_PROTOS.tcp, flags=flags)
5503 flags = self.config_flags.NAT_IS_INSIDE
5504 self.vapi.nat44_interface_add_del_feature(
5505 sw_if_index=self.pg0.sw_if_index,
5507 self.vapi.nat44_interface_add_del_feature(
5508 sw_if_index=self.pg0.sw_if_index,
5509 flags=flags, is_add=1)
5510 self.vapi.nat44_interface_add_del_output_feature(
5512 sw_if_index=self.pg1.sw_if_index)
5514 # from client to service
5515 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5516 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5517 TCP(sport=12345, dport=external_port))
5518 self.pg1.add_stream(p)
5519 self.pg_enable_capture(self.pg_interfaces)
5521 capture = self.pg0.get_capture(1)
5526 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5527 self.assertEqual(tcp.dport, local_port)
5528 self.assert_packet_checksums_valid(p)
5530 self.logger.error(ppp("Unexpected or invalid packet:", p))
5533 # from service back to client
5534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5536 TCP(sport=local_port, dport=12345))
5537 self.pg0.add_stream(p)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg1.get_capture(1)
5545 self.assertEqual(ip.src, external_addr)
5546 self.assertEqual(tcp.sport, external_port)
5547 self.assert_packet_checksums_valid(p)
5549 self.logger.error(ppp("Unexpected or invalid packet:", p))
5552 # from local network host to external network
5553 pkts = self.create_stream_in(self.pg0, self.pg1)
5554 self.pg0.add_stream(pkts)
5555 self.pg_enable_capture(self.pg_interfaces)
5557 capture = self.pg1.get_capture(len(pkts))
5558 self.verify_capture_out(capture)
5559 pkts = self.create_stream_in(self.pg0, self.pg1)
5560 self.pg0.add_stream(pkts)
5561 self.pg_enable_capture(self.pg_interfaces)
5563 capture = self.pg1.get_capture(len(pkts))
5564 self.verify_capture_out(capture)
5566 # from external network back to local network host
5567 pkts = self.create_stream_out(self.pg1)
5568 self.pg1.add_stream(pkts)
5569 self.pg_enable_capture(self.pg_interfaces)
5571 capture = self.pg0.get_capture(len(pkts))
5572 self.verify_capture_in(capture, self.pg0)
5574 def test_output_feature_and_service2(self):
5575 """ NAT44 interface output feature and service host direct access """
5576 self.vapi.nat44_forwarding_enable_disable(enable=1)
5577 self.nat44_add_address(self.nat_addr)
5578 self.vapi.nat44_interface_add_del_output_feature(
5580 sw_if_index=self.pg1.sw_if_index)
5582 # session initiated from service host - translate
5583 pkts = self.create_stream_in(self.pg0, self.pg1)
5584 self.pg0.add_stream(pkts)
5585 self.pg_enable_capture(self.pg_interfaces)
5587 capture = self.pg1.get_capture(len(pkts))
5588 self.verify_capture_out(capture)
5590 pkts = self.create_stream_out(self.pg1)
5591 self.pg1.add_stream(pkts)
5592 self.pg_enable_capture(self.pg_interfaces)
5594 capture = self.pg0.get_capture(len(pkts))
5595 self.verify_capture_in(capture, self.pg0)
5597 # session initiated from remote host - do not translate
5598 self.tcp_port_in = 60303
5599 self.udp_port_in = 60304
5600 self.icmp_id_in = 60305
5601 pkts = self.create_stream_out(self.pg1,
5602 self.pg0.remote_ip4,
5603 use_inside_ports=True)
5604 self.pg1.add_stream(pkts)
5605 self.pg_enable_capture(self.pg_interfaces)
5607 capture = self.pg0.get_capture(len(pkts))
5608 self.verify_capture_in(capture, self.pg0)
5610 pkts = self.create_stream_in(self.pg0, self.pg1)
5611 self.pg0.add_stream(pkts)
5612 self.pg_enable_capture(self.pg_interfaces)
5614 capture = self.pg1.get_capture(len(pkts))
5615 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5618 def test_output_feature_and_service3(self):
5619 """ NAT44 interface output feature and DST NAT """
5620 external_addr = '1.2.3.4'
5624 self.vapi.nat44_forwarding_enable_disable(enable=1)
5625 self.nat44_add_address(self.nat_addr)
5626 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5627 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5628 local_port, external_port,
5629 proto=IP_PROTOS.tcp, flags=flags)
5630 flags = self.config_flags.NAT_IS_INSIDE
5631 self.vapi.nat44_interface_add_del_feature(
5632 sw_if_index=self.pg0.sw_if_index,
5634 self.vapi.nat44_interface_add_del_feature(
5635 sw_if_index=self.pg0.sw_if_index,
5636 flags=flags, is_add=1)
5637 self.vapi.nat44_interface_add_del_output_feature(
5639 sw_if_index=self.pg1.sw_if_index)
5641 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5642 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5643 TCP(sport=12345, dport=external_port))
5644 self.pg0.add_stream(p)
5645 self.pg_enable_capture(self.pg_interfaces)
5647 capture = self.pg1.get_capture(1)
5652 self.assertEqual(ip.src, self.pg0.remote_ip4)
5653 self.assertEqual(tcp.sport, 12345)
5654 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5655 self.assertEqual(tcp.dport, local_port)
5656 self.assert_packet_checksums_valid(p)
5658 self.logger.error(ppp("Unexpected or invalid packet:", p))
5661 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5662 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5663 TCP(sport=local_port, dport=12345))
5664 self.pg1.add_stream(p)
5665 self.pg_enable_capture(self.pg_interfaces)
5667 capture = self.pg0.get_capture(1)
5672 self.assertEqual(ip.src, external_addr)
5673 self.assertEqual(tcp.sport, external_port)
5674 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5675 self.assertEqual(tcp.dport, 12345)
5676 self.assert_packet_checksums_valid(p)
5678 self.logger.error(ppp("Unexpected or invalid packet:", p))
5681 def test_next_src_nat(self):
5682 """ On way back forward packet to nat44-in2out node. """
5683 twice_nat_addr = '10.0.1.3'
5686 post_twice_nat_port = 0
5688 self.vapi.nat44_forwarding_enable_disable(enable=1)
5689 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5690 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5691 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5692 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5693 local_port, external_port,
5694 proto=IP_PROTOS.tcp, vrf_id=1,
5696 self.vapi.nat44_interface_add_del_feature(
5697 sw_if_index=self.pg6.sw_if_index,
5700 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5701 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5702 TCP(sport=12345, dport=external_port))
5703 self.pg6.add_stream(p)
5704 self.pg_enable_capture(self.pg_interfaces)
5706 capture = self.pg6.get_capture(1)
5711 self.assertEqual(ip.src, twice_nat_addr)
5712 self.assertNotEqual(tcp.sport, 12345)
5713 post_twice_nat_port = tcp.sport
5714 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5715 self.assertEqual(tcp.dport, local_port)
5716 self.assert_packet_checksums_valid(p)
5718 self.logger.error(ppp("Unexpected or invalid packet:", p))
5721 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5722 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5723 TCP(sport=local_port, dport=post_twice_nat_port))
5724 self.pg6.add_stream(p)
5725 self.pg_enable_capture(self.pg_interfaces)
5727 capture = self.pg6.get_capture(1)
5732 self.assertEqual(ip.src, self.pg1.remote_ip4)
5733 self.assertEqual(tcp.sport, external_port)
5734 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5735 self.assertEqual(tcp.dport, 12345)
5736 self.assert_packet_checksums_valid(p)
5738 self.logger.error(ppp("Unexpected or invalid packet:", p))
5741 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5743 twice_nat_addr = '10.0.1.3'
5751 port_in1 = port_in + 1
5752 port_in2 = port_in + 2
5757 server1 = self.pg0.remote_hosts[0]
5758 server2 = self.pg0.remote_hosts[1]
5770 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5773 self.nat44_add_address(self.nat_addr)
5774 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5778 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5780 flags |= self.config_flags.NAT_IS_TWICE_NAT
5783 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5785 proto=IP_PROTOS.tcp,
5788 locals = [{'addr': server1.ip4,
5792 {'addr': server2.ip4,
5796 out_addr = self.nat_addr
5798 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5799 external_addr=out_addr,
5800 external_port=port_out,
5801 protocol=IP_PROTOS.tcp,
5802 local_num=len(locals),
5804 flags = self.config_flags.NAT_IS_INSIDE
5805 self.vapi.nat44_interface_add_del_feature(
5806 sw_if_index=pg0.sw_if_index,
5807 flags=flags, is_add=1)
5808 self.vapi.nat44_interface_add_del_feature(
5809 sw_if_index=pg1.sw_if_index,
5816 assert client_id is not None
5818 client = self.pg0.remote_hosts[0]
5819 elif client_id == 2:
5820 client = self.pg0.remote_hosts[1]
5822 client = pg1.remote_hosts[0]
5823 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5824 IP(src=client.ip4, dst=self.nat_addr) /
5825 TCP(sport=eh_port_out, dport=port_out))
5827 self.pg_enable_capture(self.pg_interfaces)
5829 capture = pg0.get_capture(1)
5835 if ip.dst == server1.ip4:
5841 self.assertEqual(ip.dst, server.ip4)
5843 self.assertIn(tcp.dport, [port_in1, port_in2])
5845 self.assertEqual(tcp.dport, port_in)
5847 self.assertEqual(ip.src, twice_nat_addr)
5848 self.assertNotEqual(tcp.sport, eh_port_out)
5850 self.assertEqual(ip.src, client.ip4)
5851 self.assertEqual(tcp.sport, eh_port_out)
5853 eh_port_in = tcp.sport
5854 saved_port_in = tcp.dport
5855 self.assert_packet_checksums_valid(p)
5857 self.logger.error(ppp("Unexpected or invalid packet:", p))
5860 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5861 IP(src=server.ip4, dst=eh_addr_in) /
5862 TCP(sport=saved_port_in, dport=eh_port_in))
5864 self.pg_enable_capture(self.pg_interfaces)
5866 capture = pg1.get_capture(1)
5871 self.assertEqual(ip.dst, client.ip4)
5872 self.assertEqual(ip.src, self.nat_addr)
5873 self.assertEqual(tcp.dport, eh_port_out)
5874 self.assertEqual(tcp.sport, port_out)
5875 self.assert_packet_checksums_valid(p)
5877 self.logger.error(ppp("Unexpected or invalid packet:", p))
5881 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5882 self.assertEqual(len(sessions), 1)
5883 self.assertTrue(sessions[0].flags &
5884 self.config_flags.NAT_IS_EXT_HOST_VALID)
5885 self.assertTrue(sessions[0].flags &
5886 self.config_flags.NAT_IS_TWICE_NAT)
5887 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5888 self.vapi.nat44_del_session(
5889 address=sessions[0].inside_ip_address,
5890 port=sessions[0].inside_port,
5891 protocol=sessions[0].protocol,
5892 flags=(self.config_flags.NAT_IS_INSIDE |
5893 self.config_flags.NAT_IS_EXT_HOST_VALID),
5894 ext_host_address=sessions[0].ext_host_nat_address,
5895 ext_host_port=sessions[0].ext_host_nat_port)
5896 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5897 self.assertEqual(len(sessions), 0)
5899 def test_twice_nat(self):
5901 self.twice_nat_common()
5903 def test_self_twice_nat_positive(self):
5904 """ Self Twice NAT44 (positive test) """
5905 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5907 def test_self_twice_nat_negative(self):
5908 """ Self Twice NAT44 (negative test) """
5909 self.twice_nat_common(self_twice_nat=True)
5911 def test_twice_nat_lb(self):
5912 """ Twice NAT44 local service load balancing """
5913 self.twice_nat_common(lb=True)
5915 def test_self_twice_nat_lb_positive(self):
5916 """ Self Twice NAT44 local service load balancing (positive test) """
5917 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5920 def test_self_twice_nat_lb_negative(self):
5921 """ Self Twice NAT44 local service load balancing (negative test) """
5922 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5925 def test_twice_nat_interface_addr(self):
5926 """ Acquire twice NAT44 addresses from interface """
5927 flags = self.config_flags.NAT_IS_TWICE_NAT
5928 self.vapi.nat44_add_del_interface_addr(
5930 sw_if_index=self.pg3.sw_if_index,
5933 # no address in NAT pool
5934 adresses = self.vapi.nat44_address_dump()
5935 self.assertEqual(0, len(adresses))
5937 # configure interface address and check NAT address pool
5938 self.pg3.config_ip4()
5939 adresses = self.vapi.nat44_address_dump()
5940 self.assertEqual(1, len(adresses))
5941 self.assertEqual(str(adresses[0].ip_address),
5943 self.assertEqual(adresses[0].flags, flags)
5945 # remove interface address and check NAT address pool
5946 self.pg3.unconfig_ip4()
5947 adresses = self.vapi.nat44_address_dump()
5948 self.assertEqual(0, len(adresses))
5950 def test_tcp_close(self):
5951 """ Close TCP session from inside network - output feature """
5952 self.vapi.nat44_forwarding_enable_disable(enable=1)
5953 self.nat44_add_address(self.pg1.local_ip4)
5954 twice_nat_addr = '10.0.1.3'
5955 service_ip = '192.168.16.150'
5956 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5957 flags = self.config_flags.NAT_IS_INSIDE
5958 self.vapi.nat44_interface_add_del_feature(
5959 sw_if_index=self.pg0.sw_if_index,
5961 self.vapi.nat44_interface_add_del_feature(
5962 sw_if_index=self.pg0.sw_if_index,
5963 flags=flags, is_add=1)
5964 self.vapi.nat44_interface_add_del_output_feature(
5966 sw_if_index=self.pg1.sw_if_index)
5967 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5968 self.config_flags.NAT_IS_TWICE_NAT)
5969 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5973 proto=IP_PROTOS.tcp,
5975 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5976 start_sessnum = len(sessions)
5978 # SYN packet out->in
5979 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5980 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5981 TCP(sport=33898, dport=80, flags="S"))
5982 self.pg1.add_stream(p)
5983 self.pg_enable_capture(self.pg_interfaces)
5985 capture = self.pg0.get_capture(1)
5987 tcp_port = p[TCP].sport
5989 # SYN + ACK packet in->out
5990 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5991 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5992 TCP(sport=80, dport=tcp_port, flags="SA"))
5993 self.pg0.add_stream(p)
5994 self.pg_enable_capture(self.pg_interfaces)
5996 self.pg1.get_capture(1)
5998 # ACK packet out->in
5999 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6000 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6001 TCP(sport=33898, dport=80, flags="A"))
6002 self.pg1.add_stream(p)
6003 self.pg_enable_capture(self.pg_interfaces)
6005 self.pg0.get_capture(1)
6007 # FIN packet in -> out
6008 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6009 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6010 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6011 self.pg0.add_stream(p)
6012 self.pg_enable_capture(self.pg_interfaces)
6014 self.pg1.get_capture(1)
6016 # FIN+ACK packet out -> in
6017 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6018 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6019 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6020 self.pg1.add_stream(p)
6021 self.pg_enable_capture(self.pg_interfaces)
6023 self.pg0.get_capture(1)
6025 # ACK packet in -> out
6026 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6027 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6028 TCP(sport=80, dport=tcp_port, 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_in(self):
6039 """ Close TCP session from inside 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.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6061 tcp_transitory=2, icmp=5)
6063 self.initiate_tcp_session(self.pg0, self.pg1)
6065 # FIN packet in -> out
6066 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6067 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6068 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6069 flags="FA", seq=100, ack=300))
6070 self.pg0.add_stream(p)
6071 self.pg_enable_capture(self.pg_interfaces)
6073 self.pg1.get_capture(1)
6077 # ACK packet out -> in
6078 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6079 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6080 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6081 flags="A", seq=300, ack=101))
6084 # FIN packet out -> in
6085 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6086 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6087 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6088 flags="FA", seq=300, ack=101))
6091 self.pg1.add_stream(pkts)
6092 self.pg_enable_capture(self.pg_interfaces)
6094 self.pg0.get_capture(2)
6096 # ACK packet in -> out
6097 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6098 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6099 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6100 flags="A", seq=101, ack=301))
6101 self.pg0.add_stream(p)
6102 self.pg_enable_capture(self.pg_interfaces)
6104 self.pg1.get_capture(1)
6106 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6107 self.assertEqual(len(sessions) - start_sessnum, 1)
6109 stats = self.statistics.get_counter(
6110 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6111 out2in_drops = stats[0]
6112 stats = self.statistics.get_counter(
6113 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6114 in2out_drops = stats[0]
6116 # extra FIN packet out -> in - this should be dropped
6117 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6118 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6119 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6120 flags="FA", seq=300, ack=101))
6122 self.pg1.add_stream(p)
6123 self.pg_enable_capture(self.pg_interfaces)
6125 self.pg0.assert_nothing_captured()
6127 # extra ACK packet in -> out - this should be dropped
6128 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6129 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6130 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6131 flags="A", seq=101, ack=301))
6132 self.pg0.add_stream(p)
6133 self.pg_enable_capture(self.pg_interfaces)
6135 self.pg1.assert_nothing_captured()
6137 stats = self.statistics.get_counter(
6138 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6139 self.assertEqual(stats[0] - out2in_drops, 1)
6140 stats = self.statistics.get_counter(
6141 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6142 self.assertEqual(stats[0] - in2out_drops, 1)
6145 # extra ACK packet in -> out - this will cause session to be wiped
6146 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6147 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6148 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6149 flags="A", seq=101, ack=301))
6150 self.pg0.add_stream(p)
6151 self.pg_enable_capture(self.pg_interfaces)
6153 self.pg1.assert_nothing_captured()
6154 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6155 self.assertEqual(len(sessions) - start_sessnum, 0)
6157 def test_tcp_session_close_out(self):
6158 """ Close TCP session from outside network """
6159 self.tcp_port_out = 10505
6160 self.nat44_add_address(self.nat_addr)
6161 flags = self.config_flags.NAT_IS_TWICE_NAT
6162 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6166 proto=IP_PROTOS.tcp,
6168 flags = self.config_flags.NAT_IS_INSIDE
6169 self.vapi.nat44_interface_add_del_feature(
6170 sw_if_index=self.pg0.sw_if_index,
6171 flags=flags, is_add=1)
6172 self.vapi.nat44_interface_add_del_feature(
6173 sw_if_index=self.pg1.sw_if_index,
6176 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6177 start_sessnum = len(sessions)
6179 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6180 tcp_transitory=2, icmp=5)
6182 self.initiate_tcp_session(self.pg0, self.pg1)
6184 # FIN packet out -> in
6185 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6186 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6187 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6188 flags="FA", seq=100, ack=300))
6189 self.pg1.add_stream(p)
6190 self.pg_enable_capture(self.pg_interfaces)
6192 self.pg0.get_capture(1)
6194 # FIN+ACK packet in -> out
6195 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6196 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6197 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6198 flags="FA", seq=300, ack=101))
6200 self.pg0.add_stream(p)
6201 self.pg_enable_capture(self.pg_interfaces)
6203 self.pg1.get_capture(1)
6205 # ACK packet out -> in
6206 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6207 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6208 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6209 flags="A", seq=101, ack=301))
6210 self.pg1.add_stream(p)
6211 self.pg_enable_capture(self.pg_interfaces)
6213 self.pg0.get_capture(1)
6215 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6216 self.assertEqual(len(sessions) - start_sessnum, 1)
6218 stats = self.statistics.get_counter(
6219 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6220 out2in_drops = stats[0]
6221 stats = self.statistics.get_counter(
6222 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6223 in2out_drops = stats[0]
6225 # extra FIN packet out -> in - this should be dropped
6226 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6227 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6228 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6229 flags="FA", seq=300, ack=101))
6231 self.pg1.add_stream(p)
6232 self.pg_enable_capture(self.pg_interfaces)
6234 self.pg0.assert_nothing_captured()
6236 # extra ACK packet in -> out - this should be dropped
6237 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6238 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6239 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6240 flags="A", seq=101, ack=301))
6241 self.pg0.add_stream(p)
6242 self.pg_enable_capture(self.pg_interfaces)
6244 self.pg1.assert_nothing_captured()
6246 stats = self.statistics.get_counter(
6247 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6248 self.assertEqual(stats[0] - out2in_drops, 1)
6249 stats = self.statistics.get_counter(
6250 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6251 self.assertEqual(stats[0] - in2out_drops, 1)
6254 # extra ACK packet in -> out - this will cause session to be wiped
6255 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6256 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6257 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6258 flags="A", seq=101, ack=301))
6259 self.pg0.add_stream(p)
6260 self.pg_enable_capture(self.pg_interfaces)
6262 self.pg1.assert_nothing_captured()
6263 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6264 self.assertEqual(len(sessions) - start_sessnum, 0)
6266 def test_tcp_session_close_simultaneous(self):
6267 """ Close TCP session from inside network """
6268 self.tcp_port_out = 10505
6269 self.nat44_add_address(self.nat_addr)
6270 flags = self.config_flags.NAT_IS_TWICE_NAT
6271 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6275 proto=IP_PROTOS.tcp,
6277 flags = self.config_flags.NAT_IS_INSIDE
6278 self.vapi.nat44_interface_add_del_feature(
6279 sw_if_index=self.pg0.sw_if_index,
6280 flags=flags, is_add=1)
6281 self.vapi.nat44_interface_add_del_feature(
6282 sw_if_index=self.pg1.sw_if_index,
6285 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6286 start_sessnum = len(sessions)
6288 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6289 tcp_transitory=2, icmp=5)
6291 self.initiate_tcp_session(self.pg0, self.pg1)
6293 # FIN packet in -> out
6294 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6295 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6296 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6297 flags="FA", seq=100, ack=300))
6298 self.pg0.add_stream(p)
6299 self.pg_enable_capture(self.pg_interfaces)
6301 self.pg1.get_capture(1)
6303 # FIN packet out -> in
6304 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6305 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6306 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6307 flags="FA", seq=300, ack=100))
6308 self.pg1.add_stream(p)
6309 self.pg_enable_capture(self.pg_interfaces)
6311 self.pg0.get_capture(1)
6313 # ACK packet in -> out
6314 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6315 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6316 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6317 flags="A", seq=101, ack=301))
6318 self.pg0.add_stream(p)
6319 self.pg_enable_capture(self.pg_interfaces)
6321 self.pg1.get_capture(1)
6323 # ACK packet out -> in
6324 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6325 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6326 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6327 flags="A", seq=301, ack=101))
6328 self.pg1.add_stream(p)
6329 self.pg_enable_capture(self.pg_interfaces)
6331 self.pg0.get_capture(1)
6333 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6334 self.assertEqual(len(sessions) - start_sessnum, 1)
6336 stats = self.statistics.get_counter(
6337 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6338 out2in_drops = stats[0]
6339 stats = self.statistics.get_counter(
6340 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6341 in2out_drops = stats[0]
6343 # extra FIN packet out -> in - this should be dropped
6344 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6345 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6346 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6347 flags="FA", seq=300, ack=101))
6349 self.pg1.add_stream(p)
6350 self.pg_enable_capture(self.pg_interfaces)
6352 self.pg0.assert_nothing_captured()
6354 # extra ACK packet in -> out - this should be dropped
6355 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6356 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6357 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6358 flags="A", seq=101, ack=301))
6359 self.pg0.add_stream(p)
6360 self.pg_enable_capture(self.pg_interfaces)
6362 self.pg1.assert_nothing_captured()
6364 stats = self.statistics.get_counter(
6365 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6366 self.assertEqual(stats[0] - out2in_drops, 1)
6367 stats = self.statistics.get_counter(
6368 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6369 self.assertEqual(stats[0] - in2out_drops, 1)
6372 # extra ACK packet in -> out - this will cause session to be wiped
6373 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6374 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6375 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6376 flags="A", seq=101, ack=301))
6377 self.pg0.add_stream(p)
6378 self.pg_enable_capture(self.pg_interfaces)
6380 self.pg1.assert_nothing_captured()
6381 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6382 self.assertEqual(len(sessions) - start_sessnum, 0)
6384 def test_one_armed_nat44_static(self):
6385 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6386 remote_host = self.pg4.remote_hosts[0]
6387 local_host = self.pg4.remote_hosts[1]
6392 self.vapi.nat44_forwarding_enable_disable(enable=1)
6393 self.nat44_add_address(self.nat_addr, twice_nat=1)
6394 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6395 self.config_flags.NAT_IS_TWICE_NAT)
6396 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6397 local_port, external_port,
6398 proto=IP_PROTOS.tcp, flags=flags)
6399 flags = self.config_flags.NAT_IS_INSIDE
6400 self.vapi.nat44_interface_add_del_feature(
6401 sw_if_index=self.pg4.sw_if_index,
6403 self.vapi.nat44_interface_add_del_feature(
6404 sw_if_index=self.pg4.sw_if_index,
6405 flags=flags, is_add=1)
6407 # from client to service
6408 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6409 IP(src=remote_host.ip4, dst=self.nat_addr) /
6410 TCP(sport=12345, dport=external_port))
6411 self.pg4.add_stream(p)
6412 self.pg_enable_capture(self.pg_interfaces)
6414 capture = self.pg4.get_capture(1)
6419 self.assertEqual(ip.dst, local_host.ip4)
6420 self.assertEqual(ip.src, self.nat_addr)
6421 self.assertEqual(tcp.dport, local_port)
6422 self.assertNotEqual(tcp.sport, 12345)
6423 eh_port_in = tcp.sport
6424 self.assert_packet_checksums_valid(p)
6426 self.logger.error(ppp("Unexpected or invalid packet:", p))
6429 # from service back to client
6430 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6431 IP(src=local_host.ip4, dst=self.nat_addr) /
6432 TCP(sport=local_port, dport=eh_port_in))
6433 self.pg4.add_stream(p)
6434 self.pg_enable_capture(self.pg_interfaces)
6436 capture = self.pg4.get_capture(1)
6441 self.assertEqual(ip.src, self.nat_addr)
6442 self.assertEqual(ip.dst, remote_host.ip4)
6443 self.assertEqual(tcp.sport, external_port)
6444 self.assertEqual(tcp.dport, 12345)
6445 self.assert_packet_checksums_valid(p)
6447 self.logger.error(ppp("Unexpected or invalid packet:", p))
6450 def test_static_with_port_out2(self):
6451 """ 1:1 NAPT asymmetrical rule """
6456 self.vapi.nat44_forwarding_enable_disable(enable=1)
6457 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6458 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6459 local_port, external_port,
6460 proto=IP_PROTOS.tcp, flags=flags)
6461 flags = self.config_flags.NAT_IS_INSIDE
6462 self.vapi.nat44_interface_add_del_feature(
6463 sw_if_index=self.pg0.sw_if_index,
6464 flags=flags, is_add=1)
6465 self.vapi.nat44_interface_add_del_feature(
6466 sw_if_index=self.pg1.sw_if_index,
6469 # from client to service
6470 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6471 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6472 TCP(sport=12345, dport=external_port))
6473 self.pg1.add_stream(p)
6474 self.pg_enable_capture(self.pg_interfaces)
6476 capture = self.pg0.get_capture(1)
6481 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6482 self.assertEqual(tcp.dport, local_port)
6483 self.assert_packet_checksums_valid(p)
6485 self.logger.error(ppp("Unexpected or invalid packet:", p))
6489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6490 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6491 ICMP(type=11) / capture[0][IP])
6492 self.pg0.add_stream(p)
6493 self.pg_enable_capture(self.pg_interfaces)
6495 capture = self.pg1.get_capture(1)
6498 self.assertEqual(p[IP].src, self.nat_addr)
6500 self.assertEqual(inner.dst, self.nat_addr)
6501 self.assertEqual(inner[TCPerror].dport, external_port)
6503 self.logger.error(ppp("Unexpected or invalid packet:", p))
6506 # from service back to client
6507 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6508 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6509 TCP(sport=local_port, dport=12345))
6510 self.pg0.add_stream(p)
6511 self.pg_enable_capture(self.pg_interfaces)
6513 capture = self.pg1.get_capture(1)
6518 self.assertEqual(ip.src, self.nat_addr)
6519 self.assertEqual(tcp.sport, external_port)
6520 self.assert_packet_checksums_valid(p)
6522 self.logger.error(ppp("Unexpected or invalid packet:", p))
6526 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6527 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6528 ICMP(type=11) / capture[0][IP])
6529 self.pg1.add_stream(p)
6530 self.pg_enable_capture(self.pg_interfaces)
6532 capture = self.pg0.get_capture(1)
6535 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6537 self.assertEqual(inner.src, self.pg0.remote_ip4)
6538 self.assertEqual(inner[TCPerror].sport, local_port)
6540 self.logger.error(ppp("Unexpected or invalid packet:", p))
6543 # from client to server (no translation)
6544 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6545 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6546 TCP(sport=12346, dport=local_port))
6547 self.pg1.add_stream(p)
6548 self.pg_enable_capture(self.pg_interfaces)
6550 capture = self.pg0.get_capture(1)
6555 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6556 self.assertEqual(tcp.dport, local_port)
6557 self.assert_packet_checksums_valid(p)
6559 self.logger.error(ppp("Unexpected or invalid packet:", p))
6562 # from service back to client (no translation)
6563 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6564 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6565 TCP(sport=local_port, dport=12346))
6566 self.pg0.add_stream(p)
6567 self.pg_enable_capture(self.pg_interfaces)
6569 capture = self.pg1.get_capture(1)
6574 self.assertEqual(ip.src, self.pg0.remote_ip4)
6575 self.assertEqual(tcp.sport, local_port)
6576 self.assert_packet_checksums_valid(p)
6578 self.logger.error(ppp("Unexpected or invalid packet:", p))
6581 def test_output_feature(self):
6582 """ NAT44 interface output feature (in2out postrouting) """
6583 self.vapi.nat44_forwarding_enable_disable(enable=1)
6584 self.nat44_add_address(self.nat_addr)
6585 self.vapi.nat44_interface_add_del_feature(
6586 sw_if_index=self.pg0.sw_if_index,
6588 self.vapi.nat44_interface_add_del_output_feature(
6590 sw_if_index=self.pg1.sw_if_index)
6593 pkts = self.create_stream_in(self.pg0, self.pg1)
6594 self.pg0.add_stream(pkts)
6595 self.pg_enable_capture(self.pg_interfaces)
6597 capture = self.pg1.get_capture(len(pkts))
6598 self.verify_capture_out(capture)
6601 pkts = self.create_stream_out(self.pg1)
6602 self.pg1.add_stream(pkts)
6603 self.pg_enable_capture(self.pg_interfaces)
6605 capture = self.pg0.get_capture(len(pkts))
6606 self.verify_capture_in(capture, self.pg0)
6608 def test_output_feature_stateful_acl(self):
6609 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6610 self.nat44_add_address(self.nat_addr)
6611 self.vapi.nat44_interface_add_del_output_feature(
6612 sw_if_index=self.pg0.sw_if_index,
6613 flags=self.config_flags.NAT_IS_INSIDE,
6615 self.vapi.nat44_interface_add_del_output_feature(
6616 sw_if_index=self.pg1.sw_if_index,
6617 flags=self.config_flags.NAT_IS_OUTSIDE,
6620 # First ensure that the NAT is working sans ACL
6622 # send packets out2in, no sessions yet so packets should drop
6623 pkts_out2in = self.create_stream_out(self.pg1)
6624 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6626 # send packets into inside intf, ensure received via outside intf
6627 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6628 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6630 self.verify_capture_out(capture)
6632 # send out2in again, with sessions created it should work now
6633 pkts_out2in = self.create_stream_out(self.pg1)
6634 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6636 self.verify_capture_in(capture, self.pg0)
6638 # Create an ACL blocking everything
6639 out2in_deny_rule = AclRule(is_permit=0)
6640 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6641 out2in_acl.add_vpp_config()
6643 # create an ACL to permit/reflect everything
6644 in2out_reflect_rule = AclRule(is_permit=2)
6645 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6646 in2out_acl.add_vpp_config()
6648 # apply as input acl on interface and confirm it blocks everything
6649 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6650 n_input=1, acls=[out2in_acl])
6651 acl_if.add_vpp_config()
6652 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6655 acl_if.acls = [out2in_acl, in2out_acl]
6656 acl_if.add_vpp_config()
6657 # send in2out to generate ACL state (NAT state was created earlier)
6658 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6660 self.verify_capture_out(capture)
6662 # send out2in again. ACL state exists so it should work now.
6663 # TCP packets with the syn flag set also need the ack flag
6664 for p in pkts_out2in:
6665 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6666 p[TCP].flags |= 0x10
6667 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6669 self.verify_capture_in(capture, self.pg0)
6670 self.logger.info(self.vapi.cli("show trace"))
6672 def test_multiple_vrf(self):
6673 """ Multiple VRF setup """
6674 external_addr = '1.2.3.4'
6679 self.vapi.nat44_forwarding_enable_disable(enable=1)
6680 self.nat44_add_address(self.nat_addr)
6681 flags = self.config_flags.NAT_IS_INSIDE
6682 self.vapi.nat44_interface_add_del_feature(
6683 sw_if_index=self.pg0.sw_if_index,
6685 self.vapi.nat44_interface_add_del_feature(
6686 sw_if_index=self.pg0.sw_if_index,
6687 flags=flags, is_add=1)
6688 self.vapi.nat44_interface_add_del_output_feature(
6690 sw_if_index=self.pg1.sw_if_index)
6691 self.vapi.nat44_interface_add_del_feature(
6692 sw_if_index=self.pg5.sw_if_index,
6694 self.vapi.nat44_interface_add_del_feature(
6695 sw_if_index=self.pg5.sw_if_index,
6696 flags=flags, is_add=1)
6697 self.vapi.nat44_interface_add_del_feature(
6698 sw_if_index=self.pg6.sw_if_index,
6700 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6701 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6702 local_port, external_port, vrf_id=1,
6703 proto=IP_PROTOS.tcp, flags=flags)
6704 self.nat44_add_static_mapping(
6705 self.pg0.remote_ip4,
6706 external_sw_if_index=self.pg0.sw_if_index,
6707 local_port=local_port,
6709 external_port=external_port,
6710 proto=IP_PROTOS.tcp,
6714 # from client to service (both VRF1)
6715 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6716 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6717 TCP(sport=12345, dport=external_port))
6718 self.pg6.add_stream(p)
6719 self.pg_enable_capture(self.pg_interfaces)
6721 capture = self.pg5.get_capture(1)
6726 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6727 self.assertEqual(tcp.dport, local_port)
6728 self.assert_packet_checksums_valid(p)
6730 self.logger.error(ppp("Unexpected or invalid packet:", p))
6733 # from service back to client (both VRF1)
6734 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6735 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6736 TCP(sport=local_port, dport=12345))
6737 self.pg5.add_stream(p)
6738 self.pg_enable_capture(self.pg_interfaces)
6740 capture = self.pg6.get_capture(1)
6745 self.assertEqual(ip.src, external_addr)
6746 self.assertEqual(tcp.sport, external_port)
6747 self.assert_packet_checksums_valid(p)
6749 self.logger.error(ppp("Unexpected or invalid packet:", p))
6752 # dynamic NAT from VRF1 to VRF0 (output-feature)
6753 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6754 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6755 TCP(sport=2345, dport=22))
6756 self.pg5.add_stream(p)
6757 self.pg_enable_capture(self.pg_interfaces)
6759 capture = self.pg1.get_capture(1)
6764 self.assertEqual(ip.src, self.nat_addr)
6765 self.assertNotEqual(tcp.sport, 2345)
6766 self.assert_packet_checksums_valid(p)
6769 self.logger.error(ppp("Unexpected or invalid packet:", p))
6772 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6773 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6774 TCP(sport=22, dport=port))
6775 self.pg1.add_stream(p)
6776 self.pg_enable_capture(self.pg_interfaces)
6778 capture = self.pg5.get_capture(1)
6783 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6784 self.assertEqual(tcp.dport, 2345)
6785 self.assert_packet_checksums_valid(p)
6787 self.logger.error(ppp("Unexpected or invalid packet:", p))
6790 # from client VRF1 to service VRF0
6791 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6792 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6793 TCP(sport=12346, dport=external_port))
6794 self.pg6.add_stream(p)
6795 self.pg_enable_capture(self.pg_interfaces)
6797 capture = self.pg0.get_capture(1)
6802 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6803 self.assertEqual(tcp.dport, local_port)
6804 self.assert_packet_checksums_valid(p)
6806 self.logger.error(ppp("Unexpected or invalid packet:", p))
6809 # from service VRF0 back to client VRF1
6810 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6811 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6812 TCP(sport=local_port, dport=12346))
6813 self.pg0.add_stream(p)
6814 self.pg_enable_capture(self.pg_interfaces)
6816 capture = self.pg6.get_capture(1)
6821 self.assertEqual(ip.src, self.pg0.local_ip4)
6822 self.assertEqual(tcp.sport, external_port)
6823 self.assert_packet_checksums_valid(p)
6825 self.logger.error(ppp("Unexpected or invalid packet:", p))
6828 # from client VRF0 to service VRF1
6829 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6830 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6831 TCP(sport=12347, dport=external_port))
6832 self.pg0.add_stream(p)
6833 self.pg_enable_capture(self.pg_interfaces)
6835 capture = self.pg5.get_capture(1)
6840 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6841 self.assertEqual(tcp.dport, local_port)
6842 self.assert_packet_checksums_valid(p)
6844 self.logger.error(ppp("Unexpected or invalid packet:", p))
6847 # from service VRF1 back to client VRF0
6848 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6849 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6850 TCP(sport=local_port, dport=12347))
6851 self.pg5.add_stream(p)
6852 self.pg_enable_capture(self.pg_interfaces)
6854 capture = self.pg0.get_capture(1)
6859 self.assertEqual(ip.src, external_addr)
6860 self.assertEqual(tcp.sport, external_port)
6861 self.assert_packet_checksums_valid(p)
6863 self.logger.error(ppp("Unexpected or invalid packet:", p))
6866 # from client to server (both VRF1, no translation)
6867 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6868 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6869 TCP(sport=12348, dport=local_port))
6870 self.pg6.add_stream(p)
6871 self.pg_enable_capture(self.pg_interfaces)
6873 capture = self.pg5.get_capture(1)
6878 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6879 self.assertEqual(tcp.dport, local_port)
6880 self.assert_packet_checksums_valid(p)
6882 self.logger.error(ppp("Unexpected or invalid packet:", p))
6885 # from server back to client (both VRF1, no translation)
6886 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6887 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6888 TCP(sport=local_port, dport=12348))
6889 self.pg5.add_stream(p)
6890 self.pg_enable_capture(self.pg_interfaces)
6892 capture = self.pg6.get_capture(1)
6897 self.assertEqual(ip.src, self.pg5.remote_ip4)
6898 self.assertEqual(tcp.sport, local_port)
6899 self.assert_packet_checksums_valid(p)
6901 self.logger.error(ppp("Unexpected or invalid packet:", p))
6904 # from client VRF1 to server VRF0 (no translation)
6905 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6906 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6907 TCP(sport=local_port, dport=12349))
6908 self.pg0.add_stream(p)
6909 self.pg_enable_capture(self.pg_interfaces)
6911 capture = self.pg6.get_capture(1)
6916 self.assertEqual(ip.src, self.pg0.remote_ip4)
6917 self.assertEqual(tcp.sport, local_port)
6918 self.assert_packet_checksums_valid(p)
6920 self.logger.error(ppp("Unexpected or invalid packet:", p))
6923 # from server VRF0 back to client VRF1 (no translation)
6924 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6925 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6926 TCP(sport=local_port, dport=12349))
6927 self.pg0.add_stream(p)
6928 self.pg_enable_capture(self.pg_interfaces)
6930 capture = self.pg6.get_capture(1)
6935 self.assertEqual(ip.src, self.pg0.remote_ip4)
6936 self.assertEqual(tcp.sport, local_port)
6937 self.assert_packet_checksums_valid(p)
6939 self.logger.error(ppp("Unexpected or invalid packet:", p))
6942 # from client VRF0 to server VRF1 (no translation)
6943 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6944 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6945 TCP(sport=12344, dport=local_port))
6946 self.pg0.add_stream(p)
6947 self.pg_enable_capture(self.pg_interfaces)
6949 capture = self.pg5.get_capture(1)
6954 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6955 self.assertEqual(tcp.dport, local_port)
6956 self.assert_packet_checksums_valid(p)
6958 self.logger.error(ppp("Unexpected or invalid packet:", p))
6961 # from server VRF1 back to client VRF0 (no translation)
6962 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6963 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6964 TCP(sport=local_port, dport=12344))
6965 self.pg5.add_stream(p)
6966 self.pg_enable_capture(self.pg_interfaces)
6968 capture = self.pg0.get_capture(1)
6973 self.assertEqual(ip.src, self.pg5.remote_ip4)
6974 self.assertEqual(tcp.sport, local_port)
6975 self.assert_packet_checksums_valid(p)
6977 self.logger.error(ppp("Unexpected or invalid packet:", p))
6980 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6981 def test_session_timeout(self):
6982 """ NAT44 session timeouts """
6983 self.nat44_add_address(self.nat_addr)
6984 flags = self.config_flags.NAT_IS_INSIDE
6985 self.vapi.nat44_interface_add_del_feature(
6986 sw_if_index=self.pg0.sw_if_index,
6987 flags=flags, is_add=1)
6988 self.vapi.nat44_interface_add_del_feature(
6989 sw_if_index=self.pg1.sw_if_index,
6991 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6992 tcp_transitory=240, icmp=5)
6996 for i in range(0, max_sessions):
6997 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6998 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6999 IP(src=src, dst=self.pg1.remote_ip4) /
7000 ICMP(id=1025, type='echo-request'))
7002 self.pg0.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7005 self.pg1.get_capture(max_sessions)
7010 for i in range(0, max_sessions):
7011 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7012 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7013 IP(src=src, dst=self.pg1.remote_ip4) /
7014 ICMP(id=1026, type='echo-request'))
7016 self.pg0.add_stream(pkts)
7017 self.pg_enable_capture(self.pg_interfaces)
7019 self.pg1.get_capture(max_sessions)
7022 users = self.vapi.nat44_user_dump()
7024 nsessions = nsessions + user.nsessions
7025 self.assertLess(nsessions, 2 * max_sessions)
7027 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7028 def test_session_rst_timeout(self):
7029 """ NAT44 session RST timeouts """
7030 self.nat44_add_address(self.nat_addr)
7031 flags = self.config_flags.NAT_IS_INSIDE
7032 self.vapi.nat44_interface_add_del_feature(
7033 sw_if_index=self.pg0.sw_if_index,
7034 flags=flags, is_add=1)
7035 self.vapi.nat44_interface_add_del_feature(
7036 sw_if_index=self.pg1.sw_if_index,
7038 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7039 tcp_transitory=5, icmp=60)
7041 self.initiate_tcp_session(self.pg0, self.pg1)
7042 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7043 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7044 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7046 self.pg0.add_stream(p)
7047 self.pg_enable_capture(self.pg_interfaces)
7049 self.pg1.get_capture(1)
7053 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7054 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7055 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
7057 self.pg0.add_stream(p)
7058 self.pg_enable_capture(self.pg_interfaces)
7060 self.pg1.get_capture(1)
7062 def test_syslog_sess(self):
7063 """ Test syslog session creation and deletion """
7064 self.vapi.syslog_set_filter(
7065 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
7066 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
7067 self.nat44_add_address(self.nat_addr)
7068 flags = self.config_flags.NAT_IS_INSIDE
7069 self.vapi.nat44_interface_add_del_feature(
7070 sw_if_index=self.pg0.sw_if_index,
7071 flags=flags, is_add=1)
7072 self.vapi.nat44_interface_add_del_feature(
7073 sw_if_index=self.pg1.sw_if_index,
7076 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7077 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7078 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7079 self.pg0.add_stream(p)
7080 self.pg_enable_capture(self.pg_interfaces)
7082 capture = self.pg1.get_capture(1)
7083 self.tcp_port_out = capture[0][TCP].sport
7084 capture = self.pg2.get_capture(1)
7085 self.verify_syslog_sess(capture[0][Raw].load)
7087 self.pg_enable_capture(self.pg_interfaces)
7089 self.nat44_add_address(self.nat_addr, is_add=0)
7090 capture = self.pg2.get_capture(1)
7091 self.verify_syslog_sess(capture[0][Raw].load, False)
7093 def test_ed_users_dump(self):
7094 """ API test - nat44_user_dump """
7095 flags = self.config_flags.NAT_IS_INSIDE
7096 self.vapi.nat44_interface_add_del_feature(
7097 sw_if_index=self.pg0.sw_if_index,
7098 flags=flags, is_add=1)
7099 self.vapi.nat44_interface_add_del_feature(
7100 sw_if_index=self.pg1.sw_if_index,
7102 self.vapi.nat44_forwarding_enable_disable(enable=1)
7104 real_ip = self.pg0.remote_ip4
7105 alias_ip = self.nat_addr
7106 flags = self.config_flags.NAT_IS_ADDR_ONLY
7107 self.vapi.nat44_add_del_static_mapping(is_add=1,
7108 local_ip_address=real_ip,
7109 external_ip_address=alias_ip,
7110 external_sw_if_index=0xFFFFFFFF,
7113 users = self.vapi.nat44_user_dump()
7114 self.assertEqual(len(users), 0)
7116 # in2out - static mapping match
7118 pkts = self.create_stream_out(self.pg1)
7119 self.pg1.add_stream(pkts)
7120 self.pg_enable_capture(self.pg_interfaces)
7122 capture = self.pg0.get_capture(len(pkts))
7123 self.verify_capture_in(capture, self.pg0)
7125 pkts = self.create_stream_in(self.pg0, self.pg1)
7126 self.pg0.add_stream(pkts)
7127 self.pg_enable_capture(self.pg_interfaces)
7129 capture = self.pg1.get_capture(len(pkts))
7130 self.verify_capture_out(capture, same_port=True)
7132 users = self.vapi.nat44_user_dump()
7133 self.assertEqual(len(users), 1)
7134 static_user = users[0]
7135 self.assertEqual(static_user.nstaticsessions, 3)
7136 self.assertEqual(static_user.nsessions, 0)
7138 # in2out - no static mapping match
7140 host0 = self.pg0.remote_hosts[0]
7141 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
7143 pkts = self.create_stream_out(self.pg1,
7144 dst_ip=self.pg0.remote_ip4,
7145 use_inside_ports=True)
7146 self.pg1.add_stream(pkts)
7147 self.pg_enable_capture(self.pg_interfaces)
7149 capture = self.pg0.get_capture(len(pkts))
7150 self.verify_capture_in(capture, self.pg0)
7152 pkts = self.create_stream_in(self.pg0, self.pg1)
7153 self.pg0.add_stream(pkts)
7154 self.pg_enable_capture(self.pg_interfaces)
7156 capture = self.pg1.get_capture(len(pkts))
7157 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7160 self.pg0.remote_hosts[0] = host0
7162 users = self.vapi.nat44_user_dump()
7163 self.assertEqual(len(users), 2)
7164 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7165 non_static_user = users[1]
7166 static_user = users[0]
7168 non_static_user = users[0]
7169 static_user = users[1]
7170 self.assertEqual(static_user.nstaticsessions, 3)
7171 self.assertEqual(static_user.nsessions, 0)
7172 self.assertEqual(non_static_user.nstaticsessions, 0)
7173 self.assertEqual(non_static_user.nsessions, 3)
7175 users = self.vapi.nat44_user_dump()
7176 self.assertEqual(len(users), 2)
7177 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7178 non_static_user = users[1]
7179 static_user = users[0]
7181 non_static_user = users[0]
7182 static_user = users[1]
7183 self.assertEqual(static_user.nstaticsessions, 3)
7184 self.assertEqual(static_user.nsessions, 0)
7185 self.assertEqual(non_static_user.nstaticsessions, 0)
7186 self.assertEqual(non_static_user.nsessions, 3)
7189 self.vapi.nat44_forwarding_enable_disable(enable=0)
7190 flags = self.config_flags.NAT_IS_ADDR_ONLY
7191 self.vapi.nat44_add_del_static_mapping(
7193 local_ip_address=real_ip,
7194 external_ip_address=alias_ip,
7195 external_sw_if_index=0xFFFFFFFF,
7199 super(TestNAT44EndpointDependent, self).tearDown()
7200 if not self.vpp_dead:
7202 self.vapi.cli("clear logging")
7204 def show_commands_at_teardown(self):
7205 self.logger.info(self.vapi.cli("show nat44 addresses"))
7206 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7207 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7208 self.logger.info(self.vapi.cli("show nat44 interface address"))
7209 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7210 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7211 self.logger.info(self.vapi.cli("show nat timeouts"))
7214 class TestNAT44EndpointDependent2(MethodHolder):
7215 """ Endpoint-Dependent mapping and filtering extra test cases """
7217 translation_buckets = 5
7220 def setUpConstants(cls):
7221 super(TestNAT44EndpointDependent2, cls).setUpConstants()
7222 cls.vpp_cmdline.extend([
7223 "nat", "{", "endpoint-dependent",
7224 "translation hash buckets %d" % cls.translation_buckets,
7229 def setUpClass(cls):
7230 super(TestNAT44EndpointDependent2, cls).setUpClass()
7231 cls.vapi.cli("set log class nat level debug")
7233 cls.nat_addr = '10.0.0.3'
7235 cls.create_pg_interfaces(range(2))
7237 for i in cls.pg_interfaces:
7243 super(TestNAT44EndpointDependent2, self).setUp()
7244 self.vapi.nat_set_timeouts(
7245 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7246 self.nat44_add_address(self.nat_addr)
7247 flags = self.config_flags.NAT_IS_INSIDE
7248 self.vapi.nat44_interface_add_del_feature(
7249 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7250 self.vapi.nat44_interface_add_del_feature(
7251 sw_if_index=self.pg1.sw_if_index, is_add=1)
7254 def tearDownClass(cls):
7255 super(TestNAT44EndpointDependent2, cls).tearDownClass()
7257 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7258 # SYN packet in->out
7259 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7260 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7261 TCP(sport=sport, dport=ext_dport, flags="S"))
7263 self.pg_enable_capture(self.pg_interfaces)
7265 capture = out_if.get_capture(1)
7267 tcp_port_out = p[TCP].sport
7269 # SYN + ACK packet out->in
7270 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7271 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7272 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7273 out_if.add_stream(p)
7274 self.pg_enable_capture(self.pg_interfaces)
7276 in_if.get_capture(1)
7278 # ACK packet in->out
7279 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7280 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7281 TCP(sport=sport, dport=ext_dport, flags="A"))
7283 self.pg_enable_capture(self.pg_interfaces)
7285 out_if.get_capture(1)
7289 def test_lru_cleanup(self):
7290 """ LRU cleanup algorithm """
7291 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7292 max_translations = 10 * self.translation_buckets
7294 for i in range(0, max_translations - 1):
7295 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7296 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7297 UDP(sport=7000+i, dport=80))
7300 self.pg0.add_stream(pkts)
7301 self.pg_enable_capture(self.pg_interfaces)
7303 self.pg1.get_capture(len(pkts))
7304 self.sleep(1.5, "wait for timeouts")
7307 for i in range(0, max_translations - 1):
7308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7309 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7310 ICMP(id=8000+i, type='echo-request'))
7313 self.pg0.add_stream(pkts)
7314 self.pg_enable_capture(self.pg_interfaces)
7316 self.pg1.get_capture(len(pkts))
7319 class TestNAT44Out2InDPO(MethodHolder):
7320 """ NAT44 Test Cases using out2in DPO """
7323 def setUpConstants(cls):
7324 super(TestNAT44Out2InDPO, cls).setUpConstants()
7325 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7328 def setUpClass(cls):
7329 super(TestNAT44Out2InDPO, cls).setUpClass()
7330 cls.vapi.cli("set log class nat level debug")
7332 cls.tcp_port_in = 6303
7333 cls.tcp_port_out = 6303
7334 cls.udp_port_in = 6304
7335 cls.udp_port_out = 6304
7336 cls.icmp_id_in = 6305
7337 cls.icmp_id_out = 6305
7338 cls.nat_addr = '10.0.0.3'
7339 cls.dst_ip4 = '192.168.70.1'
7341 cls.create_pg_interfaces(range(2))
7344 cls.pg0.config_ip4()
7345 cls.pg0.resolve_arp()
7348 cls.pg1.config_ip6()
7349 cls.pg1.resolve_ndp()
7351 r1 = VppIpRoute(cls, "::", 0,
7352 [VppRoutePath(cls.pg1.remote_ip6,
7353 cls.pg1.sw_if_index)],
7358 def tearDownClass(cls):
7359 super(TestNAT44Out2InDPO, cls).tearDownClass()
7361 def configure_xlat(self):
7362 self.dst_ip6_pfx = '1:2:3::'
7363 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7365 self.dst_ip6_pfx_len = 96
7366 self.src_ip6_pfx = '4:5:6::'
7367 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7369 self.src_ip6_pfx_len = 96
7370 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7371 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7372 '\x00\x00\x00\x00', 0)
7374 @unittest.skip('Temporary disabled')
7375 def test_464xlat_ce(self):
7376 """ Test 464XLAT CE with NAT44 """
7378 nat_config = self.vapi.nat_show_config()
7379 self.assertEqual(1, nat_config.out2in_dpo)
7381 self.configure_xlat()
7383 flags = self.config_flags.NAT_IS_INSIDE
7384 self.vapi.nat44_interface_add_del_feature(
7385 sw_if_index=self.pg0.sw_if_index,
7386 flags=flags, is_add=1)
7387 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7388 last_ip_address=self.nat_addr_n,
7389 vrf_id=0xFFFFFFFF, is_add=1)
7391 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7392 self.dst_ip6_pfx_len)
7393 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7394 self.src_ip6_pfx_len)
7397 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7398 self.pg0.add_stream(pkts)
7399 self.pg_enable_capture(self.pg_interfaces)
7401 capture = self.pg1.get_capture(len(pkts))
7402 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7405 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7407 self.pg1.add_stream(pkts)
7408 self.pg_enable_capture(self.pg_interfaces)
7410 capture = self.pg0.get_capture(len(pkts))
7411 self.verify_capture_in(capture, self.pg0)
7413 self.vapi.nat44_interface_add_del_feature(
7414 sw_if_index=self.pg0.sw_if_index,
7416 self.vapi.nat44_add_del_address_range(
7417 first_ip_address=self.nat_addr_n,
7418 last_ip_address=self.nat_addr_n,
7421 @unittest.skip('Temporary disabled')
7422 def test_464xlat_ce_no_nat(self):
7423 """ Test 464XLAT CE without NAT44 """
7425 self.configure_xlat()
7427 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7428 self.dst_ip6_pfx_len)
7429 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7430 self.src_ip6_pfx_len)
7432 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7433 self.pg0.add_stream(pkts)
7434 self.pg_enable_capture(self.pg_interfaces)
7436 capture = self.pg1.get_capture(len(pkts))
7437 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7438 nat_ip=out_dst_ip6, same_port=True)
7440 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7441 self.pg1.add_stream(pkts)
7442 self.pg_enable_capture(self.pg_interfaces)
7444 capture = self.pg0.get_capture(len(pkts))
7445 self.verify_capture_in(capture, self.pg0)
7448 class TestDeterministicNAT(MethodHolder):
7449 """ Deterministic NAT Test Cases """
7452 def setUpConstants(cls):
7453 super(TestDeterministicNAT, cls).setUpConstants()
7454 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7457 def setUpClass(cls):
7458 super(TestDeterministicNAT, cls).setUpClass()
7459 cls.vapi.cli("set log class nat level debug")
7461 cls.tcp_port_in = 6303
7462 cls.tcp_external_port = 6303
7463 cls.udp_port_in = 6304
7464 cls.udp_external_port = 6304
7465 cls.icmp_id_in = 6305
7466 cls.nat_addr = '10.0.0.3'
7468 cls.create_pg_interfaces(range(3))
7469 cls.interfaces = list(cls.pg_interfaces)
7471 for i in cls.interfaces:
7476 cls.pg0.generate_remote_hosts(2)
7477 cls.pg0.configure_ipv4_neighbors()
7480 def tearDownClass(cls):
7481 super(TestDeterministicNAT, cls).tearDownClass()
7483 def create_stream_in(self, in_if, out_if, ttl=64):
7485 Create packet stream for inside network
7487 :param in_if: Inside interface
7488 :param out_if: Outside interface
7489 :param ttl: TTL of generated packets
7493 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7494 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7495 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7499 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7500 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7501 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7505 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7506 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7507 ICMP(id=self.icmp_id_in, type='echo-request'))
7512 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7514 Create packet stream for outside network
7516 :param out_if: Outside interface
7517 :param dst_ip: Destination IP address (Default use global NAT address)
7518 :param ttl: TTL of generated packets
7521 dst_ip = self.nat_addr
7524 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7525 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7526 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7530 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7531 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7532 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7536 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7537 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7538 ICMP(id=self.icmp_external_id, type='echo-reply'))
7543 def verify_capture_out(self, capture, nat_ip=None):
7545 Verify captured packets on outside network
7547 :param capture: Captured packets
7548 :param nat_ip: Translated IP address (Default use global NAT address)
7549 :param same_port: Source port number is not translated (Default False)
7552 nat_ip = self.nat_addr
7553 for packet in capture:
7555 self.assertEqual(packet[IP].src, nat_ip)
7556 if packet.haslayer(TCP):
7557 self.tcp_port_out = packet[TCP].sport
7558 elif packet.haslayer(UDP):
7559 self.udp_port_out = packet[UDP].sport
7561 self.icmp_external_id = packet[ICMP].id
7563 self.logger.error(ppp("Unexpected or invalid packet "
7564 "(outside network):", packet))
7567 def test_deterministic_mode(self):
7568 """ NAT plugin run deterministic mode """
7569 in_addr = '172.16.255.0'
7570 out_addr = '172.17.255.50'
7571 in_addr_t = '172.16.255.20'
7575 nat_config = self.vapi.nat_show_config()
7576 self.assertEqual(1, nat_config.deterministic)
7578 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7579 in_plen=in_plen, out_addr=out_addr,
7582 rep1 = self.vapi.nat_det_forward(in_addr_t)
7583 self.assertEqual(str(rep1.out_addr), out_addr)
7584 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7586 self.assertEqual(str(rep2.in_addr), in_addr_t)
7588 deterministic_mappings = self.vapi.nat_det_map_dump()
7589 self.assertEqual(len(deterministic_mappings), 1)
7590 dsm = deterministic_mappings[0]
7591 self.assertEqual(in_addr, str(dsm.in_addr))
7592 self.assertEqual(in_plen, dsm.in_plen)
7593 self.assertEqual(out_addr, str(dsm.out_addr))
7594 self.assertEqual(out_plen, dsm.out_plen)
7596 self.clear_nat_det()
7597 deterministic_mappings = self.vapi.nat_det_map_dump()
7598 self.assertEqual(len(deterministic_mappings), 0)
7600 def test_set_timeouts(self):
7601 """ Set deterministic NAT timeouts """
7602 timeouts_before = self.vapi.nat_get_timeouts()
7604 self.vapi.nat_set_timeouts(
7605 udp=timeouts_before.udp + 10,
7606 tcp_established=timeouts_before.tcp_established + 10,
7607 tcp_transitory=timeouts_before.tcp_transitory + 10,
7608 icmp=timeouts_before.icmp + 10)
7610 timeouts_after = self.vapi.nat_get_timeouts()
7612 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7613 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7614 self.assertNotEqual(timeouts_before.tcp_established,
7615 timeouts_after.tcp_established)
7616 self.assertNotEqual(timeouts_before.tcp_transitory,
7617 timeouts_after.tcp_transitory)
7619 def test_det_in(self):
7620 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7622 nat_ip = "10.0.0.10"
7624 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7626 out_addr=socket.inet_aton(nat_ip),
7629 flags = self.config_flags.NAT_IS_INSIDE
7630 self.vapi.nat44_interface_add_del_feature(
7631 sw_if_index=self.pg0.sw_if_index,
7632 flags=flags, is_add=1)
7633 self.vapi.nat44_interface_add_del_feature(
7634 sw_if_index=self.pg1.sw_if_index,
7638 pkts = self.create_stream_in(self.pg0, self.pg1)
7639 self.pg0.add_stream(pkts)
7640 self.pg_enable_capture(self.pg_interfaces)
7642 capture = self.pg1.get_capture(len(pkts))
7643 self.verify_capture_out(capture, nat_ip)
7646 pkts = self.create_stream_out(self.pg1, nat_ip)
7647 self.pg1.add_stream(pkts)
7648 self.pg_enable_capture(self.pg_interfaces)
7650 capture = self.pg0.get_capture(len(pkts))
7651 self.verify_capture_in(capture, self.pg0)
7654 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7655 self.assertEqual(len(sessions), 3)
7659 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7660 self.assertEqual(s.in_port, self.tcp_port_in)
7661 self.assertEqual(s.out_port, self.tcp_port_out)
7662 self.assertEqual(s.ext_port, self.tcp_external_port)
7666 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7667 self.assertEqual(s.in_port, self.udp_port_in)
7668 self.assertEqual(s.out_port, self.udp_port_out)
7669 self.assertEqual(s.ext_port, self.udp_external_port)
7673 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7674 self.assertEqual(s.in_port, self.icmp_id_in)
7675 self.assertEqual(s.out_port, self.icmp_external_id)
7677 def test_multiple_users(self):
7678 """ Deterministic NAT multiple users """
7680 nat_ip = "10.0.0.10"
7682 external_port = 6303
7684 host0 = self.pg0.remote_hosts[0]
7685 host1 = self.pg0.remote_hosts[1]
7687 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7688 out_addr=socket.inet_aton(nat_ip),
7690 flags = self.config_flags.NAT_IS_INSIDE
7691 self.vapi.nat44_interface_add_del_feature(
7692 sw_if_index=self.pg0.sw_if_index,
7693 flags=flags, is_add=1)
7694 self.vapi.nat44_interface_add_del_feature(
7695 sw_if_index=self.pg1.sw_if_index,
7699 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7700 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7701 TCP(sport=port_in, dport=external_port))
7702 self.pg0.add_stream(p)
7703 self.pg_enable_capture(self.pg_interfaces)
7705 capture = self.pg1.get_capture(1)
7710 self.assertEqual(ip.src, nat_ip)
7711 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7712 self.assertEqual(tcp.dport, external_port)
7713 port_out0 = tcp.sport
7715 self.logger.error(ppp("Unexpected or invalid packet:", p))
7719 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7720 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7721 TCP(sport=port_in, dport=external_port))
7722 self.pg0.add_stream(p)
7723 self.pg_enable_capture(self.pg_interfaces)
7725 capture = self.pg1.get_capture(1)
7730 self.assertEqual(ip.src, nat_ip)
7731 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7732 self.assertEqual(tcp.dport, external_port)
7733 port_out1 = tcp.sport
7735 self.logger.error(ppp("Unexpected or invalid packet:", p))
7738 dms = self.vapi.nat_det_map_dump()
7739 self.assertEqual(1, len(dms))
7740 self.assertEqual(2, dms[0].ses_num)
7743 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7744 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7745 TCP(sport=external_port, dport=port_out0))
7746 self.pg1.add_stream(p)
7747 self.pg_enable_capture(self.pg_interfaces)
7749 capture = self.pg0.get_capture(1)
7754 self.assertEqual(ip.src, self.pg1.remote_ip4)
7755 self.assertEqual(ip.dst, host0.ip4)
7756 self.assertEqual(tcp.dport, port_in)
7757 self.assertEqual(tcp.sport, external_port)
7759 self.logger.error(ppp("Unexpected or invalid packet:", p))
7763 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7764 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7765 TCP(sport=external_port, dport=port_out1))
7766 self.pg1.add_stream(p)
7767 self.pg_enable_capture(self.pg_interfaces)
7769 capture = self.pg0.get_capture(1)
7774 self.assertEqual(ip.src, self.pg1.remote_ip4)
7775 self.assertEqual(ip.dst, host1.ip4)
7776 self.assertEqual(tcp.dport, port_in)
7777 self.assertEqual(tcp.sport, external_port)
7779 self.logger.error(ppp("Unexpected or invalid packet", p))
7782 # session close api test
7783 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7785 self.pg1.remote_ip4,
7787 dms = self.vapi.nat_det_map_dump()
7788 self.assertEqual(dms[0].ses_num, 1)
7790 self.vapi.nat_det_close_session_in(host0.ip4,
7792 self.pg1.remote_ip4,
7794 dms = self.vapi.nat_det_map_dump()
7795 self.assertEqual(dms[0].ses_num, 0)
7797 def test_tcp_session_close_detection_in(self):
7798 """ Deterministic NAT TCP session close from inside network """
7799 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7801 out_addr=socket.inet_aton(self.nat_addr),
7803 flags = self.config_flags.NAT_IS_INSIDE
7804 self.vapi.nat44_interface_add_del_feature(
7805 sw_if_index=self.pg0.sw_if_index,
7806 flags=flags, is_add=1)
7807 self.vapi.nat44_interface_add_del_feature(
7808 sw_if_index=self.pg1.sw_if_index,
7811 self.initiate_tcp_session(self.pg0, self.pg1)
7813 # close the session from inside
7815 # FIN packet in -> out
7816 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7817 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7818 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7820 self.pg0.add_stream(p)
7821 self.pg_enable_capture(self.pg_interfaces)
7823 self.pg1.get_capture(1)
7827 # ACK packet out -> in
7828 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7829 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7830 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7834 # FIN packet out -> in
7835 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7836 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7837 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7841 self.pg1.add_stream(pkts)
7842 self.pg_enable_capture(self.pg_interfaces)
7844 self.pg0.get_capture(2)
7846 # ACK packet in -> out
7847 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7848 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7849 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7851 self.pg0.add_stream(p)
7852 self.pg_enable_capture(self.pg_interfaces)
7854 self.pg1.get_capture(1)
7856 # Check if deterministic NAT44 closed the session
7857 dms = self.vapi.nat_det_map_dump()
7858 self.assertEqual(0, dms[0].ses_num)
7860 self.logger.error("TCP session termination failed")
7863 def test_tcp_session_close_detection_out(self):
7864 """ Deterministic NAT TCP session close from outside network """
7865 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7867 out_addr=socket.inet_aton(self.nat_addr),
7869 flags = self.config_flags.NAT_IS_INSIDE
7870 self.vapi.nat44_interface_add_del_feature(
7871 sw_if_index=self.pg0.sw_if_index,
7872 flags=flags, is_add=1)
7873 self.vapi.nat44_interface_add_del_feature(
7874 sw_if_index=self.pg1.sw_if_index,
7877 self.initiate_tcp_session(self.pg0, self.pg1)
7879 # close the session from outside
7881 # FIN packet out -> in
7882 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7883 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7884 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7886 self.pg1.add_stream(p)
7887 self.pg_enable_capture(self.pg_interfaces)
7889 self.pg0.get_capture(1)
7893 # ACK packet in -> out
7894 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7895 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7896 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7900 # ACK packet in -> out
7901 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7902 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7903 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7907 self.pg0.add_stream(pkts)
7908 self.pg_enable_capture(self.pg_interfaces)
7910 self.pg1.get_capture(2)
7912 # ACK packet out -> in
7913 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7914 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7915 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7917 self.pg1.add_stream(p)
7918 self.pg_enable_capture(self.pg_interfaces)
7920 self.pg0.get_capture(1)
7922 # Check if deterministic NAT44 closed the session
7923 dms = self.vapi.nat_det_map_dump()
7924 self.assertEqual(0, dms[0].ses_num)
7926 self.logger.error("TCP session termination failed")
7929 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7930 def test_session_timeout(self):
7931 """ Deterministic NAT session timeouts """
7932 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7934 out_addr=socket.inet_aton(self.nat_addr),
7936 flags = self.config_flags.NAT_IS_INSIDE
7937 self.vapi.nat44_interface_add_del_feature(
7938 sw_if_index=self.pg0.sw_if_index,
7939 flags=flags, is_add=1)
7940 self.vapi.nat44_interface_add_del_feature(
7941 sw_if_index=self.pg1.sw_if_index,
7944 self.initiate_tcp_session(self.pg0, self.pg1)
7945 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7947 pkts = self.create_stream_in(self.pg0, self.pg1)
7948 self.pg0.add_stream(pkts)
7949 self.pg_enable_capture(self.pg_interfaces)
7951 capture = self.pg1.get_capture(len(pkts))
7954 dms = self.vapi.nat_det_map_dump()
7955 self.assertEqual(0, dms[0].ses_num)
7957 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7958 def test_session_limit_per_user(self):
7959 """ Deterministic NAT maximum sessions per user limit """
7960 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7962 out_addr=socket.inet_aton(self.nat_addr),
7964 flags = self.config_flags.NAT_IS_INSIDE
7965 self.vapi.nat44_interface_add_del_feature(
7966 sw_if_index=self.pg0.sw_if_index,
7967 flags=flags, is_add=1)
7968 self.vapi.nat44_interface_add_del_feature(
7969 sw_if_index=self.pg1.sw_if_index,
7971 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7972 src_address=self.pg2.local_ip4,
7974 template_interval=10)
7975 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7979 for port in range(1025, 2025):
7980 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7981 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7982 UDP(sport=port, dport=port))
7985 self.pg0.add_stream(pkts)
7986 self.pg_enable_capture(self.pg_interfaces)
7988 capture = self.pg1.get_capture(len(pkts))
7990 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7991 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7992 UDP(sport=3001, dport=3002))
7993 self.pg0.add_stream(p)
7994 self.pg_enable_capture(self.pg_interfaces)
7996 capture = self.pg1.assert_nothing_captured()
7998 # verify ICMP error packet
7999 capture = self.pg0.get_capture(1)
8001 self.assertTrue(p.haslayer(ICMP))
8003 self.assertEqual(icmp.type, 3)
8004 self.assertEqual(icmp.code, 1)
8005 self.assertTrue(icmp.haslayer(IPerror))
8006 inner_ip = icmp[IPerror]
8007 self.assertEqual(inner_ip[UDPerror].sport, 3001)
8008 self.assertEqual(inner_ip[UDPerror].dport, 3002)
8010 dms = self.vapi.nat_det_map_dump()
8012 self.assertEqual(1000, dms[0].ses_num)
8014 # verify IPFIX logging
8015 self.vapi.ipfix_flush()
8017 capture = self.pg2.get_capture(2)
8018 ipfix = IPFIXDecoder()
8019 # first load template
8021 self.assertTrue(p.haslayer(IPFIX))
8022 if p.haslayer(Template):
8023 ipfix.add_template(p.getlayer(Template))
8024 # verify events in data set
8026 if p.haslayer(Data):
8027 data = ipfix.decode_data_set(p.getlayer(Set))
8028 self.verify_ipfix_max_entries_per_user(data,
8030 self.pg0.remote_ip4)
8032 def clear_nat_det(self):
8034 Clear deterministic NAT configuration.
8036 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
8038 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8039 tcp_transitory=240, icmp=60)
8040 deterministic_mappings = self.vapi.nat_det_map_dump()
8041 for dsm in deterministic_mappings:
8042 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
8043 in_plen=dsm.in_plen,
8044 out_addr=dsm.out_addr,
8045 out_plen=dsm.out_plen)
8047 interfaces = self.vapi.nat44_interface_dump()
8048 for intf in interfaces:
8049 self.vapi.nat44_interface_add_del_feature(
8050 sw_if_index=intf.sw_if_index,
8054 super(TestDeterministicNAT, self).tearDown()
8055 if not self.vpp_dead:
8056 self.clear_nat_det()
8058 def show_commands_at_teardown(self):
8059 self.logger.info(self.vapi.cli("show nat44 interfaces"))
8060 self.logger.info(self.vapi.cli("show nat timeouts"))
8062 self.vapi.cli("show nat44 deterministic mappings"))
8064 self.vapi.cli("show nat44 deterministic sessions"))
8067 class TestNAT64(MethodHolder):
8068 """ NAT64 Test Cases """
8071 def setUpConstants(cls):
8072 super(TestNAT64, cls).setUpConstants()
8073 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
8074 "nat64 st hash buckets 256", "}"])
8077 def setUpClass(cls):
8078 super(TestNAT64, cls).setUpClass()
8080 cls.tcp_port_in = 6303
8081 cls.tcp_port_out = 6303
8082 cls.udp_port_in = 6304
8083 cls.udp_port_out = 6304
8084 cls.icmp_id_in = 6305
8085 cls.icmp_id_out = 6305
8086 cls.tcp_external_port = 80
8087 cls.nat_addr = '10.0.0.3'
8088 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8090 cls.vrf1_nat_addr = '10.0.10.3'
8091 cls.ipfix_src_port = 4739
8092 cls.ipfix_domain_id = 1
8094 cls.create_pg_interfaces(range(6))
8095 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
8096 cls.ip6_interfaces.append(cls.pg_interfaces[2])
8097 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
8099 cls.vapi.ip_table_add_del(is_add=1,
8100 table={'table_id': cls.vrf1_id,
8103 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
8105 cls.pg0.generate_remote_hosts(2)
8107 for i in cls.ip6_interfaces:
8110 i.configure_ipv6_neighbors()
8112 for i in cls.ip4_interfaces:
8118 cls.pg3.config_ip4()
8119 cls.pg3.resolve_arp()
8120 cls.pg3.config_ip6()
8121 cls.pg3.configure_ipv6_neighbors()
8124 cls.pg5.config_ip6()
8127 def tearDownClass(cls):
8128 super(TestNAT64, cls).tearDownClass()
8130 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
8131 """ NAT64 inside interface handles Neighbor Advertisement """
8133 flags = self.config_flags.NAT_IS_INSIDE
8134 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8135 sw_if_index=self.pg5.sw_if_index)
8138 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8139 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8140 ICMPv6EchoRequest())
8142 self.pg5.add_stream(pkts)
8143 self.pg_enable_capture(self.pg_interfaces)
8146 # Wait for Neighbor Solicitation
8147 capture = self.pg5.get_capture(len(pkts))
8150 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8151 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
8152 tgt = packet[ICMPv6ND_NS].tgt
8154 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8157 # Send Neighbor Advertisement
8158 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8159 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8160 ICMPv6ND_NA(tgt=tgt) /
8161 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
8163 self.pg5.add_stream(pkts)
8164 self.pg_enable_capture(self.pg_interfaces)
8167 # Try to send ping again
8169 self.pg5.add_stream(pkts)
8170 self.pg_enable_capture(self.pg_interfaces)
8173 # Wait for ping reply
8174 capture = self.pg5.get_capture(len(pkts))
8177 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8178 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
8179 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
8181 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8184 def test_pool(self):
8185 """ Add/delete address to NAT64 pool """
8186 nat_addr = '1.2.3.4'
8188 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8190 vrf_id=0xFFFFFFFF, is_add=1)
8192 addresses = self.vapi.nat64_pool_addr_dump()
8193 self.assertEqual(len(addresses), 1)
8194 self.assertEqual(str(addresses[0].address), nat_addr)
8196 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8198 vrf_id=0xFFFFFFFF, is_add=0)
8200 addresses = self.vapi.nat64_pool_addr_dump()
8201 self.assertEqual(len(addresses), 0)
8203 def test_interface(self):
8204 """ Enable/disable NAT64 feature on the interface """
8205 flags = self.config_flags.NAT_IS_INSIDE
8206 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8207 sw_if_index=self.pg0.sw_if_index)
8208 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8209 sw_if_index=self.pg1.sw_if_index)
8211 interfaces = self.vapi.nat64_interface_dump()
8212 self.assertEqual(len(interfaces), 2)
8215 for intf in interfaces:
8216 if intf.sw_if_index == self.pg0.sw_if_index:
8217 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
8219 elif intf.sw_if_index == self.pg1.sw_if_index:
8220 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
8222 self.assertTrue(pg0_found)
8223 self.assertTrue(pg1_found)
8225 features = self.vapi.cli("show interface features pg0")
8226 self.assertIn('nat64-in2out', features)
8227 features = self.vapi.cli("show interface features pg1")
8228 self.assertIn('nat64-out2in', features)
8230 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8231 sw_if_index=self.pg0.sw_if_index)
8232 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8233 sw_if_index=self.pg1.sw_if_index)
8235 interfaces = self.vapi.nat64_interface_dump()
8236 self.assertEqual(len(interfaces), 0)
8238 def test_static_bib(self):
8239 """ Add/delete static BIB entry """
8240 in_addr = '2001:db8:85a3::8a2e:370:7334'
8241 out_addr = '10.1.1.3'
8244 proto = IP_PROTOS.tcp
8246 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8247 i_port=in_port, o_port=out_port,
8248 proto=proto, vrf_id=0, is_add=1)
8249 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8252 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8254 self.assertEqual(str(bibe.i_addr), in_addr)
8255 self.assertEqual(str(bibe.o_addr), out_addr)
8256 self.assertEqual(bibe.i_port, in_port)
8257 self.assertEqual(bibe.o_port, out_port)
8258 self.assertEqual(static_bib_num, 1)
8259 bibs = self.statistics.get_counter('/nat64/total-bibs')
8260 self.assertEqual(bibs[0][0], 1)
8262 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8263 i_port=in_port, o_port=out_port,
8264 proto=proto, vrf_id=0, is_add=0)
8265 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8268 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8270 self.assertEqual(static_bib_num, 0)
8271 bibs = self.statistics.get_counter('/nat64/total-bibs')
8272 self.assertEqual(bibs[0][0], 0)
8274 def test_set_timeouts(self):
8275 """ Set NAT64 timeouts """
8276 # verify default values
8277 timeouts = self.vapi.nat_get_timeouts()
8278 self.assertEqual(timeouts.udp, 300)
8279 self.assertEqual(timeouts.icmp, 60)
8280 self.assertEqual(timeouts.tcp_transitory, 240)
8281 self.assertEqual(timeouts.tcp_established, 7440)
8283 # set and verify custom values
8284 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
8285 tcp_transitory=250, icmp=30)
8286 timeouts = self.vapi.nat_get_timeouts()
8287 self.assertEqual(timeouts.udp, 200)
8288 self.assertEqual(timeouts.icmp, 30)
8289 self.assertEqual(timeouts.tcp_transitory, 250)
8290 self.assertEqual(timeouts.tcp_established, 7450)
8292 def test_dynamic(self):
8293 """ NAT64 dynamic translation test """
8294 self.tcp_port_in = 6303
8295 self.udp_port_in = 6304
8296 self.icmp_id_in = 6305
8298 ses_num_start = self.nat64_get_ses_num()
8300 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8301 end_addr=self.nat_addr,
8304 flags = self.config_flags.NAT_IS_INSIDE
8305 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8306 sw_if_index=self.pg0.sw_if_index)
8307 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8308 sw_if_index=self.pg1.sw_if_index)
8311 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8312 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8313 icmpn = self.statistics.get_err_counter(
8314 '/err/nat64-in2out/ICMP packets')
8315 totaln = self.statistics.get_err_counter(
8316 '/err/nat64-in2out/good in2out packets processed')
8318 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8319 self.pg0.add_stream(pkts)
8320 self.pg_enable_capture(self.pg_interfaces)
8322 capture = self.pg1.get_capture(len(pkts))
8323 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8324 dst_ip=self.pg1.remote_ip4)
8326 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8327 self.assertEqual(err - tcpn, 1)
8328 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8329 self.assertEqual(err - udpn, 1)
8330 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8331 self.assertEqual(err - icmpn, 1)
8332 err = self.statistics.get_err_counter(
8333 '/err/nat64-in2out/good in2out packets processed')
8334 self.assertEqual(err - totaln, 3)
8337 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8338 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8339 icmpn = self.statistics.get_err_counter(
8340 '/err/nat64-out2in/ICMP packets')
8341 totaln = self.statistics.get_err_counter(
8342 '/err/nat64-out2in/good out2in packets processed')
8344 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8345 self.pg1.add_stream(pkts)
8346 self.pg_enable_capture(self.pg_interfaces)
8348 capture = self.pg0.get_capture(len(pkts))
8349 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8350 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8352 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8353 self.assertEqual(err - tcpn, 2)
8354 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8355 self.assertEqual(err - udpn, 1)
8356 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8357 self.assertEqual(err - icmpn, 1)
8358 err = self.statistics.get_err_counter(
8359 '/err/nat64-out2in/good out2in packets processed')
8360 self.assertEqual(err - totaln, 4)
8362 bibs = self.statistics.get_counter('/nat64/total-bibs')
8363 self.assertEqual(bibs[0][0], 3)
8364 sessions = self.statistics.get_counter('/nat64/total-sessions')
8365 self.assertEqual(sessions[0][0], 3)
8368 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8369 self.pg0.add_stream(pkts)
8370 self.pg_enable_capture(self.pg_interfaces)
8372 capture = self.pg1.get_capture(len(pkts))
8373 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8374 dst_ip=self.pg1.remote_ip4)
8377 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8378 self.pg1.add_stream(pkts)
8379 self.pg_enable_capture(self.pg_interfaces)
8381 capture = self.pg0.get_capture(len(pkts))
8382 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8384 ses_num_end = self.nat64_get_ses_num()
8386 self.assertEqual(ses_num_end - ses_num_start, 3)
8388 # tenant with specific VRF
8389 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8390 end_addr=self.vrf1_nat_addr,
8391 vrf_id=self.vrf1_id, is_add=1)
8392 flags = self.config_flags.NAT_IS_INSIDE
8393 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8394 sw_if_index=self.pg2.sw_if_index)
8396 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8397 self.pg2.add_stream(pkts)
8398 self.pg_enable_capture(self.pg_interfaces)
8400 capture = self.pg1.get_capture(len(pkts))
8401 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8402 dst_ip=self.pg1.remote_ip4)
8404 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8405 self.pg1.add_stream(pkts)
8406 self.pg_enable_capture(self.pg_interfaces)
8408 capture = self.pg2.get_capture(len(pkts))
8409 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8411 def test_static(self):
8412 """ NAT64 static translation test """
8413 self.tcp_port_in = 60303
8414 self.udp_port_in = 60304
8415 self.icmp_id_in = 60305
8416 self.tcp_port_out = 60303
8417 self.udp_port_out = 60304
8418 self.icmp_id_out = 60305
8420 ses_num_start = self.nat64_get_ses_num()
8422 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8423 end_addr=self.nat_addr,
8426 flags = self.config_flags.NAT_IS_INSIDE
8427 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8428 sw_if_index=self.pg0.sw_if_index)
8429 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8430 sw_if_index=self.pg1.sw_if_index)
8432 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8433 o_addr=self.nat_addr,
8434 i_port=self.tcp_port_in,
8435 o_port=self.tcp_port_out,
8436 proto=IP_PROTOS.tcp, vrf_id=0,
8438 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8439 o_addr=self.nat_addr,
8440 i_port=self.udp_port_in,
8441 o_port=self.udp_port_out,
8442 proto=IP_PROTOS.udp, vrf_id=0,
8444 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8445 o_addr=self.nat_addr,
8446 i_port=self.icmp_id_in,
8447 o_port=self.icmp_id_out,
8448 proto=IP_PROTOS.icmp, vrf_id=0,
8452 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8453 self.pg0.add_stream(pkts)
8454 self.pg_enable_capture(self.pg_interfaces)
8456 capture = self.pg1.get_capture(len(pkts))
8457 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8458 dst_ip=self.pg1.remote_ip4, same_port=True)
8461 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8462 self.pg1.add_stream(pkts)
8463 self.pg_enable_capture(self.pg_interfaces)
8465 capture = self.pg0.get_capture(len(pkts))
8466 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8467 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8469 ses_num_end = self.nat64_get_ses_num()
8471 self.assertEqual(ses_num_end - ses_num_start, 3)
8473 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8474 def test_session_timeout(self):
8475 """ NAT64 session timeout """
8476 self.icmp_id_in = 1234
8477 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8478 end_addr=self.nat_addr,
8481 flags = self.config_flags.NAT_IS_INSIDE
8482 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8483 sw_if_index=self.pg0.sw_if_index)
8484 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8485 sw_if_index=self.pg1.sw_if_index)
8486 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8490 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8491 self.pg0.add_stream(pkts)
8492 self.pg_enable_capture(self.pg_interfaces)
8494 capture = self.pg1.get_capture(len(pkts))
8496 ses_num_before_timeout = self.nat64_get_ses_num()
8500 # ICMP and TCP session after timeout
8501 ses_num_after_timeout = self.nat64_get_ses_num()
8502 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8504 def test_icmp_error(self):
8505 """ NAT64 ICMP Error message translation """
8506 self.tcp_port_in = 6303
8507 self.udp_port_in = 6304
8508 self.icmp_id_in = 6305
8510 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8511 end_addr=self.nat_addr,
8514 flags = self.config_flags.NAT_IS_INSIDE
8515 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8516 sw_if_index=self.pg0.sw_if_index)
8517 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8518 sw_if_index=self.pg1.sw_if_index)
8520 # send some packets to create sessions
8521 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8522 self.pg0.add_stream(pkts)
8523 self.pg_enable_capture(self.pg_interfaces)
8525 capture_ip4 = self.pg1.get_capture(len(pkts))
8526 self.verify_capture_out(capture_ip4,
8527 nat_ip=self.nat_addr,
8528 dst_ip=self.pg1.remote_ip4)
8530 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8531 self.pg1.add_stream(pkts)
8532 self.pg_enable_capture(self.pg_interfaces)
8534 capture_ip6 = self.pg0.get_capture(len(pkts))
8535 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8536 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8537 self.pg0.remote_ip6)
8540 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8541 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8542 ICMPv6DestUnreach(code=1) /
8543 packet[IPv6] for packet in capture_ip6]
8544 self.pg0.add_stream(pkts)
8545 self.pg_enable_capture(self.pg_interfaces)
8547 capture = self.pg1.get_capture(len(pkts))
8548 for packet in capture:
8550 self.assertEqual(packet[IP].src, self.nat_addr)
8551 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8552 self.assertEqual(packet[ICMP].type, 3)
8553 self.assertEqual(packet[ICMP].code, 13)
8554 inner = packet[IPerror]
8555 self.assertEqual(inner.src, self.pg1.remote_ip4)
8556 self.assertEqual(inner.dst, self.nat_addr)
8557 self.assert_packet_checksums_valid(packet)
8558 if inner.haslayer(TCPerror):
8559 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8560 elif inner.haslayer(UDPerror):
8561 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8563 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8565 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8569 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8570 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8571 ICMP(type=3, code=13) /
8572 packet[IP] for packet in capture_ip4]
8573 self.pg1.add_stream(pkts)
8574 self.pg_enable_capture(self.pg_interfaces)
8576 capture = self.pg0.get_capture(len(pkts))
8577 for packet in capture:
8579 self.assertEqual(packet[IPv6].src, ip.src)
8580 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8581 icmp = packet[ICMPv6DestUnreach]
8582 self.assertEqual(icmp.code, 1)
8583 inner = icmp[IPerror6]
8584 self.assertEqual(inner.src, self.pg0.remote_ip6)
8585 self.assertEqual(inner.dst, ip.src)
8586 self.assert_icmpv6_checksum_valid(packet)
8587 if inner.haslayer(TCPerror):
8588 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8589 elif inner.haslayer(UDPerror):
8590 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8592 self.assertEqual(inner[ICMPv6EchoRequest].id,
8595 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8598 def test_hairpinning(self):
8599 """ NAT64 hairpinning """
8601 client = self.pg0.remote_hosts[0]
8602 server = self.pg0.remote_hosts[1]
8603 server_tcp_in_port = 22
8604 server_tcp_out_port = 4022
8605 server_udp_in_port = 23
8606 server_udp_out_port = 4023
8607 client_tcp_in_port = 1234
8608 client_udp_in_port = 1235
8609 client_tcp_out_port = 0
8610 client_udp_out_port = 0
8611 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8612 nat_addr_ip6 = ip.src
8614 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8615 end_addr=self.nat_addr,
8618 flags = self.config_flags.NAT_IS_INSIDE
8619 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8620 sw_if_index=self.pg0.sw_if_index)
8621 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8622 sw_if_index=self.pg1.sw_if_index)
8624 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8625 o_addr=self.nat_addr,
8626 i_port=server_tcp_in_port,
8627 o_port=server_tcp_out_port,
8628 proto=IP_PROTOS.tcp, vrf_id=0,
8630 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8631 o_addr=self.nat_addr,
8632 i_port=server_udp_in_port,
8633 o_port=server_udp_out_port,
8634 proto=IP_PROTOS.udp, vrf_id=0,
8639 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8640 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8641 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8643 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8644 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8645 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8647 self.pg0.add_stream(pkts)
8648 self.pg_enable_capture(self.pg_interfaces)
8650 capture = self.pg0.get_capture(len(pkts))
8651 for packet in capture:
8653 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8654 self.assertEqual(packet[IPv6].dst, server.ip6)
8655 self.assert_packet_checksums_valid(packet)
8656 if packet.haslayer(TCP):
8657 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8658 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8659 client_tcp_out_port = packet[TCP].sport
8661 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8662 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8663 client_udp_out_port = packet[UDP].sport
8665 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8670 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8671 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8672 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8674 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8675 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8676 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8678 self.pg0.add_stream(pkts)
8679 self.pg_enable_capture(self.pg_interfaces)
8681 capture = self.pg0.get_capture(len(pkts))
8682 for packet in capture:
8684 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8685 self.assertEqual(packet[IPv6].dst, client.ip6)
8686 self.assert_packet_checksums_valid(packet)
8687 if packet.haslayer(TCP):
8688 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8689 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8691 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8692 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8694 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8699 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8700 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8701 ICMPv6DestUnreach(code=1) /
8702 packet[IPv6] for packet in capture]
8703 self.pg0.add_stream(pkts)
8704 self.pg_enable_capture(self.pg_interfaces)
8706 capture = self.pg0.get_capture(len(pkts))
8707 for packet in capture:
8709 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8710 self.assertEqual(packet[IPv6].dst, server.ip6)
8711 icmp = packet[ICMPv6DestUnreach]
8712 self.assertEqual(icmp.code, 1)
8713 inner = icmp[IPerror6]
8714 self.assertEqual(inner.src, server.ip6)
8715 self.assertEqual(inner.dst, nat_addr_ip6)
8716 self.assert_packet_checksums_valid(packet)
8717 if inner.haslayer(TCPerror):
8718 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8719 self.assertEqual(inner[TCPerror].dport,
8720 client_tcp_out_port)
8722 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8723 self.assertEqual(inner[UDPerror].dport,
8724 client_udp_out_port)
8726 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8729 def test_prefix(self):
8730 """ NAT64 Network-Specific Prefix """
8732 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8733 end_addr=self.nat_addr,
8736 flags = self.config_flags.NAT_IS_INSIDE
8737 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8738 sw_if_index=self.pg0.sw_if_index)
8739 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8740 sw_if_index=self.pg1.sw_if_index)
8741 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8742 end_addr=self.vrf1_nat_addr,
8743 vrf_id=self.vrf1_id, is_add=1)
8744 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8745 sw_if_index=self.pg2.sw_if_index)
8748 global_pref64 = "2001:db8::"
8749 global_pref64_len = 32
8750 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8751 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8754 prefix = self.vapi.nat64_prefix_dump()
8755 self.assertEqual(len(prefix), 1)
8756 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8757 self.assertEqual(prefix[0].vrf_id, 0)
8759 # Add tenant specific prefix
8760 vrf1_pref64 = "2001:db8:122:300::"
8761 vrf1_pref64_len = 56
8762 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8763 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8764 vrf_id=self.vrf1_id, is_add=1)
8766 prefix = self.vapi.nat64_prefix_dump()
8767 self.assertEqual(len(prefix), 2)
8770 pkts = self.create_stream_in_ip6(self.pg0,
8773 plen=global_pref64_len)
8774 self.pg0.add_stream(pkts)
8775 self.pg_enable_capture(self.pg_interfaces)
8777 capture = self.pg1.get_capture(len(pkts))
8778 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8779 dst_ip=self.pg1.remote_ip4)
8781 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8782 self.pg1.add_stream(pkts)
8783 self.pg_enable_capture(self.pg_interfaces)
8785 capture = self.pg0.get_capture(len(pkts))
8786 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8789 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8791 # Tenant specific prefix
8792 pkts = self.create_stream_in_ip6(self.pg2,
8795 plen=vrf1_pref64_len)
8796 self.pg2.add_stream(pkts)
8797 self.pg_enable_capture(self.pg_interfaces)
8799 capture = self.pg1.get_capture(len(pkts))
8800 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8801 dst_ip=self.pg1.remote_ip4)
8803 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8804 self.pg1.add_stream(pkts)
8805 self.pg_enable_capture(self.pg_interfaces)
8807 capture = self.pg2.get_capture(len(pkts))
8808 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8811 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8813 def test_unknown_proto(self):
8814 """ NAT64 translate packet with unknown protocol """
8816 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8817 end_addr=self.nat_addr,
8820 flags = self.config_flags.NAT_IS_INSIDE
8821 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8822 sw_if_index=self.pg0.sw_if_index)
8823 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8824 sw_if_index=self.pg1.sw_if_index)
8825 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8828 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8829 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8830 TCP(sport=self.tcp_port_in, dport=20))
8831 self.pg0.add_stream(p)
8832 self.pg_enable_capture(self.pg_interfaces)
8834 p = self.pg1.get_capture(1)
8836 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8837 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8839 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8840 TCP(sport=1234, dport=1234))
8841 self.pg0.add_stream(p)
8842 self.pg_enable_capture(self.pg_interfaces)
8844 p = self.pg1.get_capture(1)
8847 self.assertEqual(packet[IP].src, self.nat_addr)
8848 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8849 self.assertEqual(packet.haslayer(GRE), 1)
8850 self.assert_packet_checksums_valid(packet)
8852 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8856 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8857 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8859 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8860 TCP(sport=1234, dport=1234))
8861 self.pg1.add_stream(p)
8862 self.pg_enable_capture(self.pg_interfaces)
8864 p = self.pg0.get_capture(1)
8867 self.assertEqual(packet[IPv6].src, remote_ip6)
8868 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8869 self.assertEqual(packet[IPv6].nh, 47)
8871 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8874 def test_hairpinning_unknown_proto(self):
8875 """ NAT64 translate packet with unknown protocol - hairpinning """
8877 client = self.pg0.remote_hosts[0]
8878 server = self.pg0.remote_hosts[1]
8879 server_tcp_in_port = 22
8880 server_tcp_out_port = 4022
8881 client_tcp_in_port = 1234
8882 client_tcp_out_port = 1235
8883 server_nat_ip = "10.0.0.100"
8884 client_nat_ip = "10.0.0.110"
8885 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8886 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8888 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8889 end_addr=client_nat_ip,
8892 flags = self.config_flags.NAT_IS_INSIDE
8893 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8894 sw_if_index=self.pg0.sw_if_index)
8895 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8896 sw_if_index=self.pg1.sw_if_index)
8898 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8899 o_addr=server_nat_ip,
8900 i_port=server_tcp_in_port,
8901 o_port=server_tcp_out_port,
8902 proto=IP_PROTOS.tcp, vrf_id=0,
8905 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8906 o_addr=server_nat_ip, i_port=0,
8908 proto=IP_PROTOS.gre, vrf_id=0,
8911 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8912 o_addr=client_nat_ip,
8913 i_port=client_tcp_in_port,
8914 o_port=client_tcp_out_port,
8915 proto=IP_PROTOS.tcp, vrf_id=0,
8919 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8920 IPv6(src=client.ip6, dst=server_nat_ip6) /
8921 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8922 self.pg0.add_stream(p)
8923 self.pg_enable_capture(self.pg_interfaces)
8925 p = self.pg0.get_capture(1)
8927 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8928 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8930 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8931 TCP(sport=1234, dport=1234))
8932 self.pg0.add_stream(p)
8933 self.pg_enable_capture(self.pg_interfaces)
8935 p = self.pg0.get_capture(1)
8938 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8939 self.assertEqual(packet[IPv6].dst, server.ip6)
8940 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8942 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8946 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8947 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8949 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8950 TCP(sport=1234, dport=1234))
8951 self.pg0.add_stream(p)
8952 self.pg_enable_capture(self.pg_interfaces)
8954 p = self.pg0.get_capture(1)
8957 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8958 self.assertEqual(packet[IPv6].dst, client.ip6)
8959 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8961 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8964 def test_one_armed_nat64(self):
8965 """ One armed NAT64 """
8967 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8971 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8972 end_addr=self.nat_addr,
8975 flags = self.config_flags.NAT_IS_INSIDE
8976 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8977 sw_if_index=self.pg3.sw_if_index)
8978 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8979 sw_if_index=self.pg3.sw_if_index)
8982 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8983 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8984 TCP(sport=12345, dport=80))
8985 self.pg3.add_stream(p)
8986 self.pg_enable_capture(self.pg_interfaces)
8988 capture = self.pg3.get_capture(1)
8993 self.assertEqual(ip.src, self.nat_addr)
8994 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8995 self.assertNotEqual(tcp.sport, 12345)
8996 external_port = tcp.sport
8997 self.assertEqual(tcp.dport, 80)
8998 self.assert_packet_checksums_valid(p)
9000 self.logger.error(ppp("Unexpected or invalid packet:", p))
9004 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
9005 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
9006 TCP(sport=80, dport=external_port))
9007 self.pg3.add_stream(p)
9008 self.pg_enable_capture(self.pg_interfaces)
9010 capture = self.pg3.get_capture(1)
9015 self.assertEqual(ip.src, remote_host_ip6)
9016 self.assertEqual(ip.dst, self.pg3.remote_ip6)
9017 self.assertEqual(tcp.sport, 80)
9018 self.assertEqual(tcp.dport, 12345)
9019 self.assert_packet_checksums_valid(p)
9021 self.logger.error(ppp("Unexpected or invalid packet:", p))
9024 def test_frag_in_order(self):
9025 """ NAT64 translate fragments arriving in order """
9026 self.tcp_port_in = random.randint(1025, 65535)
9028 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9029 end_addr=self.nat_addr,
9032 flags = self.config_flags.NAT_IS_INSIDE
9033 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9034 sw_if_index=self.pg0.sw_if_index)
9035 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9036 sw_if_index=self.pg1.sw_if_index)
9040 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9041 self.tcp_port_in, 20, data)
9042 self.pg0.add_stream(pkts)
9043 self.pg_enable_capture(self.pg_interfaces)
9045 frags = self.pg1.get_capture(len(pkts))
9046 p = self.reass_frags_and_verify(frags,
9048 self.pg1.remote_ip4)
9049 self.assertEqual(p[TCP].dport, 20)
9050 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9051 self.tcp_port_out = p[TCP].sport
9052 self.assertEqual(data, p[Raw].load)
9055 data = b"A" * 4 + b"b" * 16 + b"C" * 3
9056 pkts = self.create_stream_frag(self.pg1,
9061 self.pg1.add_stream(pkts)
9062 self.pg_enable_capture(self.pg_interfaces)
9064 frags = self.pg0.get_capture(len(pkts))
9065 self.logger.debug(ppc("Captured:", frags))
9066 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9067 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9068 self.assertEqual(p[TCP].sport, 20)
9069 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9070 self.assertEqual(data, p[Raw].load)
9072 def test_reass_hairpinning(self):
9073 """ NAT64 fragments hairpinning """
9075 server = self.pg0.remote_hosts[1]
9076 server_in_port = random.randint(1025, 65535)
9077 server_out_port = random.randint(1025, 65535)
9078 client_in_port = random.randint(1025, 65535)
9079 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
9080 nat_addr_ip6 = ip.src
9082 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9083 end_addr=self.nat_addr,
9086 flags = self.config_flags.NAT_IS_INSIDE
9087 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9088 sw_if_index=self.pg0.sw_if_index)
9089 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9090 sw_if_index=self.pg1.sw_if_index)
9092 # add static BIB entry for server
9093 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
9094 o_addr=self.nat_addr,
9095 i_port=server_in_port,
9096 o_port=server_out_port,
9097 proto=IP_PROTOS.tcp, vrf_id=0,
9100 # send packet from host to server
9101 pkts = self.create_stream_frag_ip6(self.pg0,
9106 self.pg0.add_stream(pkts)
9107 self.pg_enable_capture(self.pg_interfaces)
9109 frags = self.pg0.get_capture(len(pkts))
9110 self.logger.debug(ppc("Captured:", frags))
9111 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
9112 self.assertNotEqual(p[TCP].sport, client_in_port)
9113 self.assertEqual(p[TCP].dport, server_in_port)
9114 self.assertEqual(data, p[Raw].load)
9116 def test_frag_out_of_order(self):
9117 """ NAT64 translate fragments arriving out of order """
9118 self.tcp_port_in = random.randint(1025, 65535)
9120 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9121 end_addr=self.nat_addr,
9124 flags = self.config_flags.NAT_IS_INSIDE
9125 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9126 sw_if_index=self.pg0.sw_if_index)
9127 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9128 sw_if_index=self.pg1.sw_if_index)
9132 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9133 self.tcp_port_in, 20, data)
9135 self.pg0.add_stream(pkts)
9136 self.pg_enable_capture(self.pg_interfaces)
9138 frags = self.pg1.get_capture(len(pkts))
9139 p = self.reass_frags_and_verify(frags,
9141 self.pg1.remote_ip4)
9142 self.assertEqual(p[TCP].dport, 20)
9143 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9144 self.tcp_port_out = p[TCP].sport
9145 self.assertEqual(data, p[Raw].load)
9148 data = b"A" * 4 + b"B" * 16 + b"C" * 3
9149 pkts = self.create_stream_frag(self.pg1,
9155 self.pg1.add_stream(pkts)
9156 self.pg_enable_capture(self.pg_interfaces)
9158 frags = self.pg0.get_capture(len(pkts))
9159 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9160 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9161 self.assertEqual(p[TCP].sport, 20)
9162 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9163 self.assertEqual(data, p[Raw].load)
9165 def test_interface_addr(self):
9166 """ Acquire NAT64 pool addresses from interface """
9167 self.vapi.nat64_add_del_interface_addr(
9169 sw_if_index=self.pg4.sw_if_index)
9171 # no address in NAT64 pool
9172 addresses = self.vapi.nat44_address_dump()
9173 self.assertEqual(0, len(addresses))
9175 # configure interface address and check NAT64 address pool
9176 self.pg4.config_ip4()
9177 addresses = self.vapi.nat64_pool_addr_dump()
9178 self.assertEqual(len(addresses), 1)
9180 self.assertEqual(str(addresses[0].address),
9183 # remove interface address and check NAT64 address pool
9184 self.pg4.unconfig_ip4()
9185 addresses = self.vapi.nat64_pool_addr_dump()
9186 self.assertEqual(0, len(addresses))
9188 @unittest.skipUnless(running_extended_tests, "part of extended tests")
9189 def test_ipfix_max_bibs_sessions(self):
9190 """ IPFIX logging maximum session and BIB entries exceeded """
9193 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9197 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9198 end_addr=self.nat_addr,
9201 flags = self.config_flags.NAT_IS_INSIDE
9202 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9203 sw_if_index=self.pg0.sw_if_index)
9204 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9205 sw_if_index=self.pg1.sw_if_index)
9209 for i in range(0, max_bibs):
9210 src = "fd01:aa::%x" % (i)
9211 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9212 IPv6(src=src, dst=remote_host_ip6) /
9213 TCP(sport=12345, dport=80))
9215 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9216 IPv6(src=src, dst=remote_host_ip6) /
9217 TCP(sport=12345, dport=22))
9219 self.pg0.add_stream(pkts)
9220 self.pg_enable_capture(self.pg_interfaces)
9222 self.pg1.get_capture(max_sessions)
9224 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9225 src_address=self.pg3.local_ip4,
9227 template_interval=10)
9228 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9229 src_port=self.ipfix_src_port,
9232 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9233 IPv6(src=src, dst=remote_host_ip6) /
9234 TCP(sport=12345, dport=25))
9235 self.pg0.add_stream(p)
9236 self.pg_enable_capture(self.pg_interfaces)
9238 self.pg1.assert_nothing_captured()
9240 self.vapi.ipfix_flush()
9241 capture = self.pg3.get_capture(7)
9242 ipfix = IPFIXDecoder()
9243 # first load template
9245 self.assertTrue(p.haslayer(IPFIX))
9246 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9247 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9248 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9249 self.assertEqual(p[UDP].dport, 4739)
9250 self.assertEqual(p[IPFIX].observationDomainID,
9251 self.ipfix_domain_id)
9252 if p.haslayer(Template):
9253 ipfix.add_template(p.getlayer(Template))
9254 # verify events in data set
9256 if p.haslayer(Data):
9257 data = ipfix.decode_data_set(p.getlayer(Set))
9258 self.verify_ipfix_max_sessions(data, max_sessions)
9260 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9261 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9262 TCP(sport=12345, dport=80))
9263 self.pg0.add_stream(p)
9264 self.pg_enable_capture(self.pg_interfaces)
9266 self.pg1.assert_nothing_captured()
9268 self.vapi.ipfix_flush()
9269 capture = self.pg3.get_capture(1)
9270 # verify events in data set
9272 self.assertTrue(p.haslayer(IPFIX))
9273 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9274 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9275 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9276 self.assertEqual(p[UDP].dport, 4739)
9277 self.assertEqual(p[IPFIX].observationDomainID,
9278 self.ipfix_domain_id)
9279 if p.haslayer(Data):
9280 data = ipfix.decode_data_set(p.getlayer(Set))
9281 self.verify_ipfix_max_bibs(data, max_bibs)
9283 def test_ipfix_bib_ses(self):
9284 """ IPFIX logging NAT64 BIB/session create and delete events """
9285 self.tcp_port_in = random.randint(1025, 65535)
9286 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9290 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9291 end_addr=self.nat_addr,
9294 flags = self.config_flags.NAT_IS_INSIDE
9295 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9296 sw_if_index=self.pg0.sw_if_index)
9297 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9298 sw_if_index=self.pg1.sw_if_index)
9299 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9300 src_address=self.pg3.local_ip4,
9302 template_interval=10)
9303 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9304 src_port=self.ipfix_src_port,
9308 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9309 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9310 TCP(sport=self.tcp_port_in, dport=25))
9311 self.pg0.add_stream(p)
9312 self.pg_enable_capture(self.pg_interfaces)
9314 p = self.pg1.get_capture(1)
9315 self.tcp_port_out = p[0][TCP].sport
9316 self.vapi.ipfix_flush()
9317 capture = self.pg3.get_capture(8)
9318 ipfix = IPFIXDecoder()
9319 # first load template
9321 self.assertTrue(p.haslayer(IPFIX))
9322 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9323 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9324 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9325 self.assertEqual(p[UDP].dport, 4739)
9326 self.assertEqual(p[IPFIX].observationDomainID,
9327 self.ipfix_domain_id)
9328 if p.haslayer(Template):
9329 ipfix.add_template(p.getlayer(Template))
9330 # verify events in data set
9332 if p.haslayer(Data):
9333 data = ipfix.decode_data_set(p.getlayer(Set))
9334 if scapy.compat.orb(data[0][230]) == 10:
9335 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
9336 elif scapy.compat.orb(data[0][230]) == 6:
9337 self.verify_ipfix_nat64_ses(data,
9339 self.pg0.remote_ip6,
9340 self.pg1.remote_ip4,
9343 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9346 self.pg_enable_capture(self.pg_interfaces)
9347 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9348 end_addr=self.nat_addr,
9351 self.vapi.ipfix_flush()
9352 capture = self.pg3.get_capture(2)
9353 # verify events in data set
9355 self.assertTrue(p.haslayer(IPFIX))
9356 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9357 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9358 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9359 self.assertEqual(p[UDP].dport, 4739)
9360 self.assertEqual(p[IPFIX].observationDomainID,
9361 self.ipfix_domain_id)
9362 if p.haslayer(Data):
9363 data = ipfix.decode_data_set(p.getlayer(Set))
9364 if scapy.compat.orb(data[0][230]) == 11:
9365 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
9366 elif scapy.compat.orb(data[0][230]) == 7:
9367 self.verify_ipfix_nat64_ses(data,
9369 self.pg0.remote_ip6,
9370 self.pg1.remote_ip4,
9373 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9375 def test_syslog_sess(self):
9376 """ Test syslog session creation and deletion """
9377 self.tcp_port_in = random.randint(1025, 65535)
9378 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9382 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9383 end_addr=self.nat_addr,
9386 flags = self.config_flags.NAT_IS_INSIDE
9387 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9388 sw_if_index=self.pg0.sw_if_index)
9389 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9390 sw_if_index=self.pg1.sw_if_index)
9391 self.vapi.syslog_set_filter(
9392 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9393 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9395 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9396 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9397 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9398 self.pg0.add_stream(p)
9399 self.pg_enable_capture(self.pg_interfaces)
9401 p = self.pg1.get_capture(1)
9402 self.tcp_port_out = p[0][TCP].sport
9403 capture = self.pg3.get_capture(1)
9404 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9406 self.pg_enable_capture(self.pg_interfaces)
9408 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9409 end_addr=self.nat_addr,
9412 capture = self.pg3.get_capture(1)
9413 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9415 def nat64_get_ses_num(self):
9417 Return number of active NAT64 sessions.
9419 st = self.vapi.nat64_st_dump(proto=255)
9422 def clear_nat64(self):
9424 Clear NAT64 configuration.
9426 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9427 src_port=self.ipfix_src_port,
9429 self.ipfix_src_port = 4739
9430 self.ipfix_domain_id = 1
9432 self.vapi.syslog_set_filter(
9433 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9435 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9436 tcp_transitory=240, icmp=60)
9438 interfaces = self.vapi.nat64_interface_dump()
9439 for intf in interfaces:
9440 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9441 sw_if_index=intf.sw_if_index)
9443 bib = self.vapi.nat64_bib_dump(proto=255)
9445 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9446 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9454 adresses = self.vapi.nat64_pool_addr_dump()
9455 for addr in adresses:
9456 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9457 end_addr=addr.address,
9461 prefixes = self.vapi.nat64_prefix_dump()
9462 for prefix in prefixes:
9463 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9464 vrf_id=prefix.vrf_id, is_add=0)
9466 bibs = self.statistics.get_counter('/nat64/total-bibs')
9467 self.assertEqual(bibs[0][0], 0)
9468 sessions = self.statistics.get_counter('/nat64/total-sessions')
9469 self.assertEqual(sessions[0][0], 0)
9472 super(TestNAT64, self).tearDown()
9473 if not self.vpp_dead:
9476 def show_commands_at_teardown(self):
9477 self.logger.info(self.vapi.cli("show nat64 pool"))
9478 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9479 self.logger.info(self.vapi.cli("show nat64 prefix"))
9480 self.logger.info(self.vapi.cli("show nat64 bib all"))
9481 self.logger.info(self.vapi.cli("show nat64 session table all"))
9484 class TestNAT66(MethodHolder):
9485 """ NAT66 Test Cases """
9488 def setUpClass(cls):
9489 super(TestNAT66, cls).setUpClass()
9491 cls.nat_addr = 'fd01:ff::2'
9493 cls.create_pg_interfaces(range(2))
9494 cls.interfaces = list(cls.pg_interfaces)
9496 for i in cls.interfaces:
9499 i.configure_ipv6_neighbors()
9502 def tearDownClass(cls):
9503 super(TestNAT66, cls).tearDownClass()
9505 def test_static(self):
9506 """ 1:1 NAT66 test """
9507 flags = self.config_flags.NAT_IS_INSIDE
9508 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9509 sw_if_index=self.pg0.sw_if_index)
9510 self.vapi.nat66_add_del_interface(is_add=1,
9511 sw_if_index=self.pg1.sw_if_index)
9512 self.vapi.nat66_add_del_static_mapping(
9513 local_ip_address=self.pg0.remote_ip6,
9514 external_ip_address=self.nat_addr,
9519 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9520 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9523 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9524 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9527 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9528 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9529 ICMPv6EchoRequest())
9531 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9532 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9533 GRE() / IP() / TCP())
9535 self.pg0.add_stream(pkts)
9536 self.pg_enable_capture(self.pg_interfaces)
9538 capture = self.pg1.get_capture(len(pkts))
9540 for packet in capture:
9542 self.assertEqual(packet[IPv6].src, self.nat_addr)
9543 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9544 self.assert_packet_checksums_valid(packet)
9546 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9551 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9552 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9555 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9556 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9559 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9560 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9563 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9564 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9565 GRE() / IP() / TCP())
9567 self.pg1.add_stream(pkts)
9568 self.pg_enable_capture(self.pg_interfaces)
9570 capture = self.pg0.get_capture(len(pkts))
9571 for packet in capture:
9573 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9574 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9575 self.assert_packet_checksums_valid(packet)
9577 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9580 sm = self.vapi.nat66_static_mapping_dump()
9581 self.assertEqual(len(sm), 1)
9582 self.assertEqual(sm[0].total_pkts, 8)
9584 def test_check_no_translate(self):
9585 """ NAT66 translate only when egress interface is outside interface """
9586 flags = self.config_flags.NAT_IS_INSIDE
9587 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9588 sw_if_index=self.pg0.sw_if_index)
9589 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9590 sw_if_index=self.pg1.sw_if_index)
9591 self.vapi.nat66_add_del_static_mapping(
9592 local_ip_address=self.pg0.remote_ip6,
9593 external_ip_address=self.nat_addr,
9597 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9598 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9600 self.pg0.add_stream([p])
9601 self.pg_enable_capture(self.pg_interfaces)
9603 capture = self.pg1.get_capture(1)
9606 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9607 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9612 def clear_nat66(self):
9614 Clear NAT66 configuration.
9616 interfaces = self.vapi.nat66_interface_dump()
9617 for intf in interfaces:
9618 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9619 sw_if_index=intf.sw_if_index)
9621 static_mappings = self.vapi.nat66_static_mapping_dump()
9622 for sm in static_mappings:
9623 self.vapi.nat66_add_del_static_mapping(
9624 local_ip_address=sm.local_ip_address,
9625 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9629 super(TestNAT66, self).tearDown()
9632 def show_commands_at_teardown(self):
9633 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9634 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9637 if __name__ == '__main__':
9638 unittest.main(testRunner=VppTestRunner)