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_output_feature_vrf(self):
4716 """ NAT44 dynamic translation test: output-feature, VRF"""
4718 # other then default (0)
4721 self.nat44_add_address(self.nat_addr)
4722 flags = self.config_flags.NAT_IS_INSIDE
4723 self.vapi.nat44_interface_add_del_output_feature(
4724 sw_if_index=self.pg7.sw_if_index,
4725 flags=flags, is_add=1)
4726 self.vapi.nat44_interface_add_del_output_feature(
4727 sw_if_index=self.pg8.sw_if_index,
4731 self.vapi.ip_table_add_del(is_add=1,
4732 table={'table_id': new_vrf_id})
4734 self.pg7.unconfig_ip4()
4735 self.pg7.set_table_ip4(new_vrf_id)
4736 self.pg7.config_ip4()
4737 self.pg7.resolve_arp()
4739 self.pg8.unconfig_ip4()
4740 self.pg8.set_table_ip4(new_vrf_id)
4741 self.pg8.config_ip4()
4742 self.pg8.resolve_arp()
4744 nat_config = self.vapi.nat_show_config()
4745 self.assertEqual(1, nat_config.endpoint_dependent)
4748 tcpn = self.statistics.get_err_counter(
4749 '/err/nat44-ed-in2out-slowpath/TCP packets')
4750 udpn = self.statistics.get_err_counter(
4751 '/err/nat44-ed-in2out-slowpath/UDP packets')
4752 icmpn = self.statistics.get_err_counter(
4753 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4754 totaln = self.statistics.get_err_counter(
4755 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4757 pkts = self.create_stream_in(self.pg7, self.pg8)
4758 self.pg7.add_stream(pkts)
4759 self.pg_enable_capture(self.pg_interfaces)
4761 capture = self.pg8.get_capture(len(pkts))
4762 self.verify_capture_out(capture)
4764 err = self.statistics.get_err_counter(
4765 '/err/nat44-ed-in2out-slowpath/TCP packets')
4766 self.assertEqual(err - tcpn, 2)
4767 err = self.statistics.get_err_counter(
4768 '/err/nat44-ed-in2out-slowpath/UDP packets')
4769 self.assertEqual(err - udpn, 1)
4770 err = self.statistics.get_err_counter(
4771 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4772 self.assertEqual(err - icmpn, 1)
4773 err = self.statistics.get_err_counter(
4774 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4775 self.assertEqual(err - totaln, 4)
4778 tcpn = self.statistics.get_err_counter(
4779 '/err/nat44-ed-out2in/TCP packets')
4780 udpn = self.statistics.get_err_counter(
4781 '/err/nat44-ed-out2in/UDP packets')
4782 icmpn = self.statistics.get_err_counter(
4783 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4784 totaln = self.statistics.get_err_counter(
4785 '/err/nat44-ed-out2in/good out2in packets processed')
4787 pkts = self.create_stream_out(self.pg8)
4788 self.pg8.add_stream(pkts)
4789 self.pg_enable_capture(self.pg_interfaces)
4791 capture = self.pg7.get_capture(len(pkts))
4792 self.verify_capture_in(capture, self.pg7)
4794 err = self.statistics.get_err_counter(
4795 '/err/nat44-ed-out2in/TCP packets')
4796 self.assertEqual(err - tcpn, 2)
4797 err = self.statistics.get_err_counter(
4798 '/err/nat44-ed-out2in/UDP packets')
4799 self.assertEqual(err - udpn, 1)
4800 err = self.statistics.get_err_counter(
4801 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4802 self.assertEqual(err - icmpn, 1)
4803 err = self.statistics.get_err_counter(
4804 '/err/nat44-ed-out2in/good out2in packets processed')
4805 self.assertEqual(err - totaln, 3)
4807 sessions = self.statistics.get_counter('/nat44/total-sessions')
4808 self.assertEqual(sessions[0][0], 3)
4811 self.pg7.unconfig_ip4()
4812 self.pg7.set_table_ip4(1)
4813 self.pg7.config_ip4()
4814 self.pg7.resolve_arp()
4816 self.pg8.unconfig_ip4()
4817 self.pg8.set_table_ip4(1)
4818 self.pg8.config_ip4()
4819 self.pg8.resolve_arp()
4821 self.vapi.ip_table_add_del(is_add=0,
4822 table={'table_id': new_vrf_id})
4824 def test_forwarding(self):
4825 """ NAT44 forwarding test """
4827 flags = self.config_flags.NAT_IS_INSIDE
4828 self.vapi.nat44_interface_add_del_feature(
4829 sw_if_index=self.pg0.sw_if_index,
4830 flags=flags, is_add=1)
4831 self.vapi.nat44_interface_add_del_feature(
4832 sw_if_index=self.pg1.sw_if_index,
4834 self.vapi.nat44_forwarding_enable_disable(enable=1)
4836 real_ip = self.pg0.remote_ip4
4837 alias_ip = self.nat_addr
4838 flags = self.config_flags.NAT_IS_ADDR_ONLY
4839 self.vapi.nat44_add_del_static_mapping(is_add=1,
4840 local_ip_address=real_ip,
4841 external_ip_address=alias_ip,
4842 external_sw_if_index=0xFFFFFFFF,
4846 # in2out - static mapping match
4848 pkts = self.create_stream_out(self.pg1)
4849 self.pg1.add_stream(pkts)
4850 self.pg_enable_capture(self.pg_interfaces)
4852 capture = self.pg0.get_capture(len(pkts))
4853 self.verify_capture_in(capture, self.pg0)
4855 pkts = self.create_stream_in(self.pg0, self.pg1)
4856 self.pg0.add_stream(pkts)
4857 self.pg_enable_capture(self.pg_interfaces)
4859 capture = self.pg1.get_capture(len(pkts))
4860 self.verify_capture_out(capture, same_port=True)
4862 # in2out - no static mapping match
4864 host0 = self.pg0.remote_hosts[0]
4865 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4867 pkts = self.create_stream_out(self.pg1,
4868 dst_ip=self.pg0.remote_ip4,
4869 use_inside_ports=True)
4870 self.pg1.add_stream(pkts)
4871 self.pg_enable_capture(self.pg_interfaces)
4873 capture = self.pg0.get_capture(len(pkts))
4874 self.verify_capture_in(capture, self.pg0)
4876 pkts = self.create_stream_in(self.pg0, self.pg1)
4877 self.pg0.add_stream(pkts)
4878 self.pg_enable_capture(self.pg_interfaces)
4880 capture = self.pg1.get_capture(len(pkts))
4881 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4884 self.pg0.remote_hosts[0] = host0
4886 user = self.pg0.remote_hosts[1]
4887 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4888 self.assertEqual(len(sessions), 3)
4889 self.assertTrue(sessions[0].flags &
4890 self.config_flags.NAT_IS_EXT_HOST_VALID)
4891 self.vapi.nat44_del_session(
4892 address=sessions[0].inside_ip_address,
4893 port=sessions[0].inside_port,
4894 protocol=sessions[0].protocol,
4895 flags=(self.config_flags.NAT_IS_INSIDE |
4896 self.config_flags.NAT_IS_EXT_HOST_VALID),
4897 ext_host_address=sessions[0].ext_host_address,
4898 ext_host_port=sessions[0].ext_host_port)
4899 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4900 self.assertEqual(len(sessions), 2)
4903 self.vapi.nat44_forwarding_enable_disable(enable=0)
4904 flags = self.config_flags.NAT_IS_ADDR_ONLY
4905 self.vapi.nat44_add_del_static_mapping(
4907 local_ip_address=real_ip,
4908 external_ip_address=alias_ip,
4909 external_sw_if_index=0xFFFFFFFF,
4912 def test_static_lb(self):
4913 """ NAT44 local service load balancing """
4914 external_addr_n = self.nat_addr
4917 server1 = self.pg0.remote_hosts[0]
4918 server2 = self.pg0.remote_hosts[1]
4920 locals = [{'addr': server1.ip4,
4924 {'addr': server2.ip4,
4929 self.nat44_add_address(self.nat_addr)
4930 self.vapi.nat44_add_del_lb_static_mapping(
4932 external_addr=external_addr_n,
4933 external_port=external_port,
4934 protocol=IP_PROTOS.tcp,
4935 local_num=len(locals),
4937 flags = self.config_flags.NAT_IS_INSIDE
4938 self.vapi.nat44_interface_add_del_feature(
4939 sw_if_index=self.pg0.sw_if_index,
4940 flags=flags, is_add=1)
4941 self.vapi.nat44_interface_add_del_feature(
4942 sw_if_index=self.pg1.sw_if_index,
4945 # from client to service
4946 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4947 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4948 TCP(sport=12345, dport=external_port))
4949 self.pg1.add_stream(p)
4950 self.pg_enable_capture(self.pg_interfaces)
4952 capture = self.pg0.get_capture(1)
4958 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4959 if ip.dst == server1.ip4:
4963 self.assertEqual(tcp.dport, local_port)
4964 self.assert_packet_checksums_valid(p)
4966 self.logger.error(ppp("Unexpected or invalid packet:", p))
4969 # from service back to client
4970 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4971 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4972 TCP(sport=local_port, dport=12345))
4973 self.pg0.add_stream(p)
4974 self.pg_enable_capture(self.pg_interfaces)
4976 capture = self.pg1.get_capture(1)
4981 self.assertEqual(ip.src, self.nat_addr)
4982 self.assertEqual(tcp.sport, external_port)
4983 self.assert_packet_checksums_valid(p)
4985 self.logger.error(ppp("Unexpected or invalid packet:", p))
4988 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
4989 self.assertEqual(len(sessions), 1)
4990 self.assertTrue(sessions[0].flags &
4991 self.config_flags.NAT_IS_EXT_HOST_VALID)
4992 self.vapi.nat44_del_session(
4993 address=sessions[0].inside_ip_address,
4994 port=sessions[0].inside_port,
4995 protocol=sessions[0].protocol,
4996 flags=(self.config_flags.NAT_IS_INSIDE |
4997 self.config_flags.NAT_IS_EXT_HOST_VALID),
4998 ext_host_address=sessions[0].ext_host_address,
4999 ext_host_port=sessions[0].ext_host_port)
5000 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5001 self.assertEqual(len(sessions), 0)
5003 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5004 def test_static_lb_multi_clients(self):
5005 """ NAT44 local service load balancing - multiple clients"""
5007 external_addr = self.nat_addr
5010 server1 = self.pg0.remote_hosts[0]
5011 server2 = self.pg0.remote_hosts[1]
5012 server3 = self.pg0.remote_hosts[2]
5014 locals = [{'addr': server1.ip4,
5018 {'addr': server2.ip4,
5023 self.nat44_add_address(self.nat_addr)
5024 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5025 external_addr=external_addr,
5026 external_port=external_port,
5027 protocol=IP_PROTOS.tcp,
5028 local_num=len(locals),
5030 flags = self.config_flags.NAT_IS_INSIDE
5031 self.vapi.nat44_interface_add_del_feature(
5032 sw_if_index=self.pg0.sw_if_index,
5033 flags=flags, is_add=1)
5034 self.vapi.nat44_interface_add_del_feature(
5035 sw_if_index=self.pg1.sw_if_index,
5040 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5042 for client in clients:
5043 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5044 IP(src=client, dst=self.nat_addr) /
5045 TCP(sport=12345, dport=external_port))
5047 self.pg1.add_stream(pkts)
5048 self.pg_enable_capture(self.pg_interfaces)
5050 capture = self.pg0.get_capture(len(pkts))
5052 if p[IP].dst == server1.ip4:
5056 self.assertGreater(server1_n, server2_n)
5059 'addr': server3.ip4,
5066 self.vapi.nat44_lb_static_mapping_add_del_local(
5068 external_addr=external_addr,
5069 external_port=external_port,
5071 protocol=IP_PROTOS.tcp)
5075 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5077 for client in clients:
5078 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5079 IP(src=client, dst=self.nat_addr) /
5080 TCP(sport=12346, dport=external_port))
5082 self.assertGreater(len(pkts), 0)
5083 self.pg1.add_stream(pkts)
5084 self.pg_enable_capture(self.pg_interfaces)
5086 capture = self.pg0.get_capture(len(pkts))
5088 if p[IP].dst == server1.ip4:
5090 elif p[IP].dst == server2.ip4:
5094 self.assertGreater(server1_n, 0)
5095 self.assertGreater(server2_n, 0)
5096 self.assertGreater(server3_n, 0)
5099 'addr': server2.ip4,
5105 # remove one back-end
5106 self.vapi.nat44_lb_static_mapping_add_del_local(
5108 external_addr=external_addr,
5109 external_port=external_port,
5111 protocol=IP_PROTOS.tcp)
5115 self.pg1.add_stream(pkts)
5116 self.pg_enable_capture(self.pg_interfaces)
5118 capture = self.pg0.get_capture(len(pkts))
5120 if p[IP].dst == server1.ip4:
5122 elif p[IP].dst == server2.ip4:
5126 self.assertGreater(server1_n, 0)
5127 self.assertEqual(server2_n, 0)
5128 self.assertGreater(server3_n, 0)
5130 def test_static_lb_2(self):
5131 """ NAT44 local service load balancing (asymmetrical rule) """
5132 external_addr = self.nat_addr
5135 server1 = self.pg0.remote_hosts[0]
5136 server2 = self.pg0.remote_hosts[1]
5138 locals = [{'addr': server1.ip4,
5142 {'addr': server2.ip4,
5147 self.vapi.nat44_forwarding_enable_disable(enable=1)
5148 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5149 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5150 external_addr=external_addr,
5151 external_port=external_port,
5152 protocol=IP_PROTOS.tcp,
5153 local_num=len(locals),
5155 flags = self.config_flags.NAT_IS_INSIDE
5156 self.vapi.nat44_interface_add_del_feature(
5157 sw_if_index=self.pg0.sw_if_index,
5158 flags=flags, is_add=1)
5159 self.vapi.nat44_interface_add_del_feature(
5160 sw_if_index=self.pg1.sw_if_index,
5163 # from client to service
5164 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5165 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5166 TCP(sport=12345, dport=external_port))
5167 self.pg1.add_stream(p)
5168 self.pg_enable_capture(self.pg_interfaces)
5170 capture = self.pg0.get_capture(1)
5176 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5177 if ip.dst == server1.ip4:
5181 self.assertEqual(tcp.dport, local_port)
5182 self.assert_packet_checksums_valid(p)
5184 self.logger.error(ppp("Unexpected or invalid packet:", p))
5187 # from service back to client
5188 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5189 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5190 TCP(sport=local_port, dport=12345))
5191 self.pg0.add_stream(p)
5192 self.pg_enable_capture(self.pg_interfaces)
5194 capture = self.pg1.get_capture(1)
5199 self.assertEqual(ip.src, self.nat_addr)
5200 self.assertEqual(tcp.sport, external_port)
5201 self.assert_packet_checksums_valid(p)
5203 self.logger.error(ppp("Unexpected or invalid packet:", p))
5206 # from client to server (no translation)
5207 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5208 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5209 TCP(sport=12346, dport=local_port))
5210 self.pg1.add_stream(p)
5211 self.pg_enable_capture(self.pg_interfaces)
5213 capture = self.pg0.get_capture(1)
5219 self.assertEqual(ip.dst, server1.ip4)
5220 self.assertEqual(tcp.dport, local_port)
5221 self.assert_packet_checksums_valid(p)
5223 self.logger.error(ppp("Unexpected or invalid packet:", p))
5226 # from service back to client (no translation)
5227 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5228 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5229 TCP(sport=local_port, dport=12346))
5230 self.pg0.add_stream(p)
5231 self.pg_enable_capture(self.pg_interfaces)
5233 capture = self.pg1.get_capture(1)
5238 self.assertEqual(ip.src, server1.ip4)
5239 self.assertEqual(tcp.sport, local_port)
5240 self.assert_packet_checksums_valid(p)
5242 self.logger.error(ppp("Unexpected or invalid packet:", p))
5245 def test_lb_affinity(self):
5246 """ NAT44 local service load balancing affinity """
5247 external_addr = self.nat_addr
5250 server1 = self.pg0.remote_hosts[0]
5251 server2 = self.pg0.remote_hosts[1]
5253 locals = [{'addr': server1.ip4,
5257 {'addr': server2.ip4,
5262 self.nat44_add_address(self.nat_addr)
5263 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5264 external_addr=external_addr,
5265 external_port=external_port,
5266 protocol=IP_PROTOS.tcp,
5268 local_num=len(locals),
5270 flags = self.config_flags.NAT_IS_INSIDE
5271 self.vapi.nat44_interface_add_del_feature(
5272 sw_if_index=self.pg0.sw_if_index,
5273 flags=flags, is_add=1)
5274 self.vapi.nat44_interface_add_del_feature(
5275 sw_if_index=self.pg1.sw_if_index,
5278 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5279 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5280 TCP(sport=1025, dport=external_port))
5281 self.pg1.add_stream(p)
5282 self.pg_enable_capture(self.pg_interfaces)
5284 capture = self.pg0.get_capture(1)
5285 backend = capture[0][IP].dst
5287 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5288 self.assertEqual(len(sessions), 1)
5289 self.assertTrue(sessions[0].flags &
5290 self.config_flags.NAT_IS_EXT_HOST_VALID)
5291 self.vapi.nat44_del_session(
5292 address=sessions[0].inside_ip_address,
5293 port=sessions[0].inside_port,
5294 protocol=sessions[0].protocol,
5295 flags=(self.config_flags.NAT_IS_INSIDE |
5296 self.config_flags.NAT_IS_EXT_HOST_VALID),
5297 ext_host_address=sessions[0].ext_host_address,
5298 ext_host_port=sessions[0].ext_host_port)
5301 for port in range(1030, 1100):
5302 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5303 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5304 TCP(sport=port, dport=external_port))
5306 self.pg1.add_stream(pkts)
5307 self.pg_enable_capture(self.pg_interfaces)
5309 capture = self.pg0.get_capture(len(pkts))
5311 self.assertEqual(p[IP].dst, backend)
5313 def test_unknown_proto(self):
5314 """ NAT44 translate packet with unknown protocol """
5315 self.nat44_add_address(self.nat_addr)
5316 flags = self.config_flags.NAT_IS_INSIDE
5317 self.vapi.nat44_interface_add_del_feature(
5318 sw_if_index=self.pg0.sw_if_index,
5319 flags=flags, is_add=1)
5320 self.vapi.nat44_interface_add_del_feature(
5321 sw_if_index=self.pg1.sw_if_index,
5325 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5326 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5327 TCP(sport=self.tcp_port_in, dport=20))
5328 self.pg0.add_stream(p)
5329 self.pg_enable_capture(self.pg_interfaces)
5331 p = self.pg1.get_capture(1)
5333 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5334 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5336 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5337 TCP(sport=1234, dport=1234))
5338 self.pg0.add_stream(p)
5339 self.pg_enable_capture(self.pg_interfaces)
5341 p = self.pg1.get_capture(1)
5344 self.assertEqual(packet[IP].src, self.nat_addr)
5345 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5346 self.assertEqual(packet.haslayer(GRE), 1)
5347 self.assert_packet_checksums_valid(packet)
5349 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5353 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5354 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5356 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5357 TCP(sport=1234, dport=1234))
5358 self.pg1.add_stream(p)
5359 self.pg_enable_capture(self.pg_interfaces)
5361 p = self.pg0.get_capture(1)
5364 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5365 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5366 self.assertEqual(packet.haslayer(GRE), 1)
5367 self.assert_packet_checksums_valid(packet)
5369 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5372 def test_hairpinning_unknown_proto(self):
5373 """ NAT44 translate packet with unknown protocol - hairpinning """
5374 host = self.pg0.remote_hosts[0]
5375 server = self.pg0.remote_hosts[1]
5377 server_out_port = 8765
5378 server_nat_ip = "10.0.0.11"
5380 self.nat44_add_address(self.nat_addr)
5381 flags = self.config_flags.NAT_IS_INSIDE
5382 self.vapi.nat44_interface_add_del_feature(
5383 sw_if_index=self.pg0.sw_if_index,
5384 flags=flags, is_add=1)
5385 self.vapi.nat44_interface_add_del_feature(
5386 sw_if_index=self.pg1.sw_if_index,
5389 # add static mapping for server
5390 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5393 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5394 IP(src=host.ip4, dst=server_nat_ip) /
5395 TCP(sport=host_in_port, dport=server_out_port))
5396 self.pg0.add_stream(p)
5397 self.pg_enable_capture(self.pg_interfaces)
5399 self.pg0.get_capture(1)
5401 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5402 IP(src=host.ip4, dst=server_nat_ip) /
5404 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5405 TCP(sport=1234, dport=1234))
5406 self.pg0.add_stream(p)
5407 self.pg_enable_capture(self.pg_interfaces)
5409 p = self.pg0.get_capture(1)
5412 self.assertEqual(packet[IP].src, self.nat_addr)
5413 self.assertEqual(packet[IP].dst, server.ip4)
5414 self.assertEqual(packet.haslayer(GRE), 1)
5415 self.assert_packet_checksums_valid(packet)
5417 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5421 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5422 IP(src=server.ip4, dst=self.nat_addr) /
5424 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5425 TCP(sport=1234, dport=1234))
5426 self.pg0.add_stream(p)
5427 self.pg_enable_capture(self.pg_interfaces)
5429 p = self.pg0.get_capture(1)
5432 self.assertEqual(packet[IP].src, server_nat_ip)
5433 self.assertEqual(packet[IP].dst, host.ip4)
5434 self.assertEqual(packet.haslayer(GRE), 1)
5435 self.assert_packet_checksums_valid(packet)
5437 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5440 def test_output_feature_and_service(self):
5441 """ NAT44 interface output feature and services """
5442 external_addr = '1.2.3.4'
5446 self.vapi.nat44_forwarding_enable_disable(enable=1)
5447 self.nat44_add_address(self.nat_addr)
5448 flags = self.config_flags.NAT_IS_ADDR_ONLY
5449 self.vapi.nat44_add_del_identity_mapping(
5450 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5451 flags=flags, is_add=1)
5452 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5453 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5454 local_port, external_port,
5455 proto=IP_PROTOS.tcp, flags=flags)
5456 flags = self.config_flags.NAT_IS_INSIDE
5457 self.vapi.nat44_interface_add_del_feature(
5458 sw_if_index=self.pg0.sw_if_index,
5460 self.vapi.nat44_interface_add_del_feature(
5461 sw_if_index=self.pg0.sw_if_index,
5462 flags=flags, is_add=1)
5463 self.vapi.nat44_interface_add_del_output_feature(
5465 sw_if_index=self.pg1.sw_if_index)
5467 # from client to service
5468 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5469 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5470 TCP(sport=12345, dport=external_port))
5471 self.pg1.add_stream(p)
5472 self.pg_enable_capture(self.pg_interfaces)
5474 capture = self.pg0.get_capture(1)
5479 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5480 self.assertEqual(tcp.dport, local_port)
5481 self.assert_packet_checksums_valid(p)
5483 self.logger.error(ppp("Unexpected or invalid packet:", p))
5486 # from service back to client
5487 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5488 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5489 TCP(sport=local_port, dport=12345))
5490 self.pg0.add_stream(p)
5491 self.pg_enable_capture(self.pg_interfaces)
5493 capture = self.pg1.get_capture(1)
5498 self.assertEqual(ip.src, external_addr)
5499 self.assertEqual(tcp.sport, external_port)
5500 self.assert_packet_checksums_valid(p)
5502 self.logger.error(ppp("Unexpected or invalid packet:", p))
5505 # from local network host to external network
5506 pkts = self.create_stream_in(self.pg0, self.pg1)
5507 self.pg0.add_stream(pkts)
5508 self.pg_enable_capture(self.pg_interfaces)
5510 capture = self.pg1.get_capture(len(pkts))
5511 self.verify_capture_out(capture)
5512 pkts = self.create_stream_in(self.pg0, self.pg1)
5513 self.pg0.add_stream(pkts)
5514 self.pg_enable_capture(self.pg_interfaces)
5516 capture = self.pg1.get_capture(len(pkts))
5517 self.verify_capture_out(capture)
5519 # from external network back to local network host
5520 pkts = self.create_stream_out(self.pg1)
5521 self.pg1.add_stream(pkts)
5522 self.pg_enable_capture(self.pg_interfaces)
5524 capture = self.pg0.get_capture(len(pkts))
5525 self.verify_capture_in(capture, self.pg0)
5527 def test_output_feature_and_service2(self):
5528 """ NAT44 interface output feature and service host direct access """
5529 self.vapi.nat44_forwarding_enable_disable(enable=1)
5530 self.nat44_add_address(self.nat_addr)
5531 self.vapi.nat44_interface_add_del_output_feature(
5533 sw_if_index=self.pg1.sw_if_index)
5535 # session initiated from service host - translate
5536 pkts = self.create_stream_in(self.pg0, self.pg1)
5537 self.pg0.add_stream(pkts)
5538 self.pg_enable_capture(self.pg_interfaces)
5540 capture = self.pg1.get_capture(len(pkts))
5541 self.verify_capture_out(capture)
5543 pkts = self.create_stream_out(self.pg1)
5544 self.pg1.add_stream(pkts)
5545 self.pg_enable_capture(self.pg_interfaces)
5547 capture = self.pg0.get_capture(len(pkts))
5548 self.verify_capture_in(capture, self.pg0)
5550 # session initiated from remote host - do not translate
5551 self.tcp_port_in = 60303
5552 self.udp_port_in = 60304
5553 self.icmp_id_in = 60305
5554 pkts = self.create_stream_out(self.pg1,
5555 self.pg0.remote_ip4,
5556 use_inside_ports=True)
5557 self.pg1.add_stream(pkts)
5558 self.pg_enable_capture(self.pg_interfaces)
5560 capture = self.pg0.get_capture(len(pkts))
5561 self.verify_capture_in(capture, self.pg0)
5563 pkts = self.create_stream_in(self.pg0, self.pg1)
5564 self.pg0.add_stream(pkts)
5565 self.pg_enable_capture(self.pg_interfaces)
5567 capture = self.pg1.get_capture(len(pkts))
5568 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5571 def test_output_feature_and_service3(self):
5572 """ NAT44 interface output feature and DST NAT """
5573 external_addr = '1.2.3.4'
5577 self.vapi.nat44_forwarding_enable_disable(enable=1)
5578 self.nat44_add_address(self.nat_addr)
5579 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5580 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5581 local_port, external_port,
5582 proto=IP_PROTOS.tcp, flags=flags)
5583 flags = self.config_flags.NAT_IS_INSIDE
5584 self.vapi.nat44_interface_add_del_feature(
5585 sw_if_index=self.pg0.sw_if_index,
5587 self.vapi.nat44_interface_add_del_feature(
5588 sw_if_index=self.pg0.sw_if_index,
5589 flags=flags, is_add=1)
5590 self.vapi.nat44_interface_add_del_output_feature(
5592 sw_if_index=self.pg1.sw_if_index)
5594 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5595 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5596 TCP(sport=12345, dport=external_port))
5597 self.pg0.add_stream(p)
5598 self.pg_enable_capture(self.pg_interfaces)
5600 capture = self.pg1.get_capture(1)
5605 self.assertEqual(ip.src, self.pg0.remote_ip4)
5606 self.assertEqual(tcp.sport, 12345)
5607 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5608 self.assertEqual(tcp.dport, local_port)
5609 self.assert_packet_checksums_valid(p)
5611 self.logger.error(ppp("Unexpected or invalid packet:", p))
5614 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5615 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5616 TCP(sport=local_port, dport=12345))
5617 self.pg1.add_stream(p)
5618 self.pg_enable_capture(self.pg_interfaces)
5620 capture = self.pg0.get_capture(1)
5625 self.assertEqual(ip.src, external_addr)
5626 self.assertEqual(tcp.sport, external_port)
5627 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5628 self.assertEqual(tcp.dport, 12345)
5629 self.assert_packet_checksums_valid(p)
5631 self.logger.error(ppp("Unexpected or invalid packet:", p))
5634 def test_next_src_nat(self):
5635 """ On way back forward packet to nat44-in2out node. """
5636 twice_nat_addr = '10.0.1.3'
5639 post_twice_nat_port = 0
5641 self.vapi.nat44_forwarding_enable_disable(enable=1)
5642 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5643 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5644 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5645 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5646 local_port, external_port,
5647 proto=IP_PROTOS.tcp, vrf_id=1,
5649 self.vapi.nat44_interface_add_del_feature(
5650 sw_if_index=self.pg6.sw_if_index,
5653 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5654 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5655 TCP(sport=12345, dport=external_port))
5656 self.pg6.add_stream(p)
5657 self.pg_enable_capture(self.pg_interfaces)
5659 capture = self.pg6.get_capture(1)
5664 self.assertEqual(ip.src, twice_nat_addr)
5665 self.assertNotEqual(tcp.sport, 12345)
5666 post_twice_nat_port = tcp.sport
5667 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5668 self.assertEqual(tcp.dport, local_port)
5669 self.assert_packet_checksums_valid(p)
5671 self.logger.error(ppp("Unexpected or invalid packet:", p))
5674 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5675 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5676 TCP(sport=local_port, dport=post_twice_nat_port))
5677 self.pg6.add_stream(p)
5678 self.pg_enable_capture(self.pg_interfaces)
5680 capture = self.pg6.get_capture(1)
5685 self.assertEqual(ip.src, self.pg1.remote_ip4)
5686 self.assertEqual(tcp.sport, external_port)
5687 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5688 self.assertEqual(tcp.dport, 12345)
5689 self.assert_packet_checksums_valid(p)
5691 self.logger.error(ppp("Unexpected or invalid packet:", p))
5694 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5696 twice_nat_addr = '10.0.1.3'
5704 port_in1 = port_in + 1
5705 port_in2 = port_in + 2
5710 server1 = self.pg0.remote_hosts[0]
5711 server2 = self.pg0.remote_hosts[1]
5723 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5726 self.nat44_add_address(self.nat_addr)
5727 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5731 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5733 flags |= self.config_flags.NAT_IS_TWICE_NAT
5736 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5738 proto=IP_PROTOS.tcp,
5741 locals = [{'addr': server1.ip4,
5745 {'addr': server2.ip4,
5749 out_addr = self.nat_addr
5751 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5752 external_addr=out_addr,
5753 external_port=port_out,
5754 protocol=IP_PROTOS.tcp,
5755 local_num=len(locals),
5757 flags = self.config_flags.NAT_IS_INSIDE
5758 self.vapi.nat44_interface_add_del_feature(
5759 sw_if_index=pg0.sw_if_index,
5760 flags=flags, is_add=1)
5761 self.vapi.nat44_interface_add_del_feature(
5762 sw_if_index=pg1.sw_if_index,
5769 assert client_id is not None
5771 client = self.pg0.remote_hosts[0]
5772 elif client_id == 2:
5773 client = self.pg0.remote_hosts[1]
5775 client = pg1.remote_hosts[0]
5776 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5777 IP(src=client.ip4, dst=self.nat_addr) /
5778 TCP(sport=eh_port_out, dport=port_out))
5780 self.pg_enable_capture(self.pg_interfaces)
5782 capture = pg0.get_capture(1)
5788 if ip.dst == server1.ip4:
5794 self.assertEqual(ip.dst, server.ip4)
5796 self.assertIn(tcp.dport, [port_in1, port_in2])
5798 self.assertEqual(tcp.dport, port_in)
5800 self.assertEqual(ip.src, twice_nat_addr)
5801 self.assertNotEqual(tcp.sport, eh_port_out)
5803 self.assertEqual(ip.src, client.ip4)
5804 self.assertEqual(tcp.sport, eh_port_out)
5806 eh_port_in = tcp.sport
5807 saved_port_in = tcp.dport
5808 self.assert_packet_checksums_valid(p)
5810 self.logger.error(ppp("Unexpected or invalid packet:", p))
5813 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5814 IP(src=server.ip4, dst=eh_addr_in) /
5815 TCP(sport=saved_port_in, dport=eh_port_in))
5817 self.pg_enable_capture(self.pg_interfaces)
5819 capture = pg1.get_capture(1)
5824 self.assertEqual(ip.dst, client.ip4)
5825 self.assertEqual(ip.src, self.nat_addr)
5826 self.assertEqual(tcp.dport, eh_port_out)
5827 self.assertEqual(tcp.sport, port_out)
5828 self.assert_packet_checksums_valid(p)
5830 self.logger.error(ppp("Unexpected or invalid packet:", p))
5834 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5835 self.assertEqual(len(sessions), 1)
5836 self.assertTrue(sessions[0].flags &
5837 self.config_flags.NAT_IS_EXT_HOST_VALID)
5838 self.assertTrue(sessions[0].flags &
5839 self.config_flags.NAT_IS_TWICE_NAT)
5840 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5841 self.vapi.nat44_del_session(
5842 address=sessions[0].inside_ip_address,
5843 port=sessions[0].inside_port,
5844 protocol=sessions[0].protocol,
5845 flags=(self.config_flags.NAT_IS_INSIDE |
5846 self.config_flags.NAT_IS_EXT_HOST_VALID),
5847 ext_host_address=sessions[0].ext_host_nat_address,
5848 ext_host_port=sessions[0].ext_host_nat_port)
5849 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5850 self.assertEqual(len(sessions), 0)
5852 def test_twice_nat(self):
5854 self.twice_nat_common()
5856 def test_self_twice_nat_positive(self):
5857 """ Self Twice NAT44 (positive test) """
5858 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5860 def test_self_twice_nat_negative(self):
5861 """ Self Twice NAT44 (negative test) """
5862 self.twice_nat_common(self_twice_nat=True)
5864 def test_twice_nat_lb(self):
5865 """ Twice NAT44 local service load balancing """
5866 self.twice_nat_common(lb=True)
5868 def test_self_twice_nat_lb_positive(self):
5869 """ Self Twice NAT44 local service load balancing (positive test) """
5870 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5873 def test_self_twice_nat_lb_negative(self):
5874 """ Self Twice NAT44 local service load balancing (negative test) """
5875 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5878 def test_twice_nat_interface_addr(self):
5879 """ Acquire twice NAT44 addresses from interface """
5880 flags = self.config_flags.NAT_IS_TWICE_NAT
5881 self.vapi.nat44_add_del_interface_addr(
5883 sw_if_index=self.pg3.sw_if_index,
5886 # no address in NAT pool
5887 adresses = self.vapi.nat44_address_dump()
5888 self.assertEqual(0, len(adresses))
5890 # configure interface address and check NAT address pool
5891 self.pg3.config_ip4()
5892 adresses = self.vapi.nat44_address_dump()
5893 self.assertEqual(1, len(adresses))
5894 self.assertEqual(str(adresses[0].ip_address),
5896 self.assertEqual(adresses[0].flags, flags)
5898 # remove interface address and check NAT address pool
5899 self.pg3.unconfig_ip4()
5900 adresses = self.vapi.nat44_address_dump()
5901 self.assertEqual(0, len(adresses))
5903 def test_tcp_close(self):
5904 """ Close TCP session from inside network - output feature """
5905 self.vapi.nat44_forwarding_enable_disable(enable=1)
5906 self.nat44_add_address(self.pg1.local_ip4)
5907 twice_nat_addr = '10.0.1.3'
5908 service_ip = '192.168.16.150'
5909 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5910 flags = self.config_flags.NAT_IS_INSIDE
5911 self.vapi.nat44_interface_add_del_feature(
5912 sw_if_index=self.pg0.sw_if_index,
5914 self.vapi.nat44_interface_add_del_feature(
5915 sw_if_index=self.pg0.sw_if_index,
5916 flags=flags, is_add=1)
5917 self.vapi.nat44_interface_add_del_output_feature(
5919 sw_if_index=self.pg1.sw_if_index)
5920 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5921 self.config_flags.NAT_IS_TWICE_NAT)
5922 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5926 proto=IP_PROTOS.tcp,
5928 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5929 start_sessnum = len(sessions)
5931 # SYN packet out->in
5932 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5933 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5934 TCP(sport=33898, dport=80, flags="S"))
5935 self.pg1.add_stream(p)
5936 self.pg_enable_capture(self.pg_interfaces)
5938 capture = self.pg0.get_capture(1)
5940 tcp_port = p[TCP].sport
5942 # SYN + ACK packet in->out
5943 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5944 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5945 TCP(sport=80, dport=tcp_port, flags="SA"))
5946 self.pg0.add_stream(p)
5947 self.pg_enable_capture(self.pg_interfaces)
5949 self.pg1.get_capture(1)
5951 # ACK packet out->in
5952 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5953 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5954 TCP(sport=33898, dport=80, flags="A"))
5955 self.pg1.add_stream(p)
5956 self.pg_enable_capture(self.pg_interfaces)
5958 self.pg0.get_capture(1)
5960 # FIN packet in -> out
5961 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5962 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5963 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5964 self.pg0.add_stream(p)
5965 self.pg_enable_capture(self.pg_interfaces)
5967 self.pg1.get_capture(1)
5969 # FIN+ACK packet out -> in
5970 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5971 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5972 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5973 self.pg1.add_stream(p)
5974 self.pg_enable_capture(self.pg_interfaces)
5976 self.pg0.get_capture(1)
5978 # ACK packet in -> out
5979 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5980 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5981 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5982 self.pg0.add_stream(p)
5983 self.pg_enable_capture(self.pg_interfaces)
5985 self.pg1.get_capture(1)
5987 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
5989 self.assertEqual(len(sessions) - start_sessnum, 0)
5991 def test_tcp_session_close_in(self):
5992 """ Close TCP session from inside network """
5993 self.tcp_port_out = 10505
5994 self.nat44_add_address(self.nat_addr)
5995 flags = self.config_flags.NAT_IS_TWICE_NAT
5996 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6000 proto=IP_PROTOS.tcp,
6002 flags = self.config_flags.NAT_IS_INSIDE
6003 self.vapi.nat44_interface_add_del_feature(
6004 sw_if_index=self.pg0.sw_if_index,
6005 flags=flags, is_add=1)
6006 self.vapi.nat44_interface_add_del_feature(
6007 sw_if_index=self.pg1.sw_if_index,
6010 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6011 start_sessnum = len(sessions)
6013 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6014 tcp_transitory=2, icmp=5)
6016 self.initiate_tcp_session(self.pg0, self.pg1)
6018 # FIN packet in -> out
6019 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6020 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6021 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6022 flags="FA", seq=100, ack=300))
6023 self.pg0.add_stream(p)
6024 self.pg_enable_capture(self.pg_interfaces)
6026 self.pg1.get_capture(1)
6030 # ACK packet out -> in
6031 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6032 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6033 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6034 flags="A", seq=300, ack=101))
6037 # FIN packet out -> in
6038 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6039 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6040 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6041 flags="FA", seq=300, ack=101))
6044 self.pg1.add_stream(pkts)
6045 self.pg_enable_capture(self.pg_interfaces)
6047 self.pg0.get_capture(2)
6049 # ACK packet in -> out
6050 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6051 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6052 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6053 flags="A", seq=101, ack=301))
6054 self.pg0.add_stream(p)
6055 self.pg_enable_capture(self.pg_interfaces)
6057 self.pg1.get_capture(1)
6059 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6060 self.assertEqual(len(sessions) - start_sessnum, 1)
6062 stats = self.statistics.get_counter(
6063 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6064 out2in_drops = stats[0]
6065 stats = self.statistics.get_counter(
6066 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6067 in2out_drops = stats[0]
6069 # extra FIN packet out -> in - this should be dropped
6070 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6071 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6072 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6073 flags="FA", seq=300, ack=101))
6075 self.pg1.add_stream(p)
6076 self.pg_enable_capture(self.pg_interfaces)
6078 self.pg0.assert_nothing_captured()
6080 # extra ACK packet in -> out - this should be dropped
6081 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6082 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6083 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6084 flags="A", seq=101, ack=301))
6085 self.pg0.add_stream(p)
6086 self.pg_enable_capture(self.pg_interfaces)
6088 self.pg1.assert_nothing_captured()
6090 stats = self.statistics.get_counter(
6091 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6092 self.assertEqual(stats[0] - out2in_drops, 1)
6093 stats = self.statistics.get_counter(
6094 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6095 self.assertEqual(stats[0] - in2out_drops, 1)
6098 # extra ACK packet in -> out - this will cause session to be wiped
6099 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6100 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6101 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6102 flags="A", seq=101, ack=301))
6103 self.pg0.add_stream(p)
6104 self.pg_enable_capture(self.pg_interfaces)
6106 self.pg1.assert_nothing_captured()
6107 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6108 self.assertEqual(len(sessions) - start_sessnum, 0)
6110 def test_tcp_session_close_out(self):
6111 """ Close TCP session from outside network """
6112 self.tcp_port_out = 10505
6113 self.nat44_add_address(self.nat_addr)
6114 flags = self.config_flags.NAT_IS_TWICE_NAT
6115 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6119 proto=IP_PROTOS.tcp,
6121 flags = self.config_flags.NAT_IS_INSIDE
6122 self.vapi.nat44_interface_add_del_feature(
6123 sw_if_index=self.pg0.sw_if_index,
6124 flags=flags, is_add=1)
6125 self.vapi.nat44_interface_add_del_feature(
6126 sw_if_index=self.pg1.sw_if_index,
6129 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6130 start_sessnum = len(sessions)
6132 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6133 tcp_transitory=2, icmp=5)
6135 self.initiate_tcp_session(self.pg0, self.pg1)
6137 # FIN packet out -> in
6138 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6139 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6140 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6141 flags="FA", seq=100, ack=300))
6142 self.pg1.add_stream(p)
6143 self.pg_enable_capture(self.pg_interfaces)
6145 self.pg0.get_capture(1)
6147 # FIN+ACK packet in -> out
6148 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6149 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6150 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6151 flags="FA", seq=300, ack=101))
6153 self.pg0.add_stream(p)
6154 self.pg_enable_capture(self.pg_interfaces)
6156 self.pg1.get_capture(1)
6158 # ACK packet out -> in
6159 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6160 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6161 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6162 flags="A", seq=101, ack=301))
6163 self.pg1.add_stream(p)
6164 self.pg_enable_capture(self.pg_interfaces)
6166 self.pg0.get_capture(1)
6168 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6169 self.assertEqual(len(sessions) - start_sessnum, 1)
6171 stats = self.statistics.get_counter(
6172 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6173 out2in_drops = stats[0]
6174 stats = self.statistics.get_counter(
6175 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6176 in2out_drops = stats[0]
6178 # extra FIN packet out -> in - this should be dropped
6179 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6180 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6181 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6182 flags="FA", seq=300, ack=101))
6184 self.pg1.add_stream(p)
6185 self.pg_enable_capture(self.pg_interfaces)
6187 self.pg0.assert_nothing_captured()
6189 # extra ACK packet in -> out - this should be dropped
6190 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6191 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6192 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6193 flags="A", seq=101, ack=301))
6194 self.pg0.add_stream(p)
6195 self.pg_enable_capture(self.pg_interfaces)
6197 self.pg1.assert_nothing_captured()
6199 stats = self.statistics.get_counter(
6200 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6201 self.assertEqual(stats[0] - out2in_drops, 1)
6202 stats = self.statistics.get_counter(
6203 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6204 self.assertEqual(stats[0] - in2out_drops, 1)
6207 # extra ACK packet in -> out - this will cause session to be wiped
6208 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6209 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6210 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6211 flags="A", seq=101, ack=301))
6212 self.pg0.add_stream(p)
6213 self.pg_enable_capture(self.pg_interfaces)
6215 self.pg1.assert_nothing_captured()
6216 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6217 self.assertEqual(len(sessions) - start_sessnum, 0)
6219 def test_tcp_session_close_simultaneous(self):
6220 """ Close TCP session from inside network """
6221 self.tcp_port_out = 10505
6222 self.nat44_add_address(self.nat_addr)
6223 flags = self.config_flags.NAT_IS_TWICE_NAT
6224 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6228 proto=IP_PROTOS.tcp,
6230 flags = self.config_flags.NAT_IS_INSIDE
6231 self.vapi.nat44_interface_add_del_feature(
6232 sw_if_index=self.pg0.sw_if_index,
6233 flags=flags, is_add=1)
6234 self.vapi.nat44_interface_add_del_feature(
6235 sw_if_index=self.pg1.sw_if_index,
6238 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6239 start_sessnum = len(sessions)
6241 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6242 tcp_transitory=2, icmp=5)
6244 self.initiate_tcp_session(self.pg0, self.pg1)
6246 # FIN packet in -> out
6247 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6248 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6249 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6250 flags="FA", seq=100, ack=300))
6251 self.pg0.add_stream(p)
6252 self.pg_enable_capture(self.pg_interfaces)
6254 self.pg1.get_capture(1)
6256 # FIN packet out -> in
6257 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6258 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6259 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6260 flags="FA", seq=300, ack=100))
6261 self.pg1.add_stream(p)
6262 self.pg_enable_capture(self.pg_interfaces)
6264 self.pg0.get_capture(1)
6266 # ACK packet in -> out
6267 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6268 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6269 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6270 flags="A", seq=101, ack=301))
6271 self.pg0.add_stream(p)
6272 self.pg_enable_capture(self.pg_interfaces)
6274 self.pg1.get_capture(1)
6276 # ACK packet out -> in
6277 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6278 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6279 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6280 flags="A", seq=301, ack=101))
6281 self.pg1.add_stream(p)
6282 self.pg_enable_capture(self.pg_interfaces)
6284 self.pg0.get_capture(1)
6286 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6287 self.assertEqual(len(sessions) - start_sessnum, 1)
6289 stats = self.statistics.get_counter(
6290 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6291 out2in_drops = stats[0]
6292 stats = self.statistics.get_counter(
6293 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6294 in2out_drops = stats[0]
6296 # extra FIN packet out -> in - this should be dropped
6297 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6298 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6299 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6300 flags="FA", seq=300, ack=101))
6302 self.pg1.add_stream(p)
6303 self.pg_enable_capture(self.pg_interfaces)
6305 self.pg0.assert_nothing_captured()
6307 # extra ACK packet in -> out - this should be dropped
6308 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6309 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6310 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6311 flags="A", seq=101, ack=301))
6312 self.pg0.add_stream(p)
6313 self.pg_enable_capture(self.pg_interfaces)
6315 self.pg1.assert_nothing_captured()
6317 stats = self.statistics.get_counter(
6318 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6319 self.assertEqual(stats[0] - out2in_drops, 1)
6320 stats = self.statistics.get_counter(
6321 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6322 self.assertEqual(stats[0] - in2out_drops, 1)
6325 # extra ACK packet in -> out - this will cause session to be wiped
6326 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6327 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6328 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6329 flags="A", seq=101, ack=301))
6330 self.pg0.add_stream(p)
6331 self.pg_enable_capture(self.pg_interfaces)
6333 self.pg1.assert_nothing_captured()
6334 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6335 self.assertEqual(len(sessions) - start_sessnum, 0)
6337 def test_one_armed_nat44_static(self):
6338 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6339 remote_host = self.pg4.remote_hosts[0]
6340 local_host = self.pg4.remote_hosts[1]
6345 self.vapi.nat44_forwarding_enable_disable(enable=1)
6346 self.nat44_add_address(self.nat_addr, twice_nat=1)
6347 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6348 self.config_flags.NAT_IS_TWICE_NAT)
6349 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6350 local_port, external_port,
6351 proto=IP_PROTOS.tcp, flags=flags)
6352 flags = self.config_flags.NAT_IS_INSIDE
6353 self.vapi.nat44_interface_add_del_feature(
6354 sw_if_index=self.pg4.sw_if_index,
6356 self.vapi.nat44_interface_add_del_feature(
6357 sw_if_index=self.pg4.sw_if_index,
6358 flags=flags, is_add=1)
6360 # from client to service
6361 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6362 IP(src=remote_host.ip4, dst=self.nat_addr) /
6363 TCP(sport=12345, dport=external_port))
6364 self.pg4.add_stream(p)
6365 self.pg_enable_capture(self.pg_interfaces)
6367 capture = self.pg4.get_capture(1)
6372 self.assertEqual(ip.dst, local_host.ip4)
6373 self.assertEqual(ip.src, self.nat_addr)
6374 self.assertEqual(tcp.dport, local_port)
6375 self.assertNotEqual(tcp.sport, 12345)
6376 eh_port_in = tcp.sport
6377 self.assert_packet_checksums_valid(p)
6379 self.logger.error(ppp("Unexpected or invalid packet:", p))
6382 # from service back to client
6383 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6384 IP(src=local_host.ip4, dst=self.nat_addr) /
6385 TCP(sport=local_port, dport=eh_port_in))
6386 self.pg4.add_stream(p)
6387 self.pg_enable_capture(self.pg_interfaces)
6389 capture = self.pg4.get_capture(1)
6394 self.assertEqual(ip.src, self.nat_addr)
6395 self.assertEqual(ip.dst, remote_host.ip4)
6396 self.assertEqual(tcp.sport, external_port)
6397 self.assertEqual(tcp.dport, 12345)
6398 self.assert_packet_checksums_valid(p)
6400 self.logger.error(ppp("Unexpected or invalid packet:", p))
6403 def test_static_with_port_out2(self):
6404 """ 1:1 NAPT asymmetrical rule """
6409 self.vapi.nat44_forwarding_enable_disable(enable=1)
6410 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6411 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6412 local_port, external_port,
6413 proto=IP_PROTOS.tcp, flags=flags)
6414 flags = self.config_flags.NAT_IS_INSIDE
6415 self.vapi.nat44_interface_add_del_feature(
6416 sw_if_index=self.pg0.sw_if_index,
6417 flags=flags, is_add=1)
6418 self.vapi.nat44_interface_add_del_feature(
6419 sw_if_index=self.pg1.sw_if_index,
6422 # from client to service
6423 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6424 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6425 TCP(sport=12345, dport=external_port))
6426 self.pg1.add_stream(p)
6427 self.pg_enable_capture(self.pg_interfaces)
6429 capture = self.pg0.get_capture(1)
6434 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6435 self.assertEqual(tcp.dport, local_port)
6436 self.assert_packet_checksums_valid(p)
6438 self.logger.error(ppp("Unexpected or invalid packet:", p))
6442 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6443 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6444 ICMP(type=11) / capture[0][IP])
6445 self.pg0.add_stream(p)
6446 self.pg_enable_capture(self.pg_interfaces)
6448 capture = self.pg1.get_capture(1)
6451 self.assertEqual(p[IP].src, self.nat_addr)
6453 self.assertEqual(inner.dst, self.nat_addr)
6454 self.assertEqual(inner[TCPerror].dport, external_port)
6456 self.logger.error(ppp("Unexpected or invalid packet:", p))
6459 # from service back to client
6460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6462 TCP(sport=local_port, dport=12345))
6463 self.pg0.add_stream(p)
6464 self.pg_enable_capture(self.pg_interfaces)
6466 capture = self.pg1.get_capture(1)
6471 self.assertEqual(ip.src, self.nat_addr)
6472 self.assertEqual(tcp.sport, external_port)
6473 self.assert_packet_checksums_valid(p)
6475 self.logger.error(ppp("Unexpected or invalid packet:", p))
6479 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6480 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6481 ICMP(type=11) / capture[0][IP])
6482 self.pg1.add_stream(p)
6483 self.pg_enable_capture(self.pg_interfaces)
6485 capture = self.pg0.get_capture(1)
6488 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6490 self.assertEqual(inner.src, self.pg0.remote_ip4)
6491 self.assertEqual(inner[TCPerror].sport, local_port)
6493 self.logger.error(ppp("Unexpected or invalid packet:", p))
6496 # from client to server (no translation)
6497 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6498 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6499 TCP(sport=12346, dport=local_port))
6500 self.pg1.add_stream(p)
6501 self.pg_enable_capture(self.pg_interfaces)
6503 capture = self.pg0.get_capture(1)
6508 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6509 self.assertEqual(tcp.dport, local_port)
6510 self.assert_packet_checksums_valid(p)
6512 self.logger.error(ppp("Unexpected or invalid packet:", p))
6515 # from service back to client (no translation)
6516 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6517 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6518 TCP(sport=local_port, dport=12346))
6519 self.pg0.add_stream(p)
6520 self.pg_enable_capture(self.pg_interfaces)
6522 capture = self.pg1.get_capture(1)
6527 self.assertEqual(ip.src, self.pg0.remote_ip4)
6528 self.assertEqual(tcp.sport, local_port)
6529 self.assert_packet_checksums_valid(p)
6531 self.logger.error(ppp("Unexpected or invalid packet:", p))
6534 def test_output_feature(self):
6535 """ NAT44 interface output feature (in2out postrouting) """
6536 self.vapi.nat44_forwarding_enable_disable(enable=1)
6537 self.nat44_add_address(self.nat_addr)
6538 self.vapi.nat44_interface_add_del_feature(
6539 sw_if_index=self.pg0.sw_if_index,
6541 self.vapi.nat44_interface_add_del_output_feature(
6543 sw_if_index=self.pg1.sw_if_index)
6546 pkts = self.create_stream_in(self.pg0, self.pg1)
6547 self.pg0.add_stream(pkts)
6548 self.pg_enable_capture(self.pg_interfaces)
6550 capture = self.pg1.get_capture(len(pkts))
6551 self.verify_capture_out(capture)
6554 pkts = self.create_stream_out(self.pg1)
6555 self.pg1.add_stream(pkts)
6556 self.pg_enable_capture(self.pg_interfaces)
6558 capture = self.pg0.get_capture(len(pkts))
6559 self.verify_capture_in(capture, self.pg0)
6561 def test_output_feature_stateful_acl(self):
6562 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6563 self.nat44_add_address(self.nat_addr)
6564 self.vapi.nat44_interface_add_del_output_feature(
6565 sw_if_index=self.pg0.sw_if_index,
6566 flags=self.config_flags.NAT_IS_INSIDE,
6568 self.vapi.nat44_interface_add_del_output_feature(
6569 sw_if_index=self.pg1.sw_if_index,
6570 flags=self.config_flags.NAT_IS_OUTSIDE,
6573 # First ensure that the NAT is working sans ACL
6575 # send packets out2in, no sessions yet so packets should drop
6576 pkts_out2in = self.create_stream_out(self.pg1)
6577 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6579 # send packets into inside intf, ensure received via outside intf
6580 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6581 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6583 self.verify_capture_out(capture)
6585 # send out2in again, with sessions created it should work now
6586 pkts_out2in = self.create_stream_out(self.pg1)
6587 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6589 self.verify_capture_in(capture, self.pg0)
6591 # Create an ACL blocking everything
6592 out2in_deny_rule = AclRule(is_permit=0)
6593 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6594 out2in_acl.add_vpp_config()
6596 # create an ACL to permit/reflect everything
6597 in2out_reflect_rule = AclRule(is_permit=2)
6598 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6599 in2out_acl.add_vpp_config()
6601 # apply as input acl on interface and confirm it blocks everything
6602 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6603 n_input=1, acls=[out2in_acl])
6604 acl_if.add_vpp_config()
6605 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6608 acl_if.acls = [out2in_acl, in2out_acl]
6609 acl_if.add_vpp_config()
6610 # send in2out to generate ACL state (NAT state was created earlier)
6611 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6613 self.verify_capture_out(capture)
6615 # send out2in again. ACL state exists so it should work now.
6616 # TCP packets with the syn flag set also need the ack flag
6617 for p in pkts_out2in:
6618 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6619 p[TCP].flags |= 0x10
6620 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6622 self.verify_capture_in(capture, self.pg0)
6623 self.logger.info(self.vapi.cli("show trace"))
6625 def test_multiple_vrf(self):
6626 """ Multiple VRF setup """
6627 external_addr = '1.2.3.4'
6632 self.vapi.nat44_forwarding_enable_disable(enable=1)
6633 self.nat44_add_address(self.nat_addr)
6634 flags = self.config_flags.NAT_IS_INSIDE
6635 self.vapi.nat44_interface_add_del_feature(
6636 sw_if_index=self.pg0.sw_if_index,
6638 self.vapi.nat44_interface_add_del_feature(
6639 sw_if_index=self.pg0.sw_if_index,
6640 flags=flags, is_add=1)
6641 self.vapi.nat44_interface_add_del_output_feature(
6643 sw_if_index=self.pg1.sw_if_index)
6644 self.vapi.nat44_interface_add_del_feature(
6645 sw_if_index=self.pg5.sw_if_index,
6647 self.vapi.nat44_interface_add_del_feature(
6648 sw_if_index=self.pg5.sw_if_index,
6649 flags=flags, is_add=1)
6650 self.vapi.nat44_interface_add_del_feature(
6651 sw_if_index=self.pg6.sw_if_index,
6653 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6654 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6655 local_port, external_port, vrf_id=1,
6656 proto=IP_PROTOS.tcp, flags=flags)
6657 self.nat44_add_static_mapping(
6658 self.pg0.remote_ip4,
6659 external_sw_if_index=self.pg0.sw_if_index,
6660 local_port=local_port,
6662 external_port=external_port,
6663 proto=IP_PROTOS.tcp,
6667 # from client to service (both VRF1)
6668 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6669 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6670 TCP(sport=12345, dport=external_port))
6671 self.pg6.add_stream(p)
6672 self.pg_enable_capture(self.pg_interfaces)
6674 capture = self.pg5.get_capture(1)
6679 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6680 self.assertEqual(tcp.dport, local_port)
6681 self.assert_packet_checksums_valid(p)
6683 self.logger.error(ppp("Unexpected or invalid packet:", p))
6686 # from service back to client (both VRF1)
6687 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6688 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6689 TCP(sport=local_port, dport=12345))
6690 self.pg5.add_stream(p)
6691 self.pg_enable_capture(self.pg_interfaces)
6693 capture = self.pg6.get_capture(1)
6698 self.assertEqual(ip.src, external_addr)
6699 self.assertEqual(tcp.sport, external_port)
6700 self.assert_packet_checksums_valid(p)
6702 self.logger.error(ppp("Unexpected or invalid packet:", p))
6705 # dynamic NAT from VRF1 to VRF0 (output-feature)
6706 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6707 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6708 TCP(sport=2345, dport=22))
6709 self.pg5.add_stream(p)
6710 self.pg_enable_capture(self.pg_interfaces)
6712 capture = self.pg1.get_capture(1)
6717 self.assertEqual(ip.src, self.nat_addr)
6718 self.assertNotEqual(tcp.sport, 2345)
6719 self.assert_packet_checksums_valid(p)
6722 self.logger.error(ppp("Unexpected or invalid packet:", p))
6725 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6726 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6727 TCP(sport=22, dport=port))
6728 self.pg1.add_stream(p)
6729 self.pg_enable_capture(self.pg_interfaces)
6731 capture = self.pg5.get_capture(1)
6736 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6737 self.assertEqual(tcp.dport, 2345)
6738 self.assert_packet_checksums_valid(p)
6740 self.logger.error(ppp("Unexpected or invalid packet:", p))
6743 # from client VRF1 to service VRF0
6744 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6745 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6746 TCP(sport=12346, dport=external_port))
6747 self.pg6.add_stream(p)
6748 self.pg_enable_capture(self.pg_interfaces)
6750 capture = self.pg0.get_capture(1)
6755 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6756 self.assertEqual(tcp.dport, local_port)
6757 self.assert_packet_checksums_valid(p)
6759 self.logger.error(ppp("Unexpected or invalid packet:", p))
6762 # from service VRF0 back to client VRF1
6763 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6764 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6765 TCP(sport=local_port, dport=12346))
6766 self.pg0.add_stream(p)
6767 self.pg_enable_capture(self.pg_interfaces)
6769 capture = self.pg6.get_capture(1)
6774 self.assertEqual(ip.src, self.pg0.local_ip4)
6775 self.assertEqual(tcp.sport, external_port)
6776 self.assert_packet_checksums_valid(p)
6778 self.logger.error(ppp("Unexpected or invalid packet:", p))
6781 # from client VRF0 to service VRF1
6782 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6783 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6784 TCP(sport=12347, dport=external_port))
6785 self.pg0.add_stream(p)
6786 self.pg_enable_capture(self.pg_interfaces)
6788 capture = self.pg5.get_capture(1)
6793 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6794 self.assertEqual(tcp.dport, local_port)
6795 self.assert_packet_checksums_valid(p)
6797 self.logger.error(ppp("Unexpected or invalid packet:", p))
6800 # from service VRF1 back to client VRF0
6801 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6802 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6803 TCP(sport=local_port, dport=12347))
6804 self.pg5.add_stream(p)
6805 self.pg_enable_capture(self.pg_interfaces)
6807 capture = self.pg0.get_capture(1)
6812 self.assertEqual(ip.src, external_addr)
6813 self.assertEqual(tcp.sport, external_port)
6814 self.assert_packet_checksums_valid(p)
6816 self.logger.error(ppp("Unexpected or invalid packet:", p))
6819 # from client to server (both VRF1, no translation)
6820 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6821 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6822 TCP(sport=12348, dport=local_port))
6823 self.pg6.add_stream(p)
6824 self.pg_enable_capture(self.pg_interfaces)
6826 capture = self.pg5.get_capture(1)
6831 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6832 self.assertEqual(tcp.dport, local_port)
6833 self.assert_packet_checksums_valid(p)
6835 self.logger.error(ppp("Unexpected or invalid packet:", p))
6838 # from server back to client (both VRF1, no translation)
6839 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6840 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6841 TCP(sport=local_port, dport=12348))
6842 self.pg5.add_stream(p)
6843 self.pg_enable_capture(self.pg_interfaces)
6845 capture = self.pg6.get_capture(1)
6850 self.assertEqual(ip.src, self.pg5.remote_ip4)
6851 self.assertEqual(tcp.sport, local_port)
6852 self.assert_packet_checksums_valid(p)
6854 self.logger.error(ppp("Unexpected or invalid packet:", p))
6857 # from client VRF1 to server VRF0 (no translation)
6858 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6859 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6860 TCP(sport=local_port, dport=12349))
6861 self.pg0.add_stream(p)
6862 self.pg_enable_capture(self.pg_interfaces)
6864 capture = self.pg6.get_capture(1)
6869 self.assertEqual(ip.src, self.pg0.remote_ip4)
6870 self.assertEqual(tcp.sport, local_port)
6871 self.assert_packet_checksums_valid(p)
6873 self.logger.error(ppp("Unexpected or invalid packet:", p))
6876 # from server VRF0 back to client VRF1 (no translation)
6877 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6878 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6879 TCP(sport=local_port, dport=12349))
6880 self.pg0.add_stream(p)
6881 self.pg_enable_capture(self.pg_interfaces)
6883 capture = self.pg6.get_capture(1)
6888 self.assertEqual(ip.src, self.pg0.remote_ip4)
6889 self.assertEqual(tcp.sport, local_port)
6890 self.assert_packet_checksums_valid(p)
6892 self.logger.error(ppp("Unexpected or invalid packet:", p))
6895 # from client VRF0 to server VRF1 (no translation)
6896 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6897 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6898 TCP(sport=12344, dport=local_port))
6899 self.pg0.add_stream(p)
6900 self.pg_enable_capture(self.pg_interfaces)
6902 capture = self.pg5.get_capture(1)
6907 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6908 self.assertEqual(tcp.dport, local_port)
6909 self.assert_packet_checksums_valid(p)
6911 self.logger.error(ppp("Unexpected or invalid packet:", p))
6914 # from server VRF1 back to client VRF0 (no translation)
6915 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6916 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6917 TCP(sport=local_port, dport=12344))
6918 self.pg5.add_stream(p)
6919 self.pg_enable_capture(self.pg_interfaces)
6921 capture = self.pg0.get_capture(1)
6926 self.assertEqual(ip.src, self.pg5.remote_ip4)
6927 self.assertEqual(tcp.sport, local_port)
6928 self.assert_packet_checksums_valid(p)
6930 self.logger.error(ppp("Unexpected or invalid packet:", p))
6933 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6934 def test_session_timeout(self):
6935 """ NAT44 session timeouts """
6936 self.nat44_add_address(self.nat_addr)
6937 flags = self.config_flags.NAT_IS_INSIDE
6938 self.vapi.nat44_interface_add_del_feature(
6939 sw_if_index=self.pg0.sw_if_index,
6940 flags=flags, is_add=1)
6941 self.vapi.nat44_interface_add_del_feature(
6942 sw_if_index=self.pg1.sw_if_index,
6944 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6945 tcp_transitory=240, icmp=5)
6949 for i in range(0, max_sessions):
6950 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6951 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6952 IP(src=src, dst=self.pg1.remote_ip4) /
6953 ICMP(id=1025, type='echo-request'))
6955 self.pg0.add_stream(pkts)
6956 self.pg_enable_capture(self.pg_interfaces)
6958 self.pg1.get_capture(max_sessions)
6963 for i in range(0, max_sessions):
6964 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
6965 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6966 IP(src=src, dst=self.pg1.remote_ip4) /
6967 ICMP(id=1026, type='echo-request'))
6969 self.pg0.add_stream(pkts)
6970 self.pg_enable_capture(self.pg_interfaces)
6972 self.pg1.get_capture(max_sessions)
6975 users = self.vapi.nat44_user_dump()
6977 nsessions = nsessions + user.nsessions
6978 self.assertLess(nsessions, 2 * max_sessions)
6980 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6981 def test_session_rst_timeout(self):
6982 """ NAT44 session RST 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=5, icmp=60)
6994 self.initiate_tcp_session(self.pg0, self.pg1)
6995 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6996 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6997 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6999 self.pg0.add_stream(p)
7000 self.pg_enable_capture(self.pg_interfaces)
7002 self.pg1.get_capture(1)
7006 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7007 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7008 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
7010 self.pg0.add_stream(p)
7011 self.pg_enable_capture(self.pg_interfaces)
7013 self.pg1.get_capture(1)
7015 def test_syslog_sess(self):
7016 """ Test syslog session creation and deletion """
7017 self.vapi.syslog_set_filter(
7018 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
7019 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
7020 self.nat44_add_address(self.nat_addr)
7021 flags = self.config_flags.NAT_IS_INSIDE
7022 self.vapi.nat44_interface_add_del_feature(
7023 sw_if_index=self.pg0.sw_if_index,
7024 flags=flags, is_add=1)
7025 self.vapi.nat44_interface_add_del_feature(
7026 sw_if_index=self.pg1.sw_if_index,
7029 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7030 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7031 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7032 self.pg0.add_stream(p)
7033 self.pg_enable_capture(self.pg_interfaces)
7035 capture = self.pg1.get_capture(1)
7036 self.tcp_port_out = capture[0][TCP].sport
7037 capture = self.pg2.get_capture(1)
7038 self.verify_syslog_sess(capture[0][Raw].load)
7040 self.pg_enable_capture(self.pg_interfaces)
7042 self.nat44_add_address(self.nat_addr, is_add=0)
7043 capture = self.pg2.get_capture(1)
7044 self.verify_syslog_sess(capture[0][Raw].load, False)
7047 super(TestNAT44EndpointDependent, self).tearDown()
7048 if not self.vpp_dead:
7050 self.vapi.cli("clear logging")
7052 def show_commands_at_teardown(self):
7053 self.logger.info(self.vapi.cli("show nat44 addresses"))
7054 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7055 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7056 self.logger.info(self.vapi.cli("show nat44 interface address"))
7057 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7058 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7059 self.logger.info(self.vapi.cli("show nat timeouts"))
7062 class TestNAT44EndpointDependent2(MethodHolder):
7063 """ Endpoint-Dependent mapping and filtering extra test cases """
7065 translation_buckets = 5
7068 def setUpConstants(cls):
7069 super(TestNAT44EndpointDependent2, cls).setUpConstants()
7070 cls.vpp_cmdline.extend([
7071 "nat", "{", "endpoint-dependent",
7072 "translation hash buckets %d" % cls.translation_buckets,
7077 def setUpClass(cls):
7078 super(TestNAT44EndpointDependent2, cls).setUpClass()
7079 cls.vapi.cli("set log class nat level debug")
7081 cls.nat_addr = '10.0.0.3'
7083 cls.create_pg_interfaces(range(2))
7085 for i in cls.pg_interfaces:
7091 super(TestNAT44EndpointDependent2, self).setUp()
7092 self.vapi.nat_set_timeouts(
7093 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7094 self.nat44_add_address(self.nat_addr)
7095 flags = self.config_flags.NAT_IS_INSIDE
7096 self.vapi.nat44_interface_add_del_feature(
7097 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7098 self.vapi.nat44_interface_add_del_feature(
7099 sw_if_index=self.pg1.sw_if_index, is_add=1)
7102 def tearDownClass(cls):
7103 super(TestNAT44EndpointDependent2, cls).tearDownClass()
7105 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7106 # SYN packet in->out
7107 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7108 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7109 TCP(sport=sport, dport=ext_dport, flags="S"))
7111 self.pg_enable_capture(self.pg_interfaces)
7113 capture = out_if.get_capture(1)
7115 tcp_port_out = p[TCP].sport
7117 # SYN + ACK packet out->in
7118 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7119 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7120 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7121 out_if.add_stream(p)
7122 self.pg_enable_capture(self.pg_interfaces)
7124 in_if.get_capture(1)
7126 # ACK packet in->out
7127 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7128 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7129 TCP(sport=sport, dport=ext_dport, flags="A"))
7131 self.pg_enable_capture(self.pg_interfaces)
7133 out_if.get_capture(1)
7137 def test_lru_cleanup(self):
7138 """ LRU cleanup algorithm """
7139 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7140 max_translations = 10 * self.translation_buckets
7142 for i in range(0, max_translations - 1):
7143 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7144 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7145 UDP(sport=7000+i, dport=80))
7148 self.pg0.add_stream(pkts)
7149 self.pg_enable_capture(self.pg_interfaces)
7151 self.pg1.get_capture(len(pkts))
7152 self.sleep(1.5, "wait for timeouts")
7155 for i in range(0, max_translations - 1):
7156 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7157 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7158 ICMP(id=8000+i, type='echo-request'))
7161 self.pg0.add_stream(pkts)
7162 self.pg_enable_capture(self.pg_interfaces)
7164 self.pg1.get_capture(len(pkts))
7167 class TestNAT44Out2InDPO(MethodHolder):
7168 """ NAT44 Test Cases using out2in DPO """
7171 def setUpConstants(cls):
7172 super(TestNAT44Out2InDPO, cls).setUpConstants()
7173 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7176 def setUpClass(cls):
7177 super(TestNAT44Out2InDPO, cls).setUpClass()
7178 cls.vapi.cli("set log class nat level debug")
7180 cls.tcp_port_in = 6303
7181 cls.tcp_port_out = 6303
7182 cls.udp_port_in = 6304
7183 cls.udp_port_out = 6304
7184 cls.icmp_id_in = 6305
7185 cls.icmp_id_out = 6305
7186 cls.nat_addr = '10.0.0.3'
7187 cls.dst_ip4 = '192.168.70.1'
7189 cls.create_pg_interfaces(range(2))
7192 cls.pg0.config_ip4()
7193 cls.pg0.resolve_arp()
7196 cls.pg1.config_ip6()
7197 cls.pg1.resolve_ndp()
7199 r1 = VppIpRoute(cls, "::", 0,
7200 [VppRoutePath(cls.pg1.remote_ip6,
7201 cls.pg1.sw_if_index)],
7206 def tearDownClass(cls):
7207 super(TestNAT44Out2InDPO, cls).tearDownClass()
7209 def configure_xlat(self):
7210 self.dst_ip6_pfx = '1:2:3::'
7211 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7213 self.dst_ip6_pfx_len = 96
7214 self.src_ip6_pfx = '4:5:6::'
7215 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7217 self.src_ip6_pfx_len = 96
7218 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7219 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7220 '\x00\x00\x00\x00', 0)
7222 @unittest.skip('Temporary disabled')
7223 def test_464xlat_ce(self):
7224 """ Test 464XLAT CE with NAT44 """
7226 nat_config = self.vapi.nat_show_config()
7227 self.assertEqual(1, nat_config.out2in_dpo)
7229 self.configure_xlat()
7231 flags = self.config_flags.NAT_IS_INSIDE
7232 self.vapi.nat44_interface_add_del_feature(
7233 sw_if_index=self.pg0.sw_if_index,
7234 flags=flags, is_add=1)
7235 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7236 last_ip_address=self.nat_addr_n,
7237 vrf_id=0xFFFFFFFF, is_add=1)
7239 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7240 self.dst_ip6_pfx_len)
7241 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7242 self.src_ip6_pfx_len)
7245 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7246 self.pg0.add_stream(pkts)
7247 self.pg_enable_capture(self.pg_interfaces)
7249 capture = self.pg1.get_capture(len(pkts))
7250 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7253 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7255 self.pg1.add_stream(pkts)
7256 self.pg_enable_capture(self.pg_interfaces)
7258 capture = self.pg0.get_capture(len(pkts))
7259 self.verify_capture_in(capture, self.pg0)
7261 self.vapi.nat44_interface_add_del_feature(
7262 sw_if_index=self.pg0.sw_if_index,
7264 self.vapi.nat44_add_del_address_range(
7265 first_ip_address=self.nat_addr_n,
7266 last_ip_address=self.nat_addr_n,
7269 @unittest.skip('Temporary disabled')
7270 def test_464xlat_ce_no_nat(self):
7271 """ Test 464XLAT CE without NAT44 """
7273 self.configure_xlat()
7275 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7276 self.dst_ip6_pfx_len)
7277 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7278 self.src_ip6_pfx_len)
7280 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7281 self.pg0.add_stream(pkts)
7282 self.pg_enable_capture(self.pg_interfaces)
7284 capture = self.pg1.get_capture(len(pkts))
7285 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7286 nat_ip=out_dst_ip6, same_port=True)
7288 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7289 self.pg1.add_stream(pkts)
7290 self.pg_enable_capture(self.pg_interfaces)
7292 capture = self.pg0.get_capture(len(pkts))
7293 self.verify_capture_in(capture, self.pg0)
7296 class TestDeterministicNAT(MethodHolder):
7297 """ Deterministic NAT Test Cases """
7300 def setUpConstants(cls):
7301 super(TestDeterministicNAT, cls).setUpConstants()
7302 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7305 def setUpClass(cls):
7306 super(TestDeterministicNAT, cls).setUpClass()
7307 cls.vapi.cli("set log class nat level debug")
7309 cls.tcp_port_in = 6303
7310 cls.tcp_external_port = 6303
7311 cls.udp_port_in = 6304
7312 cls.udp_external_port = 6304
7313 cls.icmp_id_in = 6305
7314 cls.nat_addr = '10.0.0.3'
7316 cls.create_pg_interfaces(range(3))
7317 cls.interfaces = list(cls.pg_interfaces)
7319 for i in cls.interfaces:
7324 cls.pg0.generate_remote_hosts(2)
7325 cls.pg0.configure_ipv4_neighbors()
7328 def tearDownClass(cls):
7329 super(TestDeterministicNAT, cls).tearDownClass()
7331 def create_stream_in(self, in_if, out_if, ttl=64):
7333 Create packet stream for inside network
7335 :param in_if: Inside interface
7336 :param out_if: Outside interface
7337 :param ttl: TTL of generated packets
7341 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7342 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7343 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7347 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7348 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7349 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7353 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7354 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7355 ICMP(id=self.icmp_id_in, type='echo-request'))
7360 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7362 Create packet stream for outside network
7364 :param out_if: Outside interface
7365 :param dst_ip: Destination IP address (Default use global NAT address)
7366 :param ttl: TTL of generated packets
7369 dst_ip = self.nat_addr
7372 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7373 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7374 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7378 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7379 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7380 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7384 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7385 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7386 ICMP(id=self.icmp_external_id, type='echo-reply'))
7391 def verify_capture_out(self, capture, nat_ip=None):
7393 Verify captured packets on outside network
7395 :param capture: Captured packets
7396 :param nat_ip: Translated IP address (Default use global NAT address)
7397 :param same_port: Source port number is not translated (Default False)
7400 nat_ip = self.nat_addr
7401 for packet in capture:
7403 self.assertEqual(packet[IP].src, nat_ip)
7404 if packet.haslayer(TCP):
7405 self.tcp_port_out = packet[TCP].sport
7406 elif packet.haslayer(UDP):
7407 self.udp_port_out = packet[UDP].sport
7409 self.icmp_external_id = packet[ICMP].id
7411 self.logger.error(ppp("Unexpected or invalid packet "
7412 "(outside network):", packet))
7415 def test_deterministic_mode(self):
7416 """ NAT plugin run deterministic mode """
7417 in_addr = '172.16.255.0'
7418 out_addr = '172.17.255.50'
7419 in_addr_t = '172.16.255.20'
7423 nat_config = self.vapi.nat_show_config()
7424 self.assertEqual(1, nat_config.deterministic)
7426 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7427 in_plen=in_plen, out_addr=out_addr,
7430 rep1 = self.vapi.nat_det_forward(in_addr_t)
7431 self.assertEqual(str(rep1.out_addr), out_addr)
7432 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7434 self.assertEqual(str(rep2.in_addr), in_addr_t)
7436 deterministic_mappings = self.vapi.nat_det_map_dump()
7437 self.assertEqual(len(deterministic_mappings), 1)
7438 dsm = deterministic_mappings[0]
7439 self.assertEqual(in_addr, str(dsm.in_addr))
7440 self.assertEqual(in_plen, dsm.in_plen)
7441 self.assertEqual(out_addr, str(dsm.out_addr))
7442 self.assertEqual(out_plen, dsm.out_plen)
7444 self.clear_nat_det()
7445 deterministic_mappings = self.vapi.nat_det_map_dump()
7446 self.assertEqual(len(deterministic_mappings), 0)
7448 def test_set_timeouts(self):
7449 """ Set deterministic NAT timeouts """
7450 timeouts_before = self.vapi.nat_get_timeouts()
7452 self.vapi.nat_set_timeouts(
7453 udp=timeouts_before.udp + 10,
7454 tcp_established=timeouts_before.tcp_established + 10,
7455 tcp_transitory=timeouts_before.tcp_transitory + 10,
7456 icmp=timeouts_before.icmp + 10)
7458 timeouts_after = self.vapi.nat_get_timeouts()
7460 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7461 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7462 self.assertNotEqual(timeouts_before.tcp_established,
7463 timeouts_after.tcp_established)
7464 self.assertNotEqual(timeouts_before.tcp_transitory,
7465 timeouts_after.tcp_transitory)
7467 def test_det_in(self):
7468 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7470 nat_ip = "10.0.0.10"
7472 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7474 out_addr=socket.inet_aton(nat_ip),
7477 flags = self.config_flags.NAT_IS_INSIDE
7478 self.vapi.nat44_interface_add_del_feature(
7479 sw_if_index=self.pg0.sw_if_index,
7480 flags=flags, is_add=1)
7481 self.vapi.nat44_interface_add_del_feature(
7482 sw_if_index=self.pg1.sw_if_index,
7486 pkts = self.create_stream_in(self.pg0, self.pg1)
7487 self.pg0.add_stream(pkts)
7488 self.pg_enable_capture(self.pg_interfaces)
7490 capture = self.pg1.get_capture(len(pkts))
7491 self.verify_capture_out(capture, nat_ip)
7494 pkts = self.create_stream_out(self.pg1, nat_ip)
7495 self.pg1.add_stream(pkts)
7496 self.pg_enable_capture(self.pg_interfaces)
7498 capture = self.pg0.get_capture(len(pkts))
7499 self.verify_capture_in(capture, self.pg0)
7502 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7503 self.assertEqual(len(sessions), 3)
7507 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7508 self.assertEqual(s.in_port, self.tcp_port_in)
7509 self.assertEqual(s.out_port, self.tcp_port_out)
7510 self.assertEqual(s.ext_port, self.tcp_external_port)
7514 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7515 self.assertEqual(s.in_port, self.udp_port_in)
7516 self.assertEqual(s.out_port, self.udp_port_out)
7517 self.assertEqual(s.ext_port, self.udp_external_port)
7521 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7522 self.assertEqual(s.in_port, self.icmp_id_in)
7523 self.assertEqual(s.out_port, self.icmp_external_id)
7525 def test_multiple_users(self):
7526 """ Deterministic NAT multiple users """
7528 nat_ip = "10.0.0.10"
7530 external_port = 6303
7532 host0 = self.pg0.remote_hosts[0]
7533 host1 = self.pg0.remote_hosts[1]
7535 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7536 out_addr=socket.inet_aton(nat_ip),
7538 flags = self.config_flags.NAT_IS_INSIDE
7539 self.vapi.nat44_interface_add_del_feature(
7540 sw_if_index=self.pg0.sw_if_index,
7541 flags=flags, is_add=1)
7542 self.vapi.nat44_interface_add_del_feature(
7543 sw_if_index=self.pg1.sw_if_index,
7547 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7548 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7549 TCP(sport=port_in, dport=external_port))
7550 self.pg0.add_stream(p)
7551 self.pg_enable_capture(self.pg_interfaces)
7553 capture = self.pg1.get_capture(1)
7558 self.assertEqual(ip.src, nat_ip)
7559 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7560 self.assertEqual(tcp.dport, external_port)
7561 port_out0 = tcp.sport
7563 self.logger.error(ppp("Unexpected or invalid packet:", p))
7567 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7568 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7569 TCP(sport=port_in, dport=external_port))
7570 self.pg0.add_stream(p)
7571 self.pg_enable_capture(self.pg_interfaces)
7573 capture = self.pg1.get_capture(1)
7578 self.assertEqual(ip.src, nat_ip)
7579 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7580 self.assertEqual(tcp.dport, external_port)
7581 port_out1 = tcp.sport
7583 self.logger.error(ppp("Unexpected or invalid packet:", p))
7586 dms = self.vapi.nat_det_map_dump()
7587 self.assertEqual(1, len(dms))
7588 self.assertEqual(2, dms[0].ses_num)
7591 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7592 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7593 TCP(sport=external_port, dport=port_out0))
7594 self.pg1.add_stream(p)
7595 self.pg_enable_capture(self.pg_interfaces)
7597 capture = self.pg0.get_capture(1)
7602 self.assertEqual(ip.src, self.pg1.remote_ip4)
7603 self.assertEqual(ip.dst, host0.ip4)
7604 self.assertEqual(tcp.dport, port_in)
7605 self.assertEqual(tcp.sport, external_port)
7607 self.logger.error(ppp("Unexpected or invalid packet:", p))
7611 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7612 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7613 TCP(sport=external_port, dport=port_out1))
7614 self.pg1.add_stream(p)
7615 self.pg_enable_capture(self.pg_interfaces)
7617 capture = self.pg0.get_capture(1)
7622 self.assertEqual(ip.src, self.pg1.remote_ip4)
7623 self.assertEqual(ip.dst, host1.ip4)
7624 self.assertEqual(tcp.dport, port_in)
7625 self.assertEqual(tcp.sport, external_port)
7627 self.logger.error(ppp("Unexpected or invalid packet", p))
7630 # session close api test
7631 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7633 self.pg1.remote_ip4,
7635 dms = self.vapi.nat_det_map_dump()
7636 self.assertEqual(dms[0].ses_num, 1)
7638 self.vapi.nat_det_close_session_in(host0.ip4,
7640 self.pg1.remote_ip4,
7642 dms = self.vapi.nat_det_map_dump()
7643 self.assertEqual(dms[0].ses_num, 0)
7645 def test_tcp_session_close_detection_in(self):
7646 """ Deterministic NAT TCP session close from inside network """
7647 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7649 out_addr=socket.inet_aton(self.nat_addr),
7651 flags = self.config_flags.NAT_IS_INSIDE
7652 self.vapi.nat44_interface_add_del_feature(
7653 sw_if_index=self.pg0.sw_if_index,
7654 flags=flags, is_add=1)
7655 self.vapi.nat44_interface_add_del_feature(
7656 sw_if_index=self.pg1.sw_if_index,
7659 self.initiate_tcp_session(self.pg0, self.pg1)
7661 # close the session from inside
7663 # FIN packet in -> out
7664 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7665 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7666 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7668 self.pg0.add_stream(p)
7669 self.pg_enable_capture(self.pg_interfaces)
7671 self.pg1.get_capture(1)
7675 # ACK packet out -> in
7676 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7677 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7678 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7682 # FIN packet out -> in
7683 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7684 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7685 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7689 self.pg1.add_stream(pkts)
7690 self.pg_enable_capture(self.pg_interfaces)
7692 self.pg0.get_capture(2)
7694 # ACK packet in -> out
7695 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7696 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7697 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7699 self.pg0.add_stream(p)
7700 self.pg_enable_capture(self.pg_interfaces)
7702 self.pg1.get_capture(1)
7704 # Check if deterministic NAT44 closed the session
7705 dms = self.vapi.nat_det_map_dump()
7706 self.assertEqual(0, dms[0].ses_num)
7708 self.logger.error("TCP session termination failed")
7711 def test_tcp_session_close_detection_out(self):
7712 """ Deterministic NAT TCP session close from outside network """
7713 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7715 out_addr=socket.inet_aton(self.nat_addr),
7717 flags = self.config_flags.NAT_IS_INSIDE
7718 self.vapi.nat44_interface_add_del_feature(
7719 sw_if_index=self.pg0.sw_if_index,
7720 flags=flags, is_add=1)
7721 self.vapi.nat44_interface_add_del_feature(
7722 sw_if_index=self.pg1.sw_if_index,
7725 self.initiate_tcp_session(self.pg0, self.pg1)
7727 # close the session from outside
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,
7734 self.pg1.add_stream(p)
7735 self.pg_enable_capture(self.pg_interfaces)
7737 self.pg0.get_capture(1)
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,
7748 # ACK packet in -> out
7749 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7750 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7751 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7755 self.pg0.add_stream(pkts)
7756 self.pg_enable_capture(self.pg_interfaces)
7758 self.pg1.get_capture(2)
7760 # ACK packet out -> in
7761 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7762 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7763 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7765 self.pg1.add_stream(p)
7766 self.pg_enable_capture(self.pg_interfaces)
7768 self.pg0.get_capture(1)
7770 # Check if deterministic NAT44 closed the session
7771 dms = self.vapi.nat_det_map_dump()
7772 self.assertEqual(0, dms[0].ses_num)
7774 self.logger.error("TCP session termination failed")
7777 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7778 def test_session_timeout(self):
7779 """ Deterministic NAT session timeouts """
7780 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7782 out_addr=socket.inet_aton(self.nat_addr),
7784 flags = self.config_flags.NAT_IS_INSIDE
7785 self.vapi.nat44_interface_add_del_feature(
7786 sw_if_index=self.pg0.sw_if_index,
7787 flags=flags, is_add=1)
7788 self.vapi.nat44_interface_add_del_feature(
7789 sw_if_index=self.pg1.sw_if_index,
7792 self.initiate_tcp_session(self.pg0, self.pg1)
7793 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7795 pkts = self.create_stream_in(self.pg0, self.pg1)
7796 self.pg0.add_stream(pkts)
7797 self.pg_enable_capture(self.pg_interfaces)
7799 capture = self.pg1.get_capture(len(pkts))
7802 dms = self.vapi.nat_det_map_dump()
7803 self.assertEqual(0, dms[0].ses_num)
7805 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7806 def test_session_limit_per_user(self):
7807 """ Deterministic NAT maximum sessions per user limit """
7808 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7810 out_addr=socket.inet_aton(self.nat_addr),
7812 flags = self.config_flags.NAT_IS_INSIDE
7813 self.vapi.nat44_interface_add_del_feature(
7814 sw_if_index=self.pg0.sw_if_index,
7815 flags=flags, is_add=1)
7816 self.vapi.nat44_interface_add_del_feature(
7817 sw_if_index=self.pg1.sw_if_index,
7819 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7820 src_address=self.pg2.local_ip4,
7822 template_interval=10)
7823 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7827 for port in range(1025, 2025):
7828 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7829 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7830 UDP(sport=port, dport=port))
7833 self.pg0.add_stream(pkts)
7834 self.pg_enable_capture(self.pg_interfaces)
7836 capture = self.pg1.get_capture(len(pkts))
7838 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7839 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7840 UDP(sport=3001, dport=3002))
7841 self.pg0.add_stream(p)
7842 self.pg_enable_capture(self.pg_interfaces)
7844 capture = self.pg1.assert_nothing_captured()
7846 # verify ICMP error packet
7847 capture = self.pg0.get_capture(1)
7849 self.assertTrue(p.haslayer(ICMP))
7851 self.assertEqual(icmp.type, 3)
7852 self.assertEqual(icmp.code, 1)
7853 self.assertTrue(icmp.haslayer(IPerror))
7854 inner_ip = icmp[IPerror]
7855 self.assertEqual(inner_ip[UDPerror].sport, 3001)
7856 self.assertEqual(inner_ip[UDPerror].dport, 3002)
7858 dms = self.vapi.nat_det_map_dump()
7860 self.assertEqual(1000, dms[0].ses_num)
7862 # verify IPFIX logging
7863 self.vapi.ipfix_flush()
7865 capture = self.pg2.get_capture(2)
7866 ipfix = IPFIXDecoder()
7867 # first load template
7869 self.assertTrue(p.haslayer(IPFIX))
7870 if p.haslayer(Template):
7871 ipfix.add_template(p.getlayer(Template))
7872 # verify events in data set
7874 if p.haslayer(Data):
7875 data = ipfix.decode_data_set(p.getlayer(Set))
7876 self.verify_ipfix_max_entries_per_user(data,
7878 self.pg0.remote_ip4)
7880 def clear_nat_det(self):
7882 Clear deterministic NAT configuration.
7884 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7886 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7887 tcp_transitory=240, icmp=60)
7888 deterministic_mappings = self.vapi.nat_det_map_dump()
7889 for dsm in deterministic_mappings:
7890 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
7891 in_plen=dsm.in_plen,
7892 out_addr=dsm.out_addr,
7893 out_plen=dsm.out_plen)
7895 interfaces = self.vapi.nat44_interface_dump()
7896 for intf in interfaces:
7897 self.vapi.nat44_interface_add_del_feature(
7898 sw_if_index=intf.sw_if_index,
7902 super(TestDeterministicNAT, self).tearDown()
7903 if not self.vpp_dead:
7904 self.clear_nat_det()
7906 def show_commands_at_teardown(self):
7907 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7908 self.logger.info(self.vapi.cli("show nat timeouts"))
7910 self.vapi.cli("show nat44 deterministic mappings"))
7912 self.vapi.cli("show nat44 deterministic sessions"))
7915 class TestNAT64(MethodHolder):
7916 """ NAT64 Test Cases """
7919 def setUpConstants(cls):
7920 super(TestNAT64, cls).setUpConstants()
7921 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7922 "nat64 st hash buckets 256", "}"])
7925 def setUpClass(cls):
7926 super(TestNAT64, cls).setUpClass()
7928 cls.tcp_port_in = 6303
7929 cls.tcp_port_out = 6303
7930 cls.udp_port_in = 6304
7931 cls.udp_port_out = 6304
7932 cls.icmp_id_in = 6305
7933 cls.icmp_id_out = 6305
7934 cls.tcp_external_port = 80
7935 cls.nat_addr = '10.0.0.3'
7936 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7938 cls.vrf1_nat_addr = '10.0.10.3'
7939 cls.ipfix_src_port = 4739
7940 cls.ipfix_domain_id = 1
7942 cls.create_pg_interfaces(range(6))
7943 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7944 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7945 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7947 cls.vapi.ip_table_add_del(is_add=1,
7948 table={'table_id': cls.vrf1_id,
7951 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7953 cls.pg0.generate_remote_hosts(2)
7955 for i in cls.ip6_interfaces:
7958 i.configure_ipv6_neighbors()
7960 for i in cls.ip4_interfaces:
7966 cls.pg3.config_ip4()
7967 cls.pg3.resolve_arp()
7968 cls.pg3.config_ip6()
7969 cls.pg3.configure_ipv6_neighbors()
7972 cls.pg5.config_ip6()
7975 def tearDownClass(cls):
7976 super(TestNAT64, cls).tearDownClass()
7978 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7979 """ NAT64 inside interface handles Neighbor Advertisement """
7981 flags = self.config_flags.NAT_IS_INSIDE
7982 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7983 sw_if_index=self.pg5.sw_if_index)
7986 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7987 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7988 ICMPv6EchoRequest())
7990 self.pg5.add_stream(pkts)
7991 self.pg_enable_capture(self.pg_interfaces)
7994 # Wait for Neighbor Solicitation
7995 capture = self.pg5.get_capture(len(pkts))
7998 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7999 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
8000 tgt = packet[ICMPv6ND_NS].tgt
8002 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8005 # Send Neighbor Advertisement
8006 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8007 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8008 ICMPv6ND_NA(tgt=tgt) /
8009 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
8011 self.pg5.add_stream(pkts)
8012 self.pg_enable_capture(self.pg_interfaces)
8015 # Try to send ping again
8017 self.pg5.add_stream(pkts)
8018 self.pg_enable_capture(self.pg_interfaces)
8021 # Wait for ping reply
8022 capture = self.pg5.get_capture(len(pkts))
8025 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8026 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
8027 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
8029 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8032 def test_pool(self):
8033 """ Add/delete address to NAT64 pool """
8034 nat_addr = '1.2.3.4'
8036 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8038 vrf_id=0xFFFFFFFF, is_add=1)
8040 addresses = self.vapi.nat64_pool_addr_dump()
8041 self.assertEqual(len(addresses), 1)
8042 self.assertEqual(str(addresses[0].address), nat_addr)
8044 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8046 vrf_id=0xFFFFFFFF, is_add=0)
8048 addresses = self.vapi.nat64_pool_addr_dump()
8049 self.assertEqual(len(addresses), 0)
8051 def test_interface(self):
8052 """ Enable/disable NAT64 feature on the interface """
8053 flags = self.config_flags.NAT_IS_INSIDE
8054 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8055 sw_if_index=self.pg0.sw_if_index)
8056 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8057 sw_if_index=self.pg1.sw_if_index)
8059 interfaces = self.vapi.nat64_interface_dump()
8060 self.assertEqual(len(interfaces), 2)
8063 for intf in interfaces:
8064 if intf.sw_if_index == self.pg0.sw_if_index:
8065 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
8067 elif intf.sw_if_index == self.pg1.sw_if_index:
8068 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
8070 self.assertTrue(pg0_found)
8071 self.assertTrue(pg1_found)
8073 features = self.vapi.cli("show interface features pg0")
8074 self.assertIn('nat64-in2out', features)
8075 features = self.vapi.cli("show interface features pg1")
8076 self.assertIn('nat64-out2in', features)
8078 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8079 sw_if_index=self.pg0.sw_if_index)
8080 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8081 sw_if_index=self.pg1.sw_if_index)
8083 interfaces = self.vapi.nat64_interface_dump()
8084 self.assertEqual(len(interfaces), 0)
8086 def test_static_bib(self):
8087 """ Add/delete static BIB entry """
8088 in_addr = '2001:db8:85a3::8a2e:370:7334'
8089 out_addr = '10.1.1.3'
8092 proto = IP_PROTOS.tcp
8094 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8095 i_port=in_port, o_port=out_port,
8096 proto=proto, vrf_id=0, is_add=1)
8097 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8100 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8102 self.assertEqual(str(bibe.i_addr), in_addr)
8103 self.assertEqual(str(bibe.o_addr), out_addr)
8104 self.assertEqual(bibe.i_port, in_port)
8105 self.assertEqual(bibe.o_port, out_port)
8106 self.assertEqual(static_bib_num, 1)
8107 bibs = self.statistics.get_counter('/nat64/total-bibs')
8108 self.assertEqual(bibs[0][0], 1)
8110 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8111 i_port=in_port, o_port=out_port,
8112 proto=proto, vrf_id=0, is_add=0)
8113 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8116 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8118 self.assertEqual(static_bib_num, 0)
8119 bibs = self.statistics.get_counter('/nat64/total-bibs')
8120 self.assertEqual(bibs[0][0], 0)
8122 def test_set_timeouts(self):
8123 """ Set NAT64 timeouts """
8124 # verify default values
8125 timeouts = self.vapi.nat_get_timeouts()
8126 self.assertEqual(timeouts.udp, 300)
8127 self.assertEqual(timeouts.icmp, 60)
8128 self.assertEqual(timeouts.tcp_transitory, 240)
8129 self.assertEqual(timeouts.tcp_established, 7440)
8131 # set and verify custom values
8132 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
8133 tcp_transitory=250, icmp=30)
8134 timeouts = self.vapi.nat_get_timeouts()
8135 self.assertEqual(timeouts.udp, 200)
8136 self.assertEqual(timeouts.icmp, 30)
8137 self.assertEqual(timeouts.tcp_transitory, 250)
8138 self.assertEqual(timeouts.tcp_established, 7450)
8140 def test_dynamic(self):
8141 """ NAT64 dynamic translation test """
8142 self.tcp_port_in = 6303
8143 self.udp_port_in = 6304
8144 self.icmp_id_in = 6305
8146 ses_num_start = self.nat64_get_ses_num()
8148 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8149 end_addr=self.nat_addr,
8152 flags = self.config_flags.NAT_IS_INSIDE
8153 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8154 sw_if_index=self.pg0.sw_if_index)
8155 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8156 sw_if_index=self.pg1.sw_if_index)
8159 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8160 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8161 icmpn = self.statistics.get_err_counter(
8162 '/err/nat64-in2out/ICMP packets')
8163 totaln = self.statistics.get_err_counter(
8164 '/err/nat64-in2out/good in2out packets processed')
8166 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8167 self.pg0.add_stream(pkts)
8168 self.pg_enable_capture(self.pg_interfaces)
8170 capture = self.pg1.get_capture(len(pkts))
8171 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8172 dst_ip=self.pg1.remote_ip4)
8174 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8175 self.assertEqual(err - tcpn, 1)
8176 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8177 self.assertEqual(err - udpn, 1)
8178 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8179 self.assertEqual(err - icmpn, 1)
8180 err = self.statistics.get_err_counter(
8181 '/err/nat64-in2out/good in2out packets processed')
8182 self.assertEqual(err - totaln, 3)
8185 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8186 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8187 icmpn = self.statistics.get_err_counter(
8188 '/err/nat64-out2in/ICMP packets')
8189 totaln = self.statistics.get_err_counter(
8190 '/err/nat64-out2in/good out2in packets processed')
8192 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8193 self.pg1.add_stream(pkts)
8194 self.pg_enable_capture(self.pg_interfaces)
8196 capture = self.pg0.get_capture(len(pkts))
8197 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8198 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8200 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8201 self.assertEqual(err - tcpn, 2)
8202 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8203 self.assertEqual(err - udpn, 1)
8204 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8205 self.assertEqual(err - icmpn, 1)
8206 err = self.statistics.get_err_counter(
8207 '/err/nat64-out2in/good out2in packets processed')
8208 self.assertEqual(err - totaln, 4)
8210 bibs = self.statistics.get_counter('/nat64/total-bibs')
8211 self.assertEqual(bibs[0][0], 3)
8212 sessions = self.statistics.get_counter('/nat64/total-sessions')
8213 self.assertEqual(sessions[0][0], 3)
8216 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8217 self.pg0.add_stream(pkts)
8218 self.pg_enable_capture(self.pg_interfaces)
8220 capture = self.pg1.get_capture(len(pkts))
8221 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8222 dst_ip=self.pg1.remote_ip4)
8225 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8226 self.pg1.add_stream(pkts)
8227 self.pg_enable_capture(self.pg_interfaces)
8229 capture = self.pg0.get_capture(len(pkts))
8230 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8232 ses_num_end = self.nat64_get_ses_num()
8234 self.assertEqual(ses_num_end - ses_num_start, 3)
8236 # tenant with specific VRF
8237 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8238 end_addr=self.vrf1_nat_addr,
8239 vrf_id=self.vrf1_id, is_add=1)
8240 flags = self.config_flags.NAT_IS_INSIDE
8241 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8242 sw_if_index=self.pg2.sw_if_index)
8244 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8245 self.pg2.add_stream(pkts)
8246 self.pg_enable_capture(self.pg_interfaces)
8248 capture = self.pg1.get_capture(len(pkts))
8249 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8250 dst_ip=self.pg1.remote_ip4)
8252 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8253 self.pg1.add_stream(pkts)
8254 self.pg_enable_capture(self.pg_interfaces)
8256 capture = self.pg2.get_capture(len(pkts))
8257 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8259 def test_static(self):
8260 """ NAT64 static translation test """
8261 self.tcp_port_in = 60303
8262 self.udp_port_in = 60304
8263 self.icmp_id_in = 60305
8264 self.tcp_port_out = 60303
8265 self.udp_port_out = 60304
8266 self.icmp_id_out = 60305
8268 ses_num_start = self.nat64_get_ses_num()
8270 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8271 end_addr=self.nat_addr,
8274 flags = self.config_flags.NAT_IS_INSIDE
8275 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8276 sw_if_index=self.pg0.sw_if_index)
8277 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8278 sw_if_index=self.pg1.sw_if_index)
8280 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8281 o_addr=self.nat_addr,
8282 i_port=self.tcp_port_in,
8283 o_port=self.tcp_port_out,
8284 proto=IP_PROTOS.tcp, vrf_id=0,
8286 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8287 o_addr=self.nat_addr,
8288 i_port=self.udp_port_in,
8289 o_port=self.udp_port_out,
8290 proto=IP_PROTOS.udp, vrf_id=0,
8292 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8293 o_addr=self.nat_addr,
8294 i_port=self.icmp_id_in,
8295 o_port=self.icmp_id_out,
8296 proto=IP_PROTOS.icmp, vrf_id=0,
8300 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8301 self.pg0.add_stream(pkts)
8302 self.pg_enable_capture(self.pg_interfaces)
8304 capture = self.pg1.get_capture(len(pkts))
8305 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8306 dst_ip=self.pg1.remote_ip4, same_port=True)
8309 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8310 self.pg1.add_stream(pkts)
8311 self.pg_enable_capture(self.pg_interfaces)
8313 capture = self.pg0.get_capture(len(pkts))
8314 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8315 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8317 ses_num_end = self.nat64_get_ses_num()
8319 self.assertEqual(ses_num_end - ses_num_start, 3)
8321 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8322 def test_session_timeout(self):
8323 """ NAT64 session timeout """
8324 self.icmp_id_in = 1234
8325 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8326 end_addr=self.nat_addr,
8329 flags = self.config_flags.NAT_IS_INSIDE
8330 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8331 sw_if_index=self.pg0.sw_if_index)
8332 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8333 sw_if_index=self.pg1.sw_if_index)
8334 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8338 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8339 self.pg0.add_stream(pkts)
8340 self.pg_enable_capture(self.pg_interfaces)
8342 capture = self.pg1.get_capture(len(pkts))
8344 ses_num_before_timeout = self.nat64_get_ses_num()
8348 # ICMP and TCP session after timeout
8349 ses_num_after_timeout = self.nat64_get_ses_num()
8350 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8352 def test_icmp_error(self):
8353 """ NAT64 ICMP Error message translation """
8354 self.tcp_port_in = 6303
8355 self.udp_port_in = 6304
8356 self.icmp_id_in = 6305
8358 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8359 end_addr=self.nat_addr,
8362 flags = self.config_flags.NAT_IS_INSIDE
8363 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8364 sw_if_index=self.pg0.sw_if_index)
8365 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8366 sw_if_index=self.pg1.sw_if_index)
8368 # send some packets to create sessions
8369 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8370 self.pg0.add_stream(pkts)
8371 self.pg_enable_capture(self.pg_interfaces)
8373 capture_ip4 = self.pg1.get_capture(len(pkts))
8374 self.verify_capture_out(capture_ip4,
8375 nat_ip=self.nat_addr,
8376 dst_ip=self.pg1.remote_ip4)
8378 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8379 self.pg1.add_stream(pkts)
8380 self.pg_enable_capture(self.pg_interfaces)
8382 capture_ip6 = self.pg0.get_capture(len(pkts))
8383 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8384 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8385 self.pg0.remote_ip6)
8388 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8389 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8390 ICMPv6DestUnreach(code=1) /
8391 packet[IPv6] for packet in capture_ip6]
8392 self.pg0.add_stream(pkts)
8393 self.pg_enable_capture(self.pg_interfaces)
8395 capture = self.pg1.get_capture(len(pkts))
8396 for packet in capture:
8398 self.assertEqual(packet[IP].src, self.nat_addr)
8399 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8400 self.assertEqual(packet[ICMP].type, 3)
8401 self.assertEqual(packet[ICMP].code, 13)
8402 inner = packet[IPerror]
8403 self.assertEqual(inner.src, self.pg1.remote_ip4)
8404 self.assertEqual(inner.dst, self.nat_addr)
8405 self.assert_packet_checksums_valid(packet)
8406 if inner.haslayer(TCPerror):
8407 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8408 elif inner.haslayer(UDPerror):
8409 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8411 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8413 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8417 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8418 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8419 ICMP(type=3, code=13) /
8420 packet[IP] for packet in capture_ip4]
8421 self.pg1.add_stream(pkts)
8422 self.pg_enable_capture(self.pg_interfaces)
8424 capture = self.pg0.get_capture(len(pkts))
8425 for packet in capture:
8427 self.assertEqual(packet[IPv6].src, ip.src)
8428 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8429 icmp = packet[ICMPv6DestUnreach]
8430 self.assertEqual(icmp.code, 1)
8431 inner = icmp[IPerror6]
8432 self.assertEqual(inner.src, self.pg0.remote_ip6)
8433 self.assertEqual(inner.dst, ip.src)
8434 self.assert_icmpv6_checksum_valid(packet)
8435 if inner.haslayer(TCPerror):
8436 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8437 elif inner.haslayer(UDPerror):
8438 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8440 self.assertEqual(inner[ICMPv6EchoRequest].id,
8443 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8446 def test_hairpinning(self):
8447 """ NAT64 hairpinning """
8449 client = self.pg0.remote_hosts[0]
8450 server = self.pg0.remote_hosts[1]
8451 server_tcp_in_port = 22
8452 server_tcp_out_port = 4022
8453 server_udp_in_port = 23
8454 server_udp_out_port = 4023
8455 client_tcp_in_port = 1234
8456 client_udp_in_port = 1235
8457 client_tcp_out_port = 0
8458 client_udp_out_port = 0
8459 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8460 nat_addr_ip6 = ip.src
8462 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8463 end_addr=self.nat_addr,
8466 flags = self.config_flags.NAT_IS_INSIDE
8467 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8468 sw_if_index=self.pg0.sw_if_index)
8469 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8470 sw_if_index=self.pg1.sw_if_index)
8472 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8473 o_addr=self.nat_addr,
8474 i_port=server_tcp_in_port,
8475 o_port=server_tcp_out_port,
8476 proto=IP_PROTOS.tcp, vrf_id=0,
8478 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8479 o_addr=self.nat_addr,
8480 i_port=server_udp_in_port,
8481 o_port=server_udp_out_port,
8482 proto=IP_PROTOS.udp, vrf_id=0,
8487 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8488 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8489 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8491 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8492 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8493 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8495 self.pg0.add_stream(pkts)
8496 self.pg_enable_capture(self.pg_interfaces)
8498 capture = self.pg0.get_capture(len(pkts))
8499 for packet in capture:
8501 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8502 self.assertEqual(packet[IPv6].dst, server.ip6)
8503 self.assert_packet_checksums_valid(packet)
8504 if packet.haslayer(TCP):
8505 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8506 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8507 client_tcp_out_port = packet[TCP].sport
8509 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8510 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8511 client_udp_out_port = packet[UDP].sport
8513 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8518 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8519 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8520 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8522 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8523 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8524 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8526 self.pg0.add_stream(pkts)
8527 self.pg_enable_capture(self.pg_interfaces)
8529 capture = self.pg0.get_capture(len(pkts))
8530 for packet in capture:
8532 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8533 self.assertEqual(packet[IPv6].dst, client.ip6)
8534 self.assert_packet_checksums_valid(packet)
8535 if packet.haslayer(TCP):
8536 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8537 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8539 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8540 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8542 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8547 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8548 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8549 ICMPv6DestUnreach(code=1) /
8550 packet[IPv6] for packet in capture]
8551 self.pg0.add_stream(pkts)
8552 self.pg_enable_capture(self.pg_interfaces)
8554 capture = self.pg0.get_capture(len(pkts))
8555 for packet in capture:
8557 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8558 self.assertEqual(packet[IPv6].dst, server.ip6)
8559 icmp = packet[ICMPv6DestUnreach]
8560 self.assertEqual(icmp.code, 1)
8561 inner = icmp[IPerror6]
8562 self.assertEqual(inner.src, server.ip6)
8563 self.assertEqual(inner.dst, nat_addr_ip6)
8564 self.assert_packet_checksums_valid(packet)
8565 if inner.haslayer(TCPerror):
8566 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8567 self.assertEqual(inner[TCPerror].dport,
8568 client_tcp_out_port)
8570 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8571 self.assertEqual(inner[UDPerror].dport,
8572 client_udp_out_port)
8574 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8577 def test_prefix(self):
8578 """ NAT64 Network-Specific Prefix """
8580 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8581 end_addr=self.nat_addr,
8584 flags = self.config_flags.NAT_IS_INSIDE
8585 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8586 sw_if_index=self.pg0.sw_if_index)
8587 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8588 sw_if_index=self.pg1.sw_if_index)
8589 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8590 end_addr=self.vrf1_nat_addr,
8591 vrf_id=self.vrf1_id, is_add=1)
8592 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8593 sw_if_index=self.pg2.sw_if_index)
8596 global_pref64 = "2001:db8::"
8597 global_pref64_len = 32
8598 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8599 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8602 prefix = self.vapi.nat64_prefix_dump()
8603 self.assertEqual(len(prefix), 1)
8604 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8605 self.assertEqual(prefix[0].vrf_id, 0)
8607 # Add tenant specific prefix
8608 vrf1_pref64 = "2001:db8:122:300::"
8609 vrf1_pref64_len = 56
8610 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8611 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8612 vrf_id=self.vrf1_id, is_add=1)
8614 prefix = self.vapi.nat64_prefix_dump()
8615 self.assertEqual(len(prefix), 2)
8618 pkts = self.create_stream_in_ip6(self.pg0,
8621 plen=global_pref64_len)
8622 self.pg0.add_stream(pkts)
8623 self.pg_enable_capture(self.pg_interfaces)
8625 capture = self.pg1.get_capture(len(pkts))
8626 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8627 dst_ip=self.pg1.remote_ip4)
8629 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8630 self.pg1.add_stream(pkts)
8631 self.pg_enable_capture(self.pg_interfaces)
8633 capture = self.pg0.get_capture(len(pkts))
8634 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8637 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8639 # Tenant specific prefix
8640 pkts = self.create_stream_in_ip6(self.pg2,
8643 plen=vrf1_pref64_len)
8644 self.pg2.add_stream(pkts)
8645 self.pg_enable_capture(self.pg_interfaces)
8647 capture = self.pg1.get_capture(len(pkts))
8648 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8649 dst_ip=self.pg1.remote_ip4)
8651 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8652 self.pg1.add_stream(pkts)
8653 self.pg_enable_capture(self.pg_interfaces)
8655 capture = self.pg2.get_capture(len(pkts))
8656 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8659 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8661 def test_unknown_proto(self):
8662 """ NAT64 translate packet with unknown protocol """
8664 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8665 end_addr=self.nat_addr,
8668 flags = self.config_flags.NAT_IS_INSIDE
8669 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8670 sw_if_index=self.pg0.sw_if_index)
8671 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8672 sw_if_index=self.pg1.sw_if_index)
8673 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8676 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8677 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8678 TCP(sport=self.tcp_port_in, dport=20))
8679 self.pg0.add_stream(p)
8680 self.pg_enable_capture(self.pg_interfaces)
8682 p = self.pg1.get_capture(1)
8684 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8685 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8687 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8688 TCP(sport=1234, dport=1234))
8689 self.pg0.add_stream(p)
8690 self.pg_enable_capture(self.pg_interfaces)
8692 p = self.pg1.get_capture(1)
8695 self.assertEqual(packet[IP].src, self.nat_addr)
8696 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8697 self.assertEqual(packet.haslayer(GRE), 1)
8698 self.assert_packet_checksums_valid(packet)
8700 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8704 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8705 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8707 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8708 TCP(sport=1234, dport=1234))
8709 self.pg1.add_stream(p)
8710 self.pg_enable_capture(self.pg_interfaces)
8712 p = self.pg0.get_capture(1)
8715 self.assertEqual(packet[IPv6].src, remote_ip6)
8716 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8717 self.assertEqual(packet[IPv6].nh, 47)
8719 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8722 def test_hairpinning_unknown_proto(self):
8723 """ NAT64 translate packet with unknown protocol - hairpinning """
8725 client = self.pg0.remote_hosts[0]
8726 server = self.pg0.remote_hosts[1]
8727 server_tcp_in_port = 22
8728 server_tcp_out_port = 4022
8729 client_tcp_in_port = 1234
8730 client_tcp_out_port = 1235
8731 server_nat_ip = "10.0.0.100"
8732 client_nat_ip = "10.0.0.110"
8733 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8734 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8736 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8737 end_addr=client_nat_ip,
8740 flags = self.config_flags.NAT_IS_INSIDE
8741 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8742 sw_if_index=self.pg0.sw_if_index)
8743 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8744 sw_if_index=self.pg1.sw_if_index)
8746 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8747 o_addr=server_nat_ip,
8748 i_port=server_tcp_in_port,
8749 o_port=server_tcp_out_port,
8750 proto=IP_PROTOS.tcp, vrf_id=0,
8753 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8754 o_addr=server_nat_ip, i_port=0,
8756 proto=IP_PROTOS.gre, vrf_id=0,
8759 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8760 o_addr=client_nat_ip,
8761 i_port=client_tcp_in_port,
8762 o_port=client_tcp_out_port,
8763 proto=IP_PROTOS.tcp, vrf_id=0,
8767 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8768 IPv6(src=client.ip6, dst=server_nat_ip6) /
8769 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8770 self.pg0.add_stream(p)
8771 self.pg_enable_capture(self.pg_interfaces)
8773 p = self.pg0.get_capture(1)
8775 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8776 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8778 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8779 TCP(sport=1234, dport=1234))
8780 self.pg0.add_stream(p)
8781 self.pg_enable_capture(self.pg_interfaces)
8783 p = self.pg0.get_capture(1)
8786 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8787 self.assertEqual(packet[IPv6].dst, server.ip6)
8788 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8790 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8794 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8795 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8797 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8798 TCP(sport=1234, dport=1234))
8799 self.pg0.add_stream(p)
8800 self.pg_enable_capture(self.pg_interfaces)
8802 p = self.pg0.get_capture(1)
8805 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8806 self.assertEqual(packet[IPv6].dst, client.ip6)
8807 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8809 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8812 def test_one_armed_nat64(self):
8813 """ One armed NAT64 """
8815 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8819 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8820 end_addr=self.nat_addr,
8823 flags = self.config_flags.NAT_IS_INSIDE
8824 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8825 sw_if_index=self.pg3.sw_if_index)
8826 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8827 sw_if_index=self.pg3.sw_if_index)
8830 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8831 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8832 TCP(sport=12345, dport=80))
8833 self.pg3.add_stream(p)
8834 self.pg_enable_capture(self.pg_interfaces)
8836 capture = self.pg3.get_capture(1)
8841 self.assertEqual(ip.src, self.nat_addr)
8842 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8843 self.assertNotEqual(tcp.sport, 12345)
8844 external_port = tcp.sport
8845 self.assertEqual(tcp.dport, 80)
8846 self.assert_packet_checksums_valid(p)
8848 self.logger.error(ppp("Unexpected or invalid packet:", p))
8852 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8853 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8854 TCP(sport=80, dport=external_port))
8855 self.pg3.add_stream(p)
8856 self.pg_enable_capture(self.pg_interfaces)
8858 capture = self.pg3.get_capture(1)
8863 self.assertEqual(ip.src, remote_host_ip6)
8864 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8865 self.assertEqual(tcp.sport, 80)
8866 self.assertEqual(tcp.dport, 12345)
8867 self.assert_packet_checksums_valid(p)
8869 self.logger.error(ppp("Unexpected or invalid packet:", p))
8872 def test_frag_in_order(self):
8873 """ NAT64 translate fragments arriving in order """
8874 self.tcp_port_in = random.randint(1025, 65535)
8876 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8877 end_addr=self.nat_addr,
8880 flags = self.config_flags.NAT_IS_INSIDE
8881 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8882 sw_if_index=self.pg0.sw_if_index)
8883 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8884 sw_if_index=self.pg1.sw_if_index)
8888 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8889 self.tcp_port_in, 20, data)
8890 self.pg0.add_stream(pkts)
8891 self.pg_enable_capture(self.pg_interfaces)
8893 frags = self.pg1.get_capture(len(pkts))
8894 p = self.reass_frags_and_verify(frags,
8896 self.pg1.remote_ip4)
8897 self.assertEqual(p[TCP].dport, 20)
8898 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8899 self.tcp_port_out = p[TCP].sport
8900 self.assertEqual(data, p[Raw].load)
8903 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8904 pkts = self.create_stream_frag(self.pg1,
8909 self.pg1.add_stream(pkts)
8910 self.pg_enable_capture(self.pg_interfaces)
8912 frags = self.pg0.get_capture(len(pkts))
8913 self.logger.debug(ppc("Captured:", frags))
8914 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8915 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8916 self.assertEqual(p[TCP].sport, 20)
8917 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8918 self.assertEqual(data, p[Raw].load)
8920 def test_reass_hairpinning(self):
8921 """ NAT64 fragments hairpinning """
8923 server = self.pg0.remote_hosts[1]
8924 server_in_port = random.randint(1025, 65535)
8925 server_out_port = random.randint(1025, 65535)
8926 client_in_port = random.randint(1025, 65535)
8927 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8928 nat_addr_ip6 = ip.src
8930 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8931 end_addr=self.nat_addr,
8934 flags = self.config_flags.NAT_IS_INSIDE
8935 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8936 sw_if_index=self.pg0.sw_if_index)
8937 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8938 sw_if_index=self.pg1.sw_if_index)
8940 # add static BIB entry for server
8941 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8942 o_addr=self.nat_addr,
8943 i_port=server_in_port,
8944 o_port=server_out_port,
8945 proto=IP_PROTOS.tcp, vrf_id=0,
8948 # send packet from host to server
8949 pkts = self.create_stream_frag_ip6(self.pg0,
8954 self.pg0.add_stream(pkts)
8955 self.pg_enable_capture(self.pg_interfaces)
8957 frags = self.pg0.get_capture(len(pkts))
8958 self.logger.debug(ppc("Captured:", frags))
8959 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8960 self.assertNotEqual(p[TCP].sport, client_in_port)
8961 self.assertEqual(p[TCP].dport, server_in_port)
8962 self.assertEqual(data, p[Raw].load)
8964 def test_frag_out_of_order(self):
8965 """ NAT64 translate fragments arriving out of order """
8966 self.tcp_port_in = random.randint(1025, 65535)
8968 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8969 end_addr=self.nat_addr,
8972 flags = self.config_flags.NAT_IS_INSIDE
8973 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8974 sw_if_index=self.pg0.sw_if_index)
8975 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8976 sw_if_index=self.pg1.sw_if_index)
8980 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8981 self.tcp_port_in, 20, data)
8983 self.pg0.add_stream(pkts)
8984 self.pg_enable_capture(self.pg_interfaces)
8986 frags = self.pg1.get_capture(len(pkts))
8987 p = self.reass_frags_and_verify(frags,
8989 self.pg1.remote_ip4)
8990 self.assertEqual(p[TCP].dport, 20)
8991 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8992 self.tcp_port_out = p[TCP].sport
8993 self.assertEqual(data, p[Raw].load)
8996 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8997 pkts = self.create_stream_frag(self.pg1,
9003 self.pg1.add_stream(pkts)
9004 self.pg_enable_capture(self.pg_interfaces)
9006 frags = self.pg0.get_capture(len(pkts))
9007 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9008 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9009 self.assertEqual(p[TCP].sport, 20)
9010 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9011 self.assertEqual(data, p[Raw].load)
9013 def test_interface_addr(self):
9014 """ Acquire NAT64 pool addresses from interface """
9015 self.vapi.nat64_add_del_interface_addr(
9017 sw_if_index=self.pg4.sw_if_index)
9019 # no address in NAT64 pool
9020 addresses = self.vapi.nat44_address_dump()
9021 self.assertEqual(0, len(addresses))
9023 # configure interface address and check NAT64 address pool
9024 self.pg4.config_ip4()
9025 addresses = self.vapi.nat64_pool_addr_dump()
9026 self.assertEqual(len(addresses), 1)
9028 self.assertEqual(str(addresses[0].address),
9031 # remove interface address and check NAT64 address pool
9032 self.pg4.unconfig_ip4()
9033 addresses = self.vapi.nat64_pool_addr_dump()
9034 self.assertEqual(0, len(addresses))
9036 @unittest.skipUnless(running_extended_tests, "part of extended tests")
9037 def test_ipfix_max_bibs_sessions(self):
9038 """ IPFIX logging maximum session and BIB entries exceeded """
9041 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9045 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9046 end_addr=self.nat_addr,
9049 flags = self.config_flags.NAT_IS_INSIDE
9050 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9051 sw_if_index=self.pg0.sw_if_index)
9052 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9053 sw_if_index=self.pg1.sw_if_index)
9057 for i in range(0, max_bibs):
9058 src = "fd01:aa::%x" % (i)
9059 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9060 IPv6(src=src, dst=remote_host_ip6) /
9061 TCP(sport=12345, dport=80))
9063 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9064 IPv6(src=src, dst=remote_host_ip6) /
9065 TCP(sport=12345, dport=22))
9067 self.pg0.add_stream(pkts)
9068 self.pg_enable_capture(self.pg_interfaces)
9070 self.pg1.get_capture(max_sessions)
9072 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9073 src_address=self.pg3.local_ip4,
9075 template_interval=10)
9076 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9077 src_port=self.ipfix_src_port,
9080 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9081 IPv6(src=src, dst=remote_host_ip6) /
9082 TCP(sport=12345, dport=25))
9083 self.pg0.add_stream(p)
9084 self.pg_enable_capture(self.pg_interfaces)
9086 self.pg1.assert_nothing_captured()
9088 self.vapi.ipfix_flush()
9089 capture = self.pg3.get_capture(7)
9090 ipfix = IPFIXDecoder()
9091 # first load template
9093 self.assertTrue(p.haslayer(IPFIX))
9094 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9095 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9096 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9097 self.assertEqual(p[UDP].dport, 4739)
9098 self.assertEqual(p[IPFIX].observationDomainID,
9099 self.ipfix_domain_id)
9100 if p.haslayer(Template):
9101 ipfix.add_template(p.getlayer(Template))
9102 # verify events in data set
9104 if p.haslayer(Data):
9105 data = ipfix.decode_data_set(p.getlayer(Set))
9106 self.verify_ipfix_max_sessions(data, max_sessions)
9108 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9109 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9110 TCP(sport=12345, dport=80))
9111 self.pg0.add_stream(p)
9112 self.pg_enable_capture(self.pg_interfaces)
9114 self.pg1.assert_nothing_captured()
9116 self.vapi.ipfix_flush()
9117 capture = self.pg3.get_capture(1)
9118 # verify events in data set
9120 self.assertTrue(p.haslayer(IPFIX))
9121 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9122 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9123 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9124 self.assertEqual(p[UDP].dport, 4739)
9125 self.assertEqual(p[IPFIX].observationDomainID,
9126 self.ipfix_domain_id)
9127 if p.haslayer(Data):
9128 data = ipfix.decode_data_set(p.getlayer(Set))
9129 self.verify_ipfix_max_bibs(data, max_bibs)
9131 def test_ipfix_bib_ses(self):
9132 """ IPFIX logging NAT64 BIB/session create and delete events """
9133 self.tcp_port_in = random.randint(1025, 65535)
9134 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9138 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9139 end_addr=self.nat_addr,
9142 flags = self.config_flags.NAT_IS_INSIDE
9143 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9144 sw_if_index=self.pg0.sw_if_index)
9145 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9146 sw_if_index=self.pg1.sw_if_index)
9147 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9148 src_address=self.pg3.local_ip4,
9150 template_interval=10)
9151 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9152 src_port=self.ipfix_src_port,
9156 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9157 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9158 TCP(sport=self.tcp_port_in, dport=25))
9159 self.pg0.add_stream(p)
9160 self.pg_enable_capture(self.pg_interfaces)
9162 p = self.pg1.get_capture(1)
9163 self.tcp_port_out = p[0][TCP].sport
9164 self.vapi.ipfix_flush()
9165 capture = self.pg3.get_capture(8)
9166 ipfix = IPFIXDecoder()
9167 # first load template
9169 self.assertTrue(p.haslayer(IPFIX))
9170 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9171 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9172 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9173 self.assertEqual(p[UDP].dport, 4739)
9174 self.assertEqual(p[IPFIX].observationDomainID,
9175 self.ipfix_domain_id)
9176 if p.haslayer(Template):
9177 ipfix.add_template(p.getlayer(Template))
9178 # verify events in data set
9180 if p.haslayer(Data):
9181 data = ipfix.decode_data_set(p.getlayer(Set))
9182 if scapy.compat.orb(data[0][230]) == 10:
9183 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
9184 elif scapy.compat.orb(data[0][230]) == 6:
9185 self.verify_ipfix_nat64_ses(data,
9187 self.pg0.remote_ip6,
9188 self.pg1.remote_ip4,
9191 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9194 self.pg_enable_capture(self.pg_interfaces)
9195 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9196 end_addr=self.nat_addr,
9199 self.vapi.ipfix_flush()
9200 capture = self.pg3.get_capture(2)
9201 # verify events in data set
9203 self.assertTrue(p.haslayer(IPFIX))
9204 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9205 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9206 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9207 self.assertEqual(p[UDP].dport, 4739)
9208 self.assertEqual(p[IPFIX].observationDomainID,
9209 self.ipfix_domain_id)
9210 if p.haslayer(Data):
9211 data = ipfix.decode_data_set(p.getlayer(Set))
9212 if scapy.compat.orb(data[0][230]) == 11:
9213 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
9214 elif scapy.compat.orb(data[0][230]) == 7:
9215 self.verify_ipfix_nat64_ses(data,
9217 self.pg0.remote_ip6,
9218 self.pg1.remote_ip4,
9221 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9223 def test_syslog_sess(self):
9224 """ Test syslog session creation and deletion """
9225 self.tcp_port_in = random.randint(1025, 65535)
9226 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9230 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9231 end_addr=self.nat_addr,
9234 flags = self.config_flags.NAT_IS_INSIDE
9235 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9236 sw_if_index=self.pg0.sw_if_index)
9237 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9238 sw_if_index=self.pg1.sw_if_index)
9239 self.vapi.syslog_set_filter(
9240 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9241 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9243 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9244 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9245 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9246 self.pg0.add_stream(p)
9247 self.pg_enable_capture(self.pg_interfaces)
9249 p = self.pg1.get_capture(1)
9250 self.tcp_port_out = p[0][TCP].sport
9251 capture = self.pg3.get_capture(1)
9252 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9254 self.pg_enable_capture(self.pg_interfaces)
9256 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9257 end_addr=self.nat_addr,
9260 capture = self.pg3.get_capture(1)
9261 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9263 def nat64_get_ses_num(self):
9265 Return number of active NAT64 sessions.
9267 st = self.vapi.nat64_st_dump(proto=255)
9270 def clear_nat64(self):
9272 Clear NAT64 configuration.
9274 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9275 src_port=self.ipfix_src_port,
9277 self.ipfix_src_port = 4739
9278 self.ipfix_domain_id = 1
9280 self.vapi.syslog_set_filter(
9281 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9283 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9284 tcp_transitory=240, icmp=60)
9286 interfaces = self.vapi.nat64_interface_dump()
9287 for intf in interfaces:
9288 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9289 sw_if_index=intf.sw_if_index)
9291 bib = self.vapi.nat64_bib_dump(proto=255)
9293 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9294 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9302 adresses = self.vapi.nat64_pool_addr_dump()
9303 for addr in adresses:
9304 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9305 end_addr=addr.address,
9309 prefixes = self.vapi.nat64_prefix_dump()
9310 for prefix in prefixes:
9311 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9312 vrf_id=prefix.vrf_id, is_add=0)
9314 bibs = self.statistics.get_counter('/nat64/total-bibs')
9315 self.assertEqual(bibs[0][0], 0)
9316 sessions = self.statistics.get_counter('/nat64/total-sessions')
9317 self.assertEqual(sessions[0][0], 0)
9320 super(TestNAT64, self).tearDown()
9321 if not self.vpp_dead:
9324 def show_commands_at_teardown(self):
9325 self.logger.info(self.vapi.cli("show nat64 pool"))
9326 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9327 self.logger.info(self.vapi.cli("show nat64 prefix"))
9328 self.logger.info(self.vapi.cli("show nat64 bib all"))
9329 self.logger.info(self.vapi.cli("show nat64 session table all"))
9332 class TestNAT66(MethodHolder):
9333 """ NAT66 Test Cases """
9336 def setUpClass(cls):
9337 super(TestNAT66, cls).setUpClass()
9339 cls.nat_addr = 'fd01:ff::2'
9341 cls.create_pg_interfaces(range(2))
9342 cls.interfaces = list(cls.pg_interfaces)
9344 for i in cls.interfaces:
9347 i.configure_ipv6_neighbors()
9350 def tearDownClass(cls):
9351 super(TestNAT66, cls).tearDownClass()
9353 def test_static(self):
9354 """ 1:1 NAT66 test """
9355 flags = self.config_flags.NAT_IS_INSIDE
9356 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9357 sw_if_index=self.pg0.sw_if_index)
9358 self.vapi.nat66_add_del_interface(is_add=1,
9359 sw_if_index=self.pg1.sw_if_index)
9360 self.vapi.nat66_add_del_static_mapping(
9361 local_ip_address=self.pg0.remote_ip6,
9362 external_ip_address=self.nat_addr,
9367 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9368 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9371 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9372 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9375 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9376 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9377 ICMPv6EchoRequest())
9379 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9380 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9381 GRE() / IP() / TCP())
9383 self.pg0.add_stream(pkts)
9384 self.pg_enable_capture(self.pg_interfaces)
9386 capture = self.pg1.get_capture(len(pkts))
9388 for packet in capture:
9390 self.assertEqual(packet[IPv6].src, self.nat_addr)
9391 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9392 self.assert_packet_checksums_valid(packet)
9394 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9399 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9400 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9403 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9404 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9407 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9408 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9411 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9412 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9413 GRE() / IP() / TCP())
9415 self.pg1.add_stream(pkts)
9416 self.pg_enable_capture(self.pg_interfaces)
9418 capture = self.pg0.get_capture(len(pkts))
9419 for packet in capture:
9421 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9422 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9423 self.assert_packet_checksums_valid(packet)
9425 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9428 sm = self.vapi.nat66_static_mapping_dump()
9429 self.assertEqual(len(sm), 1)
9430 self.assertEqual(sm[0].total_pkts, 8)
9432 def test_check_no_translate(self):
9433 """ NAT66 translate only when egress interface is outside interface """
9434 flags = self.config_flags.NAT_IS_INSIDE
9435 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9436 sw_if_index=self.pg0.sw_if_index)
9437 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9438 sw_if_index=self.pg1.sw_if_index)
9439 self.vapi.nat66_add_del_static_mapping(
9440 local_ip_address=self.pg0.remote_ip6,
9441 external_ip_address=self.nat_addr,
9445 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9446 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9448 self.pg0.add_stream([p])
9449 self.pg_enable_capture(self.pg_interfaces)
9451 capture = self.pg1.get_capture(1)
9454 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9455 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9457 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9460 def clear_nat66(self):
9462 Clear NAT66 configuration.
9464 interfaces = self.vapi.nat66_interface_dump()
9465 for intf in interfaces:
9466 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9467 sw_if_index=intf.sw_if_index)
9469 static_mappings = self.vapi.nat66_static_mapping_dump()
9470 for sm in static_mappings:
9471 self.vapi.nat66_add_del_static_mapping(
9472 local_ip_address=sm.local_ip_address,
9473 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9477 super(TestNAT66, self).tearDown()
9480 def show_commands_at_teardown(self):
9481 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9482 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9485 if __name__ == '__main__':
9486 unittest.main(testRunner=VppTestRunner)