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)
7094 super(TestNAT44EndpointDependent, self).tearDown()
7095 if not self.vpp_dead:
7097 self.vapi.cli("clear logging")
7099 def show_commands_at_teardown(self):
7100 self.logger.info(self.vapi.cli("show nat44 addresses"))
7101 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7102 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7103 self.logger.info(self.vapi.cli("show nat44 interface address"))
7104 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7105 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7106 self.logger.info(self.vapi.cli("show nat timeouts"))
7109 class TestNAT44EndpointDependent2(MethodHolder):
7110 """ Endpoint-Dependent mapping and filtering extra test cases """
7112 translation_buckets = 5
7115 def setUpConstants(cls):
7116 super(TestNAT44EndpointDependent2, cls).setUpConstants()
7117 cls.vpp_cmdline.extend([
7118 "nat", "{", "endpoint-dependent",
7119 "translation hash buckets %d" % cls.translation_buckets,
7124 def setUpClass(cls):
7125 super(TestNAT44EndpointDependent2, cls).setUpClass()
7126 cls.vapi.cli("set log class nat level debug")
7128 cls.nat_addr = '10.0.0.3'
7130 cls.create_pg_interfaces(range(2))
7132 for i in cls.pg_interfaces:
7138 super(TestNAT44EndpointDependent2, self).setUp()
7139 self.vapi.nat_set_timeouts(
7140 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7141 self.nat44_add_address(self.nat_addr)
7142 flags = self.config_flags.NAT_IS_INSIDE
7143 self.vapi.nat44_interface_add_del_feature(
7144 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7145 self.vapi.nat44_interface_add_del_feature(
7146 sw_if_index=self.pg1.sw_if_index, is_add=1)
7149 def tearDownClass(cls):
7150 super(TestNAT44EndpointDependent2, cls).tearDownClass()
7152 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7153 # SYN packet in->out
7154 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7155 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7156 TCP(sport=sport, dport=ext_dport, flags="S"))
7158 self.pg_enable_capture(self.pg_interfaces)
7160 capture = out_if.get_capture(1)
7162 tcp_port_out = p[TCP].sport
7164 # SYN + ACK packet out->in
7165 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7166 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7167 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7168 out_if.add_stream(p)
7169 self.pg_enable_capture(self.pg_interfaces)
7171 in_if.get_capture(1)
7173 # ACK packet in->out
7174 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7175 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7176 TCP(sport=sport, dport=ext_dport, flags="A"))
7178 self.pg_enable_capture(self.pg_interfaces)
7180 out_if.get_capture(1)
7184 def test_lru_cleanup(self):
7185 """ LRU cleanup algorithm """
7186 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7187 max_translations = 10 * self.translation_buckets
7189 for i in range(0, max_translations - 1):
7190 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7191 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7192 UDP(sport=7000+i, dport=80))
7195 self.pg0.add_stream(pkts)
7196 self.pg_enable_capture(self.pg_interfaces)
7198 self.pg1.get_capture(len(pkts))
7199 self.sleep(1.5, "wait for timeouts")
7202 for i in range(0, max_translations - 1):
7203 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7204 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7205 ICMP(id=8000+i, type='echo-request'))
7208 self.pg0.add_stream(pkts)
7209 self.pg_enable_capture(self.pg_interfaces)
7211 self.pg1.get_capture(len(pkts))
7214 class TestNAT44Out2InDPO(MethodHolder):
7215 """ NAT44 Test Cases using out2in DPO """
7218 def setUpConstants(cls):
7219 super(TestNAT44Out2InDPO, cls).setUpConstants()
7220 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7223 def setUpClass(cls):
7224 super(TestNAT44Out2InDPO, cls).setUpClass()
7225 cls.vapi.cli("set log class nat level debug")
7227 cls.tcp_port_in = 6303
7228 cls.tcp_port_out = 6303
7229 cls.udp_port_in = 6304
7230 cls.udp_port_out = 6304
7231 cls.icmp_id_in = 6305
7232 cls.icmp_id_out = 6305
7233 cls.nat_addr = '10.0.0.3'
7234 cls.dst_ip4 = '192.168.70.1'
7236 cls.create_pg_interfaces(range(2))
7239 cls.pg0.config_ip4()
7240 cls.pg0.resolve_arp()
7243 cls.pg1.config_ip6()
7244 cls.pg1.resolve_ndp()
7246 r1 = VppIpRoute(cls, "::", 0,
7247 [VppRoutePath(cls.pg1.remote_ip6,
7248 cls.pg1.sw_if_index)],
7253 def tearDownClass(cls):
7254 super(TestNAT44Out2InDPO, cls).tearDownClass()
7256 def configure_xlat(self):
7257 self.dst_ip6_pfx = '1:2:3::'
7258 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7260 self.dst_ip6_pfx_len = 96
7261 self.src_ip6_pfx = '4:5:6::'
7262 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7264 self.src_ip6_pfx_len = 96
7265 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7266 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7267 '\x00\x00\x00\x00', 0)
7269 @unittest.skip('Temporary disabled')
7270 def test_464xlat_ce(self):
7271 """ Test 464XLAT CE with NAT44 """
7273 nat_config = self.vapi.nat_show_config()
7274 self.assertEqual(1, nat_config.out2in_dpo)
7276 self.configure_xlat()
7278 flags = self.config_flags.NAT_IS_INSIDE
7279 self.vapi.nat44_interface_add_del_feature(
7280 sw_if_index=self.pg0.sw_if_index,
7281 flags=flags, is_add=1)
7282 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7283 last_ip_address=self.nat_addr_n,
7284 vrf_id=0xFFFFFFFF, is_add=1)
7286 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7287 self.dst_ip6_pfx_len)
7288 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7289 self.src_ip6_pfx_len)
7292 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7293 self.pg0.add_stream(pkts)
7294 self.pg_enable_capture(self.pg_interfaces)
7296 capture = self.pg1.get_capture(len(pkts))
7297 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7300 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7302 self.pg1.add_stream(pkts)
7303 self.pg_enable_capture(self.pg_interfaces)
7305 capture = self.pg0.get_capture(len(pkts))
7306 self.verify_capture_in(capture, self.pg0)
7308 self.vapi.nat44_interface_add_del_feature(
7309 sw_if_index=self.pg0.sw_if_index,
7311 self.vapi.nat44_add_del_address_range(
7312 first_ip_address=self.nat_addr_n,
7313 last_ip_address=self.nat_addr_n,
7316 @unittest.skip('Temporary disabled')
7317 def test_464xlat_ce_no_nat(self):
7318 """ Test 464XLAT CE without NAT44 """
7320 self.configure_xlat()
7322 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7323 self.dst_ip6_pfx_len)
7324 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7325 self.src_ip6_pfx_len)
7327 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7328 self.pg0.add_stream(pkts)
7329 self.pg_enable_capture(self.pg_interfaces)
7331 capture = self.pg1.get_capture(len(pkts))
7332 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7333 nat_ip=out_dst_ip6, same_port=True)
7335 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7336 self.pg1.add_stream(pkts)
7337 self.pg_enable_capture(self.pg_interfaces)
7339 capture = self.pg0.get_capture(len(pkts))
7340 self.verify_capture_in(capture, self.pg0)
7343 class TestDeterministicNAT(MethodHolder):
7344 """ Deterministic NAT Test Cases """
7347 def setUpConstants(cls):
7348 super(TestDeterministicNAT, cls).setUpConstants()
7349 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7352 def setUpClass(cls):
7353 super(TestDeterministicNAT, cls).setUpClass()
7354 cls.vapi.cli("set log class nat level debug")
7356 cls.tcp_port_in = 6303
7357 cls.tcp_external_port = 6303
7358 cls.udp_port_in = 6304
7359 cls.udp_external_port = 6304
7360 cls.icmp_id_in = 6305
7361 cls.nat_addr = '10.0.0.3'
7363 cls.create_pg_interfaces(range(3))
7364 cls.interfaces = list(cls.pg_interfaces)
7366 for i in cls.interfaces:
7371 cls.pg0.generate_remote_hosts(2)
7372 cls.pg0.configure_ipv4_neighbors()
7375 def tearDownClass(cls):
7376 super(TestDeterministicNAT, cls).tearDownClass()
7378 def create_stream_in(self, in_if, out_if, ttl=64):
7380 Create packet stream for inside network
7382 :param in_if: Inside interface
7383 :param out_if: Outside interface
7384 :param ttl: TTL of generated packets
7388 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7389 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7390 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7394 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7395 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7396 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7400 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7401 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7402 ICMP(id=self.icmp_id_in, type='echo-request'))
7407 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7409 Create packet stream for outside network
7411 :param out_if: Outside interface
7412 :param dst_ip: Destination IP address (Default use global NAT address)
7413 :param ttl: TTL of generated packets
7416 dst_ip = self.nat_addr
7419 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7420 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7421 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7425 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7426 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7427 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7431 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7432 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7433 ICMP(id=self.icmp_external_id, type='echo-reply'))
7438 def verify_capture_out(self, capture, nat_ip=None):
7440 Verify captured packets on outside network
7442 :param capture: Captured packets
7443 :param nat_ip: Translated IP address (Default use global NAT address)
7444 :param same_port: Source port number is not translated (Default False)
7447 nat_ip = self.nat_addr
7448 for packet in capture:
7450 self.assertEqual(packet[IP].src, nat_ip)
7451 if packet.haslayer(TCP):
7452 self.tcp_port_out = packet[TCP].sport
7453 elif packet.haslayer(UDP):
7454 self.udp_port_out = packet[UDP].sport
7456 self.icmp_external_id = packet[ICMP].id
7458 self.logger.error(ppp("Unexpected or invalid packet "
7459 "(outside network):", packet))
7462 def test_deterministic_mode(self):
7463 """ NAT plugin run deterministic mode """
7464 in_addr = '172.16.255.0'
7465 out_addr = '172.17.255.50'
7466 in_addr_t = '172.16.255.20'
7470 nat_config = self.vapi.nat_show_config()
7471 self.assertEqual(1, nat_config.deterministic)
7473 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7474 in_plen=in_plen, out_addr=out_addr,
7477 rep1 = self.vapi.nat_det_forward(in_addr_t)
7478 self.assertEqual(str(rep1.out_addr), out_addr)
7479 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7481 self.assertEqual(str(rep2.in_addr), in_addr_t)
7483 deterministic_mappings = self.vapi.nat_det_map_dump()
7484 self.assertEqual(len(deterministic_mappings), 1)
7485 dsm = deterministic_mappings[0]
7486 self.assertEqual(in_addr, str(dsm.in_addr))
7487 self.assertEqual(in_plen, dsm.in_plen)
7488 self.assertEqual(out_addr, str(dsm.out_addr))
7489 self.assertEqual(out_plen, dsm.out_plen)
7491 self.clear_nat_det()
7492 deterministic_mappings = self.vapi.nat_det_map_dump()
7493 self.assertEqual(len(deterministic_mappings), 0)
7495 def test_set_timeouts(self):
7496 """ Set deterministic NAT timeouts """
7497 timeouts_before = self.vapi.nat_get_timeouts()
7499 self.vapi.nat_set_timeouts(
7500 udp=timeouts_before.udp + 10,
7501 tcp_established=timeouts_before.tcp_established + 10,
7502 tcp_transitory=timeouts_before.tcp_transitory + 10,
7503 icmp=timeouts_before.icmp + 10)
7505 timeouts_after = self.vapi.nat_get_timeouts()
7507 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7508 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7509 self.assertNotEqual(timeouts_before.tcp_established,
7510 timeouts_after.tcp_established)
7511 self.assertNotEqual(timeouts_before.tcp_transitory,
7512 timeouts_after.tcp_transitory)
7514 def test_det_in(self):
7515 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7517 nat_ip = "10.0.0.10"
7519 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7521 out_addr=socket.inet_aton(nat_ip),
7524 flags = self.config_flags.NAT_IS_INSIDE
7525 self.vapi.nat44_interface_add_del_feature(
7526 sw_if_index=self.pg0.sw_if_index,
7527 flags=flags, is_add=1)
7528 self.vapi.nat44_interface_add_del_feature(
7529 sw_if_index=self.pg1.sw_if_index,
7533 pkts = self.create_stream_in(self.pg0, self.pg1)
7534 self.pg0.add_stream(pkts)
7535 self.pg_enable_capture(self.pg_interfaces)
7537 capture = self.pg1.get_capture(len(pkts))
7538 self.verify_capture_out(capture, nat_ip)
7541 pkts = self.create_stream_out(self.pg1, nat_ip)
7542 self.pg1.add_stream(pkts)
7543 self.pg_enable_capture(self.pg_interfaces)
7545 capture = self.pg0.get_capture(len(pkts))
7546 self.verify_capture_in(capture, self.pg0)
7549 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7550 self.assertEqual(len(sessions), 3)
7554 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7555 self.assertEqual(s.in_port, self.tcp_port_in)
7556 self.assertEqual(s.out_port, self.tcp_port_out)
7557 self.assertEqual(s.ext_port, self.tcp_external_port)
7561 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7562 self.assertEqual(s.in_port, self.udp_port_in)
7563 self.assertEqual(s.out_port, self.udp_port_out)
7564 self.assertEqual(s.ext_port, self.udp_external_port)
7568 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7569 self.assertEqual(s.in_port, self.icmp_id_in)
7570 self.assertEqual(s.out_port, self.icmp_external_id)
7572 def test_multiple_users(self):
7573 """ Deterministic NAT multiple users """
7575 nat_ip = "10.0.0.10"
7577 external_port = 6303
7579 host0 = self.pg0.remote_hosts[0]
7580 host1 = self.pg0.remote_hosts[1]
7582 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7583 out_addr=socket.inet_aton(nat_ip),
7585 flags = self.config_flags.NAT_IS_INSIDE
7586 self.vapi.nat44_interface_add_del_feature(
7587 sw_if_index=self.pg0.sw_if_index,
7588 flags=flags, is_add=1)
7589 self.vapi.nat44_interface_add_del_feature(
7590 sw_if_index=self.pg1.sw_if_index,
7594 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7595 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7596 TCP(sport=port_in, dport=external_port))
7597 self.pg0.add_stream(p)
7598 self.pg_enable_capture(self.pg_interfaces)
7600 capture = self.pg1.get_capture(1)
7605 self.assertEqual(ip.src, nat_ip)
7606 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7607 self.assertEqual(tcp.dport, external_port)
7608 port_out0 = tcp.sport
7610 self.logger.error(ppp("Unexpected or invalid packet:", p))
7614 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7615 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7616 TCP(sport=port_in, dport=external_port))
7617 self.pg0.add_stream(p)
7618 self.pg_enable_capture(self.pg_interfaces)
7620 capture = self.pg1.get_capture(1)
7625 self.assertEqual(ip.src, nat_ip)
7626 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7627 self.assertEqual(tcp.dport, external_port)
7628 port_out1 = tcp.sport
7630 self.logger.error(ppp("Unexpected or invalid packet:", p))
7633 dms = self.vapi.nat_det_map_dump()
7634 self.assertEqual(1, len(dms))
7635 self.assertEqual(2, dms[0].ses_num)
7638 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7639 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7640 TCP(sport=external_port, dport=port_out0))
7641 self.pg1.add_stream(p)
7642 self.pg_enable_capture(self.pg_interfaces)
7644 capture = self.pg0.get_capture(1)
7649 self.assertEqual(ip.src, self.pg1.remote_ip4)
7650 self.assertEqual(ip.dst, host0.ip4)
7651 self.assertEqual(tcp.dport, port_in)
7652 self.assertEqual(tcp.sport, external_port)
7654 self.logger.error(ppp("Unexpected or invalid packet:", p))
7658 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7659 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7660 TCP(sport=external_port, dport=port_out1))
7661 self.pg1.add_stream(p)
7662 self.pg_enable_capture(self.pg_interfaces)
7664 capture = self.pg0.get_capture(1)
7669 self.assertEqual(ip.src, self.pg1.remote_ip4)
7670 self.assertEqual(ip.dst, host1.ip4)
7671 self.assertEqual(tcp.dport, port_in)
7672 self.assertEqual(tcp.sport, external_port)
7674 self.logger.error(ppp("Unexpected or invalid packet", p))
7677 # session close api test
7678 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7680 self.pg1.remote_ip4,
7682 dms = self.vapi.nat_det_map_dump()
7683 self.assertEqual(dms[0].ses_num, 1)
7685 self.vapi.nat_det_close_session_in(host0.ip4,
7687 self.pg1.remote_ip4,
7689 dms = self.vapi.nat_det_map_dump()
7690 self.assertEqual(dms[0].ses_num, 0)
7692 def test_tcp_session_close_detection_in(self):
7693 """ Deterministic NAT TCP session close from inside network """
7694 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7696 out_addr=socket.inet_aton(self.nat_addr),
7698 flags = self.config_flags.NAT_IS_INSIDE
7699 self.vapi.nat44_interface_add_del_feature(
7700 sw_if_index=self.pg0.sw_if_index,
7701 flags=flags, is_add=1)
7702 self.vapi.nat44_interface_add_del_feature(
7703 sw_if_index=self.pg1.sw_if_index,
7706 self.initiate_tcp_session(self.pg0, self.pg1)
7708 # close the session from inside
7710 # FIN packet in -> out
7711 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7712 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7713 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7715 self.pg0.add_stream(p)
7716 self.pg_enable_capture(self.pg_interfaces)
7718 self.pg1.get_capture(1)
7722 # ACK packet out -> in
7723 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7724 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7725 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7729 # FIN packet out -> in
7730 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7731 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7732 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7736 self.pg1.add_stream(pkts)
7737 self.pg_enable_capture(self.pg_interfaces)
7739 self.pg0.get_capture(2)
7741 # ACK packet in -> out
7742 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7743 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7744 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7746 self.pg0.add_stream(p)
7747 self.pg_enable_capture(self.pg_interfaces)
7749 self.pg1.get_capture(1)
7751 # Check if deterministic NAT44 closed the session
7752 dms = self.vapi.nat_det_map_dump()
7753 self.assertEqual(0, dms[0].ses_num)
7755 self.logger.error("TCP session termination failed")
7758 def test_tcp_session_close_detection_out(self):
7759 """ Deterministic NAT TCP session close from outside network """
7760 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7762 out_addr=socket.inet_aton(self.nat_addr),
7764 flags = self.config_flags.NAT_IS_INSIDE
7765 self.vapi.nat44_interface_add_del_feature(
7766 sw_if_index=self.pg0.sw_if_index,
7767 flags=flags, is_add=1)
7768 self.vapi.nat44_interface_add_del_feature(
7769 sw_if_index=self.pg1.sw_if_index,
7772 self.initiate_tcp_session(self.pg0, self.pg1)
7774 # close the session from outside
7776 # FIN packet out -> in
7777 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7778 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7779 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7781 self.pg1.add_stream(p)
7782 self.pg_enable_capture(self.pg_interfaces)
7784 self.pg0.get_capture(1)
7788 # ACK packet in -> out
7789 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7790 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7791 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7795 # ACK packet in -> out
7796 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7797 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7798 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7802 self.pg0.add_stream(pkts)
7803 self.pg_enable_capture(self.pg_interfaces)
7805 self.pg1.get_capture(2)
7807 # ACK packet out -> in
7808 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7809 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7810 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7812 self.pg1.add_stream(p)
7813 self.pg_enable_capture(self.pg_interfaces)
7815 self.pg0.get_capture(1)
7817 # Check if deterministic NAT44 closed the session
7818 dms = self.vapi.nat_det_map_dump()
7819 self.assertEqual(0, dms[0].ses_num)
7821 self.logger.error("TCP session termination failed")
7824 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7825 def test_session_timeout(self):
7826 """ Deterministic NAT session timeouts """
7827 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7829 out_addr=socket.inet_aton(self.nat_addr),
7831 flags = self.config_flags.NAT_IS_INSIDE
7832 self.vapi.nat44_interface_add_del_feature(
7833 sw_if_index=self.pg0.sw_if_index,
7834 flags=flags, is_add=1)
7835 self.vapi.nat44_interface_add_del_feature(
7836 sw_if_index=self.pg1.sw_if_index,
7839 self.initiate_tcp_session(self.pg0, self.pg1)
7840 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7842 pkts = self.create_stream_in(self.pg0, self.pg1)
7843 self.pg0.add_stream(pkts)
7844 self.pg_enable_capture(self.pg_interfaces)
7846 capture = self.pg1.get_capture(len(pkts))
7849 dms = self.vapi.nat_det_map_dump()
7850 self.assertEqual(0, dms[0].ses_num)
7852 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7853 def test_session_limit_per_user(self):
7854 """ Deterministic NAT maximum sessions per user limit """
7855 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7857 out_addr=socket.inet_aton(self.nat_addr),
7859 flags = self.config_flags.NAT_IS_INSIDE
7860 self.vapi.nat44_interface_add_del_feature(
7861 sw_if_index=self.pg0.sw_if_index,
7862 flags=flags, is_add=1)
7863 self.vapi.nat44_interface_add_del_feature(
7864 sw_if_index=self.pg1.sw_if_index,
7866 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7867 src_address=self.pg2.local_ip4,
7869 template_interval=10)
7870 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7874 for port in range(1025, 2025):
7875 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7876 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7877 UDP(sport=port, dport=port))
7880 self.pg0.add_stream(pkts)
7881 self.pg_enable_capture(self.pg_interfaces)
7883 capture = self.pg1.get_capture(len(pkts))
7885 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7886 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7887 UDP(sport=3001, dport=3002))
7888 self.pg0.add_stream(p)
7889 self.pg_enable_capture(self.pg_interfaces)
7891 capture = self.pg1.assert_nothing_captured()
7893 # verify ICMP error packet
7894 capture = self.pg0.get_capture(1)
7896 self.assertTrue(p.haslayer(ICMP))
7898 self.assertEqual(icmp.type, 3)
7899 self.assertEqual(icmp.code, 1)
7900 self.assertTrue(icmp.haslayer(IPerror))
7901 inner_ip = icmp[IPerror]
7902 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7903 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7905 dms = self.vapi.nat_det_map_dump()
7907 self.assertEqual(1000, dms[0].ses_num)
7909 # verify IPFIX logging
7910 self.vapi.ipfix_flush()
7912 capture = self.pg2.get_capture(2)
7913 ipfix = IPFIXDecoder()
7914 # first load template
7916 self.assertTrue(p.haslayer(IPFIX))
7917 if p.haslayer(Template):
7918 ipfix.add_template(p.getlayer(Template))
7919 # verify events in data set
7921 if p.haslayer(Data):
7922 data = ipfix.decode_data_set(p.getlayer(Set))
7923 self.verify_ipfix_max_entries_per_user(data,
7925 self.pg0.remote_ip4)
7927 def clear_nat_det(self):
7929 Clear deterministic NAT configuration.
7931 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7933 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7934 tcp_transitory=240, icmp=60)
7935 deterministic_mappings = self.vapi.nat_det_map_dump()
7936 for dsm in deterministic_mappings:
7937 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7938 in_plen=dsm.in_plen,
7939 out_addr=dsm.out_addr,
7940 out_plen=dsm.out_plen)
7942 interfaces = self.vapi.nat44_interface_dump()
7943 for intf in interfaces:
7944 self.vapi.nat44_interface_add_del_feature(
7945 sw_if_index=intf.sw_if_index,
7949 super(TestDeterministicNAT, self).tearDown()
7950 if not self.vpp_dead:
7951 self.clear_nat_det()
7953 def show_commands_at_teardown(self):
7954 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7955 self.logger.info(self.vapi.cli("show nat timeouts"))
7957 self.vapi.cli("show nat44 deterministic mappings"))
7959 self.vapi.cli("show nat44 deterministic sessions"))
7962 class TestNAT64(MethodHolder):
7963 """ NAT64 Test Cases """
7966 def setUpConstants(cls):
7967 super(TestNAT64, cls).setUpConstants()
7968 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7969 "nat64 st hash buckets 256", "}"])
7972 def setUpClass(cls):
7973 super(TestNAT64, cls).setUpClass()
7975 cls.tcp_port_in = 6303
7976 cls.tcp_port_out = 6303
7977 cls.udp_port_in = 6304
7978 cls.udp_port_out = 6304
7979 cls.icmp_id_in = 6305
7980 cls.icmp_id_out = 6305
7981 cls.tcp_external_port = 80
7982 cls.nat_addr = '10.0.0.3'
7983 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7985 cls.vrf1_nat_addr = '10.0.10.3'
7986 cls.ipfix_src_port = 4739
7987 cls.ipfix_domain_id = 1
7989 cls.create_pg_interfaces(range(6))
7990 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7991 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7992 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7994 cls.vapi.ip_table_add_del(is_add=1,
7995 table={'table_id': cls.vrf1_id,
7998 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
8000 cls.pg0.generate_remote_hosts(2)
8002 for i in cls.ip6_interfaces:
8005 i.configure_ipv6_neighbors()
8007 for i in cls.ip4_interfaces:
8013 cls.pg3.config_ip4()
8014 cls.pg3.resolve_arp()
8015 cls.pg3.config_ip6()
8016 cls.pg3.configure_ipv6_neighbors()
8019 cls.pg5.config_ip6()
8022 def tearDownClass(cls):
8023 super(TestNAT64, cls).tearDownClass()
8025 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
8026 """ NAT64 inside interface handles Neighbor Advertisement """
8028 flags = self.config_flags.NAT_IS_INSIDE
8029 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8030 sw_if_index=self.pg5.sw_if_index)
8033 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8034 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8035 ICMPv6EchoRequest())
8037 self.pg5.add_stream(pkts)
8038 self.pg_enable_capture(self.pg_interfaces)
8041 # Wait for Neighbor Solicitation
8042 capture = self.pg5.get_capture(len(pkts))
8045 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8046 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
8047 tgt = packet[ICMPv6ND_NS].tgt
8049 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8052 # Send Neighbor Advertisement
8053 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8054 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8055 ICMPv6ND_NA(tgt=tgt) /
8056 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
8058 self.pg5.add_stream(pkts)
8059 self.pg_enable_capture(self.pg_interfaces)
8062 # Try to send ping again
8064 self.pg5.add_stream(pkts)
8065 self.pg_enable_capture(self.pg_interfaces)
8068 # Wait for ping reply
8069 capture = self.pg5.get_capture(len(pkts))
8072 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8073 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
8074 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
8076 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8079 def test_pool(self):
8080 """ Add/delete address to NAT64 pool """
8081 nat_addr = '1.2.3.4'
8083 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8085 vrf_id=0xFFFFFFFF, is_add=1)
8087 addresses = self.vapi.nat64_pool_addr_dump()
8088 self.assertEqual(len(addresses), 1)
8089 self.assertEqual(str(addresses[0].address), nat_addr)
8091 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8093 vrf_id=0xFFFFFFFF, is_add=0)
8095 addresses = self.vapi.nat64_pool_addr_dump()
8096 self.assertEqual(len(addresses), 0)
8098 def test_interface(self):
8099 """ Enable/disable NAT64 feature on the interface """
8100 flags = self.config_flags.NAT_IS_INSIDE
8101 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8102 sw_if_index=self.pg0.sw_if_index)
8103 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8104 sw_if_index=self.pg1.sw_if_index)
8106 interfaces = self.vapi.nat64_interface_dump()
8107 self.assertEqual(len(interfaces), 2)
8110 for intf in interfaces:
8111 if intf.sw_if_index == self.pg0.sw_if_index:
8112 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
8114 elif intf.sw_if_index == self.pg1.sw_if_index:
8115 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
8117 self.assertTrue(pg0_found)
8118 self.assertTrue(pg1_found)
8120 features = self.vapi.cli("show interface features pg0")
8121 self.assertIn('nat64-in2out', features)
8122 features = self.vapi.cli("show interface features pg1")
8123 self.assertIn('nat64-out2in', features)
8125 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8126 sw_if_index=self.pg0.sw_if_index)
8127 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8128 sw_if_index=self.pg1.sw_if_index)
8130 interfaces = self.vapi.nat64_interface_dump()
8131 self.assertEqual(len(interfaces), 0)
8133 def test_static_bib(self):
8134 """ Add/delete static BIB entry """
8135 in_addr = '2001:db8:85a3::8a2e:370:7334'
8136 out_addr = '10.1.1.3'
8139 proto = IP_PROTOS.tcp
8141 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8142 i_port=in_port, o_port=out_port,
8143 proto=proto, vrf_id=0, is_add=1)
8144 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8147 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8149 self.assertEqual(str(bibe.i_addr), in_addr)
8150 self.assertEqual(str(bibe.o_addr), out_addr)
8151 self.assertEqual(bibe.i_port, in_port)
8152 self.assertEqual(bibe.o_port, out_port)
8153 self.assertEqual(static_bib_num, 1)
8154 bibs = self.statistics.get_counter('/nat64/total-bibs')
8155 self.assertEqual(bibs[0][0], 1)
8157 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8158 i_port=in_port, o_port=out_port,
8159 proto=proto, vrf_id=0, is_add=0)
8160 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8163 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8165 self.assertEqual(static_bib_num, 0)
8166 bibs = self.statistics.get_counter('/nat64/total-bibs')
8167 self.assertEqual(bibs[0][0], 0)
8169 def test_set_timeouts(self):
8170 """ Set NAT64 timeouts """
8171 # verify default values
8172 timeouts = self.vapi.nat_get_timeouts()
8173 self.assertEqual(timeouts.udp, 300)
8174 self.assertEqual(timeouts.icmp, 60)
8175 self.assertEqual(timeouts.tcp_transitory, 240)
8176 self.assertEqual(timeouts.tcp_established, 7440)
8178 # set and verify custom values
8179 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
8180 tcp_transitory=250, icmp=30)
8181 timeouts = self.vapi.nat_get_timeouts()
8182 self.assertEqual(timeouts.udp, 200)
8183 self.assertEqual(timeouts.icmp, 30)
8184 self.assertEqual(timeouts.tcp_transitory, 250)
8185 self.assertEqual(timeouts.tcp_established, 7450)
8187 def test_dynamic(self):
8188 """ NAT64 dynamic translation test """
8189 self.tcp_port_in = 6303
8190 self.udp_port_in = 6304
8191 self.icmp_id_in = 6305
8193 ses_num_start = self.nat64_get_ses_num()
8195 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8196 end_addr=self.nat_addr,
8199 flags = self.config_flags.NAT_IS_INSIDE
8200 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8201 sw_if_index=self.pg0.sw_if_index)
8202 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8203 sw_if_index=self.pg1.sw_if_index)
8206 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8207 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8208 icmpn = self.statistics.get_err_counter(
8209 '/err/nat64-in2out/ICMP packets')
8210 totaln = self.statistics.get_err_counter(
8211 '/err/nat64-in2out/good in2out packets processed')
8213 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8214 self.pg0.add_stream(pkts)
8215 self.pg_enable_capture(self.pg_interfaces)
8217 capture = self.pg1.get_capture(len(pkts))
8218 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8219 dst_ip=self.pg1.remote_ip4)
8221 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8222 self.assertEqual(err - tcpn, 1)
8223 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8224 self.assertEqual(err - udpn, 1)
8225 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8226 self.assertEqual(err - icmpn, 1)
8227 err = self.statistics.get_err_counter(
8228 '/err/nat64-in2out/good in2out packets processed')
8229 self.assertEqual(err - totaln, 3)
8232 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8233 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8234 icmpn = self.statistics.get_err_counter(
8235 '/err/nat64-out2in/ICMP packets')
8236 totaln = self.statistics.get_err_counter(
8237 '/err/nat64-out2in/good out2in packets processed')
8239 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8240 self.pg1.add_stream(pkts)
8241 self.pg_enable_capture(self.pg_interfaces)
8243 capture = self.pg0.get_capture(len(pkts))
8244 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8245 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8247 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8248 self.assertEqual(err - tcpn, 2)
8249 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8250 self.assertEqual(err - udpn, 1)
8251 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8252 self.assertEqual(err - icmpn, 1)
8253 err = self.statistics.get_err_counter(
8254 '/err/nat64-out2in/good out2in packets processed')
8255 self.assertEqual(err - totaln, 4)
8257 bibs = self.statistics.get_counter('/nat64/total-bibs')
8258 self.assertEqual(bibs[0][0], 3)
8259 sessions = self.statistics.get_counter('/nat64/total-sessions')
8260 self.assertEqual(sessions[0][0], 3)
8263 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8264 self.pg0.add_stream(pkts)
8265 self.pg_enable_capture(self.pg_interfaces)
8267 capture = self.pg1.get_capture(len(pkts))
8268 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8269 dst_ip=self.pg1.remote_ip4)
8272 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8273 self.pg1.add_stream(pkts)
8274 self.pg_enable_capture(self.pg_interfaces)
8276 capture = self.pg0.get_capture(len(pkts))
8277 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8279 ses_num_end = self.nat64_get_ses_num()
8281 self.assertEqual(ses_num_end - ses_num_start, 3)
8283 # tenant with specific VRF
8284 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8285 end_addr=self.vrf1_nat_addr,
8286 vrf_id=self.vrf1_id, is_add=1)
8287 flags = self.config_flags.NAT_IS_INSIDE
8288 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8289 sw_if_index=self.pg2.sw_if_index)
8291 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8292 self.pg2.add_stream(pkts)
8293 self.pg_enable_capture(self.pg_interfaces)
8295 capture = self.pg1.get_capture(len(pkts))
8296 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8297 dst_ip=self.pg1.remote_ip4)
8299 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8300 self.pg1.add_stream(pkts)
8301 self.pg_enable_capture(self.pg_interfaces)
8303 capture = self.pg2.get_capture(len(pkts))
8304 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8306 def test_static(self):
8307 """ NAT64 static translation test """
8308 self.tcp_port_in = 60303
8309 self.udp_port_in = 60304
8310 self.icmp_id_in = 60305
8311 self.tcp_port_out = 60303
8312 self.udp_port_out = 60304
8313 self.icmp_id_out = 60305
8315 ses_num_start = self.nat64_get_ses_num()
8317 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8318 end_addr=self.nat_addr,
8321 flags = self.config_flags.NAT_IS_INSIDE
8322 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8323 sw_if_index=self.pg0.sw_if_index)
8324 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8325 sw_if_index=self.pg1.sw_if_index)
8327 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8328 o_addr=self.nat_addr,
8329 i_port=self.tcp_port_in,
8330 o_port=self.tcp_port_out,
8331 proto=IP_PROTOS.tcp, vrf_id=0,
8333 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8334 o_addr=self.nat_addr,
8335 i_port=self.udp_port_in,
8336 o_port=self.udp_port_out,
8337 proto=IP_PROTOS.udp, vrf_id=0,
8339 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8340 o_addr=self.nat_addr,
8341 i_port=self.icmp_id_in,
8342 o_port=self.icmp_id_out,
8343 proto=IP_PROTOS.icmp, vrf_id=0,
8347 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8348 self.pg0.add_stream(pkts)
8349 self.pg_enable_capture(self.pg_interfaces)
8351 capture = self.pg1.get_capture(len(pkts))
8352 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8353 dst_ip=self.pg1.remote_ip4, same_port=True)
8356 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8357 self.pg1.add_stream(pkts)
8358 self.pg_enable_capture(self.pg_interfaces)
8360 capture = self.pg0.get_capture(len(pkts))
8361 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8362 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8364 ses_num_end = self.nat64_get_ses_num()
8366 self.assertEqual(ses_num_end - ses_num_start, 3)
8368 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8369 def test_session_timeout(self):
8370 """ NAT64 session timeout """
8371 self.icmp_id_in = 1234
8372 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8373 end_addr=self.nat_addr,
8376 flags = self.config_flags.NAT_IS_INSIDE
8377 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8378 sw_if_index=self.pg0.sw_if_index)
8379 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8380 sw_if_index=self.pg1.sw_if_index)
8381 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8385 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8386 self.pg0.add_stream(pkts)
8387 self.pg_enable_capture(self.pg_interfaces)
8389 capture = self.pg1.get_capture(len(pkts))
8391 ses_num_before_timeout = self.nat64_get_ses_num()
8395 # ICMP and TCP session after timeout
8396 ses_num_after_timeout = self.nat64_get_ses_num()
8397 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8399 def test_icmp_error(self):
8400 """ NAT64 ICMP Error message translation """
8401 self.tcp_port_in = 6303
8402 self.udp_port_in = 6304
8403 self.icmp_id_in = 6305
8405 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8406 end_addr=self.nat_addr,
8409 flags = self.config_flags.NAT_IS_INSIDE
8410 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8411 sw_if_index=self.pg0.sw_if_index)
8412 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8413 sw_if_index=self.pg1.sw_if_index)
8415 # send some packets to create sessions
8416 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8417 self.pg0.add_stream(pkts)
8418 self.pg_enable_capture(self.pg_interfaces)
8420 capture_ip4 = self.pg1.get_capture(len(pkts))
8421 self.verify_capture_out(capture_ip4,
8422 nat_ip=self.nat_addr,
8423 dst_ip=self.pg1.remote_ip4)
8425 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8426 self.pg1.add_stream(pkts)
8427 self.pg_enable_capture(self.pg_interfaces)
8429 capture_ip6 = self.pg0.get_capture(len(pkts))
8430 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8431 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8432 self.pg0.remote_ip6)
8435 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8436 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8437 ICMPv6DestUnreach(code=1) /
8438 packet[IPv6] for packet in capture_ip6]
8439 self.pg0.add_stream(pkts)
8440 self.pg_enable_capture(self.pg_interfaces)
8442 capture = self.pg1.get_capture(len(pkts))
8443 for packet in capture:
8445 self.assertEqual(packet[IP].src, self.nat_addr)
8446 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8447 self.assertEqual(packet[ICMP].type, 3)
8448 self.assertEqual(packet[ICMP].code, 13)
8449 inner = packet[IPerror]
8450 self.assertEqual(inner.src, self.pg1.remote_ip4)
8451 self.assertEqual(inner.dst, self.nat_addr)
8452 self.assert_packet_checksums_valid(packet)
8453 if inner.haslayer(TCPerror):
8454 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8455 elif inner.haslayer(UDPerror):
8456 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8458 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8460 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8464 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8465 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8466 ICMP(type=3, code=13) /
8467 packet[IP] for packet in capture_ip4]
8468 self.pg1.add_stream(pkts)
8469 self.pg_enable_capture(self.pg_interfaces)
8471 capture = self.pg0.get_capture(len(pkts))
8472 for packet in capture:
8474 self.assertEqual(packet[IPv6].src, ip.src)
8475 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8476 icmp = packet[ICMPv6DestUnreach]
8477 self.assertEqual(icmp.code, 1)
8478 inner = icmp[IPerror6]
8479 self.assertEqual(inner.src, self.pg0.remote_ip6)
8480 self.assertEqual(inner.dst, ip.src)
8481 self.assert_icmpv6_checksum_valid(packet)
8482 if inner.haslayer(TCPerror):
8483 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8484 elif inner.haslayer(UDPerror):
8485 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8487 self.assertEqual(inner[ICMPv6EchoRequest].id,
8490 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8493 def test_hairpinning(self):
8494 """ NAT64 hairpinning """
8496 client = self.pg0.remote_hosts[0]
8497 server = self.pg0.remote_hosts[1]
8498 server_tcp_in_port = 22
8499 server_tcp_out_port = 4022
8500 server_udp_in_port = 23
8501 server_udp_out_port = 4023
8502 client_tcp_in_port = 1234
8503 client_udp_in_port = 1235
8504 client_tcp_out_port = 0
8505 client_udp_out_port = 0
8506 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8507 nat_addr_ip6 = ip.src
8509 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8510 end_addr=self.nat_addr,
8513 flags = self.config_flags.NAT_IS_INSIDE
8514 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8515 sw_if_index=self.pg0.sw_if_index)
8516 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8517 sw_if_index=self.pg1.sw_if_index)
8519 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8520 o_addr=self.nat_addr,
8521 i_port=server_tcp_in_port,
8522 o_port=server_tcp_out_port,
8523 proto=IP_PROTOS.tcp, vrf_id=0,
8525 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8526 o_addr=self.nat_addr,
8527 i_port=server_udp_in_port,
8528 o_port=server_udp_out_port,
8529 proto=IP_PROTOS.udp, vrf_id=0,
8534 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8535 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8536 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8538 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8539 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8540 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8542 self.pg0.add_stream(pkts)
8543 self.pg_enable_capture(self.pg_interfaces)
8545 capture = self.pg0.get_capture(len(pkts))
8546 for packet in capture:
8548 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8549 self.assertEqual(packet[IPv6].dst, server.ip6)
8550 self.assert_packet_checksums_valid(packet)
8551 if packet.haslayer(TCP):
8552 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8553 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8554 client_tcp_out_port = packet[TCP].sport
8556 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8557 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8558 client_udp_out_port = packet[UDP].sport
8560 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8565 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8566 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8567 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8569 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8570 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8571 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8573 self.pg0.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, nat_addr_ip6)
8580 self.assertEqual(packet[IPv6].dst, client.ip6)
8581 self.assert_packet_checksums_valid(packet)
8582 if packet.haslayer(TCP):
8583 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8584 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8586 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8587 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8589 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8594 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8595 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8596 ICMPv6DestUnreach(code=1) /
8597 packet[IPv6] for packet in capture]
8598 self.pg0.add_stream(pkts)
8599 self.pg_enable_capture(self.pg_interfaces)
8601 capture = self.pg0.get_capture(len(pkts))
8602 for packet in capture:
8604 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8605 self.assertEqual(packet[IPv6].dst, server.ip6)
8606 icmp = packet[ICMPv6DestUnreach]
8607 self.assertEqual(icmp.code, 1)
8608 inner = icmp[IPerror6]
8609 self.assertEqual(inner.src, server.ip6)
8610 self.assertEqual(inner.dst, nat_addr_ip6)
8611 self.assert_packet_checksums_valid(packet)
8612 if inner.haslayer(TCPerror):
8613 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8614 self.assertEqual(inner[TCPerror].dport,
8615 client_tcp_out_port)
8617 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8618 self.assertEqual(inner[UDPerror].dport,
8619 client_udp_out_port)
8621 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8624 def test_prefix(self):
8625 """ NAT64 Network-Specific Prefix """
8627 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8628 end_addr=self.nat_addr,
8631 flags = self.config_flags.NAT_IS_INSIDE
8632 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8633 sw_if_index=self.pg0.sw_if_index)
8634 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8635 sw_if_index=self.pg1.sw_if_index)
8636 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8637 end_addr=self.vrf1_nat_addr,
8638 vrf_id=self.vrf1_id, is_add=1)
8639 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8640 sw_if_index=self.pg2.sw_if_index)
8643 global_pref64 = "2001:db8::"
8644 global_pref64_len = 32
8645 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8646 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8649 prefix = self.vapi.nat64_prefix_dump()
8650 self.assertEqual(len(prefix), 1)
8651 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8652 self.assertEqual(prefix[0].vrf_id, 0)
8654 # Add tenant specific prefix
8655 vrf1_pref64 = "2001:db8:122:300::"
8656 vrf1_pref64_len = 56
8657 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8658 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8659 vrf_id=self.vrf1_id, is_add=1)
8661 prefix = self.vapi.nat64_prefix_dump()
8662 self.assertEqual(len(prefix), 2)
8665 pkts = self.create_stream_in_ip6(self.pg0,
8668 plen=global_pref64_len)
8669 self.pg0.add_stream(pkts)
8670 self.pg_enable_capture(self.pg_interfaces)
8672 capture = self.pg1.get_capture(len(pkts))
8673 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8674 dst_ip=self.pg1.remote_ip4)
8676 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8677 self.pg1.add_stream(pkts)
8678 self.pg_enable_capture(self.pg_interfaces)
8680 capture = self.pg0.get_capture(len(pkts))
8681 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8684 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8686 # Tenant specific prefix
8687 pkts = self.create_stream_in_ip6(self.pg2,
8690 plen=vrf1_pref64_len)
8691 self.pg2.add_stream(pkts)
8692 self.pg_enable_capture(self.pg_interfaces)
8694 capture = self.pg1.get_capture(len(pkts))
8695 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8696 dst_ip=self.pg1.remote_ip4)
8698 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8699 self.pg1.add_stream(pkts)
8700 self.pg_enable_capture(self.pg_interfaces)
8702 capture = self.pg2.get_capture(len(pkts))
8703 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8706 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8708 def test_unknown_proto(self):
8709 """ NAT64 translate packet with unknown protocol """
8711 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8712 end_addr=self.nat_addr,
8715 flags = self.config_flags.NAT_IS_INSIDE
8716 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8717 sw_if_index=self.pg0.sw_if_index)
8718 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8719 sw_if_index=self.pg1.sw_if_index)
8720 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8723 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8724 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8725 TCP(sport=self.tcp_port_in, dport=20))
8726 self.pg0.add_stream(p)
8727 self.pg_enable_capture(self.pg_interfaces)
8729 p = self.pg1.get_capture(1)
8731 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8732 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8734 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8735 TCP(sport=1234, dport=1234))
8736 self.pg0.add_stream(p)
8737 self.pg_enable_capture(self.pg_interfaces)
8739 p = self.pg1.get_capture(1)
8742 self.assertEqual(packet[IP].src, self.nat_addr)
8743 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8744 self.assertEqual(packet.haslayer(GRE), 1)
8745 self.assert_packet_checksums_valid(packet)
8747 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8751 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8752 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8754 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8755 TCP(sport=1234, dport=1234))
8756 self.pg1.add_stream(p)
8757 self.pg_enable_capture(self.pg_interfaces)
8759 p = self.pg0.get_capture(1)
8762 self.assertEqual(packet[IPv6].src, remote_ip6)
8763 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8764 self.assertEqual(packet[IPv6].nh, 47)
8766 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8769 def test_hairpinning_unknown_proto(self):
8770 """ NAT64 translate packet with unknown protocol - hairpinning """
8772 client = self.pg0.remote_hosts[0]
8773 server = self.pg0.remote_hosts[1]
8774 server_tcp_in_port = 22
8775 server_tcp_out_port = 4022
8776 client_tcp_in_port = 1234
8777 client_tcp_out_port = 1235
8778 server_nat_ip = "10.0.0.100"
8779 client_nat_ip = "10.0.0.110"
8780 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8781 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8783 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8784 end_addr=client_nat_ip,
8787 flags = self.config_flags.NAT_IS_INSIDE
8788 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8789 sw_if_index=self.pg0.sw_if_index)
8790 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8791 sw_if_index=self.pg1.sw_if_index)
8793 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8794 o_addr=server_nat_ip,
8795 i_port=server_tcp_in_port,
8796 o_port=server_tcp_out_port,
8797 proto=IP_PROTOS.tcp, vrf_id=0,
8800 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8801 o_addr=server_nat_ip, i_port=0,
8803 proto=IP_PROTOS.gre, vrf_id=0,
8806 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8807 o_addr=client_nat_ip,
8808 i_port=client_tcp_in_port,
8809 o_port=client_tcp_out_port,
8810 proto=IP_PROTOS.tcp, vrf_id=0,
8814 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8815 IPv6(src=client.ip6, dst=server_nat_ip6) /
8816 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8817 self.pg0.add_stream(p)
8818 self.pg_enable_capture(self.pg_interfaces)
8820 p = self.pg0.get_capture(1)
8822 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8823 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8825 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8826 TCP(sport=1234, dport=1234))
8827 self.pg0.add_stream(p)
8828 self.pg_enable_capture(self.pg_interfaces)
8830 p = self.pg0.get_capture(1)
8833 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8834 self.assertEqual(packet[IPv6].dst, server.ip6)
8835 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8837 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8841 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8842 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8844 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8845 TCP(sport=1234, dport=1234))
8846 self.pg0.add_stream(p)
8847 self.pg_enable_capture(self.pg_interfaces)
8849 p = self.pg0.get_capture(1)
8852 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8853 self.assertEqual(packet[IPv6].dst, client.ip6)
8854 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8856 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8859 def test_one_armed_nat64(self):
8860 """ One armed NAT64 """
8862 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8866 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8867 end_addr=self.nat_addr,
8870 flags = self.config_flags.NAT_IS_INSIDE
8871 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8872 sw_if_index=self.pg3.sw_if_index)
8873 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8874 sw_if_index=self.pg3.sw_if_index)
8877 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8878 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8879 TCP(sport=12345, dport=80))
8880 self.pg3.add_stream(p)
8881 self.pg_enable_capture(self.pg_interfaces)
8883 capture = self.pg3.get_capture(1)
8888 self.assertEqual(ip.src, self.nat_addr)
8889 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8890 self.assertNotEqual(tcp.sport, 12345)
8891 external_port = tcp.sport
8892 self.assertEqual(tcp.dport, 80)
8893 self.assert_packet_checksums_valid(p)
8895 self.logger.error(ppp("Unexpected or invalid packet:", p))
8899 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8900 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8901 TCP(sport=80, dport=external_port))
8902 self.pg3.add_stream(p)
8903 self.pg_enable_capture(self.pg_interfaces)
8905 capture = self.pg3.get_capture(1)
8910 self.assertEqual(ip.src, remote_host_ip6)
8911 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8912 self.assertEqual(tcp.sport, 80)
8913 self.assertEqual(tcp.dport, 12345)
8914 self.assert_packet_checksums_valid(p)
8916 self.logger.error(ppp("Unexpected or invalid packet:", p))
8919 def test_frag_in_order(self):
8920 """ NAT64 translate fragments arriving in order """
8921 self.tcp_port_in = random.randint(1025, 65535)
8923 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8924 end_addr=self.nat_addr,
8927 flags = self.config_flags.NAT_IS_INSIDE
8928 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8929 sw_if_index=self.pg0.sw_if_index)
8930 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8931 sw_if_index=self.pg1.sw_if_index)
8935 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8936 self.tcp_port_in, 20, data)
8937 self.pg0.add_stream(pkts)
8938 self.pg_enable_capture(self.pg_interfaces)
8940 frags = self.pg1.get_capture(len(pkts))
8941 p = self.reass_frags_and_verify(frags,
8943 self.pg1.remote_ip4)
8944 self.assertEqual(p[TCP].dport, 20)
8945 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8946 self.tcp_port_out = p[TCP].sport
8947 self.assertEqual(data, p[Raw].load)
8950 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8951 pkts = self.create_stream_frag(self.pg1,
8956 self.pg1.add_stream(pkts)
8957 self.pg_enable_capture(self.pg_interfaces)
8959 frags = self.pg0.get_capture(len(pkts))
8960 self.logger.debug(ppc("Captured:", frags))
8961 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8962 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8963 self.assertEqual(p[TCP].sport, 20)
8964 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8965 self.assertEqual(data, p[Raw].load)
8967 def test_reass_hairpinning(self):
8968 """ NAT64 fragments hairpinning """
8970 server = self.pg0.remote_hosts[1]
8971 server_in_port = random.randint(1025, 65535)
8972 server_out_port = random.randint(1025, 65535)
8973 client_in_port = random.randint(1025, 65535)
8974 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8975 nat_addr_ip6 = ip.src
8977 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8978 end_addr=self.nat_addr,
8981 flags = self.config_flags.NAT_IS_INSIDE
8982 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8983 sw_if_index=self.pg0.sw_if_index)
8984 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8985 sw_if_index=self.pg1.sw_if_index)
8987 # add static BIB entry for server
8988 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8989 o_addr=self.nat_addr,
8990 i_port=server_in_port,
8991 o_port=server_out_port,
8992 proto=IP_PROTOS.tcp, vrf_id=0,
8995 # send packet from host to server
8996 pkts = self.create_stream_frag_ip6(self.pg0,
9001 self.pg0.add_stream(pkts)
9002 self.pg_enable_capture(self.pg_interfaces)
9004 frags = self.pg0.get_capture(len(pkts))
9005 self.logger.debug(ppc("Captured:", frags))
9006 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
9007 self.assertNotEqual(p[TCP].sport, client_in_port)
9008 self.assertEqual(p[TCP].dport, server_in_port)
9009 self.assertEqual(data, p[Raw].load)
9011 def test_frag_out_of_order(self):
9012 """ NAT64 translate fragments arriving out of order """
9013 self.tcp_port_in = random.randint(1025, 65535)
9015 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9016 end_addr=self.nat_addr,
9019 flags = self.config_flags.NAT_IS_INSIDE
9020 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9021 sw_if_index=self.pg0.sw_if_index)
9022 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9023 sw_if_index=self.pg1.sw_if_index)
9027 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9028 self.tcp_port_in, 20, data)
9030 self.pg0.add_stream(pkts)
9031 self.pg_enable_capture(self.pg_interfaces)
9033 frags = self.pg1.get_capture(len(pkts))
9034 p = self.reass_frags_and_verify(frags,
9036 self.pg1.remote_ip4)
9037 self.assertEqual(p[TCP].dport, 20)
9038 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9039 self.tcp_port_out = p[TCP].sport
9040 self.assertEqual(data, p[Raw].load)
9043 data = b"A" * 4 + b"B" * 16 + b"C" * 3
9044 pkts = self.create_stream_frag(self.pg1,
9050 self.pg1.add_stream(pkts)
9051 self.pg_enable_capture(self.pg_interfaces)
9053 frags = self.pg0.get_capture(len(pkts))
9054 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9055 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9056 self.assertEqual(p[TCP].sport, 20)
9057 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9058 self.assertEqual(data, p[Raw].load)
9060 def test_interface_addr(self):
9061 """ Acquire NAT64 pool addresses from interface """
9062 self.vapi.nat64_add_del_interface_addr(
9064 sw_if_index=self.pg4.sw_if_index)
9066 # no address in NAT64 pool
9067 addresses = self.vapi.nat44_address_dump()
9068 self.assertEqual(0, len(addresses))
9070 # configure interface address and check NAT64 address pool
9071 self.pg4.config_ip4()
9072 addresses = self.vapi.nat64_pool_addr_dump()
9073 self.assertEqual(len(addresses), 1)
9075 self.assertEqual(str(addresses[0].address),
9078 # remove interface address and check NAT64 address pool
9079 self.pg4.unconfig_ip4()
9080 addresses = self.vapi.nat64_pool_addr_dump()
9081 self.assertEqual(0, len(addresses))
9083 @unittest.skipUnless(running_extended_tests, "part of extended tests")
9084 def test_ipfix_max_bibs_sessions(self):
9085 """ IPFIX logging maximum session and BIB entries exceeded """
9088 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9092 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9093 end_addr=self.nat_addr,
9096 flags = self.config_flags.NAT_IS_INSIDE
9097 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9098 sw_if_index=self.pg0.sw_if_index)
9099 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9100 sw_if_index=self.pg1.sw_if_index)
9104 for i in range(0, max_bibs):
9105 src = "fd01:aa::%x" % (i)
9106 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9107 IPv6(src=src, dst=remote_host_ip6) /
9108 TCP(sport=12345, dport=80))
9110 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9111 IPv6(src=src, dst=remote_host_ip6) /
9112 TCP(sport=12345, dport=22))
9114 self.pg0.add_stream(pkts)
9115 self.pg_enable_capture(self.pg_interfaces)
9117 self.pg1.get_capture(max_sessions)
9119 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9120 src_address=self.pg3.local_ip4,
9122 template_interval=10)
9123 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9124 src_port=self.ipfix_src_port,
9127 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9128 IPv6(src=src, dst=remote_host_ip6) /
9129 TCP(sport=12345, dport=25))
9130 self.pg0.add_stream(p)
9131 self.pg_enable_capture(self.pg_interfaces)
9133 self.pg1.assert_nothing_captured()
9135 self.vapi.ipfix_flush()
9136 capture = self.pg3.get_capture(7)
9137 ipfix = IPFIXDecoder()
9138 # first load template
9140 self.assertTrue(p.haslayer(IPFIX))
9141 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9142 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9143 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9144 self.assertEqual(p[UDP].dport, 4739)
9145 self.assertEqual(p[IPFIX].observationDomainID,
9146 self.ipfix_domain_id)
9147 if p.haslayer(Template):
9148 ipfix.add_template(p.getlayer(Template))
9149 # verify events in data set
9151 if p.haslayer(Data):
9152 data = ipfix.decode_data_set(p.getlayer(Set))
9153 self.verify_ipfix_max_sessions(data, max_sessions)
9155 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9156 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9157 TCP(sport=12345, dport=80))
9158 self.pg0.add_stream(p)
9159 self.pg_enable_capture(self.pg_interfaces)
9161 self.pg1.assert_nothing_captured()
9163 self.vapi.ipfix_flush()
9164 capture = self.pg3.get_capture(1)
9165 # verify events in data set
9167 self.assertTrue(p.haslayer(IPFIX))
9168 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9169 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9170 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9171 self.assertEqual(p[UDP].dport, 4739)
9172 self.assertEqual(p[IPFIX].observationDomainID,
9173 self.ipfix_domain_id)
9174 if p.haslayer(Data):
9175 data = ipfix.decode_data_set(p.getlayer(Set))
9176 self.verify_ipfix_max_bibs(data, max_bibs)
9178 def test_ipfix_bib_ses(self):
9179 """ IPFIX logging NAT64 BIB/session create and delete events """
9180 self.tcp_port_in = random.randint(1025, 65535)
9181 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9185 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9186 end_addr=self.nat_addr,
9189 flags = self.config_flags.NAT_IS_INSIDE
9190 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9191 sw_if_index=self.pg0.sw_if_index)
9192 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9193 sw_if_index=self.pg1.sw_if_index)
9194 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9195 src_address=self.pg3.local_ip4,
9197 template_interval=10)
9198 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9199 src_port=self.ipfix_src_port,
9203 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9204 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9205 TCP(sport=self.tcp_port_in, dport=25))
9206 self.pg0.add_stream(p)
9207 self.pg_enable_capture(self.pg_interfaces)
9209 p = self.pg1.get_capture(1)
9210 self.tcp_port_out = p[0][TCP].sport
9211 self.vapi.ipfix_flush()
9212 capture = self.pg3.get_capture(8)
9213 ipfix = IPFIXDecoder()
9214 # first load template
9216 self.assertTrue(p.haslayer(IPFIX))
9217 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9218 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9219 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9220 self.assertEqual(p[UDP].dport, 4739)
9221 self.assertEqual(p[IPFIX].observationDomainID,
9222 self.ipfix_domain_id)
9223 if p.haslayer(Template):
9224 ipfix.add_template(p.getlayer(Template))
9225 # verify events in data set
9227 if p.haslayer(Data):
9228 data = ipfix.decode_data_set(p.getlayer(Set))
9229 if scapy.compat.orb(data[0][230]) == 10:
9230 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
9231 elif scapy.compat.orb(data[0][230]) == 6:
9232 self.verify_ipfix_nat64_ses(data,
9234 self.pg0.remote_ip6,
9235 self.pg1.remote_ip4,
9238 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9241 self.pg_enable_capture(self.pg_interfaces)
9242 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9243 end_addr=self.nat_addr,
9246 self.vapi.ipfix_flush()
9247 capture = self.pg3.get_capture(2)
9248 # verify events in data set
9250 self.assertTrue(p.haslayer(IPFIX))
9251 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9252 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9253 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9254 self.assertEqual(p[UDP].dport, 4739)
9255 self.assertEqual(p[IPFIX].observationDomainID,
9256 self.ipfix_domain_id)
9257 if p.haslayer(Data):
9258 data = ipfix.decode_data_set(p.getlayer(Set))
9259 if scapy.compat.orb(data[0][230]) == 11:
9260 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
9261 elif scapy.compat.orb(data[0][230]) == 7:
9262 self.verify_ipfix_nat64_ses(data,
9264 self.pg0.remote_ip6,
9265 self.pg1.remote_ip4,
9268 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9270 def test_syslog_sess(self):
9271 """ Test syslog session creation and deletion """
9272 self.tcp_port_in = random.randint(1025, 65535)
9273 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9277 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9278 end_addr=self.nat_addr,
9281 flags = self.config_flags.NAT_IS_INSIDE
9282 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9283 sw_if_index=self.pg0.sw_if_index)
9284 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9285 sw_if_index=self.pg1.sw_if_index)
9286 self.vapi.syslog_set_filter(
9287 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9288 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9290 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9291 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9292 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9293 self.pg0.add_stream(p)
9294 self.pg_enable_capture(self.pg_interfaces)
9296 p = self.pg1.get_capture(1)
9297 self.tcp_port_out = p[0][TCP].sport
9298 capture = self.pg3.get_capture(1)
9299 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9301 self.pg_enable_capture(self.pg_interfaces)
9303 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9304 end_addr=self.nat_addr,
9307 capture = self.pg3.get_capture(1)
9308 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9310 def nat64_get_ses_num(self):
9312 Return number of active NAT64 sessions.
9314 st = self.vapi.nat64_st_dump(proto=255)
9317 def clear_nat64(self):
9319 Clear NAT64 configuration.
9321 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9322 src_port=self.ipfix_src_port,
9324 self.ipfix_src_port = 4739
9325 self.ipfix_domain_id = 1
9327 self.vapi.syslog_set_filter(
9328 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9330 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9331 tcp_transitory=240, icmp=60)
9333 interfaces = self.vapi.nat64_interface_dump()
9334 for intf in interfaces:
9335 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9336 sw_if_index=intf.sw_if_index)
9338 bib = self.vapi.nat64_bib_dump(proto=255)
9340 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9341 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9349 adresses = self.vapi.nat64_pool_addr_dump()
9350 for addr in adresses:
9351 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9352 end_addr=addr.address,
9356 prefixes = self.vapi.nat64_prefix_dump()
9357 for prefix in prefixes:
9358 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9359 vrf_id=prefix.vrf_id, is_add=0)
9361 bibs = self.statistics.get_counter('/nat64/total-bibs')
9362 self.assertEqual(bibs[0][0], 0)
9363 sessions = self.statistics.get_counter('/nat64/total-sessions')
9364 self.assertEqual(sessions[0][0], 0)
9367 super(TestNAT64, self).tearDown()
9368 if not self.vpp_dead:
9371 def show_commands_at_teardown(self):
9372 self.logger.info(self.vapi.cli("show nat64 pool"))
9373 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9374 self.logger.info(self.vapi.cli("show nat64 prefix"))
9375 self.logger.info(self.vapi.cli("show nat64 bib all"))
9376 self.logger.info(self.vapi.cli("show nat64 session table all"))
9379 class TestNAT66(MethodHolder):
9380 """ NAT66 Test Cases """
9383 def setUpClass(cls):
9384 super(TestNAT66, cls).setUpClass()
9386 cls.nat_addr = 'fd01:ff::2'
9388 cls.create_pg_interfaces(range(2))
9389 cls.interfaces = list(cls.pg_interfaces)
9391 for i in cls.interfaces:
9394 i.configure_ipv6_neighbors()
9397 def tearDownClass(cls):
9398 super(TestNAT66, cls).tearDownClass()
9400 def test_static(self):
9401 """ 1:1 NAT66 test """
9402 flags = self.config_flags.NAT_IS_INSIDE
9403 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9404 sw_if_index=self.pg0.sw_if_index)
9405 self.vapi.nat66_add_del_interface(is_add=1,
9406 sw_if_index=self.pg1.sw_if_index)
9407 self.vapi.nat66_add_del_static_mapping(
9408 local_ip_address=self.pg0.remote_ip6,
9409 external_ip_address=self.nat_addr,
9414 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9415 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9418 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9419 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9422 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9423 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9424 ICMPv6EchoRequest())
9426 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9427 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9428 GRE() / IP() / TCP())
9430 self.pg0.add_stream(pkts)
9431 self.pg_enable_capture(self.pg_interfaces)
9433 capture = self.pg1.get_capture(len(pkts))
9435 for packet in capture:
9437 self.assertEqual(packet[IPv6].src, self.nat_addr)
9438 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9439 self.assert_packet_checksums_valid(packet)
9441 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9446 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9447 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9450 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9451 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9454 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9455 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9458 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9459 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9460 GRE() / IP() / TCP())
9462 self.pg1.add_stream(pkts)
9463 self.pg_enable_capture(self.pg_interfaces)
9465 capture = self.pg0.get_capture(len(pkts))
9466 for packet in capture:
9468 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9469 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9470 self.assert_packet_checksums_valid(packet)
9472 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9475 sm = self.vapi.nat66_static_mapping_dump()
9476 self.assertEqual(len(sm), 1)
9477 self.assertEqual(sm[0].total_pkts, 8)
9479 def test_check_no_translate(self):
9480 """ NAT66 translate only when egress interface is outside interface """
9481 flags = self.config_flags.NAT_IS_INSIDE
9482 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9483 sw_if_index=self.pg0.sw_if_index)
9484 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9485 sw_if_index=self.pg1.sw_if_index)
9486 self.vapi.nat66_add_del_static_mapping(
9487 local_ip_address=self.pg0.remote_ip6,
9488 external_ip_address=self.nat_addr,
9492 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9493 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9495 self.pg0.add_stream([p])
9496 self.pg_enable_capture(self.pg_interfaces)
9498 capture = self.pg1.get_capture(1)
9501 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9502 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9504 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9507 def clear_nat66(self):
9509 Clear NAT66 configuration.
9511 interfaces = self.vapi.nat66_interface_dump()
9512 for intf in interfaces:
9513 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9514 sw_if_index=intf.sw_if_index)
9516 static_mappings = self.vapi.nat66_static_mapping_dump()
9517 for sm in static_mappings:
9518 self.vapi.nat66_add_del_static_mapping(
9519 local_ip_address=sm.local_ip_address,
9520 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9524 super(TestNAT66, self).tearDown()
9527 def show_commands_at_teardown(self):
9528 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9529 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9532 if __name__ == '__main__':
9533 unittest.main(testRunner=VppTestRunner)