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, ignore_port=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):
480 packet[TCP].sport, self.tcp_port_in)
483 packet[TCP].sport, self.tcp_port_in)
484 self.tcp_port_out = packet[TCP].sport
485 self.assert_packet_checksums_valid(packet)
486 elif packet.haslayer(UDP):
490 packet[UDP].sport, self.udp_port_in)
493 packet[UDP].sport, self.udp_port_in)
494 self.udp_port_out = packet[UDP].sport
499 packet[ICMP46].id, self.icmp_id_in)
502 packet[ICMP46].id, self.icmp_id_in)
503 self.icmp_id_out = packet[ICMP46].id
504 self.assert_packet_checksums_valid(packet)
506 self.logger.error(ppp("Unexpected or invalid packet "
507 "(outside network):", packet))
510 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
513 Verify captured packets on outside network
515 :param capture: Captured packets
516 :param nat_ip: Translated IP address
517 :param same_port: Source port number is not translated (Default False)
518 :param dst_ip: Destination IP address (Default do not verify)
520 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
523 def verify_capture_in(self, capture, in_if):
525 Verify captured packets on inside network
527 :param capture: Captured packets
528 :param in_if: Inside interface
530 for packet in capture:
532 self.assert_packet_checksums_valid(packet)
533 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
534 if packet.haslayer(TCP):
535 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
536 elif packet.haslayer(UDP):
537 self.assertEqual(packet[UDP].dport, self.udp_port_in)
539 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
541 self.logger.error(ppp("Unexpected or invalid packet "
542 "(inside network):", packet))
545 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
547 Verify captured IPv6 packets on inside network
549 :param capture: Captured packets
550 :param src_ip: Source IP
551 :param dst_ip: Destination IP address
553 for packet in capture:
555 self.assertEqual(packet[IPv6].src, src_ip)
556 self.assertEqual(packet[IPv6].dst, dst_ip)
557 self.assert_packet_checksums_valid(packet)
558 if packet.haslayer(TCP):
559 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
560 elif packet.haslayer(UDP):
561 self.assertEqual(packet[UDP].dport, self.udp_port_in)
563 self.assertEqual(packet[ICMPv6EchoReply].id,
566 self.logger.error(ppp("Unexpected or invalid packet "
567 "(inside network):", packet))
570 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
572 Verify captured packet that don't have to be translated
574 :param capture: Captured packets
575 :param ingress_if: Ingress interface
576 :param egress_if: Egress interface
578 for packet in capture:
580 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
581 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
582 if packet.haslayer(TCP):
583 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
584 elif packet.haslayer(UDP):
585 self.assertEqual(packet[UDP].sport, self.udp_port_in)
587 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
589 self.logger.error(ppp("Unexpected or invalid packet "
590 "(inside network):", packet))
593 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
596 Verify captured packets with ICMP errors on outside network
598 :param capture: Captured packets
599 :param src_ip: Translated IP address or IP address of VPP
600 (Default use global NAT address)
601 :param icmp_type: Type of error ICMP packet
602 we are expecting (Default 11)
605 src_ip = self.nat_addr
606 for packet in capture:
608 self.assertEqual(packet[IP].src, src_ip)
609 self.assertEqual(packet.haslayer(ICMP), 1)
611 self.assertEqual(icmp.type, icmp_type)
612 self.assertTrue(icmp.haslayer(IPerror))
613 inner_ip = icmp[IPerror]
614 if inner_ip.haslayer(TCPerror):
615 self.assertEqual(inner_ip[TCPerror].dport,
617 elif inner_ip.haslayer(UDPerror):
618 self.assertEqual(inner_ip[UDPerror].dport,
621 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
623 self.logger.error(ppp("Unexpected or invalid packet "
624 "(outside network):", packet))
627 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
629 Verify captured packets with ICMP errors on inside network
631 :param capture: Captured packets
632 :param in_if: Inside interface
633 :param icmp_type: Type of error ICMP packet
634 we are expecting (Default 11)
636 for packet in capture:
638 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
639 self.assertEqual(packet.haslayer(ICMP), 1)
641 self.assertEqual(icmp.type, icmp_type)
642 self.assertTrue(icmp.haslayer(IPerror))
643 inner_ip = icmp[IPerror]
644 if inner_ip.haslayer(TCPerror):
645 self.assertEqual(inner_ip[TCPerror].sport,
647 elif inner_ip.haslayer(UDPerror):
648 self.assertEqual(inner_ip[UDPerror].sport,
651 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
653 self.logger.error(ppp("Unexpected or invalid packet "
654 "(inside network):", packet))
657 def create_stream_frag(self, src_if, dst, sport, dport, data,
658 proto=IP_PROTOS.tcp, echo_reply=False):
660 Create fragmented packet stream
662 :param src_if: Source interface
663 :param dst: Destination IPv4 address
664 :param sport: Source port
665 :param dport: Destination port
666 :param data: Payload data
667 :param proto: protocol (TCP, UDP, ICMP)
668 :param echo_reply: use echo_reply if protocol is ICMP
671 if proto == IP_PROTOS.tcp:
672 p = (IP(src=src_if.remote_ip4, dst=dst) /
673 TCP(sport=sport, dport=dport) /
675 p = p.__class__(scapy.compat.raw(p))
676 chksum = p[TCP].chksum
677 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
678 elif proto == IP_PROTOS.udp:
679 proto_header = UDP(sport=sport, dport=dport)
680 elif proto == IP_PROTOS.icmp:
682 proto_header = ICMP(id=sport, type='echo-request')
684 proto_header = ICMP(id=sport, type='echo-reply')
686 raise Exception("Unsupported protocol")
687 id = random.randint(0, 65535)
689 if proto == IP_PROTOS.tcp:
692 raw = Raw(data[0:16])
693 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
694 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
698 if proto == IP_PROTOS.tcp:
699 raw = Raw(data[4:20])
701 raw = Raw(data[16:32])
702 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
703 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
707 if proto == IP_PROTOS.tcp:
711 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
712 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
718 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
719 pref=None, plen=0, frag_size=128):
721 Create fragmented packet stream
723 :param src_if: Source interface
724 :param dst: Destination IPv4 address
725 :param sport: Source TCP port
726 :param dport: Destination TCP port
727 :param data: Payload data
728 :param pref: NAT64 prefix
729 :param plen: NAT64 prefix length
730 :param fragsize: size of fragments
734 dst_ip6 = ''.join(['64:ff9b::', dst])
736 dst_ip6 = self.compose_ip6(dst, pref, plen)
738 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
739 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
740 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
741 TCP(sport=sport, dport=dport) /
744 return fragment6(p, frag_size)
746 def reass_frags_and_verify(self, frags, src, dst):
748 Reassemble and verify fragmented packet
750 :param frags: Captured fragments
751 :param src: Source IPv4 address to verify
752 :param dst: Destination IPv4 address to verify
754 :returns: Reassembled IPv4 packet
758 self.assertEqual(p[IP].src, src)
759 self.assertEqual(p[IP].dst, dst)
760 self.assert_ip_checksum_valid(p)
761 buffer.seek(p[IP].frag * 8)
762 buffer.write(bytes(p[IP].payload))
763 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
764 proto=frags[0][IP].proto)
765 if ip.proto == IP_PROTOS.tcp:
766 p = (ip / TCP(buffer.getvalue()))
767 self.logger.debug(ppp("Reassembled:", p))
768 self.assert_tcp_checksum_valid(p)
769 elif ip.proto == IP_PROTOS.udp:
770 p = (ip / UDP(buffer.getvalue()[:8]) /
771 Raw(buffer.getvalue()[8:]))
772 elif ip.proto == IP_PROTOS.icmp:
773 p = (ip / ICMP(buffer.getvalue()))
776 def reass_frags_and_verify_ip6(self, frags, src, dst):
778 Reassemble and verify fragmented packet
780 :param frags: Captured fragments
781 :param src: Source IPv6 address to verify
782 :param dst: Destination IPv6 address to verify
784 :returns: Reassembled IPv6 packet
788 self.assertEqual(p[IPv6].src, src)
789 self.assertEqual(p[IPv6].dst, dst)
790 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
791 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
792 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
793 nh=frags[0][IPv6ExtHdrFragment].nh)
794 if ip.nh == IP_PROTOS.tcp:
795 p = (ip / TCP(buffer.getvalue()))
796 elif ip.nh == IP_PROTOS.udp:
797 p = (ip / UDP(buffer.getvalue()))
798 self.logger.debug(ppp("Reassembled:", p))
799 self.assert_packet_checksums_valid(p)
802 def initiate_tcp_session(self, in_if, out_if):
804 Initiates TCP session
806 :param in_if: Inside interface
807 :param out_if: Outside interface
811 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
812 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
813 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
816 self.pg_enable_capture(self.pg_interfaces)
818 capture = out_if.get_capture(1)
820 self.tcp_port_out = p[TCP].sport
822 # SYN + ACK packet out->in
823 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
824 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
825 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
828 self.pg_enable_capture(self.pg_interfaces)
833 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
834 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
835 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
838 self.pg_enable_capture(self.pg_interfaces)
840 out_if.get_capture(1)
843 self.logger.error("TCP 3 way handshake failed")
846 def verify_ipfix_nat44_ses(self, data):
848 Verify IPFIX NAT44 session create/delete event
850 :param data: Decoded IPFIX data records
852 nat44_ses_create_num = 0
853 nat44_ses_delete_num = 0
854 self.assertEqual(6, len(data))
857 self.assertIn(scapy.compat.orb(record[230]), [4, 5])
858 if scapy.compat.orb(record[230]) == 4:
859 nat44_ses_create_num += 1
861 nat44_ses_delete_num += 1
863 self.assertEqual(self.pg0.remote_ip4,
864 str(ipaddress.IPv4Address(record[8])))
865 # postNATSourceIPv4Address
866 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
869 self.assertEqual(struct.pack("!I", 0), record[234])
870 # protocolIdentifier/sourceTransportPort
871 # /postNAPTSourceTransportPort
872 if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
873 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
874 self.assertEqual(struct.pack("!H", self.icmp_id_out),
876 elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
877 self.assertEqual(struct.pack("!H", self.tcp_port_in),
879 self.assertEqual(struct.pack("!H", self.tcp_port_out),
881 elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
882 self.assertEqual(struct.pack("!H", self.udp_port_in),
884 self.assertEqual(struct.pack("!H", self.udp_port_out),
887 self.fail("Invalid protocol")
888 self.assertEqual(3, nat44_ses_create_num)
889 self.assertEqual(3, nat44_ses_delete_num)
891 def verify_ipfix_addr_exhausted(self, data):
893 Verify IPFIX NAT addresses event
895 :param data: Decoded IPFIX data records
897 self.assertEqual(1, len(data))
900 self.assertEqual(scapy.compat.orb(record[230]), 3)
902 self.assertEqual(struct.pack("!I", 0), record[283])
904 def verify_ipfix_max_sessions(self, data, limit):
906 Verify IPFIX maximum session entries exceeded event
908 :param data: Decoded IPFIX data records
909 :param limit: Number of maximum session entries that can be created.
911 self.assertEqual(1, len(data))
914 self.assertEqual(scapy.compat.orb(record[230]), 13)
915 # natQuotaExceededEvent
916 self.assertEqual(struct.pack("I", 1), record[466])
918 self.assertEqual(struct.pack("I", limit), record[471])
920 def verify_ipfix_max_bibs(self, data, limit):
922 Verify IPFIX maximum BIB entries exceeded event
924 :param data: Decoded IPFIX data records
925 :param limit: Number of maximum BIB entries that can be created.
927 self.assertEqual(1, len(data))
930 self.assertEqual(scapy.compat.orb(record[230]), 13)
931 # natQuotaExceededEvent
932 self.assertEqual(struct.pack("I", 2), record[466])
934 self.assertEqual(struct.pack("I", limit), record[472])
936 def verify_ipfix_bib(self, data, is_create, src_addr):
938 Verify IPFIX NAT64 BIB create and delete events
940 :param data: Decoded IPFIX data records
941 :param is_create: Create event if nonzero value otherwise delete event
942 :param src_addr: IPv6 source address
944 self.assertEqual(1, len(data))
948 self.assertEqual(scapy.compat.orb(record[230]), 10)
950 self.assertEqual(scapy.compat.orb(record[230]), 11)
952 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
953 # postNATSourceIPv4Address
954 self.assertEqual(self.nat_addr_n, record[225])
956 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
958 self.assertEqual(struct.pack("!I", 0), record[234])
959 # sourceTransportPort
960 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
961 # postNAPTSourceTransportPort
962 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
964 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
967 Verify IPFIX NAT64 session create and delete events
969 :param data: Decoded IPFIX data records
970 :param is_create: Create event if nonzero value otherwise delete event
971 :param src_addr: IPv6 source address
972 :param dst_addr: IPv4 destination address
973 :param dst_port: destination TCP port
975 self.assertEqual(1, len(data))
979 self.assertEqual(scapy.compat.orb(record[230]), 6)
981 self.assertEqual(scapy.compat.orb(record[230]), 7)
983 self.assertEqual(src_addr, str(ipaddress.IPv6Address(record[27])))
984 # destinationIPv6Address
985 self.assertEqual(socket.inet_pton(socket.AF_INET6,
986 self.compose_ip6(dst_addr,
990 # postNATSourceIPv4Address
991 self.assertEqual(self.nat_addr_n, record[225])
992 # postNATDestinationIPv4Address
993 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
996 self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
998 self.assertEqual(struct.pack("!I", 0), record[234])
999 # sourceTransportPort
1000 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1001 # postNAPTSourceTransportPort
1002 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1003 # destinationTransportPort
1004 self.assertEqual(struct.pack("!H", dst_port), record[11])
1005 # postNAPTDestinationTransportPort
1006 self.assertEqual(struct.pack("!H", dst_port), record[228])
1008 def verify_no_nat44_user(self):
1009 """ Verify that there is no NAT44 user """
1010 users = self.vapi.nat44_user_dump()
1011 self.assertEqual(len(users), 0)
1012 users = self.statistics.get_counter('/nat44/total-users')
1013 self.assertEqual(users[0][0], 0)
1014 sessions = self.statistics.get_counter('/nat44/total-sessions')
1015 self.assertEqual(sessions[0][0], 0)
1017 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1019 Verify IPFIX maximum entries per user exceeded event
1021 :param data: Decoded IPFIX data records
1022 :param limit: Number of maximum entries per user
1023 :param src_addr: IPv4 source address
1025 self.assertEqual(1, len(data))
1028 self.assertEqual(scapy.compat.orb(record[230]), 13)
1029 # natQuotaExceededEvent
1030 self.assertEqual(struct.pack("I", 3), record[466])
1032 self.assertEqual(struct.pack("I", limit), record[473])
1034 self.assertEqual(socket.inet_pton(socket.AF_INET, src_addr), record[8])
1036 def verify_syslog_apmap(self, data, is_add=True):
1037 message = data.decode('utf-8')
1039 message = SyslogMessage.parse(message)
1040 except ParseError as e:
1041 self.logger.error(e)
1044 self.assertEqual(message.severity, SyslogSeverity.info)
1045 self.assertEqual(message.appname, 'NAT')
1046 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1047 sd_params = message.sd.get('napmap')
1048 self.assertTrue(sd_params is not None)
1049 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1050 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1051 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1052 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1053 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1054 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1055 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1056 self.assertTrue(sd_params.get('SSUBIX') is not None)
1057 self.assertEqual(sd_params.get('SVLAN'), '0')
1059 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1060 message = data.decode('utf-8')
1062 message = SyslogMessage.parse(message)
1063 except ParseError as e:
1064 self.logger.error(e)
1067 self.assertEqual(message.severity, SyslogSeverity.info)
1068 self.assertEqual(message.appname, 'NAT')
1069 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1070 sd_params = message.sd.get('nsess')
1071 self.assertTrue(sd_params is not None)
1073 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1074 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1076 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1078 self.assertTrue(sd_params.get('SSUBIX') is not None)
1079 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1080 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1081 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1082 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1083 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1084 self.assertEqual(sd_params.get('SVLAN'), '0')
1085 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1086 self.assertEqual(sd_params.get('XDPORT'),
1087 "%d" % self.tcp_external_port)
1089 def verify_mss_value(self, pkt, mss):
1091 Verify TCP MSS value
1096 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1097 raise TypeError("Not a TCP/IP packet")
1099 for option in pkt[TCP].options:
1100 if option[0] == 'MSS':
1101 self.assertEqual(option[1], mss)
1102 self.assert_tcp_checksum_valid(pkt)
1105 def proto2layer(proto):
1106 if proto == IP_PROTOS.tcp:
1108 elif proto == IP_PROTOS.udp:
1110 elif proto == IP_PROTOS.icmp:
1113 raise Exception("Unsupported protocol")
1115 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
1117 layer = self.proto2layer(proto)
1119 if proto == IP_PROTOS.tcp:
1120 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1122 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1123 self.port_in = random.randint(1025, 65535)
1126 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1127 self.port_in, 20, data, proto)
1128 self.pg0.add_stream(pkts)
1129 self.pg_enable_capture(self.pg_interfaces)
1131 frags = self.pg1.get_capture(len(pkts))
1132 if not dont_translate:
1133 p = self.reass_frags_and_verify(frags,
1135 self.pg1.remote_ip4)
1137 p = self.reass_frags_and_verify(frags,
1138 self.pg0.remote_ip4,
1139 self.pg1.remote_ip4)
1140 if proto != IP_PROTOS.icmp:
1141 if not dont_translate:
1142 self.assertEqual(p[layer].dport, 20)
1144 self.assertNotEqual(p[layer].sport, self.port_in)
1146 self.assertEqual(p[layer].sport, self.port_in)
1149 if not dont_translate:
1150 self.assertNotEqual(p[layer].id, self.port_in)
1152 self.assertEqual(p[layer].id, self.port_in)
1153 self.assertEqual(data, p[Raw].load)
1156 if not dont_translate:
1157 dst_addr = self.nat_addr
1159 dst_addr = self.pg0.remote_ip4
1160 if proto != IP_PROTOS.icmp:
1162 dport = p[layer].sport
1166 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport, data,
1167 proto, echo_reply=True)
1168 self.pg1.add_stream(pkts)
1169 self.pg_enable_capture(self.pg_interfaces)
1171 frags = self.pg0.get_capture(len(pkts))
1172 p = self.reass_frags_and_verify(frags,
1173 self.pg1.remote_ip4,
1174 self.pg0.remote_ip4)
1175 if proto != IP_PROTOS.icmp:
1176 self.assertEqual(p[layer].sport, 20)
1177 self.assertEqual(p[layer].dport, self.port_in)
1179 self.assertEqual(p[layer].id, self.port_in)
1180 self.assertEqual(data, p[Raw].load)
1182 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1183 layer = self.proto2layer(proto)
1185 if proto == IP_PROTOS.tcp:
1186 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1188 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1189 self.port_in = random.randint(1025, 65535)
1193 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1194 self.port_in, self.server_out_port,
1196 self.pg0.add_stream(pkts)
1197 self.pg_enable_capture(self.pg_interfaces)
1199 frags = self.pg1.get_capture(len(pkts))
1200 p = self.reass_frags_and_verify(frags,
1201 self.pg0.remote_ip4,
1202 self.server_in_addr)
1203 if proto != IP_PROTOS.icmp:
1204 self.assertEqual(p[layer].sport, self.port_in)
1205 self.assertEqual(p[layer].dport, self.server_in_port)
1207 self.assertEqual(p[layer].id, self.port_in)
1208 self.assertEqual(data, p[Raw].load)
1211 if proto != IP_PROTOS.icmp:
1212 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1213 self.server_in_port,
1214 p[layer].sport, data, proto)
1216 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1217 p[layer].id, 0, data, proto,
1219 self.pg1.add_stream(pkts)
1220 self.pg_enable_capture(self.pg_interfaces)
1222 frags = self.pg0.get_capture(len(pkts))
1223 p = self.reass_frags_and_verify(frags,
1224 self.server_out_addr,
1225 self.pg0.remote_ip4)
1226 if proto != IP_PROTOS.icmp:
1227 self.assertEqual(p[layer].sport, self.server_out_port)
1228 self.assertEqual(p[layer].dport, self.port_in)
1230 self.assertEqual(p[layer].id, self.port_in)
1231 self.assertEqual(data, p[Raw].load)
1233 def reass_hairpinning(self, proto=IP_PROTOS.tcp, ignore_port=False):
1234 layer = self.proto2layer(proto)
1236 if proto == IP_PROTOS.tcp:
1237 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1239 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1241 # send packet from host to server
1242 pkts = self.create_stream_frag(self.pg0,
1245 self.server_out_port,
1248 self.pg0.add_stream(pkts)
1249 self.pg_enable_capture(self.pg_interfaces)
1251 frags = self.pg0.get_capture(len(pkts))
1252 p = self.reass_frags_and_verify(frags,
1255 if proto != IP_PROTOS.icmp:
1257 self.assertNotEqual(p[layer].sport, self.host_in_port)
1258 self.assertEqual(p[layer].dport, self.server_in_port)
1261 self.assertNotEqual(p[layer].id, self.host_in_port)
1262 self.assertEqual(data, p[Raw].load)
1264 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False,
1266 layer = self.proto2layer(proto)
1268 if proto == IP_PROTOS.tcp:
1269 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1271 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1272 self.port_in = random.randint(1025, 65535)
1276 pkts = self.create_stream_frag(self.pg0, self.pg1.remote_ip4,
1277 self.port_in, 20, data, proto)
1279 self.pg0.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1282 frags = self.pg1.get_capture(len(pkts))
1283 if not dont_translate:
1284 p = self.reass_frags_and_verify(frags,
1286 self.pg1.remote_ip4)
1288 p = self.reass_frags_and_verify(frags,
1289 self.pg0.remote_ip4,
1290 self.pg1.remote_ip4)
1291 if proto != IP_PROTOS.icmp:
1292 if not dont_translate:
1293 self.assertEqual(p[layer].dport, 20)
1295 self.assertNotEqual(p[layer].sport, self.port_in)
1297 self.assertEqual(p[layer].sport, self.port_in)
1300 if not dont_translate:
1301 self.assertNotEqual(p[layer].id, self.port_in)
1303 self.assertEqual(p[layer].id, self.port_in)
1304 self.assertEqual(data, p[Raw].load)
1307 if not dont_translate:
1308 dst_addr = self.nat_addr
1310 dst_addr = self.pg0.remote_ip4
1311 if proto != IP_PROTOS.icmp:
1313 dport = p[layer].sport
1317 pkts = self.create_stream_frag(self.pg1, dst_addr, sport, dport,
1318 data, proto, echo_reply=True)
1320 self.pg1.add_stream(pkts)
1321 self.pg_enable_capture(self.pg_interfaces)
1323 frags = self.pg0.get_capture(len(pkts))
1324 p = self.reass_frags_and_verify(frags,
1325 self.pg1.remote_ip4,
1326 self.pg0.remote_ip4)
1327 if proto != IP_PROTOS.icmp:
1328 self.assertEqual(p[layer].sport, 20)
1329 self.assertEqual(p[layer].dport, self.port_in)
1331 self.assertEqual(p[layer].id, self.port_in)
1332 self.assertEqual(data, p[Raw].load)
1334 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1335 layer = self.proto2layer(proto)
1337 if proto == IP_PROTOS.tcp:
1338 data = b"A" * 4 + b"B" * 16 + b"C" * 3
1340 data = b"A" * 16 + b"B" * 16 + b"C" * 3
1341 self.port_in = random.randint(1025, 65535)
1345 pkts = self.create_stream_frag(self.pg0, self.server_out_addr,
1346 self.port_in, self.server_out_port,
1349 self.pg0.add_stream(pkts)
1350 self.pg_enable_capture(self.pg_interfaces)
1352 frags = self.pg1.get_capture(len(pkts))
1353 p = self.reass_frags_and_verify(frags,
1354 self.pg0.remote_ip4,
1355 self.server_in_addr)
1356 if proto != IP_PROTOS.icmp:
1357 self.assertEqual(p[layer].dport, self.server_in_port)
1358 self.assertEqual(p[layer].sport, self.port_in)
1359 self.assertEqual(p[layer].dport, self.server_in_port)
1361 self.assertEqual(p[layer].id, self.port_in)
1362 self.assertEqual(data, p[Raw].load)
1365 if proto != IP_PROTOS.icmp:
1366 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1367 self.server_in_port,
1368 p[layer].sport, data, proto)
1370 pkts = self.create_stream_frag(self.pg1, self.pg0.remote_ip4,
1371 p[layer].id, 0, data, proto,
1374 self.pg1.add_stream(pkts)
1375 self.pg_enable_capture(self.pg_interfaces)
1377 frags = self.pg0.get_capture(len(pkts))
1378 p = self.reass_frags_and_verify(frags,
1379 self.server_out_addr,
1380 self.pg0.remote_ip4)
1381 if proto != IP_PROTOS.icmp:
1382 self.assertEqual(p[layer].sport, self.server_out_port)
1383 self.assertEqual(p[layer].dport, self.port_in)
1385 self.assertEqual(p[layer].id, self.port_in)
1386 self.assertEqual(data, p[Raw].load)
1389 class TestNAT44(MethodHolder):
1390 """ NAT44 Test Cases """
1393 def setUpClass(cls):
1394 super(TestNAT44, cls).setUpClass()
1395 cls.vapi.cli("set log class nat level debug")
1397 cls.tcp_port_in = 6303
1398 cls.tcp_port_out = 6303
1399 cls.udp_port_in = 6304
1400 cls.udp_port_out = 6304
1401 cls.icmp_id_in = 6305
1402 cls.icmp_id_out = 6305
1403 cls.nat_addr = '10.0.0.3'
1404 cls.ipfix_src_port = 4739
1405 cls.ipfix_domain_id = 1
1406 cls.tcp_external_port = 80
1407 cls.udp_external_port = 69
1409 cls.create_pg_interfaces(range(10))
1410 cls.interfaces = list(cls.pg_interfaces[0:4])
1412 for i in cls.interfaces:
1417 cls.pg0.generate_remote_hosts(3)
1418 cls.pg0.configure_ipv4_neighbors()
1420 cls.pg1.generate_remote_hosts(1)
1421 cls.pg1.configure_ipv4_neighbors()
1423 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1424 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1425 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1427 cls.pg4._local_ip4 = "172.16.255.1"
1428 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1429 cls.pg4.set_table_ip4(10)
1430 cls.pg5._local_ip4 = "172.17.255.3"
1431 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1432 cls.pg5.set_table_ip4(10)
1433 cls.pg6._local_ip4 = "172.16.255.1"
1434 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1435 cls.pg6.set_table_ip4(20)
1436 for i in cls.overlapping_interfaces:
1444 cls.pg9.generate_remote_hosts(2)
1445 cls.pg9.config_ip4()
1446 cls.vapi.sw_interface_add_del_address(
1447 sw_if_index=cls.pg9.sw_if_index,
1448 prefix="10.0.0.1/24")
1451 cls.pg9.resolve_arp()
1452 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1453 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1454 cls.pg9.resolve_arp()
1457 def tearDownClass(cls):
1458 super(TestNAT44, cls).tearDownClass()
1460 def test_clear_sessions(self):
1461 """ NAT44 session clearing test """
1463 self.nat44_add_address(self.nat_addr)
1464 flags = self.config_flags.NAT_IS_INSIDE
1465 self.vapi.nat44_interface_add_del_feature(
1466 sw_if_index=self.pg0.sw_if_index,
1467 flags=flags, is_add=1)
1468 self.vapi.nat44_interface_add_del_feature(
1469 sw_if_index=self.pg1.sw_if_index,
1472 nat_config = self.vapi.nat_show_config()
1473 self.assertEqual(0, nat_config.endpoint_dependent)
1475 pkts = self.create_stream_in(self.pg0, self.pg1)
1476 self.pg0.add_stream(pkts)
1477 self.pg_enable_capture(self.pg_interfaces)
1479 capture = self.pg1.get_capture(len(pkts))
1480 self.verify_capture_out(capture)
1482 sessions = self.statistics.get_counter('/nat44/total-sessions')
1483 self.assertTrue(sessions[0][0] > 0)
1484 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1486 self.vapi.cli("clear nat44 sessions")
1488 sessions = self.statistics.get_counter('/nat44/total-sessions')
1489 self.assertEqual(sessions[0][0], 0)
1490 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1492 def test_dynamic(self):
1493 """ NAT44 dynamic translation test """
1494 self.nat44_add_address(self.nat_addr)
1495 flags = self.config_flags.NAT_IS_INSIDE
1496 self.vapi.nat44_interface_add_del_feature(
1497 sw_if_index=self.pg0.sw_if_index,
1498 flags=flags, is_add=1)
1499 self.vapi.nat44_interface_add_del_feature(
1500 sw_if_index=self.pg1.sw_if_index,
1504 tcpn = self.statistics.get_err_counter(
1505 '/err/nat44-in2out-slowpath/TCP packets')
1506 udpn = self.statistics.get_err_counter(
1507 '/err/nat44-in2out-slowpath/UDP packets')
1508 icmpn = self.statistics.get_err_counter(
1509 '/err/nat44-in2out-slowpath/ICMP packets')
1510 totaln = self.statistics.get_err_counter(
1511 '/err/nat44-in2out-slowpath/good in2out packets processed')
1513 pkts = self.create_stream_in(self.pg0, self.pg1)
1514 self.pg0.add_stream(pkts)
1515 self.pg_enable_capture(self.pg_interfaces)
1517 capture = self.pg1.get_capture(len(pkts))
1518 self.verify_capture_out(capture)
1520 err = self.statistics.get_err_counter(
1521 '/err/nat44-in2out-slowpath/TCP packets')
1522 self.assertEqual(err - tcpn, 2)
1523 err = self.statistics.get_err_counter(
1524 '/err/nat44-in2out-slowpath/UDP packets')
1525 self.assertEqual(err - udpn, 1)
1526 err = self.statistics.get_err_counter(
1527 '/err/nat44-in2out-slowpath/ICMP packets')
1528 self.assertEqual(err - icmpn, 1)
1529 err = self.statistics.get_err_counter(
1530 '/err/nat44-in2out-slowpath/good in2out packets processed')
1531 self.assertEqual(err - totaln, 4)
1534 tcpn = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1535 udpn = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1536 icmpn = self.statistics.get_err_counter(
1537 '/err/nat44-out2in/ICMP packets')
1538 totaln = self.statistics.get_err_counter(
1539 '/err/nat44-out2in/good out2in packets processed')
1541 pkts = self.create_stream_out(self.pg1)
1542 self.pg1.add_stream(pkts)
1543 self.pg_enable_capture(self.pg_interfaces)
1545 capture = self.pg0.get_capture(len(pkts))
1546 self.verify_capture_in(capture, self.pg0)
1548 err = self.statistics.get_err_counter('/err/nat44-out2in/TCP packets')
1549 self.assertEqual(err - tcpn, 2)
1550 err = self.statistics.get_err_counter('/err/nat44-out2in/UDP packets')
1551 self.assertEqual(err - udpn, 1)
1552 err = self.statistics.get_err_counter('/err/nat44-out2in/ICMP packets')
1553 self.assertEqual(err - icmpn, 1)
1554 err = self.statistics.get_err_counter(
1555 '/err/nat44-out2in/good out2in packets processed')
1556 self.assertEqual(err - totaln, 4)
1558 users = self.statistics.get_counter('/nat44/total-users')
1559 self.assertEqual(users[0][0], 1)
1560 sessions = self.statistics.get_counter('/nat44/total-sessions')
1561 self.assertEqual(sessions[0][0], 3)
1563 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1564 """ NAT44 handling of client packets with TTL=1 """
1566 self.nat44_add_address(self.nat_addr)
1567 flags = self.config_flags.NAT_IS_INSIDE
1568 self.vapi.nat44_interface_add_del_feature(
1569 sw_if_index=self.pg0.sw_if_index,
1570 flags=flags, is_add=1)
1571 self.vapi.nat44_interface_add_del_feature(
1572 sw_if_index=self.pg1.sw_if_index,
1575 # Client side - generate traffic
1576 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1577 self.pg0.add_stream(pkts)
1578 self.pg_enable_capture(self.pg_interfaces)
1581 # Client side - verify ICMP type 11 packets
1582 capture = self.pg0.get_capture(len(pkts))
1583 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1585 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1586 """ NAT44 handling of server packets with TTL=1 """
1588 self.nat44_add_address(self.nat_addr)
1589 flags = self.config_flags.NAT_IS_INSIDE
1590 self.vapi.nat44_interface_add_del_feature(
1591 sw_if_index=self.pg0.sw_if_index,
1592 flags=flags, is_add=1)
1593 self.vapi.nat44_interface_add_del_feature(
1594 sw_if_index=self.pg1.sw_if_index,
1597 # Client side - create sessions
1598 pkts = self.create_stream_in(self.pg0, self.pg1)
1599 self.pg0.add_stream(pkts)
1600 self.pg_enable_capture(self.pg_interfaces)
1603 # Server side - generate traffic
1604 capture = self.pg1.get_capture(len(pkts))
1605 self.verify_capture_out(capture)
1606 pkts = self.create_stream_out(self.pg1, ttl=1)
1607 self.pg1.add_stream(pkts)
1608 self.pg_enable_capture(self.pg_interfaces)
1611 # Server side - verify ICMP type 11 packets
1612 capture = self.pg1.get_capture(len(pkts))
1613 self.verify_capture_out_with_icmp_errors(capture,
1614 src_ip=self.pg1.local_ip4)
1616 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1617 """ NAT44 handling of error responses to client packets with TTL=2 """
1619 self.nat44_add_address(self.nat_addr)
1620 flags = self.config_flags.NAT_IS_INSIDE
1621 self.vapi.nat44_interface_add_del_feature(
1622 sw_if_index=self.pg0.sw_if_index,
1623 flags=flags, is_add=1)
1624 self.vapi.nat44_interface_add_del_feature(
1625 sw_if_index=self.pg1.sw_if_index,
1628 # Client side - generate traffic
1629 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1630 self.pg0.add_stream(pkts)
1631 self.pg_enable_capture(self.pg_interfaces)
1634 # Server side - simulate ICMP type 11 response
1635 capture = self.pg1.get_capture(len(pkts))
1636 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1637 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1638 ICMP(type=11) / packet[IP] for packet in capture]
1639 self.pg1.add_stream(pkts)
1640 self.pg_enable_capture(self.pg_interfaces)
1643 # Client side - verify ICMP type 11 packets
1644 capture = self.pg0.get_capture(len(pkts))
1645 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1647 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1648 """ NAT44 handling of error responses to server packets with TTL=2 """
1650 self.nat44_add_address(self.nat_addr)
1651 flags = self.config_flags.NAT_IS_INSIDE
1652 self.vapi.nat44_interface_add_del_feature(
1653 sw_if_index=self.pg0.sw_if_index,
1654 flags=flags, is_add=1)
1655 self.vapi.nat44_interface_add_del_feature(
1656 sw_if_index=self.pg1.sw_if_index,
1659 # Client side - create sessions
1660 pkts = self.create_stream_in(self.pg0, self.pg1)
1661 self.pg0.add_stream(pkts)
1662 self.pg_enable_capture(self.pg_interfaces)
1665 # Server side - generate traffic
1666 capture = self.pg1.get_capture(len(pkts))
1667 self.verify_capture_out(capture)
1668 pkts = self.create_stream_out(self.pg1, ttl=2)
1669 self.pg1.add_stream(pkts)
1670 self.pg_enable_capture(self.pg_interfaces)
1673 # Client side - simulate ICMP type 11 response
1674 capture = self.pg0.get_capture(len(pkts))
1675 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1676 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1677 ICMP(type=11) / packet[IP] for packet in capture]
1678 self.pg0.add_stream(pkts)
1679 self.pg_enable_capture(self.pg_interfaces)
1682 # Server side - verify ICMP type 11 packets
1683 capture = self.pg1.get_capture(len(pkts))
1684 self.verify_capture_out_with_icmp_errors(capture)
1686 def test_ping_out_interface_from_outside(self):
1687 """ Ping NAT44 out interface from outside network """
1689 self.nat44_add_address(self.nat_addr)
1690 flags = self.config_flags.NAT_IS_INSIDE
1691 self.vapi.nat44_interface_add_del_feature(
1692 sw_if_index=self.pg0.sw_if_index,
1693 flags=flags, is_add=1)
1694 self.vapi.nat44_interface_add_del_feature(
1695 sw_if_index=self.pg1.sw_if_index,
1698 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1699 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1700 ICMP(id=self.icmp_id_out, type='echo-request'))
1702 self.pg1.add_stream(pkts)
1703 self.pg_enable_capture(self.pg_interfaces)
1705 capture = self.pg1.get_capture(len(pkts))
1708 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1709 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1710 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1711 self.assertEqual(packet[ICMP].type, 0) # echo reply
1713 self.logger.error(ppp("Unexpected or invalid packet "
1714 "(outside network):", packet))
1717 def test_ping_internal_host_from_outside(self):
1718 """ Ping internal host from outside network """
1720 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1721 flags = self.config_flags.NAT_IS_INSIDE
1722 self.vapi.nat44_interface_add_del_feature(
1723 sw_if_index=self.pg0.sw_if_index,
1724 flags=flags, is_add=1)
1725 self.vapi.nat44_interface_add_del_feature(
1726 sw_if_index=self.pg1.sw_if_index,
1730 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1731 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1732 ICMP(id=self.icmp_id_out, type='echo-request'))
1733 self.pg1.add_stream(pkt)
1734 self.pg_enable_capture(self.pg_interfaces)
1736 capture = self.pg0.get_capture(1)
1737 self.verify_capture_in(capture, self.pg0)
1738 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1741 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1742 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1743 ICMP(id=self.icmp_id_in, type='echo-reply'))
1744 self.pg0.add_stream(pkt)
1745 self.pg_enable_capture(self.pg_interfaces)
1747 capture = self.pg1.get_capture(1)
1748 self.verify_capture_out(capture, same_port=True)
1749 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1751 def test_forwarding(self):
1752 """ NAT44 forwarding test """
1754 flags = self.config_flags.NAT_IS_INSIDE
1755 self.vapi.nat44_interface_add_del_feature(
1756 sw_if_index=self.pg0.sw_if_index,
1757 flags=flags, is_add=1)
1758 self.vapi.nat44_interface_add_del_feature(
1759 sw_if_index=self.pg1.sw_if_index,
1761 self.vapi.nat44_forwarding_enable_disable(enable=1)
1763 real_ip = self.pg0.remote_ip4
1764 alias_ip = self.nat_addr
1765 flags = self.config_flags.NAT_IS_ADDR_ONLY
1766 self.vapi.nat44_add_del_static_mapping(is_add=1,
1767 local_ip_address=real_ip,
1768 external_ip_address=alias_ip,
1769 external_sw_if_index=0xFFFFFFFF,
1773 # static mapping match
1775 pkts = self.create_stream_out(self.pg1)
1776 self.pg1.add_stream(pkts)
1777 self.pg_enable_capture(self.pg_interfaces)
1779 capture = self.pg0.get_capture(len(pkts))
1780 self.verify_capture_in(capture, self.pg0)
1782 pkts = self.create_stream_in(self.pg0, self.pg1)
1783 self.pg0.add_stream(pkts)
1784 self.pg_enable_capture(self.pg_interfaces)
1786 capture = self.pg1.get_capture(len(pkts))
1787 self.verify_capture_out(capture, same_port=True)
1789 # no static mapping match
1791 host0 = self.pg0.remote_hosts[0]
1792 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1794 pkts = self.create_stream_out(self.pg1,
1795 dst_ip=self.pg0.remote_ip4,
1796 use_inside_ports=True)
1797 self.pg1.add_stream(pkts)
1798 self.pg_enable_capture(self.pg_interfaces)
1800 capture = self.pg0.get_capture(len(pkts))
1801 self.verify_capture_in(capture, self.pg0)
1803 pkts = self.create_stream_in(self.pg0, self.pg1)
1804 self.pg0.add_stream(pkts)
1805 self.pg_enable_capture(self.pg_interfaces)
1807 capture = self.pg1.get_capture(len(pkts))
1808 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1811 self.pg0.remote_hosts[0] = host0
1814 self.vapi.nat44_forwarding_enable_disable(enable=0)
1815 flags = self.config_flags.NAT_IS_ADDR_ONLY
1816 self.vapi.nat44_add_del_static_mapping(
1818 local_ip_address=real_ip,
1819 external_ip_address=alias_ip,
1820 external_sw_if_index=0xFFFFFFFF,
1823 def test_static_in(self):
1824 """ 1:1 NAT initialized from inside network """
1826 nat_ip = "10.0.0.10"
1827 self.tcp_port_out = 6303
1828 self.udp_port_out = 6304
1829 self.icmp_id_out = 6305
1831 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1832 flags = self.config_flags.NAT_IS_INSIDE
1833 self.vapi.nat44_interface_add_del_feature(
1834 sw_if_index=self.pg0.sw_if_index,
1835 flags=flags, is_add=1)
1836 self.vapi.nat44_interface_add_del_feature(
1837 sw_if_index=self.pg1.sw_if_index,
1839 sm = self.vapi.nat44_static_mapping_dump()
1840 self.assertEqual(len(sm), 1)
1841 self.assertEqual(sm[0].tag, '')
1842 self.assertEqual(sm[0].protocol, 0)
1843 self.assertEqual(sm[0].local_port, 0)
1844 self.assertEqual(sm[0].external_port, 0)
1847 pkts = self.create_stream_in(self.pg0, self.pg1)
1848 self.pg0.add_stream(pkts)
1849 self.pg_enable_capture(self.pg_interfaces)
1851 capture = self.pg1.get_capture(len(pkts))
1852 self.verify_capture_out(capture, nat_ip, True)
1855 pkts = self.create_stream_out(self.pg1, nat_ip)
1856 self.pg1.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1859 capture = self.pg0.get_capture(len(pkts))
1860 self.verify_capture_in(capture, self.pg0)
1862 def test_static_out(self):
1863 """ 1:1 NAT initialized from outside network """
1865 nat_ip = "10.0.0.20"
1866 self.tcp_port_out = 6303
1867 self.udp_port_out = 6304
1868 self.icmp_id_out = 6305
1871 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1872 flags = self.config_flags.NAT_IS_INSIDE
1873 self.vapi.nat44_interface_add_del_feature(
1874 sw_if_index=self.pg0.sw_if_index,
1875 flags=flags, is_add=1)
1876 self.vapi.nat44_interface_add_del_feature(
1877 sw_if_index=self.pg1.sw_if_index,
1879 sm = self.vapi.nat44_static_mapping_dump()
1880 self.assertEqual(len(sm), 1)
1881 self.assertEqual(sm[0].tag, tag)
1884 pkts = self.create_stream_out(self.pg1, nat_ip)
1885 self.pg1.add_stream(pkts)
1886 self.pg_enable_capture(self.pg_interfaces)
1888 capture = self.pg0.get_capture(len(pkts))
1889 self.verify_capture_in(capture, self.pg0)
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1896 capture = self.pg1.get_capture(len(pkts))
1897 self.verify_capture_out(capture, nat_ip, True)
1899 def test_static_with_port_in(self):
1900 """ 1:1 NAPT initialized from inside network """
1902 self.tcp_port_out = 3606
1903 self.udp_port_out = 3607
1904 self.icmp_id_out = 3608
1906 self.nat44_add_address(self.nat_addr)
1907 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1908 self.tcp_port_in, self.tcp_port_out,
1909 proto=IP_PROTOS.tcp)
1910 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1911 self.udp_port_in, self.udp_port_out,
1912 proto=IP_PROTOS.udp)
1913 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1914 self.icmp_id_in, self.icmp_id_out,
1915 proto=IP_PROTOS.icmp)
1916 flags = self.config_flags.NAT_IS_INSIDE
1917 self.vapi.nat44_interface_add_del_feature(
1918 sw_if_index=self.pg0.sw_if_index,
1919 flags=flags, is_add=1)
1920 self.vapi.nat44_interface_add_del_feature(
1921 sw_if_index=self.pg1.sw_if_index,
1925 pkts = self.create_stream_in(self.pg0, self.pg1)
1926 self.pg0.add_stream(pkts)
1927 self.pg_enable_capture(self.pg_interfaces)
1929 capture = self.pg1.get_capture(len(pkts))
1930 self.verify_capture_out(capture)
1933 pkts = self.create_stream_out(self.pg1)
1934 self.pg1.add_stream(pkts)
1935 self.pg_enable_capture(self.pg_interfaces)
1937 capture = self.pg0.get_capture(len(pkts))
1938 self.verify_capture_in(capture, self.pg0)
1940 def test_static_with_port_out(self):
1941 """ 1:1 NAPT initialized from outside network """
1943 self.tcp_port_out = 30606
1944 self.udp_port_out = 30607
1945 self.icmp_id_out = 30608
1947 self.nat44_add_address(self.nat_addr)
1948 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1949 self.tcp_port_in, self.tcp_port_out,
1950 proto=IP_PROTOS.tcp)
1951 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1952 self.udp_port_in, self.udp_port_out,
1953 proto=IP_PROTOS.udp)
1954 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1955 self.icmp_id_in, self.icmp_id_out,
1956 proto=IP_PROTOS.icmp)
1957 flags = self.config_flags.NAT_IS_INSIDE
1958 self.vapi.nat44_interface_add_del_feature(
1959 sw_if_index=self.pg0.sw_if_index,
1960 flags=flags, is_add=1)
1961 self.vapi.nat44_interface_add_del_feature(
1962 sw_if_index=self.pg1.sw_if_index,
1966 pkts = self.create_stream_out(self.pg1)
1967 self.pg1.add_stream(pkts)
1968 self.pg_enable_capture(self.pg_interfaces)
1970 capture = self.pg0.get_capture(len(pkts))
1971 self.verify_capture_in(capture, self.pg0)
1974 pkts = self.create_stream_in(self.pg0, self.pg1)
1975 self.pg0.add_stream(pkts)
1976 self.pg_enable_capture(self.pg_interfaces)
1978 capture = self.pg1.get_capture(len(pkts))
1979 self.verify_capture_out(capture)
1981 def test_static_vrf_aware(self):
1982 """ 1:1 NAT VRF awareness """
1984 nat_ip1 = "10.0.0.30"
1985 nat_ip2 = "10.0.0.40"
1986 self.tcp_port_out = 6303
1987 self.udp_port_out = 6304
1988 self.icmp_id_out = 6305
1990 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1992 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1994 flags = self.config_flags.NAT_IS_INSIDE
1995 self.vapi.nat44_interface_add_del_feature(
1996 sw_if_index=self.pg3.sw_if_index,
1998 self.vapi.nat44_interface_add_del_feature(
1999 sw_if_index=self.pg0.sw_if_index,
2000 flags=flags, is_add=1)
2001 self.vapi.nat44_interface_add_del_feature(
2002 sw_if_index=self.pg4.sw_if_index,
2003 flags=flags, is_add=1)
2005 # inside interface VRF match NAT44 static mapping VRF
2006 pkts = self.create_stream_in(self.pg4, self.pg3)
2007 self.pg4.add_stream(pkts)
2008 self.pg_enable_capture(self.pg_interfaces)
2010 capture = self.pg3.get_capture(len(pkts))
2011 self.verify_capture_out(capture, nat_ip1, True)
2013 # inside interface VRF don't match NAT44 static mapping VRF (packets
2015 pkts = self.create_stream_in(self.pg0, self.pg3)
2016 self.pg0.add_stream(pkts)
2017 self.pg_enable_capture(self.pg_interfaces)
2019 self.pg3.assert_nothing_captured()
2021 def test_dynamic_to_static(self):
2022 """ Switch from dynamic translation to 1:1NAT """
2023 nat_ip = "10.0.0.10"
2024 self.tcp_port_out = 6303
2025 self.udp_port_out = 6304
2026 self.icmp_id_out = 6305
2028 self.nat44_add_address(self.nat_addr)
2029 flags = self.config_flags.NAT_IS_INSIDE
2030 self.vapi.nat44_interface_add_del_feature(
2031 sw_if_index=self.pg0.sw_if_index,
2032 flags=flags, is_add=1)
2033 self.vapi.nat44_interface_add_del_feature(
2034 sw_if_index=self.pg1.sw_if_index,
2038 pkts = self.create_stream_in(self.pg0, self.pg1)
2039 self.pg0.add_stream(pkts)
2040 self.pg_enable_capture(self.pg_interfaces)
2042 capture = self.pg1.get_capture(len(pkts))
2043 self.verify_capture_out(capture)
2046 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2047 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2048 self.assertEqual(len(sessions), 0)
2049 pkts = self.create_stream_in(self.pg0, self.pg1)
2050 self.pg0.add_stream(pkts)
2051 self.pg_enable_capture(self.pg_interfaces)
2053 capture = self.pg1.get_capture(len(pkts))
2054 self.verify_capture_out(capture, nat_ip, True)
2056 def test_identity_nat(self):
2057 """ Identity NAT """
2058 flags = self.config_flags.NAT_IS_ADDR_ONLY
2059 self.vapi.nat44_add_del_identity_mapping(
2060 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2061 flags=flags, is_add=1)
2062 flags = self.config_flags.NAT_IS_INSIDE
2063 self.vapi.nat44_interface_add_del_feature(
2064 sw_if_index=self.pg0.sw_if_index,
2065 flags=flags, is_add=1)
2066 self.vapi.nat44_interface_add_del_feature(
2067 sw_if_index=self.pg1.sw_if_index,
2070 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2071 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2072 TCP(sport=12345, dport=56789))
2073 self.pg1.add_stream(p)
2074 self.pg_enable_capture(self.pg_interfaces)
2076 capture = self.pg0.get_capture(1)
2081 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2082 self.assertEqual(ip.src, self.pg1.remote_ip4)
2083 self.assertEqual(tcp.dport, 56789)
2084 self.assertEqual(tcp.sport, 12345)
2085 self.assert_packet_checksums_valid(p)
2087 self.logger.error(ppp("Unexpected or invalid packet:", p))
2090 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2091 self.assertEqual(len(sessions), 0)
2092 flags = self.config_flags.NAT_IS_ADDR_ONLY
2093 self.vapi.nat44_add_del_identity_mapping(
2094 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2095 flags=flags, vrf_id=1, is_add=1)
2096 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2097 self.assertEqual(len(identity_mappings), 2)
2099 def test_multiple_inside_interfaces(self):
2100 """ NAT44 multiple non-overlapping address space inside interfaces """
2102 self.nat44_add_address(self.nat_addr)
2103 flags = self.config_flags.NAT_IS_INSIDE
2104 self.vapi.nat44_interface_add_del_feature(
2105 sw_if_index=self.pg0.sw_if_index,
2106 flags=flags, is_add=1)
2107 self.vapi.nat44_interface_add_del_feature(
2108 sw_if_index=self.pg1.sw_if_index,
2109 flags=flags, is_add=1)
2110 self.vapi.nat44_interface_add_del_feature(
2111 sw_if_index=self.pg3.sw_if_index,
2114 # between two NAT44 inside interfaces (no translation)
2115 pkts = self.create_stream_in(self.pg0, self.pg1)
2116 self.pg0.add_stream(pkts)
2117 self.pg_enable_capture(self.pg_interfaces)
2119 capture = self.pg1.get_capture(len(pkts))
2120 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2122 # from NAT44 inside to interface without NAT44 feature (no translation)
2123 pkts = self.create_stream_in(self.pg0, self.pg2)
2124 self.pg0.add_stream(pkts)
2125 self.pg_enable_capture(self.pg_interfaces)
2127 capture = self.pg2.get_capture(len(pkts))
2128 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2130 # in2out 1st interface
2131 pkts = self.create_stream_in(self.pg0, self.pg3)
2132 self.pg0.add_stream(pkts)
2133 self.pg_enable_capture(self.pg_interfaces)
2135 capture = self.pg3.get_capture(len(pkts))
2136 self.verify_capture_out(capture)
2138 # out2in 1st interface
2139 pkts = self.create_stream_out(self.pg3)
2140 self.pg3.add_stream(pkts)
2141 self.pg_enable_capture(self.pg_interfaces)
2143 capture = self.pg0.get_capture(len(pkts))
2144 self.verify_capture_in(capture, self.pg0)
2146 # in2out 2nd interface
2147 pkts = self.create_stream_in(self.pg1, self.pg3)
2148 self.pg1.add_stream(pkts)
2149 self.pg_enable_capture(self.pg_interfaces)
2151 capture = self.pg3.get_capture(len(pkts))
2152 self.verify_capture_out(capture)
2154 # out2in 2nd interface
2155 pkts = self.create_stream_out(self.pg3)
2156 self.pg3.add_stream(pkts)
2157 self.pg_enable_capture(self.pg_interfaces)
2159 capture = self.pg1.get_capture(len(pkts))
2160 self.verify_capture_in(capture, self.pg1)
2162 def test_inside_overlapping_interfaces(self):
2163 """ NAT44 multiple inside interfaces with overlapping address space """
2165 static_nat_ip = "10.0.0.10"
2166 self.nat44_add_address(self.nat_addr)
2167 flags = self.config_flags.NAT_IS_INSIDE
2168 self.vapi.nat44_interface_add_del_feature(
2169 sw_if_index=self.pg3.sw_if_index,
2171 self.vapi.nat44_interface_add_del_feature(
2172 sw_if_index=self.pg4.sw_if_index,
2173 flags=flags, is_add=1)
2174 self.vapi.nat44_interface_add_del_feature(
2175 sw_if_index=self.pg5.sw_if_index,
2176 flags=flags, is_add=1)
2177 self.vapi.nat44_interface_add_del_feature(
2178 sw_if_index=self.pg6.sw_if_index,
2179 flags=flags, is_add=1)
2180 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2183 # between NAT44 inside interfaces with same VRF (no translation)
2184 pkts = self.create_stream_in(self.pg4, self.pg5)
2185 self.pg4.add_stream(pkts)
2186 self.pg_enable_capture(self.pg_interfaces)
2188 capture = self.pg5.get_capture(len(pkts))
2189 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2191 # between NAT44 inside interfaces with different VRF (hairpinning)
2192 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2193 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2194 TCP(sport=1234, dport=5678))
2195 self.pg4.add_stream(p)
2196 self.pg_enable_capture(self.pg_interfaces)
2198 capture = self.pg6.get_capture(1)
2203 self.assertEqual(ip.src, self.nat_addr)
2204 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2205 self.assertNotEqual(tcp.sport, 1234)
2206 self.assertEqual(tcp.dport, 5678)
2208 self.logger.error(ppp("Unexpected or invalid packet:", p))
2211 # in2out 1st interface
2212 pkts = self.create_stream_in(self.pg4, self.pg3)
2213 self.pg4.add_stream(pkts)
2214 self.pg_enable_capture(self.pg_interfaces)
2216 capture = self.pg3.get_capture(len(pkts))
2217 self.verify_capture_out(capture)
2219 # out2in 1st interface
2220 pkts = self.create_stream_out(self.pg3)
2221 self.pg3.add_stream(pkts)
2222 self.pg_enable_capture(self.pg_interfaces)
2224 capture = self.pg4.get_capture(len(pkts))
2225 self.verify_capture_in(capture, self.pg4)
2227 # in2out 2nd interface
2228 pkts = self.create_stream_in(self.pg5, self.pg3)
2229 self.pg5.add_stream(pkts)
2230 self.pg_enable_capture(self.pg_interfaces)
2232 capture = self.pg3.get_capture(len(pkts))
2233 self.verify_capture_out(capture)
2235 # out2in 2nd interface
2236 pkts = self.create_stream_out(self.pg3)
2237 self.pg3.add_stream(pkts)
2238 self.pg_enable_capture(self.pg_interfaces)
2240 capture = self.pg5.get_capture(len(pkts))
2241 self.verify_capture_in(capture, self.pg5)
2244 addresses = self.vapi.nat44_address_dump()
2245 self.assertEqual(len(addresses), 1)
2246 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2247 self.assertEqual(len(sessions), 3)
2248 for session in sessions:
2249 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2250 self.assertEqual(str(session.inside_ip_address),
2251 self.pg5.remote_ip4)
2252 self.assertEqual(session.outside_ip_address,
2253 addresses[0].ip_address)
2254 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2255 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2256 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2257 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2258 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2259 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2260 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2261 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2262 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2264 # in2out 3rd interface
2265 pkts = self.create_stream_in(self.pg6, self.pg3)
2266 self.pg6.add_stream(pkts)
2267 self.pg_enable_capture(self.pg_interfaces)
2269 capture = self.pg3.get_capture(len(pkts))
2270 self.verify_capture_out(capture, static_nat_ip, True)
2272 # out2in 3rd interface
2273 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2274 self.pg3.add_stream(pkts)
2275 self.pg_enable_capture(self.pg_interfaces)
2277 capture = self.pg6.get_capture(len(pkts))
2278 self.verify_capture_in(capture, self.pg6)
2280 # general user and session dump verifications
2281 users = self.vapi.nat44_user_dump()
2282 self.assertGreaterEqual(len(users), 3)
2283 addresses = self.vapi.nat44_address_dump()
2284 self.assertEqual(len(addresses), 1)
2286 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2288 for session in sessions:
2289 self.assertEqual(user.ip_address, session.inside_ip_address)
2290 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2291 self.assertTrue(session.protocol in
2292 [IP_PROTOS.tcp, IP_PROTOS.udp,
2294 self.assertFalse(session.flags &
2295 self.config_flags.NAT_IS_EXT_HOST_VALID)
2298 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2299 self.assertGreaterEqual(len(sessions), 4)
2300 for session in sessions:
2301 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2302 self.assertEqual(str(session.inside_ip_address),
2303 self.pg4.remote_ip4)
2304 self.assertEqual(session.outside_ip_address,
2305 addresses[0].ip_address)
2308 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2309 self.assertGreaterEqual(len(sessions), 3)
2310 for session in sessions:
2311 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2312 self.assertEqual(str(session.inside_ip_address),
2313 self.pg6.remote_ip4)
2314 self.assertEqual(str(session.outside_ip_address),
2316 self.assertTrue(session.inside_port in
2317 [self.tcp_port_in, self.udp_port_in,
2320 def test_hairpinning(self):
2321 """ NAT44 hairpinning - 1:1 NAPT """
2323 host = self.pg0.remote_hosts[0]
2324 server = self.pg0.remote_hosts[1]
2327 server_in_port = 5678
2328 server_out_port = 8765
2330 self.nat44_add_address(self.nat_addr)
2331 flags = self.config_flags.NAT_IS_INSIDE
2332 self.vapi.nat44_interface_add_del_feature(
2333 sw_if_index=self.pg0.sw_if_index,
2334 flags=flags, is_add=1)
2335 self.vapi.nat44_interface_add_del_feature(
2336 sw_if_index=self.pg1.sw_if_index,
2339 # add static mapping for server
2340 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2341 server_in_port, server_out_port,
2342 proto=IP_PROTOS.tcp)
2344 # send packet from host to server
2345 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2346 IP(src=host.ip4, dst=self.nat_addr) /
2347 TCP(sport=host_in_port, dport=server_out_port))
2348 self.pg0.add_stream(p)
2349 self.pg_enable_capture(self.pg_interfaces)
2351 capture = self.pg0.get_capture(1)
2356 self.assertEqual(ip.src, self.nat_addr)
2357 self.assertEqual(ip.dst, server.ip4)
2358 self.assertNotEqual(tcp.sport, host_in_port)
2359 self.assertEqual(tcp.dport, server_in_port)
2360 self.assert_packet_checksums_valid(p)
2361 host_out_port = tcp.sport
2363 self.logger.error(ppp("Unexpected or invalid packet:", p))
2366 # send reply from server to host
2367 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2368 IP(src=server.ip4, dst=self.nat_addr) /
2369 TCP(sport=server_in_port, dport=host_out_port))
2370 self.pg0.add_stream(p)
2371 self.pg_enable_capture(self.pg_interfaces)
2373 capture = self.pg0.get_capture(1)
2378 self.assertEqual(ip.src, self.nat_addr)
2379 self.assertEqual(ip.dst, host.ip4)
2380 self.assertEqual(tcp.sport, server_out_port)
2381 self.assertEqual(tcp.dport, host_in_port)
2382 self.assert_packet_checksums_valid(p)
2384 self.logger.error(ppp("Unexpected or invalid packet:", p))
2387 def test_hairpinning2(self):
2388 """ NAT44 hairpinning - 1:1 NAT"""
2390 server1_nat_ip = "10.0.0.10"
2391 server2_nat_ip = "10.0.0.11"
2392 host = self.pg0.remote_hosts[0]
2393 server1 = self.pg0.remote_hosts[1]
2394 server2 = self.pg0.remote_hosts[2]
2395 server_tcp_port = 22
2396 server_udp_port = 20
2398 self.nat44_add_address(self.nat_addr)
2399 flags = self.config_flags.NAT_IS_INSIDE
2400 self.vapi.nat44_interface_add_del_feature(
2401 sw_if_index=self.pg0.sw_if_index,
2402 flags=flags, is_add=1)
2403 self.vapi.nat44_interface_add_del_feature(
2404 sw_if_index=self.pg1.sw_if_index,
2407 # add static mapping for servers
2408 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2409 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2413 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2414 IP(src=host.ip4, dst=server1_nat_ip) /
2415 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2417 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2418 IP(src=host.ip4, dst=server1_nat_ip) /
2419 UDP(sport=self.udp_port_in, dport=server_udp_port))
2421 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2422 IP(src=host.ip4, dst=server1_nat_ip) /
2423 ICMP(id=self.icmp_id_in, type='echo-request'))
2425 self.pg0.add_stream(pkts)
2426 self.pg_enable_capture(self.pg_interfaces)
2428 capture = self.pg0.get_capture(len(pkts))
2429 for packet in capture:
2431 self.assertEqual(packet[IP].src, self.nat_addr)
2432 self.assertEqual(packet[IP].dst, server1.ip4)
2433 if packet.haslayer(TCP):
2434 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2435 self.assertEqual(packet[TCP].dport, server_tcp_port)
2436 self.tcp_port_out = packet[TCP].sport
2437 self.assert_packet_checksums_valid(packet)
2438 elif packet.haslayer(UDP):
2439 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2440 self.assertEqual(packet[UDP].dport, server_udp_port)
2441 self.udp_port_out = packet[UDP].sport
2443 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2444 self.icmp_id_out = packet[ICMP].id
2446 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2451 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2452 IP(src=server1.ip4, dst=self.nat_addr) /
2453 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2455 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2456 IP(src=server1.ip4, dst=self.nat_addr) /
2457 UDP(sport=server_udp_port, dport=self.udp_port_out))
2459 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2460 IP(src=server1.ip4, dst=self.nat_addr) /
2461 ICMP(id=self.icmp_id_out, type='echo-reply'))
2463 self.pg0.add_stream(pkts)
2464 self.pg_enable_capture(self.pg_interfaces)
2466 capture = self.pg0.get_capture(len(pkts))
2467 for packet in capture:
2469 self.assertEqual(packet[IP].src, server1_nat_ip)
2470 self.assertEqual(packet[IP].dst, host.ip4)
2471 if packet.haslayer(TCP):
2472 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2473 self.assertEqual(packet[TCP].sport, server_tcp_port)
2474 self.assert_packet_checksums_valid(packet)
2475 elif packet.haslayer(UDP):
2476 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2477 self.assertEqual(packet[UDP].sport, server_udp_port)
2479 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2481 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2484 # server2 to server1
2486 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2487 IP(src=server2.ip4, dst=server1_nat_ip) /
2488 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2491 IP(src=server2.ip4, dst=server1_nat_ip) /
2492 UDP(sport=self.udp_port_in, dport=server_udp_port))
2494 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2495 IP(src=server2.ip4, dst=server1_nat_ip) /
2496 ICMP(id=self.icmp_id_in, type='echo-request'))
2498 self.pg0.add_stream(pkts)
2499 self.pg_enable_capture(self.pg_interfaces)
2501 capture = self.pg0.get_capture(len(pkts))
2502 for packet in capture:
2504 self.assertEqual(packet[IP].src, server2_nat_ip)
2505 self.assertEqual(packet[IP].dst, server1.ip4)
2506 if packet.haslayer(TCP):
2507 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2508 self.assertEqual(packet[TCP].dport, server_tcp_port)
2509 self.tcp_port_out = packet[TCP].sport
2510 self.assert_packet_checksums_valid(packet)
2511 elif packet.haslayer(UDP):
2512 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2513 self.assertEqual(packet[UDP].dport, server_udp_port)
2514 self.udp_port_out = packet[UDP].sport
2516 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2517 self.icmp_id_out = packet[ICMP].id
2519 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2522 # server1 to server2
2524 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2525 IP(src=server1.ip4, dst=server2_nat_ip) /
2526 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2528 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2529 IP(src=server1.ip4, dst=server2_nat_ip) /
2530 UDP(sport=server_udp_port, dport=self.udp_port_out))
2532 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2533 IP(src=server1.ip4, dst=server2_nat_ip) /
2534 ICMP(id=self.icmp_id_out, type='echo-reply'))
2536 self.pg0.add_stream(pkts)
2537 self.pg_enable_capture(self.pg_interfaces)
2539 capture = self.pg0.get_capture(len(pkts))
2540 for packet in capture:
2542 self.assertEqual(packet[IP].src, server1_nat_ip)
2543 self.assertEqual(packet[IP].dst, server2.ip4)
2544 if packet.haslayer(TCP):
2545 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2546 self.assertEqual(packet[TCP].sport, server_tcp_port)
2547 self.assert_packet_checksums_valid(packet)
2548 elif packet.haslayer(UDP):
2549 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2550 self.assertEqual(packet[UDP].sport, server_udp_port)
2552 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2554 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2557 def test_interface_addr(self):
2558 """ Acquire NAT44 addresses from interface """
2559 self.vapi.nat44_add_del_interface_addr(
2561 sw_if_index=self.pg7.sw_if_index)
2563 # no address in NAT pool
2564 addresses = self.vapi.nat44_address_dump()
2565 self.assertEqual(0, len(addresses))
2567 # configure interface address and check NAT address pool
2568 self.pg7.config_ip4()
2569 addresses = self.vapi.nat44_address_dump()
2570 self.assertEqual(1, len(addresses))
2571 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2573 # remove interface address and check NAT address pool
2574 self.pg7.unconfig_ip4()
2575 addresses = self.vapi.nat44_address_dump()
2576 self.assertEqual(0, len(addresses))
2578 def test_interface_addr_static_mapping(self):
2579 """ Static mapping with addresses from interface """
2582 self.vapi.nat44_add_del_interface_addr(
2584 sw_if_index=self.pg7.sw_if_index)
2585 self.nat44_add_static_mapping(
2587 external_sw_if_index=self.pg7.sw_if_index,
2590 # static mappings with external interface
2591 static_mappings = self.vapi.nat44_static_mapping_dump()
2592 self.assertEqual(1, len(static_mappings))
2593 self.assertEqual(self.pg7.sw_if_index,
2594 static_mappings[0].external_sw_if_index)
2595 self.assertEqual(static_mappings[0].tag, tag)
2597 # configure interface address and check static mappings
2598 self.pg7.config_ip4()
2599 static_mappings = self.vapi.nat44_static_mapping_dump()
2600 self.assertEqual(2, len(static_mappings))
2602 for sm in static_mappings:
2603 if sm.external_sw_if_index == 0xFFFFFFFF:
2604 self.assertEqual(str(sm.external_ip_address),
2606 self.assertEqual(sm.tag, tag)
2608 self.assertTrue(resolved)
2610 # remove interface address and check static mappings
2611 self.pg7.unconfig_ip4()
2612 static_mappings = self.vapi.nat44_static_mapping_dump()
2613 self.assertEqual(1, len(static_mappings))
2614 self.assertEqual(self.pg7.sw_if_index,
2615 static_mappings[0].external_sw_if_index)
2616 self.assertEqual(static_mappings[0].tag, tag)
2618 # configure interface address again and check static mappings
2619 self.pg7.config_ip4()
2620 static_mappings = self.vapi.nat44_static_mapping_dump()
2621 self.assertEqual(2, len(static_mappings))
2623 for sm in static_mappings:
2624 if sm.external_sw_if_index == 0xFFFFFFFF:
2625 self.assertEqual(str(sm.external_ip_address),
2627 self.assertEqual(sm.tag, tag)
2629 self.assertTrue(resolved)
2631 # remove static mapping
2632 self.nat44_add_static_mapping(
2634 external_sw_if_index=self.pg7.sw_if_index,
2637 static_mappings = self.vapi.nat44_static_mapping_dump()
2638 self.assertEqual(0, len(static_mappings))
2640 def test_interface_addr_identity_nat(self):
2641 """ Identity NAT with addresses from interface """
2644 self.vapi.nat44_add_del_interface_addr(
2646 sw_if_index=self.pg7.sw_if_index)
2647 self.vapi.nat44_add_del_identity_mapping(
2649 sw_if_index=self.pg7.sw_if_index,
2651 protocol=IP_PROTOS.tcp,
2654 # identity mappings with external interface
2655 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2656 self.assertEqual(1, len(identity_mappings))
2657 self.assertEqual(self.pg7.sw_if_index,
2658 identity_mappings[0].sw_if_index)
2660 # configure interface address and check identity mappings
2661 self.pg7.config_ip4()
2662 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2664 self.assertEqual(2, len(identity_mappings))
2665 for sm in identity_mappings:
2666 if sm.sw_if_index == 0xFFFFFFFF:
2667 self.assertEqual(str(identity_mappings[0].ip_address),
2669 self.assertEqual(port, identity_mappings[0].port)
2670 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2672 self.assertTrue(resolved)
2674 # remove interface address and check identity mappings
2675 self.pg7.unconfig_ip4()
2676 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2677 self.assertEqual(1, len(identity_mappings))
2678 self.assertEqual(self.pg7.sw_if_index,
2679 identity_mappings[0].sw_if_index)
2681 def test_ipfix_nat44_sess(self):
2682 """ IPFIX logging NAT44 session created/deleted """
2683 self.ipfix_domain_id = 10
2684 self.ipfix_src_port = 20202
2685 collector_port = 30303
2686 bind_layers(UDP, IPFIX, dport=30303)
2687 self.nat44_add_address(self.nat_addr)
2688 flags = self.config_flags.NAT_IS_INSIDE
2689 self.vapi.nat44_interface_add_del_feature(
2690 sw_if_index=self.pg0.sw_if_index,
2691 flags=flags, is_add=1)
2692 self.vapi.nat44_interface_add_del_feature(
2693 sw_if_index=self.pg1.sw_if_index,
2695 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2696 src_address=self.pg3.local_ip4,
2698 template_interval=10,
2699 collector_port=collector_port)
2700 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2701 src_port=self.ipfix_src_port,
2704 pkts = self.create_stream_in(self.pg0, self.pg1)
2705 self.pg0.add_stream(pkts)
2706 self.pg_enable_capture(self.pg_interfaces)
2708 capture = self.pg1.get_capture(len(pkts))
2709 self.verify_capture_out(capture)
2710 self.nat44_add_address(self.nat_addr, is_add=0)
2711 self.vapi.ipfix_flush()
2712 capture = self.pg3.get_capture(7)
2713 ipfix = IPFIXDecoder()
2714 # first load template
2716 self.assertTrue(p.haslayer(IPFIX))
2717 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2718 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2719 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2720 self.assertEqual(p[UDP].dport, collector_port)
2721 self.assertEqual(p[IPFIX].observationDomainID,
2722 self.ipfix_domain_id)
2723 if p.haslayer(Template):
2724 ipfix.add_template(p.getlayer(Template))
2725 # verify events in data set
2727 if p.haslayer(Data):
2728 data = ipfix.decode_data_set(p.getlayer(Set))
2729 self.verify_ipfix_nat44_ses(data)
2731 def test_ipfix_addr_exhausted(self):
2732 """ IPFIX logging NAT addresses exhausted """
2733 flags = self.config_flags.NAT_IS_INSIDE
2734 self.vapi.nat44_interface_add_del_feature(
2735 sw_if_index=self.pg0.sw_if_index,
2736 flags=flags, is_add=1)
2737 self.vapi.nat44_interface_add_del_feature(
2738 sw_if_index=self.pg1.sw_if_index,
2740 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2741 src_address=self.pg3.local_ip4,
2743 template_interval=10)
2744 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2745 src_port=self.ipfix_src_port,
2748 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2749 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2751 self.pg0.add_stream(p)
2752 self.pg_enable_capture(self.pg_interfaces)
2754 self.pg1.assert_nothing_captured()
2756 self.vapi.ipfix_flush()
2757 capture = self.pg3.get_capture(7)
2758 ipfix = IPFIXDecoder()
2759 # first load template
2761 self.assertTrue(p.haslayer(IPFIX))
2762 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2763 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2764 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2765 self.assertEqual(p[UDP].dport, 4739)
2766 self.assertEqual(p[IPFIX].observationDomainID,
2767 self.ipfix_domain_id)
2768 if p.haslayer(Template):
2769 ipfix.add_template(p.getlayer(Template))
2770 # verify events in data set
2772 if p.haslayer(Data):
2773 data = ipfix.decode_data_set(p.getlayer(Set))
2774 self.verify_ipfix_addr_exhausted(data)
2776 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2777 def test_ipfix_max_sessions(self):
2778 """ IPFIX logging maximum session entries exceeded """
2779 self.nat44_add_address(self.nat_addr)
2780 flags = self.config_flags.NAT_IS_INSIDE
2781 self.vapi.nat44_interface_add_del_feature(
2782 sw_if_index=self.pg0.sw_if_index,
2783 flags=flags, is_add=1)
2784 self.vapi.nat44_interface_add_del_feature(
2785 sw_if_index=self.pg1.sw_if_index,
2788 nat44_config = self.vapi.nat_show_config()
2789 max_sessions = 10 * nat44_config.translation_buckets
2792 for i in range(0, max_sessions):
2793 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2794 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2795 IP(src=src, dst=self.pg1.remote_ip4) /
2798 self.pg0.add_stream(pkts)
2799 self.pg_enable_capture(self.pg_interfaces)
2802 self.pg1.get_capture(max_sessions)
2803 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2804 src_address=self.pg3.local_ip4,
2806 template_interval=10)
2807 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2808 src_port=self.ipfix_src_port,
2811 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2812 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2814 self.pg0.add_stream(p)
2815 self.pg_enable_capture(self.pg_interfaces)
2817 self.pg1.assert_nothing_captured()
2819 self.vapi.ipfix_flush()
2820 capture = self.pg3.get_capture(7)
2821 ipfix = IPFIXDecoder()
2822 # first load template
2824 self.assertTrue(p.haslayer(IPFIX))
2825 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2826 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2827 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2828 self.assertEqual(p[UDP].dport, 4739)
2829 self.assertEqual(p[IPFIX].observationDomainID,
2830 self.ipfix_domain_id)
2831 if p.haslayer(Template):
2832 ipfix.add_template(p.getlayer(Template))
2833 # verify events in data set
2835 if p.haslayer(Data):
2836 data = ipfix.decode_data_set(p.getlayer(Set))
2837 self.verify_ipfix_max_sessions(data, max_sessions)
2839 def test_syslog_apmap(self):
2840 """ Test syslog address and port mapping creation and deletion """
2841 self.vapi.syslog_set_filter(
2842 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2843 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2844 self.nat44_add_address(self.nat_addr)
2845 flags = self.config_flags.NAT_IS_INSIDE
2846 self.vapi.nat44_interface_add_del_feature(
2847 sw_if_index=self.pg0.sw_if_index,
2848 flags=flags, is_add=1)
2849 self.vapi.nat44_interface_add_del_feature(
2850 sw_if_index=self.pg1.sw_if_index,
2853 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2854 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2855 TCP(sport=self.tcp_port_in, dport=20))
2856 self.pg0.add_stream(p)
2857 self.pg_enable_capture(self.pg_interfaces)
2859 capture = self.pg1.get_capture(1)
2860 self.tcp_port_out = capture[0][TCP].sport
2861 capture = self.pg3.get_capture(1)
2862 self.verify_syslog_apmap(capture[0][Raw].load)
2864 self.pg_enable_capture(self.pg_interfaces)
2866 self.nat44_add_address(self.nat_addr, is_add=0)
2867 capture = self.pg3.get_capture(1)
2868 self.verify_syslog_apmap(capture[0][Raw].load, False)
2870 def test_pool_addr_fib(self):
2871 """ NAT44 add pool addresses to FIB """
2872 static_addr = '10.0.0.10'
2873 self.nat44_add_address(self.nat_addr)
2874 flags = self.config_flags.NAT_IS_INSIDE
2875 self.vapi.nat44_interface_add_del_feature(
2876 sw_if_index=self.pg0.sw_if_index,
2877 flags=flags, is_add=1)
2878 self.vapi.nat44_interface_add_del_feature(
2879 sw_if_index=self.pg1.sw_if_index,
2881 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2884 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2885 ARP(op=ARP.who_has, pdst=self.nat_addr,
2886 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2887 self.pg1.add_stream(p)
2888 self.pg_enable_capture(self.pg_interfaces)
2890 capture = self.pg1.get_capture(1)
2891 self.assertTrue(capture[0].haslayer(ARP))
2892 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2895 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2896 ARP(op=ARP.who_has, pdst=static_addr,
2897 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2898 self.pg1.add_stream(p)
2899 self.pg_enable_capture(self.pg_interfaces)
2901 capture = self.pg1.get_capture(1)
2902 self.assertTrue(capture[0].haslayer(ARP))
2903 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2905 # send ARP to non-NAT44 interface
2906 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2907 ARP(op=ARP.who_has, pdst=self.nat_addr,
2908 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2909 self.pg2.add_stream(p)
2910 self.pg_enable_capture(self.pg_interfaces)
2912 self.pg1.assert_nothing_captured()
2914 # remove addresses and verify
2915 self.nat44_add_address(self.nat_addr, is_add=0)
2916 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2919 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2920 ARP(op=ARP.who_has, pdst=self.nat_addr,
2921 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2922 self.pg1.add_stream(p)
2923 self.pg_enable_capture(self.pg_interfaces)
2925 self.pg1.assert_nothing_captured()
2927 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2928 ARP(op=ARP.who_has, pdst=static_addr,
2929 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2930 self.pg1.add_stream(p)
2931 self.pg_enable_capture(self.pg_interfaces)
2933 self.pg1.assert_nothing_captured()
2935 def test_vrf_mode(self):
2936 """ NAT44 tenant VRF aware address pool mode """
2940 nat_ip1 = "10.0.0.10"
2941 nat_ip2 = "10.0.0.11"
2943 self.pg0.unconfig_ip4()
2944 self.pg1.unconfig_ip4()
2945 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
2946 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
2947 self.pg0.set_table_ip4(vrf_id1)
2948 self.pg1.set_table_ip4(vrf_id2)
2949 self.pg0.config_ip4()
2950 self.pg1.config_ip4()
2951 self.pg0.resolve_arp()
2952 self.pg1.resolve_arp()
2954 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2955 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2956 flags = self.config_flags.NAT_IS_INSIDE
2957 self.vapi.nat44_interface_add_del_feature(
2958 sw_if_index=self.pg0.sw_if_index,
2959 flags=flags, is_add=1)
2960 self.vapi.nat44_interface_add_del_feature(
2961 sw_if_index=self.pg1.sw_if_index,
2962 flags=flags, is_add=1)
2963 self.vapi.nat44_interface_add_del_feature(
2964 sw_if_index=self.pg2.sw_if_index,
2969 pkts = self.create_stream_in(self.pg0, self.pg2)
2970 self.pg0.add_stream(pkts)
2971 self.pg_enable_capture(self.pg_interfaces)
2973 capture = self.pg2.get_capture(len(pkts))
2974 self.verify_capture_out(capture, nat_ip1)
2977 pkts = self.create_stream_in(self.pg1, self.pg2)
2978 self.pg1.add_stream(pkts)
2979 self.pg_enable_capture(self.pg_interfaces)
2981 capture = self.pg2.get_capture(len(pkts))
2982 self.verify_capture_out(capture, nat_ip2)
2985 self.pg0.unconfig_ip4()
2986 self.pg1.unconfig_ip4()
2987 self.pg0.set_table_ip4(0)
2988 self.pg1.set_table_ip4(0)
2989 self.pg0.config_ip4()
2990 self.pg1.config_ip4()
2991 self.pg0.resolve_arp()
2992 self.pg1.resolve_arp()
2993 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
2994 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
2996 def test_vrf_feature_independent(self):
2997 """ NAT44 tenant VRF independent address pool mode """
2999 nat_ip1 = "10.0.0.10"
3000 nat_ip2 = "10.0.0.11"
3002 self.nat44_add_address(nat_ip1)
3003 self.nat44_add_address(nat_ip2, vrf_id=99)
3004 flags = self.config_flags.NAT_IS_INSIDE
3005 self.vapi.nat44_interface_add_del_feature(
3006 sw_if_index=self.pg0.sw_if_index,
3007 flags=flags, is_add=1)
3008 self.vapi.nat44_interface_add_del_feature(
3009 sw_if_index=self.pg1.sw_if_index,
3010 flags=flags, is_add=1)
3011 self.vapi.nat44_interface_add_del_feature(
3012 sw_if_index=self.pg2.sw_if_index,
3016 pkts = self.create_stream_in(self.pg0, self.pg2)
3017 self.pg0.add_stream(pkts)
3018 self.pg_enable_capture(self.pg_interfaces)
3020 capture = self.pg2.get_capture(len(pkts))
3021 self.verify_capture_out(capture, nat_ip1)
3024 pkts = self.create_stream_in(self.pg1, self.pg2)
3025 self.pg1.add_stream(pkts)
3026 self.pg_enable_capture(self.pg_interfaces)
3028 capture = self.pg2.get_capture(len(pkts))
3029 self.verify_capture_out(capture, nat_ip1)
3031 def create_routes_and_neigbors(self):
3032 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3033 [VppRoutePath(self.pg7.remote_ip4,
3034 self.pg7.sw_if_index)])
3035 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3036 [VppRoutePath(self.pg8.remote_ip4,
3037 self.pg8.sw_if_index)])
3041 n1 = VppNeighbor(self,
3042 self.pg7.sw_if_index,
3043 self.pg7.remote_mac,
3044 self.pg7.remote_ip4,
3046 n2 = VppNeighbor(self,
3047 self.pg8.sw_if_index,
3048 self.pg8.remote_mac,
3049 self.pg8.remote_ip4,
3054 def test_dynamic_ipless_interfaces(self):
3055 """ NAT44 interfaces without configured IP address """
3056 self.create_routes_and_neigbors()
3057 self.nat44_add_address(self.nat_addr)
3058 flags = self.config_flags.NAT_IS_INSIDE
3059 self.vapi.nat44_interface_add_del_feature(
3060 sw_if_index=self.pg7.sw_if_index,
3061 flags=flags, is_add=1)
3062 self.vapi.nat44_interface_add_del_feature(
3063 sw_if_index=self.pg8.sw_if_index,
3067 pkts = self.create_stream_in(self.pg7, self.pg8)
3068 self.pg7.add_stream(pkts)
3069 self.pg_enable_capture(self.pg_interfaces)
3071 capture = self.pg8.get_capture(len(pkts))
3072 self.verify_capture_out(capture)
3075 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3076 self.pg8.add_stream(pkts)
3077 self.pg_enable_capture(self.pg_interfaces)
3079 capture = self.pg7.get_capture(len(pkts))
3080 self.verify_capture_in(capture, self.pg7)
3082 def test_static_ipless_interfaces(self):
3083 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3085 self.create_routes_and_neigbors()
3086 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3087 flags = self.config_flags.NAT_IS_INSIDE
3088 self.vapi.nat44_interface_add_del_feature(
3089 sw_if_index=self.pg7.sw_if_index,
3090 flags=flags, is_add=1)
3091 self.vapi.nat44_interface_add_del_feature(
3092 sw_if_index=self.pg8.sw_if_index,
3096 pkts = self.create_stream_out(self.pg8)
3097 self.pg8.add_stream(pkts)
3098 self.pg_enable_capture(self.pg_interfaces)
3100 capture = self.pg7.get_capture(len(pkts))
3101 self.verify_capture_in(capture, self.pg7)
3104 pkts = self.create_stream_in(self.pg7, self.pg8)
3105 self.pg7.add_stream(pkts)
3106 self.pg_enable_capture(self.pg_interfaces)
3108 capture = self.pg8.get_capture(len(pkts))
3109 self.verify_capture_out(capture, self.nat_addr, True)
3111 def test_static_with_port_ipless_interfaces(self):
3112 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3114 self.tcp_port_out = 30606
3115 self.udp_port_out = 30607
3116 self.icmp_id_out = 30608
3118 self.create_routes_and_neigbors()
3119 self.nat44_add_address(self.nat_addr)
3120 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3121 self.tcp_port_in, self.tcp_port_out,
3122 proto=IP_PROTOS.tcp)
3123 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3124 self.udp_port_in, self.udp_port_out,
3125 proto=IP_PROTOS.udp)
3126 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3127 self.icmp_id_in, self.icmp_id_out,
3128 proto=IP_PROTOS.icmp)
3129 flags = self.config_flags.NAT_IS_INSIDE
3130 self.vapi.nat44_interface_add_del_feature(
3131 sw_if_index=self.pg7.sw_if_index,
3132 flags=flags, is_add=1)
3133 self.vapi.nat44_interface_add_del_feature(
3134 sw_if_index=self.pg8.sw_if_index,
3138 pkts = self.create_stream_out(self.pg8)
3139 self.pg8.add_stream(pkts)
3140 self.pg_enable_capture(self.pg_interfaces)
3142 capture = self.pg7.get_capture(len(pkts))
3143 self.verify_capture_in(capture, self.pg7)
3146 pkts = self.create_stream_in(self.pg7, self.pg8)
3147 self.pg7.add_stream(pkts)
3148 self.pg_enable_capture(self.pg_interfaces)
3150 capture = self.pg8.get_capture(len(pkts))
3151 self.verify_capture_out(capture)
3153 def test_static_unknown_proto(self):
3154 """ 1:1 NAT translate packet with unknown protocol """
3155 nat_ip = "10.0.0.10"
3156 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3157 flags = self.config_flags.NAT_IS_INSIDE
3158 self.vapi.nat44_interface_add_del_feature(
3159 sw_if_index=self.pg0.sw_if_index,
3160 flags=flags, is_add=1)
3161 self.vapi.nat44_interface_add_del_feature(
3162 sw_if_index=self.pg1.sw_if_index,
3166 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3167 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3169 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3170 TCP(sport=1234, dport=1234))
3171 self.pg0.add_stream(p)
3172 self.pg_enable_capture(self.pg_interfaces)
3174 p = self.pg1.get_capture(1)
3177 self.assertEqual(packet[IP].src, nat_ip)
3178 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3179 self.assertEqual(packet.haslayer(GRE), 1)
3180 self.assert_packet_checksums_valid(packet)
3182 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3186 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3187 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3189 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3190 TCP(sport=1234, dport=1234))
3191 self.pg1.add_stream(p)
3192 self.pg_enable_capture(self.pg_interfaces)
3194 p = self.pg0.get_capture(1)
3197 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3198 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3199 self.assertEqual(packet.haslayer(GRE), 1)
3200 self.assert_packet_checksums_valid(packet)
3202 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3205 def test_hairpinning_static_unknown_proto(self):
3206 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3208 host = self.pg0.remote_hosts[0]
3209 server = self.pg0.remote_hosts[1]
3211 host_nat_ip = "10.0.0.10"
3212 server_nat_ip = "10.0.0.11"
3214 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3215 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3216 flags = self.config_flags.NAT_IS_INSIDE
3217 self.vapi.nat44_interface_add_del_feature(
3218 sw_if_index=self.pg0.sw_if_index,
3219 flags=flags, is_add=1)
3220 self.vapi.nat44_interface_add_del_feature(
3221 sw_if_index=self.pg1.sw_if_index,
3225 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3226 IP(src=host.ip4, dst=server_nat_ip) /
3228 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3229 TCP(sport=1234, dport=1234))
3230 self.pg0.add_stream(p)
3231 self.pg_enable_capture(self.pg_interfaces)
3233 p = self.pg0.get_capture(1)
3236 self.assertEqual(packet[IP].src, host_nat_ip)
3237 self.assertEqual(packet[IP].dst, server.ip4)
3238 self.assertEqual(packet.haslayer(GRE), 1)
3239 self.assert_packet_checksums_valid(packet)
3241 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3245 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3246 IP(src=server.ip4, dst=host_nat_ip) /
3248 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3249 TCP(sport=1234, dport=1234))
3250 self.pg0.add_stream(p)
3251 self.pg_enable_capture(self.pg_interfaces)
3253 p = self.pg0.get_capture(1)
3256 self.assertEqual(packet[IP].src, server_nat_ip)
3257 self.assertEqual(packet[IP].dst, host.ip4)
3258 self.assertEqual(packet.haslayer(GRE), 1)
3259 self.assert_packet_checksums_valid(packet)
3261 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3264 def test_output_feature(self):
3265 """ NAT44 interface output feature (in2out postrouting) """
3266 self.nat44_add_address(self.nat_addr)
3267 flags = self.config_flags.NAT_IS_INSIDE
3268 self.vapi.nat44_interface_add_del_output_feature(
3269 is_add=1, flags=flags,
3270 sw_if_index=self.pg0.sw_if_index)
3271 self.vapi.nat44_interface_add_del_output_feature(
3272 is_add=1, flags=flags,
3273 sw_if_index=self.pg1.sw_if_index)
3274 self.vapi.nat44_interface_add_del_output_feature(
3276 sw_if_index=self.pg3.sw_if_index)
3279 pkts = self.create_stream_in(self.pg0, self.pg3)
3280 self.pg0.add_stream(pkts)
3281 self.pg_enable_capture(self.pg_interfaces)
3283 capture = self.pg3.get_capture(len(pkts))
3284 self.verify_capture_out(capture)
3287 pkts = self.create_stream_out(self.pg3)
3288 self.pg3.add_stream(pkts)
3289 self.pg_enable_capture(self.pg_interfaces)
3291 capture = self.pg0.get_capture(len(pkts))
3292 self.verify_capture_in(capture, self.pg0)
3294 # from non-NAT interface to NAT inside interface
3295 pkts = self.create_stream_in(self.pg2, self.pg0)
3296 self.pg2.add_stream(pkts)
3297 self.pg_enable_capture(self.pg_interfaces)
3299 capture = self.pg0.get_capture(len(pkts))
3300 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3302 def test_output_feature_vrf_aware(self):
3303 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3304 nat_ip_vrf10 = "10.0.0.10"
3305 nat_ip_vrf20 = "10.0.0.20"
3307 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3308 [VppRoutePath(self.pg3.remote_ip4,
3309 self.pg3.sw_if_index)],
3311 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3312 [VppRoutePath(self.pg3.remote_ip4,
3313 self.pg3.sw_if_index)],
3318 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3319 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3320 flags = self.config_flags.NAT_IS_INSIDE
3321 self.vapi.nat44_interface_add_del_output_feature(
3322 is_add=1, flags=flags,
3323 sw_if_index=self.pg4.sw_if_index)
3324 self.vapi.nat44_interface_add_del_output_feature(
3325 is_add=1, flags=flags,
3326 sw_if_index=self.pg6.sw_if_index)
3327 self.vapi.nat44_interface_add_del_output_feature(
3329 sw_if_index=self.pg3.sw_if_index)
3332 pkts = self.create_stream_in(self.pg4, self.pg3)
3333 self.pg4.add_stream(pkts)
3334 self.pg_enable_capture(self.pg_interfaces)
3336 capture = self.pg3.get_capture(len(pkts))
3337 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3340 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3341 self.pg3.add_stream(pkts)
3342 self.pg_enable_capture(self.pg_interfaces)
3344 capture = self.pg4.get_capture(len(pkts))
3345 self.verify_capture_in(capture, self.pg4)
3348 pkts = self.create_stream_in(self.pg6, self.pg3)
3349 self.pg6.add_stream(pkts)
3350 self.pg_enable_capture(self.pg_interfaces)
3352 capture = self.pg3.get_capture(len(pkts))
3353 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3356 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3357 self.pg3.add_stream(pkts)
3358 self.pg_enable_capture(self.pg_interfaces)
3360 capture = self.pg6.get_capture(len(pkts))
3361 self.verify_capture_in(capture, self.pg6)
3363 def test_output_feature_hairpinning(self):
3364 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3365 host = self.pg0.remote_hosts[0]
3366 server = self.pg0.remote_hosts[1]
3369 server_in_port = 5678
3370 server_out_port = 8765
3372 self.nat44_add_address(self.nat_addr)
3373 flags = self.config_flags.NAT_IS_INSIDE
3374 self.vapi.nat44_interface_add_del_output_feature(
3375 is_add=1, flags=flags,
3376 sw_if_index=self.pg0.sw_if_index)
3377 self.vapi.nat44_interface_add_del_output_feature(
3379 sw_if_index=self.pg1.sw_if_index)
3381 # add static mapping for server
3382 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3383 server_in_port, server_out_port,
3384 proto=IP_PROTOS.tcp)
3386 # send packet from host to server
3387 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3388 IP(src=host.ip4, dst=self.nat_addr) /
3389 TCP(sport=host_in_port, dport=server_out_port))
3390 self.pg0.add_stream(p)
3391 self.pg_enable_capture(self.pg_interfaces)
3393 capture = self.pg0.get_capture(1)
3398 self.assertEqual(ip.src, self.nat_addr)
3399 self.assertEqual(ip.dst, server.ip4)
3400 self.assertNotEqual(tcp.sport, host_in_port)
3401 self.assertEqual(tcp.dport, server_in_port)
3402 self.assert_packet_checksums_valid(p)
3403 host_out_port = tcp.sport
3405 self.logger.error(ppp("Unexpected or invalid packet:", p))
3408 # send reply from server to host
3409 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3410 IP(src=server.ip4, dst=self.nat_addr) /
3411 TCP(sport=server_in_port, dport=host_out_port))
3412 self.pg0.add_stream(p)
3413 self.pg_enable_capture(self.pg_interfaces)
3415 capture = self.pg0.get_capture(1)
3420 self.assertEqual(ip.src, self.nat_addr)
3421 self.assertEqual(ip.dst, host.ip4)
3422 self.assertEqual(tcp.sport, server_out_port)
3423 self.assertEqual(tcp.dport, host_in_port)
3424 self.assert_packet_checksums_valid(p)
3426 self.logger.error(ppp("Unexpected or invalid packet:", p))
3429 def test_one_armed_nat44(self):
3430 """ One armed NAT44 """
3431 remote_host = self.pg9.remote_hosts[0]
3432 local_host = self.pg9.remote_hosts[1]
3435 self.nat44_add_address(self.nat_addr)
3436 flags = self.config_flags.NAT_IS_INSIDE
3437 self.vapi.nat44_interface_add_del_feature(
3438 sw_if_index=self.pg9.sw_if_index,
3440 self.vapi.nat44_interface_add_del_feature(
3441 sw_if_index=self.pg9.sw_if_index,
3442 flags=flags, is_add=1)
3445 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3446 IP(src=local_host.ip4, dst=remote_host.ip4) /
3447 TCP(sport=12345, dport=80))
3448 self.pg9.add_stream(p)
3449 self.pg_enable_capture(self.pg_interfaces)
3451 capture = self.pg9.get_capture(1)
3456 self.assertEqual(ip.src, self.nat_addr)
3457 self.assertEqual(ip.dst, remote_host.ip4)
3458 self.assertNotEqual(tcp.sport, 12345)
3459 external_port = tcp.sport
3460 self.assertEqual(tcp.dport, 80)
3461 self.assert_packet_checksums_valid(p)
3463 self.logger.error(ppp("Unexpected or invalid packet:", p))
3467 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3468 IP(src=remote_host.ip4, dst=self.nat_addr) /
3469 TCP(sport=80, dport=external_port))
3470 self.pg9.add_stream(p)
3471 self.pg_enable_capture(self.pg_interfaces)
3473 capture = self.pg9.get_capture(1)
3478 self.assertEqual(ip.src, remote_host.ip4)
3479 self.assertEqual(ip.dst, local_host.ip4)
3480 self.assertEqual(tcp.sport, 80)
3481 self.assertEqual(tcp.dport, 12345)
3482 self.assert_packet_checksums_valid(p)
3484 self.logger.error(ppp("Unexpected or invalid packet:", p))
3487 err = self.statistics.get_err_counter(
3488 '/err/nat44-classify/next in2out')
3489 self.assertEqual(err, 1)
3490 err = self.statistics.get_err_counter(
3491 '/err/nat44-classify/next out2in')
3492 self.assertEqual(err, 1)
3494 def test_del_session(self):
3495 """ Delete NAT44 session """
3496 self.nat44_add_address(self.nat_addr)
3497 flags = self.config_flags.NAT_IS_INSIDE
3498 self.vapi.nat44_interface_add_del_feature(
3499 sw_if_index=self.pg0.sw_if_index,
3500 flags=flags, is_add=1)
3501 self.vapi.nat44_interface_add_del_feature(
3502 sw_if_index=self.pg1.sw_if_index,
3505 pkts = self.create_stream_in(self.pg0, self.pg1)
3506 self.pg0.add_stream(pkts)
3507 self.pg_enable_capture(self.pg_interfaces)
3509 self.pg1.get_capture(len(pkts))
3511 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3512 nsessions = len(sessions)
3514 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3515 port=sessions[0].inside_port,
3516 protocol=sessions[0].protocol,
3517 flags=self.config_flags.NAT_IS_INSIDE)
3518 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3519 port=sessions[1].outside_port,
3520 protocol=sessions[1].protocol)
3522 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3523 self.assertEqual(nsessions - len(sessions), 2)
3525 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3526 port=sessions[0].inside_port,
3527 protocol=sessions[0].protocol,
3528 flags=self.config_flags.NAT_IS_INSIDE)
3530 self.verify_no_nat44_user()
3532 def test_frag_in_order(self):
3533 """ NAT44 translate fragments arriving in order """
3535 self.nat44_add_address(self.nat_addr)
3536 flags = self.config_flags.NAT_IS_INSIDE
3537 self.vapi.nat44_interface_add_del_feature(
3538 sw_if_index=self.pg0.sw_if_index,
3539 flags=flags, is_add=1)
3540 self.vapi.nat44_interface_add_del_feature(
3541 sw_if_index=self.pg1.sw_if_index,
3544 self.frag_in_order(proto=IP_PROTOS.tcp)
3545 self.frag_in_order(proto=IP_PROTOS.udp)
3546 self.frag_in_order(proto=IP_PROTOS.icmp)
3548 def test_frag_forwarding(self):
3549 """ NAT44 forwarding fragment test """
3550 self.vapi.nat44_add_del_interface_addr(
3552 sw_if_index=self.pg1.sw_if_index)
3553 flags = self.config_flags.NAT_IS_INSIDE
3554 self.vapi.nat44_interface_add_del_feature(
3555 sw_if_index=self.pg0.sw_if_index,
3556 flags=flags, is_add=1)
3557 self.vapi.nat44_interface_add_del_feature(
3558 sw_if_index=self.pg1.sw_if_index,
3560 self.vapi.nat44_forwarding_enable_disable(enable=1)
3562 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3563 pkts = self.create_stream_frag(self.pg1,
3564 self.pg0.remote_ip4,
3568 proto=IP_PROTOS.udp)
3569 self.pg1.add_stream(pkts)
3570 self.pg_enable_capture(self.pg_interfaces)
3572 frags = self.pg0.get_capture(len(pkts))
3573 p = self.reass_frags_and_verify(frags,
3574 self.pg1.remote_ip4,
3575 self.pg0.remote_ip4)
3576 self.assertEqual(p[UDP].sport, 4789)
3577 self.assertEqual(p[UDP].dport, 4789)
3578 self.assertEqual(data, p[Raw].load)
3580 def test_reass_hairpinning(self):
3581 """ NAT44 fragments hairpinning """
3583 self.server = self.pg0.remote_hosts[1]
3584 self.host_in_port = random.randint(1025, 65535)
3585 self.server_in_port = random.randint(1025, 65535)
3586 self.server_out_port = random.randint(1025, 65535)
3588 self.nat44_add_address(self.nat_addr)
3589 flags = self.config_flags.NAT_IS_INSIDE
3590 self.vapi.nat44_interface_add_del_feature(
3591 sw_if_index=self.pg0.sw_if_index,
3592 flags=flags, is_add=1)
3593 self.vapi.nat44_interface_add_del_feature(
3594 sw_if_index=self.pg1.sw_if_index,
3596 # add static mapping for server
3597 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3598 self.server_in_port,
3599 self.server_out_port,
3600 proto=IP_PROTOS.tcp)
3601 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3602 self.server_in_port,
3603 self.server_out_port,
3604 proto=IP_PROTOS.udp)
3605 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3607 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3608 self.reass_hairpinning(proto=IP_PROTOS.udp)
3609 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3611 def test_frag_out_of_order(self):
3612 """ NAT44 translate fragments arriving out of order """
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,
3623 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3624 self.frag_out_of_order(proto=IP_PROTOS.udp)
3625 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3627 def test_port_restricted(self):
3628 """ Port restricted NAT44 (MAP-E CE) """
3629 self.nat44_add_address(self.nat_addr)
3630 flags = self.config_flags.NAT_IS_INSIDE
3631 self.vapi.nat44_interface_add_del_feature(
3632 sw_if_index=self.pg0.sw_if_index,
3633 flags=flags, is_add=1)
3634 self.vapi.nat44_interface_add_del_feature(
3635 sw_if_index=self.pg1.sw_if_index,
3637 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3642 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3643 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3644 TCP(sport=4567, dport=22))
3645 self.pg0.add_stream(p)
3646 self.pg_enable_capture(self.pg_interfaces)
3648 capture = self.pg1.get_capture(1)
3653 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3654 self.assertEqual(ip.src, self.nat_addr)
3655 self.assertEqual(tcp.dport, 22)
3656 self.assertNotEqual(tcp.sport, 4567)
3657 self.assertEqual((tcp.sport >> 6) & 63, 10)
3658 self.assert_packet_checksums_valid(p)
3660 self.logger.error(ppp("Unexpected or invalid packet:", p))
3663 def test_port_range(self):
3664 """ External address port range """
3665 self.nat44_add_address(self.nat_addr)
3666 flags = self.config_flags.NAT_IS_INSIDE
3667 self.vapi.nat44_interface_add_del_feature(
3668 sw_if_index=self.pg0.sw_if_index,
3669 flags=flags, is_add=1)
3670 self.vapi.nat44_interface_add_del_feature(
3671 sw_if_index=self.pg1.sw_if_index,
3673 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3678 for port in range(0, 5):
3679 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3680 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3681 TCP(sport=1125 + port))
3683 self.pg0.add_stream(pkts)
3684 self.pg_enable_capture(self.pg_interfaces)
3686 capture = self.pg1.get_capture(3)
3689 self.assertGreaterEqual(tcp.sport, 1025)
3690 self.assertLessEqual(tcp.sport, 1027)
3692 def test_multiple_outside_vrf(self):
3693 """ Multiple outside VRF """
3697 self.pg1.unconfig_ip4()
3698 self.pg2.unconfig_ip4()
3699 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3700 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3701 self.pg1.set_table_ip4(vrf_id1)
3702 self.pg2.set_table_ip4(vrf_id2)
3703 self.pg1.config_ip4()
3704 self.pg2.config_ip4()
3705 self.pg1.resolve_arp()
3706 self.pg2.resolve_arp()
3708 self.nat44_add_address(self.nat_addr)
3709 flags = self.config_flags.NAT_IS_INSIDE
3710 self.vapi.nat44_interface_add_del_feature(
3711 sw_if_index=self.pg0.sw_if_index,
3712 flags=flags, is_add=1)
3713 self.vapi.nat44_interface_add_del_feature(
3714 sw_if_index=self.pg1.sw_if_index,
3716 self.vapi.nat44_interface_add_del_feature(
3717 sw_if_index=self.pg2.sw_if_index,
3722 pkts = self.create_stream_in(self.pg0, self.pg1)
3723 self.pg0.add_stream(pkts)
3724 self.pg_enable_capture(self.pg_interfaces)
3726 capture = self.pg1.get_capture(len(pkts))
3727 self.verify_capture_out(capture, self.nat_addr)
3729 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3730 self.pg1.add_stream(pkts)
3731 self.pg_enable_capture(self.pg_interfaces)
3733 capture = self.pg0.get_capture(len(pkts))
3734 self.verify_capture_in(capture, self.pg0)
3736 self.tcp_port_in = 60303
3737 self.udp_port_in = 60304
3738 self.icmp_id_in = 60305
3741 pkts = self.create_stream_in(self.pg0, self.pg2)
3742 self.pg0.add_stream(pkts)
3743 self.pg_enable_capture(self.pg_interfaces)
3745 capture = self.pg2.get_capture(len(pkts))
3746 self.verify_capture_out(capture, self.nat_addr)
3748 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3749 self.pg2.add_stream(pkts)
3750 self.pg_enable_capture(self.pg_interfaces)
3752 capture = self.pg0.get_capture(len(pkts))
3753 self.verify_capture_in(capture, self.pg0)
3756 self.nat44_add_address(self.nat_addr, is_add=0)
3757 self.pg1.unconfig_ip4()
3758 self.pg2.unconfig_ip4()
3759 self.pg1.set_table_ip4(0)
3760 self.pg2.set_table_ip4(0)
3761 self.pg1.config_ip4()
3762 self.pg2.config_ip4()
3763 self.pg1.resolve_arp()
3764 self.pg2.resolve_arp()
3766 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3767 def test_session_timeout(self):
3768 """ NAT44 session timeouts """
3769 self.nat44_add_address(self.nat_addr)
3770 flags = self.config_flags.NAT_IS_INSIDE
3771 self.vapi.nat44_interface_add_del_feature(
3772 sw_if_index=self.pg0.sw_if_index,
3773 flags=flags, is_add=1)
3774 self.vapi.nat44_interface_add_del_feature(
3775 sw_if_index=self.pg1.sw_if_index,
3777 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3778 tcp_transitory=240, icmp=60)
3782 for i in range(0, max_sessions):
3783 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3784 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3785 IP(src=src, dst=self.pg1.remote_ip4) /
3786 UDP(sport=1025, dport=53))
3788 self.pg0.add_stream(pkts)
3789 self.pg_enable_capture(self.pg_interfaces)
3791 self.pg1.get_capture(max_sessions)
3796 for i in range(0, max_sessions):
3797 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3798 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3799 IP(src=src, dst=self.pg1.remote_ip4) /
3800 UDP(sport=1026, dport=53))
3802 self.pg0.add_stream(pkts)
3803 self.pg_enable_capture(self.pg_interfaces)
3805 self.pg1.get_capture(max_sessions)
3808 users = self.vapi.nat44_user_dump()
3810 nsessions = nsessions + user.nsessions
3811 self.assertLess(nsessions, 2 * max_sessions)
3813 def test_mss_clamping(self):
3814 """ TCP MSS clamping """
3815 self.nat44_add_address(self.nat_addr)
3816 flags = self.config_flags.NAT_IS_INSIDE
3817 self.vapi.nat44_interface_add_del_feature(
3818 sw_if_index=self.pg0.sw_if_index,
3819 flags=flags, is_add=1)
3820 self.vapi.nat44_interface_add_del_feature(
3821 sw_if_index=self.pg1.sw_if_index,
3824 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3825 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3826 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3827 flags="S", options=[('MSS', 1400)]))
3829 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3830 self.pg0.add_stream(p)
3831 self.pg_enable_capture(self.pg_interfaces)
3833 capture = self.pg1.get_capture(1)
3834 # Negotiated MSS value greater than configured - changed
3835 self.verify_mss_value(capture[0], 1000)
3837 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3838 self.pg0.add_stream(p)
3839 self.pg_enable_capture(self.pg_interfaces)
3841 capture = self.pg1.get_capture(1)
3842 # MSS clamping disabled - negotiated MSS unchanged
3843 self.verify_mss_value(capture[0], 1400)
3845 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3846 self.pg0.add_stream(p)
3847 self.pg_enable_capture(self.pg_interfaces)
3849 capture = self.pg1.get_capture(1)
3850 # Negotiated MSS value smaller than configured - unchanged
3851 self.verify_mss_value(capture[0], 1400)
3853 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3854 def test_ha_send(self):
3855 """ Send HA session synchronization events (active) """
3856 self.nat44_add_address(self.nat_addr)
3857 flags = self.config_flags.NAT_IS_INSIDE
3858 self.vapi.nat44_interface_add_del_feature(
3859 sw_if_index=self.pg0.sw_if_index,
3860 flags=flags, is_add=1)
3861 self.vapi.nat44_interface_add_del_feature(
3862 sw_if_index=self.pg1.sw_if_index,
3864 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3867 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3868 port=12346, session_refresh_interval=10)
3869 bind_layers(UDP, HANATStateSync, sport=12345)
3872 pkts = self.create_stream_in(self.pg0, self.pg1)
3873 self.pg0.add_stream(pkts)
3874 self.pg_enable_capture(self.pg_interfaces)
3876 capture = self.pg1.get_capture(len(pkts))
3877 self.verify_capture_out(capture)
3878 # active send HA events
3879 self.vapi.nat_ha_flush()
3880 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3881 self.assertEqual(stats[0][0], 3)
3882 capture = self.pg3.get_capture(1)
3884 self.assert_packet_checksums_valid(p)
3888 hanat = p[HANATStateSync]
3890 self.logger.error(ppp("Invalid packet:", p))
3893 self.assertEqual(ip.src, self.pg3.local_ip4)
3894 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3895 self.assertEqual(udp.sport, 12345)
3896 self.assertEqual(udp.dport, 12346)
3897 self.assertEqual(hanat.version, 1)
3898 self.assertEqual(hanat.thread_index, 0)
3899 self.assertEqual(hanat.count, 3)
3900 seq = hanat.sequence_number
3901 for event in hanat.events:
3902 self.assertEqual(event.event_type, 1)
3903 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3904 self.assertEqual(event.out_addr, self.nat_addr)
3905 self.assertEqual(event.fib_index, 0)
3907 # ACK received events
3908 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3909 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3910 UDP(sport=12346, dport=12345) /
3911 HANATStateSync(sequence_number=seq, flags='ACK'))
3912 self.pg3.add_stream(ack)
3914 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3915 self.assertEqual(stats[0][0], 1)
3917 # delete one session
3918 self.pg_enable_capture(self.pg_interfaces)
3919 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3920 port=self.tcp_port_in,
3921 protocol=IP_PROTOS.tcp,
3922 flags=self.config_flags.NAT_IS_INSIDE)
3923 self.vapi.nat_ha_flush()
3924 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3925 self.assertEqual(stats[0][0], 1)
3926 capture = self.pg3.get_capture(1)
3929 hanat = p[HANATStateSync]
3931 self.logger.error(ppp("Invalid packet:", p))
3934 self.assertGreater(hanat.sequence_number, seq)
3936 # do not send ACK, active retry send HA event again
3937 self.pg_enable_capture(self.pg_interfaces)
3939 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3940 self.assertEqual(stats[0][0], 3)
3941 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3942 self.assertEqual(stats[0][0], 1)
3943 capture = self.pg3.get_capture(3)
3944 for packet in capture:
3945 self.assertEqual(packet, p)
3947 # session counters refresh
3948 pkts = self.create_stream_out(self.pg1)
3949 self.pg1.add_stream(pkts)
3950 self.pg_enable_capture(self.pg_interfaces)
3952 self.pg0.get_capture(2)
3953 self.vapi.nat_ha_flush()
3954 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
3955 self.assertEqual(stats[0][0], 2)
3956 capture = self.pg3.get_capture(1)
3958 self.assert_packet_checksums_valid(p)
3962 hanat = p[HANATStateSync]
3964 self.logger.error(ppp("Invalid packet:", p))
3967 self.assertEqual(ip.src, self.pg3.local_ip4)
3968 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3969 self.assertEqual(udp.sport, 12345)
3970 self.assertEqual(udp.dport, 12346)
3971 self.assertEqual(hanat.version, 1)
3972 self.assertEqual(hanat.count, 2)
3973 seq = hanat.sequence_number
3974 for event in hanat.events:
3975 self.assertEqual(event.event_type, 3)
3976 self.assertEqual(event.out_addr, self.nat_addr)
3977 self.assertEqual(event.fib_index, 0)
3978 self.assertEqual(event.total_pkts, 2)
3979 self.assertGreater(event.total_bytes, 0)
3981 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3982 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3983 UDP(sport=12346, dport=12345) /
3984 HANATStateSync(sequence_number=seq, flags='ACK'))
3985 self.pg3.add_stream(ack)
3987 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3988 self.assertEqual(stats[0][0], 2)
3990 def test_ha_recv(self):
3991 """ Receive HA session synchronization events (passive) """
3992 self.nat44_add_address(self.nat_addr)
3993 flags = self.config_flags.NAT_IS_INSIDE
3994 self.vapi.nat44_interface_add_del_feature(
3995 sw_if_index=self.pg0.sw_if_index,
3996 flags=flags, is_add=1)
3997 self.vapi.nat44_interface_add_del_feature(
3998 sw_if_index=self.pg1.sw_if_index,
4000 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4003 bind_layers(UDP, HANATStateSync, sport=12345)
4005 self.tcp_port_out = random.randint(1025, 65535)
4006 self.udp_port_out = random.randint(1025, 65535)
4008 # send HA session add events to failover/passive
4009 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4010 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4011 UDP(sport=12346, dport=12345) /
4012 HANATStateSync(sequence_number=1, events=[
4013 Event(event_type='add', protocol='tcp',
4014 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4015 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4016 eh_addr=self.pg1.remote_ip4,
4017 ehn_addr=self.pg1.remote_ip4,
4018 eh_port=self.tcp_external_port,
4019 ehn_port=self.tcp_external_port, fib_index=0),
4020 Event(event_type='add', protocol='udp',
4021 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4022 in_port=self.udp_port_in, out_port=self.udp_port_out,
4023 eh_addr=self.pg1.remote_ip4,
4024 ehn_addr=self.pg1.remote_ip4,
4025 eh_port=self.udp_external_port,
4026 ehn_port=self.udp_external_port, fib_index=0)]))
4028 self.pg3.add_stream(p)
4029 self.pg_enable_capture(self.pg_interfaces)
4032 capture = self.pg3.get_capture(1)
4035 hanat = p[HANATStateSync]
4037 self.logger.error(ppp("Invalid packet:", p))
4040 self.assertEqual(hanat.sequence_number, 1)
4041 self.assertEqual(hanat.flags, 'ACK')
4042 self.assertEqual(hanat.version, 1)
4043 self.assertEqual(hanat.thread_index, 0)
4044 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4045 self.assertEqual(stats[0][0], 1)
4046 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4047 self.assertEqual(stats[0][0], 2)
4048 users = self.statistics.get_counter('/nat44/total-users')
4049 self.assertEqual(users[0][0], 1)
4050 sessions = self.statistics.get_counter('/nat44/total-sessions')
4051 self.assertEqual(sessions[0][0], 2)
4052 users = self.vapi.nat44_user_dump()
4053 self.assertEqual(len(users), 1)
4054 self.assertEqual(str(users[0].ip_address),
4055 self.pg0.remote_ip4)
4056 # there should be 2 sessions created by HA
4057 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4059 self.assertEqual(len(sessions), 2)
4060 for session in sessions:
4061 self.assertEqual(str(session.inside_ip_address),
4062 self.pg0.remote_ip4)
4063 self.assertEqual(str(session.outside_ip_address),
4065 self.assertIn(session.inside_port,
4066 [self.tcp_port_in, self.udp_port_in])
4067 self.assertIn(session.outside_port,
4068 [self.tcp_port_out, self.udp_port_out])
4069 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4071 # send HA session delete event to failover/passive
4072 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4073 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4074 UDP(sport=12346, dport=12345) /
4075 HANATStateSync(sequence_number=2, events=[
4076 Event(event_type='del', protocol='udp',
4077 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4078 in_port=self.udp_port_in, out_port=self.udp_port_out,
4079 eh_addr=self.pg1.remote_ip4,
4080 ehn_addr=self.pg1.remote_ip4,
4081 eh_port=self.udp_external_port,
4082 ehn_port=self.udp_external_port, fib_index=0)]))
4084 self.pg3.add_stream(p)
4085 self.pg_enable_capture(self.pg_interfaces)
4088 capture = self.pg3.get_capture(1)
4091 hanat = p[HANATStateSync]
4093 self.logger.error(ppp("Invalid packet:", p))
4096 self.assertEqual(hanat.sequence_number, 2)
4097 self.assertEqual(hanat.flags, 'ACK')
4098 self.assertEqual(hanat.version, 1)
4099 users = self.vapi.nat44_user_dump()
4100 self.assertEqual(len(users), 1)
4101 self.assertEqual(str(users[0].ip_address),
4102 self.pg0.remote_ip4)
4103 # now we should have only 1 session, 1 deleted by HA
4104 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4106 self.assertEqual(len(sessions), 1)
4107 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4108 self.assertEqual(stats[0][0], 1)
4110 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4111 self.assertEqual(stats, 2)
4113 # send HA session refresh event to failover/passive
4114 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4115 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4116 UDP(sport=12346, dport=12345) /
4117 HANATStateSync(sequence_number=3, events=[
4118 Event(event_type='refresh', protocol='tcp',
4119 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4120 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4121 eh_addr=self.pg1.remote_ip4,
4122 ehn_addr=self.pg1.remote_ip4,
4123 eh_port=self.tcp_external_port,
4124 ehn_port=self.tcp_external_port, fib_index=0,
4125 total_bytes=1024, total_pkts=2)]))
4126 self.pg3.add_stream(p)
4127 self.pg_enable_capture(self.pg_interfaces)
4130 capture = self.pg3.get_capture(1)
4133 hanat = p[HANATStateSync]
4135 self.logger.error(ppp("Invalid packet:", p))
4138 self.assertEqual(hanat.sequence_number, 3)
4139 self.assertEqual(hanat.flags, 'ACK')
4140 self.assertEqual(hanat.version, 1)
4141 users = self.vapi.nat44_user_dump()
4142 self.assertEqual(len(users), 1)
4143 self.assertEqual(str(users[0].ip_address),
4144 self.pg0.remote_ip4)
4145 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4147 self.assertEqual(len(sessions), 1)
4148 session = sessions[0]
4149 self.assertEqual(session.total_bytes, 1024)
4150 self.assertEqual(session.total_pkts, 2)
4151 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4152 self.assertEqual(stats[0][0], 1)
4154 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4155 self.assertEqual(stats, 3)
4157 # send packet to test session created by HA
4158 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4159 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4160 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4161 self.pg1.add_stream(p)
4162 self.pg_enable_capture(self.pg_interfaces)
4164 capture = self.pg0.get_capture(1)
4170 self.logger.error(ppp("Invalid packet:", p))
4173 self.assertEqual(ip.src, self.pg1.remote_ip4)
4174 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4175 self.assertEqual(tcp.sport, self.tcp_external_port)
4176 self.assertEqual(tcp.dport, self.tcp_port_in)
4179 super(TestNAT44, self).tearDown()
4181 self.vapi.cli("clear logging")
4183 def show_commands_at_teardown(self):
4184 self.logger.info(self.vapi.cli("show nat44 addresses"))
4185 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4186 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4187 self.logger.info(self.vapi.cli("show nat44 interface address"))
4188 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4189 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4190 self.logger.info(self.vapi.cli("show nat timeouts"))
4192 self.vapi.cli("show nat addr-port-assignment-alg"))
4193 self.logger.info(self.vapi.cli("show nat ha"))
4196 class TestNAT44EndpointDependent2(MethodHolder):
4197 """ Endpoint-Dependent mapping and filtering test cases """
4200 def setUpConstants(cls):
4201 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4202 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4205 def tearDownClass(cls):
4206 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4209 super(TestNAT44EndpointDependent2, self).tearDown()
4212 def create_and_add_ip4_table(cls, i, table_id):
4213 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4214 i.set_table_ip4(table_id)
4217 def setUpClass(cls):
4218 super(TestNAT44EndpointDependent2, cls).setUpClass()
4220 cls.create_pg_interfaces(range(3))
4221 cls.interfaces = list(cls.pg_interfaces)
4223 cls.create_and_add_ip4_table(cls.pg1, 10)
4225 for i in cls.interfaces:
4230 i.generate_remote_hosts(1)
4231 i.configure_ipv4_neighbors()
4234 super(TestNAT44EndpointDependent2, self).setUp()
4236 nat_config = self.vapi.nat_show_config()
4237 self.assertEqual(1, nat_config.endpoint_dependent)
4239 def nat_add_inside_interface(self, i):
4240 self.vapi.nat44_interface_add_del_feature(
4241 flags=self.config_flags.NAT_IS_INSIDE,
4242 sw_if_index=i.sw_if_index, is_add=1)
4244 def nat_add_outside_interface(self, i):
4245 self.vapi.nat44_interface_add_del_feature(
4246 flags=self.config_flags.NAT_IS_OUTSIDE,
4247 sw_if_index=i.sw_if_index, is_add=1)
4249 def nat_add_interface_address(self, i):
4250 self.nat_addr = i.local_ip4
4251 self.vapi.nat44_add_del_interface_addr(
4252 sw_if_index=i.sw_if_index, is_add=1)
4254 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4255 self.nat_addr = address
4256 self.nat44_add_address(address, vrf_id=vrf_id)
4258 def cli(self, command):
4259 result = self.vapi.cli(command)
4260 self.logger.info(result)
4263 def show_configuration(self):
4264 self.cli("show interface")
4265 self.cli("show interface address")
4266 self.cli("show nat44 addresses")
4267 self.cli("show nat44 interfaces")
4269 def create_tcp_stream(self, in_if, out_if, count):
4271 Create tcp packet stream
4273 :param in_if: Inside interface
4274 :param out_if: Outside interface
4275 :param count: count of packets to generate
4280 for i in range(count):
4281 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4282 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4283 TCP(sport=port + i, dport=20))
4288 def test_session_limit_per_vrf(self):
4291 inside_vrf10 = self.pg1
4296 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4297 # non existing vrf_id makes process core dump
4298 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4300 self.nat_add_inside_interface(inside)
4301 self.nat_add_inside_interface(inside_vrf10)
4302 self.nat_add_outside_interface(outside)
4305 self.nat_add_interface_address(outside)
4307 # BUG: causing core dump - when bad vrf_id is specified
4308 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4310 self.show_configuration()
4312 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4313 inside_vrf10.add_stream(stream)
4315 self.pg_enable_capture(self.pg_interfaces)
4318 capture = outside.get_capture(limit)
4320 stream = self.create_tcp_stream(inside, outside, limit * 2)
4321 inside.add_stream(stream)
4323 self.pg_enable_capture(self.pg_interfaces)
4326 capture = outside.get_capture(len(stream))
4329 class TestNAT44EndpointDependent(MethodHolder):
4330 """ Endpoint-Dependent mapping and filtering test cases """
4333 def setUpConstants(cls):
4334 super(TestNAT44EndpointDependent, cls).setUpConstants()
4335 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4338 def setUpClass(cls):
4339 super(TestNAT44EndpointDependent, cls).setUpClass()
4340 cls.vapi.cli("set log class nat level debug")
4342 cls.tcp_port_in = 6303
4343 cls.tcp_port_out = 6303
4344 cls.udp_port_in = 6304
4345 cls.udp_port_out = 6304
4346 cls.icmp_id_in = 6305
4347 cls.icmp_id_out = 6305
4348 cls.nat_addr = '10.0.0.3'
4349 cls.ipfix_src_port = 4739
4350 cls.ipfix_domain_id = 1
4351 cls.tcp_external_port = 80
4353 cls.create_pg_interfaces(range(9))
4354 cls.interfaces = list(cls.pg_interfaces[0:3])
4356 for i in cls.interfaces:
4361 cls.pg0.generate_remote_hosts(3)
4362 cls.pg0.configure_ipv4_neighbors()
4366 cls.pg4.generate_remote_hosts(2)
4367 cls.pg4.config_ip4()
4368 cls.vapi.sw_interface_add_del_address(
4369 sw_if_index=cls.pg4.sw_if_index,
4370 prefix="10.0.0.1/24")
4373 cls.pg4.resolve_arp()
4374 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4375 cls.pg4.resolve_arp()
4377 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4378 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4380 cls.pg5._local_ip4 = "10.1.1.1"
4381 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4382 cls.pg5.set_table_ip4(1)
4383 cls.pg5.config_ip4()
4385 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4386 [VppRoutePath("0.0.0.0",
4387 cls.pg5.sw_if_index)],
4392 cls.pg6._local_ip4 = "10.1.2.1"
4393 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4394 cls.pg6.set_table_ip4(1)
4395 cls.pg6.config_ip4()
4398 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4399 [VppRoutePath("0.0.0.0",
4400 cls.pg6.sw_if_index)],
4403 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4404 [VppRoutePath("0.0.0.0",
4409 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4410 [VppRoutePath("0.0.0.0", 0xffffffff,
4414 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4415 [VppRoutePath(cls.pg1.local_ip4,
4416 cls.pg1.sw_if_index)],
4423 cls.pg5.resolve_arp()
4424 cls.pg6.resolve_arp()
4427 cls.pg7.config_ip4()
4428 cls.pg7.resolve_arp()
4429 cls.pg7.generate_remote_hosts(3)
4430 cls.pg7.configure_ipv4_neighbors()
4433 cls.pg8.config_ip4()
4434 cls.pg8.resolve_arp()
4437 super(TestNAT44EndpointDependent, self).setUp()
4438 self.vapi.nat_set_timeouts(
4439 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4442 def tearDownClass(cls):
4443 super(TestNAT44EndpointDependent, cls).tearDownClass()
4445 def test_frag_in_order(self):
4446 """ NAT44 translate fragments arriving in order """
4447 self.nat44_add_address(self.nat_addr)
4448 flags = self.config_flags.NAT_IS_INSIDE
4449 self.vapi.nat44_interface_add_del_feature(
4450 sw_if_index=self.pg0.sw_if_index,
4451 flags=flags, is_add=1)
4452 self.vapi.nat44_interface_add_del_feature(
4453 sw_if_index=self.pg1.sw_if_index,
4455 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
4456 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
4457 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
4459 def test_frag_in_order_dont_translate(self):
4460 """ NAT44 don't translate fragments arriving in order """
4461 flags = self.config_flags.NAT_IS_INSIDE
4462 self.vapi.nat44_interface_add_del_feature(
4463 sw_if_index=self.pg0.sw_if_index,
4464 flags=flags, is_add=1)
4465 self.vapi.nat44_interface_add_del_feature(
4466 sw_if_index=self.pg1.sw_if_index,
4468 self.vapi.nat44_forwarding_enable_disable(enable=True)
4469 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4471 def test_frag_out_of_order(self):
4472 """ NAT44 translate fragments arriving out of order """
4473 self.nat44_add_address(self.nat_addr)
4474 flags = self.config_flags.NAT_IS_INSIDE
4475 self.vapi.nat44_interface_add_del_feature(
4476 sw_if_index=self.pg0.sw_if_index,
4477 flags=flags, is_add=1)
4478 self.vapi.nat44_interface_add_del_feature(
4479 sw_if_index=self.pg1.sw_if_index,
4481 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
4482 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
4483 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
4485 def test_frag_out_of_order_dont_translate(self):
4486 """ NAT44 don't translate fragments arriving out of order """
4487 flags = self.config_flags.NAT_IS_INSIDE
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_forwarding_enable_disable(enable=True)
4495 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4497 def test_frag_in_order_in_plus_out(self):
4498 """ in+out interface fragments in order """
4499 flags = self.config_flags.NAT_IS_INSIDE
4500 self.vapi.nat44_interface_add_del_feature(
4501 sw_if_index=self.pg0.sw_if_index,
4503 self.vapi.nat44_interface_add_del_feature(
4504 sw_if_index=self.pg0.sw_if_index,
4505 flags=flags, is_add=1)
4506 self.vapi.nat44_interface_add_del_feature(
4507 sw_if_index=self.pg1.sw_if_index,
4509 self.vapi.nat44_interface_add_del_feature(
4510 sw_if_index=self.pg1.sw_if_index,
4511 flags=flags, is_add=1)
4513 self.server = self.pg1.remote_hosts[0]
4515 self.server_in_addr = self.server.ip4
4516 self.server_out_addr = '11.11.11.11'
4517 self.server_in_port = random.randint(1025, 65535)
4518 self.server_out_port = random.randint(1025, 65535)
4520 self.nat44_add_address(self.server_out_addr)
4522 # add static mappings for server
4523 self.nat44_add_static_mapping(self.server_in_addr,
4524 self.server_out_addr,
4525 self.server_in_port,
4526 self.server_out_port,
4527 proto=IP_PROTOS.tcp)
4528 self.nat44_add_static_mapping(self.server_in_addr,
4529 self.server_out_addr,
4530 self.server_in_port,
4531 self.server_out_port,
4532 proto=IP_PROTOS.udp)
4533 self.nat44_add_static_mapping(self.server_in_addr,
4534 self.server_out_addr,
4535 proto=IP_PROTOS.icmp)
4537 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4538 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4539 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4541 def test_frag_out_of_order_in_plus_out(self):
4542 """ in+out interface fragments out of order """
4543 flags = self.config_flags.NAT_IS_INSIDE
4544 self.vapi.nat44_interface_add_del_feature(
4545 sw_if_index=self.pg0.sw_if_index,
4547 self.vapi.nat44_interface_add_del_feature(
4548 sw_if_index=self.pg0.sw_if_index,
4549 flags=flags, is_add=1)
4550 self.vapi.nat44_interface_add_del_feature(
4551 sw_if_index=self.pg1.sw_if_index,
4553 self.vapi.nat44_interface_add_del_feature(
4554 sw_if_index=self.pg1.sw_if_index,
4555 flags=flags, is_add=1)
4557 self.server = self.pg1.remote_hosts[0]
4559 self.server_in_addr = self.server.ip4
4560 self.server_out_addr = '11.11.11.11'
4561 self.server_in_port = random.randint(1025, 65535)
4562 self.server_out_port = random.randint(1025, 65535)
4564 self.nat44_add_address(self.server_out_addr)
4566 # add static mappings for server
4567 self.nat44_add_static_mapping(self.server_in_addr,
4568 self.server_out_addr,
4569 self.server_in_port,
4570 self.server_out_port,
4571 proto=IP_PROTOS.tcp)
4572 self.nat44_add_static_mapping(self.server_in_addr,
4573 self.server_out_addr,
4574 self.server_in_port,
4575 self.server_out_port,
4576 proto=IP_PROTOS.udp)
4577 self.nat44_add_static_mapping(self.server_in_addr,
4578 self.server_out_addr,
4579 proto=IP_PROTOS.icmp)
4581 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4582 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4583 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4585 def test_reass_hairpinning(self):
4586 """ NAT44 fragments hairpinning """
4587 self.server = self.pg0.remote_hosts[1]
4588 self.host_in_port = random.randint(1025, 65535)
4589 self.server_in_port = random.randint(1025, 65535)
4590 self.server_out_port = random.randint(1025, 65535)
4592 self.nat44_add_address(self.nat_addr)
4593 flags = self.config_flags.NAT_IS_INSIDE
4594 self.vapi.nat44_interface_add_del_feature(
4595 sw_if_index=self.pg0.sw_if_index,
4596 flags=flags, is_add=1)
4597 self.vapi.nat44_interface_add_del_feature(
4598 sw_if_index=self.pg1.sw_if_index,
4600 # add static mapping for server
4601 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4602 self.server_in_port,
4603 self.server_out_port,
4604 proto=IP_PROTOS.tcp)
4605 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4606 self.server_in_port,
4607 self.server_out_port,
4608 proto=IP_PROTOS.udp)
4609 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4611 self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
4612 self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
4613 self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
4615 def test_clear_sessions(self):
4616 """ NAT44 ED session clearing test """
4618 self.nat44_add_address(self.nat_addr)
4619 flags = self.config_flags.NAT_IS_INSIDE
4620 self.vapi.nat44_interface_add_del_feature(
4621 sw_if_index=self.pg0.sw_if_index,
4622 flags=flags, is_add=1)
4623 self.vapi.nat44_interface_add_del_feature(
4624 sw_if_index=self.pg1.sw_if_index,
4627 nat_config = self.vapi.nat_show_config()
4628 self.assertEqual(1, nat_config.endpoint_dependent)
4630 pkts = self.create_stream_in(self.pg0, self.pg1)
4631 self.pg0.add_stream(pkts)
4632 self.pg_enable_capture(self.pg_interfaces)
4634 capture = self.pg1.get_capture(len(pkts))
4635 self.verify_capture_out(capture, ignore_port=True)
4637 sessions = self.statistics.get_counter('/nat44/total-sessions')
4638 self.assertTrue(sessions[0][0] > 0)
4639 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4641 # just for testing purposes
4642 self.logger.info(self.vapi.cli("show nat44 summary"))
4644 self.vapi.cli("clear nat44 sessions")
4646 self.logger.info(self.vapi.cli("show nat44 summary"))
4648 sessions = self.statistics.get_counter('/nat44/total-sessions')
4649 self.assertEqual(sessions[0][0], 0)
4650 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4652 def test_dynamic(self):
4653 """ NAT44 dynamic translation test """
4655 self.nat44_add_address(self.nat_addr)
4656 flags = self.config_flags.NAT_IS_INSIDE
4657 self.vapi.nat44_interface_add_del_feature(
4658 sw_if_index=self.pg0.sw_if_index,
4659 flags=flags, is_add=1)
4660 self.vapi.nat44_interface_add_del_feature(
4661 sw_if_index=self.pg1.sw_if_index,
4664 nat_config = self.vapi.nat_show_config()
4665 self.assertEqual(1, nat_config.endpoint_dependent)
4668 tcpn = self.statistics.get_err_counter(
4669 '/err/nat44-ed-in2out-slowpath/TCP packets')
4670 udpn = self.statistics.get_err_counter(
4671 '/err/nat44-ed-in2out-slowpath/UDP packets')
4672 icmpn = self.statistics.get_err_counter(
4673 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4674 totaln = self.statistics.get_err_counter(
4675 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4677 pkts = self.create_stream_in(self.pg0, self.pg1)
4678 self.pg0.add_stream(pkts)
4679 self.pg_enable_capture(self.pg_interfaces)
4681 capture = self.pg1.get_capture(len(pkts))
4682 self.verify_capture_out(capture, ignore_port=True)
4684 err = self.statistics.get_err_counter(
4685 '/err/nat44-ed-in2out-slowpath/TCP packets')
4686 self.assertEqual(err - tcpn, 2)
4687 err = self.statistics.get_err_counter(
4688 '/err/nat44-ed-in2out-slowpath/UDP packets')
4689 self.assertEqual(err - udpn, 1)
4690 err = self.statistics.get_err_counter(
4691 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4692 self.assertEqual(err - icmpn, 1)
4693 err = self.statistics.get_err_counter(
4694 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4695 self.assertEqual(err - totaln, 4)
4698 tcpn = self.statistics.get_err_counter(
4699 '/err/nat44-ed-out2in/TCP packets')
4700 udpn = self.statistics.get_err_counter(
4701 '/err/nat44-ed-out2in/UDP packets')
4702 icmpn = self.statistics.get_err_counter(
4703 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4704 totaln = self.statistics.get_err_counter(
4705 '/err/nat44-ed-out2in/good out2in packets processed')
4707 pkts = self.create_stream_out(self.pg1)
4708 self.pg1.add_stream(pkts)
4709 self.pg_enable_capture(self.pg_interfaces)
4711 capture = self.pg0.get_capture(len(pkts))
4712 self.verify_capture_in(capture, self.pg0)
4714 err = self.statistics.get_err_counter(
4715 '/err/nat44-ed-out2in/TCP packets')
4716 self.assertEqual(err - tcpn, 2)
4717 err = self.statistics.get_err_counter(
4718 '/err/nat44-ed-out2in/UDP packets')
4719 self.assertEqual(err - udpn, 1)
4720 err = self.statistics.get_err_counter(
4721 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4722 self.assertEqual(err - icmpn, 1)
4723 err = self.statistics.get_err_counter(
4724 '/err/nat44-ed-out2in/good out2in packets processed')
4725 self.assertEqual(err - totaln, 3)
4727 sessions = self.statistics.get_counter('/nat44/total-sessions')
4728 self.assertEqual(sessions[0][0], 3)
4730 def test_dynamic_out_of_ports(self):
4731 """ NAT44 dynamic translation test: out of ports """
4733 flags = self.config_flags.NAT_IS_INSIDE
4734 self.vapi.nat44_interface_add_del_feature(
4735 sw_if_index=self.pg0.sw_if_index,
4736 flags=flags, is_add=1)
4737 self.vapi.nat44_interface_add_del_feature(
4738 sw_if_index=self.pg1.sw_if_index,
4741 nat_config = self.vapi.nat_show_config()
4742 self.assertEqual(1, nat_config.endpoint_dependent)
4744 # in2out and no NAT addresses added
4745 err_old = self.statistics.get_err_counter(
4746 '/err/nat44-ed-in2out-slowpath/out of ports')
4748 pkts = self.create_stream_in(self.pg0, self.pg1)
4749 self.pg0.add_stream(pkts)
4750 self.pg_enable_capture(self.pg_interfaces)
4752 self.pg1.get_capture(0, timeout=1)
4754 err_new = self.statistics.get_err_counter(
4755 '/err/nat44-ed-in2out-slowpath/out of ports')
4757 self.assertEqual(err_new - err_old, len(pkts))
4759 # in2out after NAT addresses added
4760 self.nat44_add_address(self.nat_addr)
4762 err_old = self.statistics.get_err_counter(
4763 '/err/nat44-ed-in2out-slowpath/out of ports')
4765 pkts = self.create_stream_in(self.pg0, self.pg1)
4766 self.pg0.add_stream(pkts)
4767 self.pg_enable_capture(self.pg_interfaces)
4769 capture = self.pg1.get_capture(len(pkts))
4770 self.verify_capture_out(capture, ignore_port=True)
4772 err_new = self.statistics.get_err_counter(
4773 '/err/nat44-ed-in2out-slowpath/out of ports')
4775 self.assertEqual(err_new, err_old)
4777 def test_dynamic_output_feature_vrf(self):
4778 """ NAT44 dynamic translation test: output-feature, VRF"""
4780 # other then default (0)
4783 self.nat44_add_address(self.nat_addr)
4784 flags = self.config_flags.NAT_IS_INSIDE
4785 self.vapi.nat44_interface_add_del_output_feature(
4786 sw_if_index=self.pg7.sw_if_index,
4787 flags=flags, is_add=1)
4788 self.vapi.nat44_interface_add_del_output_feature(
4789 sw_if_index=self.pg8.sw_if_index,
4793 self.vapi.ip_table_add_del(is_add=1,
4794 table={'table_id': new_vrf_id})
4796 self.pg7.unconfig_ip4()
4797 self.pg7.set_table_ip4(new_vrf_id)
4798 self.pg7.config_ip4()
4799 self.pg7.resolve_arp()
4801 self.pg8.unconfig_ip4()
4802 self.pg8.set_table_ip4(new_vrf_id)
4803 self.pg8.config_ip4()
4804 self.pg8.resolve_arp()
4806 nat_config = self.vapi.nat_show_config()
4807 self.assertEqual(1, nat_config.endpoint_dependent)
4810 tcpn = self.statistics.get_err_counter(
4811 '/err/nat44-ed-in2out-slowpath/TCP packets')
4812 udpn = self.statistics.get_err_counter(
4813 '/err/nat44-ed-in2out-slowpath/UDP packets')
4814 icmpn = self.statistics.get_err_counter(
4815 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4816 totaln = self.statistics.get_err_counter(
4817 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4819 pkts = self.create_stream_in(self.pg7, self.pg8)
4820 self.pg7.add_stream(pkts)
4821 self.pg_enable_capture(self.pg_interfaces)
4823 capture = self.pg8.get_capture(len(pkts))
4824 self.verify_capture_out(capture, ignore_port=True)
4826 err = self.statistics.get_err_counter(
4827 '/err/nat44-ed-in2out-slowpath/TCP packets')
4828 self.assertEqual(err - tcpn, 2)
4829 err = self.statistics.get_err_counter(
4830 '/err/nat44-ed-in2out-slowpath/UDP packets')
4831 self.assertEqual(err - udpn, 1)
4832 err = self.statistics.get_err_counter(
4833 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4834 self.assertEqual(err - icmpn, 1)
4835 err = self.statistics.get_err_counter(
4836 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4837 self.assertEqual(err - totaln, 4)
4840 tcpn = self.statistics.get_err_counter(
4841 '/err/nat44-ed-out2in/TCP packets')
4842 udpn = self.statistics.get_err_counter(
4843 '/err/nat44-ed-out2in/UDP packets')
4844 icmpn = self.statistics.get_err_counter(
4845 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4846 totaln = self.statistics.get_err_counter(
4847 '/err/nat44-ed-out2in/good out2in packets processed')
4849 pkts = self.create_stream_out(self.pg8)
4850 self.pg8.add_stream(pkts)
4851 self.pg_enable_capture(self.pg_interfaces)
4853 capture = self.pg7.get_capture(len(pkts))
4854 self.verify_capture_in(capture, self.pg7)
4856 err = self.statistics.get_err_counter(
4857 '/err/nat44-ed-out2in/TCP packets')
4858 self.assertEqual(err - tcpn, 2)
4859 err = self.statistics.get_err_counter(
4860 '/err/nat44-ed-out2in/UDP packets')
4861 self.assertEqual(err - udpn, 1)
4862 err = self.statistics.get_err_counter(
4863 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4864 self.assertEqual(err - icmpn, 1)
4865 err = self.statistics.get_err_counter(
4866 '/err/nat44-ed-out2in/good out2in packets processed')
4867 self.assertEqual(err - totaln, 3)
4869 sessions = self.statistics.get_counter('/nat44/total-sessions')
4870 self.assertEqual(sessions[0][0], 3)
4873 self.pg7.unconfig_ip4()
4874 self.pg7.set_table_ip4(1)
4875 self.pg7.config_ip4()
4876 self.pg7.resolve_arp()
4878 self.pg8.unconfig_ip4()
4879 self.pg8.set_table_ip4(1)
4880 self.pg8.config_ip4()
4881 self.pg8.resolve_arp()
4883 self.vapi.ip_table_add_del(is_add=0,
4884 table={'table_id': new_vrf_id})
4886 def test_forwarding(self):
4887 """ NAT44 forwarding test """
4889 flags = self.config_flags.NAT_IS_INSIDE
4890 self.vapi.nat44_interface_add_del_feature(
4891 sw_if_index=self.pg0.sw_if_index,
4892 flags=flags, is_add=1)
4893 self.vapi.nat44_interface_add_del_feature(
4894 sw_if_index=self.pg1.sw_if_index,
4896 self.vapi.nat44_forwarding_enable_disable(enable=1)
4898 real_ip = self.pg0.remote_ip4
4899 alias_ip = self.nat_addr
4900 flags = self.config_flags.NAT_IS_ADDR_ONLY
4901 self.vapi.nat44_add_del_static_mapping(is_add=1,
4902 local_ip_address=real_ip,
4903 external_ip_address=alias_ip,
4904 external_sw_if_index=0xFFFFFFFF,
4908 # in2out - static mapping match
4910 pkts = self.create_stream_out(self.pg1)
4911 self.pg1.add_stream(pkts)
4912 self.pg_enable_capture(self.pg_interfaces)
4914 capture = self.pg0.get_capture(len(pkts))
4915 self.verify_capture_in(capture, self.pg0)
4917 pkts = self.create_stream_in(self.pg0, self.pg1)
4918 self.pg0.add_stream(pkts)
4919 self.pg_enable_capture(self.pg_interfaces)
4921 capture = self.pg1.get_capture(len(pkts))
4922 self.verify_capture_out(capture, same_port=True)
4924 # in2out - no static mapping match
4926 host0 = self.pg0.remote_hosts[0]
4927 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4929 pkts = self.create_stream_out(self.pg1,
4930 dst_ip=self.pg0.remote_ip4,
4931 use_inside_ports=True)
4932 self.pg1.add_stream(pkts)
4933 self.pg_enable_capture(self.pg_interfaces)
4935 capture = self.pg0.get_capture(len(pkts))
4936 self.verify_capture_in(capture, self.pg0)
4938 pkts = self.create_stream_in(self.pg0, self.pg1)
4939 self.pg0.add_stream(pkts)
4940 self.pg_enable_capture(self.pg_interfaces)
4942 capture = self.pg1.get_capture(len(pkts))
4943 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4946 self.pg0.remote_hosts[0] = host0
4948 user = self.pg0.remote_hosts[1]
4949 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4950 self.assertEqual(len(sessions), 3)
4951 self.assertTrue(sessions[0].flags &
4952 self.config_flags.NAT_IS_EXT_HOST_VALID)
4953 self.vapi.nat44_del_session(
4954 address=sessions[0].inside_ip_address,
4955 port=sessions[0].inside_port,
4956 protocol=sessions[0].protocol,
4957 flags=(self.config_flags.NAT_IS_INSIDE |
4958 self.config_flags.NAT_IS_EXT_HOST_VALID),
4959 ext_host_address=sessions[0].ext_host_address,
4960 ext_host_port=sessions[0].ext_host_port)
4961 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4962 self.assertEqual(len(sessions), 2)
4965 self.vapi.nat44_forwarding_enable_disable(enable=0)
4966 flags = self.config_flags.NAT_IS_ADDR_ONLY
4967 self.vapi.nat44_add_del_static_mapping(
4969 local_ip_address=real_ip,
4970 external_ip_address=alias_ip,
4971 external_sw_if_index=0xFFFFFFFF,
4974 def test_static_lb(self):
4975 """ NAT44 local service load balancing """
4976 external_addr_n = self.nat_addr
4979 server1 = self.pg0.remote_hosts[0]
4980 server2 = self.pg0.remote_hosts[1]
4982 locals = [{'addr': server1.ip4,
4986 {'addr': server2.ip4,
4991 self.nat44_add_address(self.nat_addr)
4992 self.vapi.nat44_add_del_lb_static_mapping(
4994 external_addr=external_addr_n,
4995 external_port=external_port,
4996 protocol=IP_PROTOS.tcp,
4997 local_num=len(locals),
4999 flags = self.config_flags.NAT_IS_INSIDE
5000 self.vapi.nat44_interface_add_del_feature(
5001 sw_if_index=self.pg0.sw_if_index,
5002 flags=flags, is_add=1)
5003 self.vapi.nat44_interface_add_del_feature(
5004 sw_if_index=self.pg1.sw_if_index,
5007 # from client to service
5008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5009 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5010 TCP(sport=12345, dport=external_port))
5011 self.pg1.add_stream(p)
5012 self.pg_enable_capture(self.pg_interfaces)
5014 capture = self.pg0.get_capture(1)
5020 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5021 if ip.dst == server1.ip4:
5025 self.assertEqual(tcp.dport, local_port)
5026 self.assert_packet_checksums_valid(p)
5028 self.logger.error(ppp("Unexpected or invalid packet:", p))
5031 # from service back to client
5032 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5033 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5034 TCP(sport=local_port, dport=12345))
5035 self.pg0.add_stream(p)
5036 self.pg_enable_capture(self.pg_interfaces)
5038 capture = self.pg1.get_capture(1)
5043 self.assertEqual(ip.src, self.nat_addr)
5044 self.assertEqual(tcp.sport, external_port)
5045 self.assert_packet_checksums_valid(p)
5047 self.logger.error(ppp("Unexpected or invalid packet:", p))
5050 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5051 self.assertEqual(len(sessions), 1)
5052 self.assertTrue(sessions[0].flags &
5053 self.config_flags.NAT_IS_EXT_HOST_VALID)
5054 self.vapi.nat44_del_session(
5055 address=sessions[0].inside_ip_address,
5056 port=sessions[0].inside_port,
5057 protocol=sessions[0].protocol,
5058 flags=(self.config_flags.NAT_IS_INSIDE |
5059 self.config_flags.NAT_IS_EXT_HOST_VALID),
5060 ext_host_address=sessions[0].ext_host_address,
5061 ext_host_port=sessions[0].ext_host_port)
5062 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5063 self.assertEqual(len(sessions), 0)
5065 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5066 def test_static_lb_multi_clients(self):
5067 """ NAT44 local service load balancing - multiple clients"""
5069 external_addr = self.nat_addr
5072 server1 = self.pg0.remote_hosts[0]
5073 server2 = self.pg0.remote_hosts[1]
5074 server3 = self.pg0.remote_hosts[2]
5076 locals = [{'addr': server1.ip4,
5080 {'addr': server2.ip4,
5085 self.nat44_add_address(self.nat_addr)
5086 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5087 external_addr=external_addr,
5088 external_port=external_port,
5089 protocol=IP_PROTOS.tcp,
5090 local_num=len(locals),
5092 flags = self.config_flags.NAT_IS_INSIDE
5093 self.vapi.nat44_interface_add_del_feature(
5094 sw_if_index=self.pg0.sw_if_index,
5095 flags=flags, is_add=1)
5096 self.vapi.nat44_interface_add_del_feature(
5097 sw_if_index=self.pg1.sw_if_index,
5102 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5104 for client in clients:
5105 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5106 IP(src=client, dst=self.nat_addr) /
5107 TCP(sport=12345, dport=external_port))
5109 self.pg1.add_stream(pkts)
5110 self.pg_enable_capture(self.pg_interfaces)
5112 capture = self.pg0.get_capture(len(pkts))
5114 if p[IP].dst == server1.ip4:
5118 self.assertGreater(server1_n, server2_n)
5121 'addr': server3.ip4,
5128 self.vapi.nat44_lb_static_mapping_add_del_local(
5130 external_addr=external_addr,
5131 external_port=external_port,
5133 protocol=IP_PROTOS.tcp)
5137 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5139 for client in clients:
5140 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5141 IP(src=client, dst=self.nat_addr) /
5142 TCP(sport=12346, dport=external_port))
5144 self.assertGreater(len(pkts), 0)
5145 self.pg1.add_stream(pkts)
5146 self.pg_enable_capture(self.pg_interfaces)
5148 capture = self.pg0.get_capture(len(pkts))
5150 if p[IP].dst == server1.ip4:
5152 elif p[IP].dst == server2.ip4:
5156 self.assertGreater(server1_n, 0)
5157 self.assertGreater(server2_n, 0)
5158 self.assertGreater(server3_n, 0)
5161 'addr': server2.ip4,
5167 # remove one back-end
5168 self.vapi.nat44_lb_static_mapping_add_del_local(
5170 external_addr=external_addr,
5171 external_port=external_port,
5173 protocol=IP_PROTOS.tcp)
5177 self.pg1.add_stream(pkts)
5178 self.pg_enable_capture(self.pg_interfaces)
5180 capture = self.pg0.get_capture(len(pkts))
5182 if p[IP].dst == server1.ip4:
5184 elif p[IP].dst == server2.ip4:
5188 self.assertGreater(server1_n, 0)
5189 self.assertEqual(server2_n, 0)
5190 self.assertGreater(server3_n, 0)
5192 def test_static_lb_2(self):
5193 """ NAT44 local service load balancing (asymmetrical rule) """
5194 external_addr = self.nat_addr
5197 server1 = self.pg0.remote_hosts[0]
5198 server2 = self.pg0.remote_hosts[1]
5200 locals = [{'addr': server1.ip4,
5204 {'addr': server2.ip4,
5209 self.vapi.nat44_forwarding_enable_disable(enable=1)
5210 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5211 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5212 external_addr=external_addr,
5213 external_port=external_port,
5214 protocol=IP_PROTOS.tcp,
5215 local_num=len(locals),
5217 flags = self.config_flags.NAT_IS_INSIDE
5218 self.vapi.nat44_interface_add_del_feature(
5219 sw_if_index=self.pg0.sw_if_index,
5220 flags=flags, is_add=1)
5221 self.vapi.nat44_interface_add_del_feature(
5222 sw_if_index=self.pg1.sw_if_index,
5225 # from client to service
5226 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5227 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5228 TCP(sport=12345, dport=external_port))
5229 self.pg1.add_stream(p)
5230 self.pg_enable_capture(self.pg_interfaces)
5232 capture = self.pg0.get_capture(1)
5238 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5239 if ip.dst == server1.ip4:
5243 self.assertEqual(tcp.dport, local_port)
5244 self.assert_packet_checksums_valid(p)
5246 self.logger.error(ppp("Unexpected or invalid packet:", p))
5249 # from service back to client
5250 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5251 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5252 TCP(sport=local_port, dport=12345))
5253 self.pg0.add_stream(p)
5254 self.pg_enable_capture(self.pg_interfaces)
5256 capture = self.pg1.get_capture(1)
5261 self.assertEqual(ip.src, self.nat_addr)
5262 self.assertEqual(tcp.sport, external_port)
5263 self.assert_packet_checksums_valid(p)
5265 self.logger.error(ppp("Unexpected or invalid packet:", p))
5268 # from client to server (no translation)
5269 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5270 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5271 TCP(sport=12346, dport=local_port))
5272 self.pg1.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5275 capture = self.pg0.get_capture(1)
5281 self.assertEqual(ip.dst, server1.ip4)
5282 self.assertEqual(tcp.dport, local_port)
5283 self.assert_packet_checksums_valid(p)
5285 self.logger.error(ppp("Unexpected or invalid packet:", p))
5288 # from service back to client (no translation)
5289 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5290 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5291 TCP(sport=local_port, dport=12346))
5292 self.pg0.add_stream(p)
5293 self.pg_enable_capture(self.pg_interfaces)
5295 capture = self.pg1.get_capture(1)
5300 self.assertEqual(ip.src, server1.ip4)
5301 self.assertEqual(tcp.sport, local_port)
5302 self.assert_packet_checksums_valid(p)
5304 self.logger.error(ppp("Unexpected or invalid packet:", p))
5307 def test_lb_affinity(self):
5308 """ NAT44 local service load balancing affinity """
5309 external_addr = self.nat_addr
5312 server1 = self.pg0.remote_hosts[0]
5313 server2 = self.pg0.remote_hosts[1]
5315 locals = [{'addr': server1.ip4,
5319 {'addr': server2.ip4,
5324 self.nat44_add_address(self.nat_addr)
5325 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5326 external_addr=external_addr,
5327 external_port=external_port,
5328 protocol=IP_PROTOS.tcp,
5330 local_num=len(locals),
5332 flags = self.config_flags.NAT_IS_INSIDE
5333 self.vapi.nat44_interface_add_del_feature(
5334 sw_if_index=self.pg0.sw_if_index,
5335 flags=flags, is_add=1)
5336 self.vapi.nat44_interface_add_del_feature(
5337 sw_if_index=self.pg1.sw_if_index,
5340 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5341 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5342 TCP(sport=1025, dport=external_port))
5343 self.pg1.add_stream(p)
5344 self.pg_enable_capture(self.pg_interfaces)
5346 capture = self.pg0.get_capture(1)
5347 backend = capture[0][IP].dst
5349 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5350 self.assertEqual(len(sessions), 1)
5351 self.assertTrue(sessions[0].flags &
5352 self.config_flags.NAT_IS_EXT_HOST_VALID)
5353 self.vapi.nat44_del_session(
5354 address=sessions[0].inside_ip_address,
5355 port=sessions[0].inside_port,
5356 protocol=sessions[0].protocol,
5357 flags=(self.config_flags.NAT_IS_INSIDE |
5358 self.config_flags.NAT_IS_EXT_HOST_VALID),
5359 ext_host_address=sessions[0].ext_host_address,
5360 ext_host_port=sessions[0].ext_host_port)
5363 for port in range(1030, 1100):
5364 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5365 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5366 TCP(sport=port, dport=external_port))
5368 self.pg1.add_stream(pkts)
5369 self.pg_enable_capture(self.pg_interfaces)
5371 capture = self.pg0.get_capture(len(pkts))
5373 self.assertEqual(p[IP].dst, backend)
5375 def test_unknown_proto(self):
5376 """ NAT44 translate packet with unknown protocol """
5377 self.nat44_add_address(self.nat_addr)
5378 flags = self.config_flags.NAT_IS_INSIDE
5379 self.vapi.nat44_interface_add_del_feature(
5380 sw_if_index=self.pg0.sw_if_index,
5381 flags=flags, is_add=1)
5382 self.vapi.nat44_interface_add_del_feature(
5383 sw_if_index=self.pg1.sw_if_index,
5387 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5388 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5389 TCP(sport=self.tcp_port_in, dport=20))
5390 self.pg0.add_stream(p)
5391 self.pg_enable_capture(self.pg_interfaces)
5393 p = self.pg1.get_capture(1)
5395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5396 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5398 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5399 TCP(sport=1234, dport=1234))
5400 self.pg0.add_stream(p)
5401 self.pg_enable_capture(self.pg_interfaces)
5403 p = self.pg1.get_capture(1)
5406 self.assertEqual(packet[IP].src, self.nat_addr)
5407 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5408 self.assertEqual(packet.haslayer(GRE), 1)
5409 self.assert_packet_checksums_valid(packet)
5411 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5415 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5416 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5418 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5419 TCP(sport=1234, dport=1234))
5420 self.pg1.add_stream(p)
5421 self.pg_enable_capture(self.pg_interfaces)
5423 p = self.pg0.get_capture(1)
5426 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5427 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5428 self.assertEqual(packet.haslayer(GRE), 1)
5429 self.assert_packet_checksums_valid(packet)
5431 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5434 def test_hairpinning_unknown_proto(self):
5435 """ NAT44 translate packet with unknown protocol - hairpinning """
5436 host = self.pg0.remote_hosts[0]
5437 server = self.pg0.remote_hosts[1]
5439 server_out_port = 8765
5440 server_nat_ip = "10.0.0.11"
5442 self.nat44_add_address(self.nat_addr)
5443 flags = self.config_flags.NAT_IS_INSIDE
5444 self.vapi.nat44_interface_add_del_feature(
5445 sw_if_index=self.pg0.sw_if_index,
5446 flags=flags, is_add=1)
5447 self.vapi.nat44_interface_add_del_feature(
5448 sw_if_index=self.pg1.sw_if_index,
5451 # add static mapping for server
5452 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5455 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5456 IP(src=host.ip4, dst=server_nat_ip) /
5457 TCP(sport=host_in_port, dport=server_out_port))
5458 self.pg0.add_stream(p)
5459 self.pg_enable_capture(self.pg_interfaces)
5461 self.pg0.get_capture(1)
5463 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5464 IP(src=host.ip4, dst=server_nat_ip) /
5466 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5467 TCP(sport=1234, dport=1234))
5468 self.pg0.add_stream(p)
5469 self.pg_enable_capture(self.pg_interfaces)
5471 p = self.pg0.get_capture(1)
5474 self.assertEqual(packet[IP].src, self.nat_addr)
5475 self.assertEqual(packet[IP].dst, server.ip4)
5476 self.assertEqual(packet.haslayer(GRE), 1)
5477 self.assert_packet_checksums_valid(packet)
5479 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5483 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5484 IP(src=server.ip4, dst=self.nat_addr) /
5486 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5487 TCP(sport=1234, dport=1234))
5488 self.pg0.add_stream(p)
5489 self.pg_enable_capture(self.pg_interfaces)
5491 p = self.pg0.get_capture(1)
5494 self.assertEqual(packet[IP].src, server_nat_ip)
5495 self.assertEqual(packet[IP].dst, host.ip4)
5496 self.assertEqual(packet.haslayer(GRE), 1)
5497 self.assert_packet_checksums_valid(packet)
5499 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5502 def test_output_feature_and_service(self):
5503 """ NAT44 interface output feature and services """
5504 external_addr = '1.2.3.4'
5508 self.vapi.nat44_forwarding_enable_disable(enable=1)
5509 self.nat44_add_address(self.nat_addr)
5510 flags = self.config_flags.NAT_IS_ADDR_ONLY
5511 self.vapi.nat44_add_del_identity_mapping(
5512 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5513 flags=flags, is_add=1)
5514 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5515 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5516 local_port, external_port,
5517 proto=IP_PROTOS.tcp, flags=flags)
5518 flags = self.config_flags.NAT_IS_INSIDE
5519 self.vapi.nat44_interface_add_del_feature(
5520 sw_if_index=self.pg0.sw_if_index,
5522 self.vapi.nat44_interface_add_del_feature(
5523 sw_if_index=self.pg0.sw_if_index,
5524 flags=flags, is_add=1)
5525 self.vapi.nat44_interface_add_del_output_feature(
5527 sw_if_index=self.pg1.sw_if_index)
5529 # from client to service
5530 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5531 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5532 TCP(sport=12345, dport=external_port))
5533 self.pg1.add_stream(p)
5534 self.pg_enable_capture(self.pg_interfaces)
5536 capture = self.pg0.get_capture(1)
5541 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5542 self.assertEqual(tcp.dport, local_port)
5543 self.assert_packet_checksums_valid(p)
5545 self.logger.error(ppp("Unexpected or invalid packet:", p))
5548 # from service back to client
5549 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5550 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5551 TCP(sport=local_port, dport=12345))
5552 self.pg0.add_stream(p)
5553 self.pg_enable_capture(self.pg_interfaces)
5555 capture = self.pg1.get_capture(1)
5560 self.assertEqual(ip.src, external_addr)
5561 self.assertEqual(tcp.sport, external_port)
5562 self.assert_packet_checksums_valid(p)
5564 self.logger.error(ppp("Unexpected or invalid packet:", p))
5567 # from local network host to external network
5568 pkts = self.create_stream_in(self.pg0, self.pg1)
5569 self.pg0.add_stream(pkts)
5570 self.pg_enable_capture(self.pg_interfaces)
5572 capture = self.pg1.get_capture(len(pkts))
5573 self.verify_capture_out(capture, ignore_port=True)
5574 pkts = self.create_stream_in(self.pg0, self.pg1)
5575 self.pg0.add_stream(pkts)
5576 self.pg_enable_capture(self.pg_interfaces)
5578 capture = self.pg1.get_capture(len(pkts))
5579 self.verify_capture_out(capture, ignore_port=True)
5581 # from external network back to local network host
5582 pkts = self.create_stream_out(self.pg1)
5583 self.pg1.add_stream(pkts)
5584 self.pg_enable_capture(self.pg_interfaces)
5586 capture = self.pg0.get_capture(len(pkts))
5587 self.verify_capture_in(capture, self.pg0)
5589 def test_output_feature_and_service2(self):
5590 """ NAT44 interface output feature and service host direct access """
5591 self.vapi.nat44_forwarding_enable_disable(enable=1)
5592 self.nat44_add_address(self.nat_addr)
5593 self.vapi.nat44_interface_add_del_output_feature(
5595 sw_if_index=self.pg1.sw_if_index)
5597 # session initiated from service host - translate
5598 pkts = self.create_stream_in(self.pg0, self.pg1)
5599 self.pg0.add_stream(pkts)
5600 self.pg_enable_capture(self.pg_interfaces)
5602 capture = self.pg1.get_capture(len(pkts))
5603 self.verify_capture_out(capture, ignore_port=True)
5605 pkts = self.create_stream_out(self.pg1)
5606 self.pg1.add_stream(pkts)
5607 self.pg_enable_capture(self.pg_interfaces)
5609 capture = self.pg0.get_capture(len(pkts))
5610 self.verify_capture_in(capture, self.pg0)
5612 # session initiated from remote host - do not translate
5613 self.tcp_port_in = 60303
5614 self.udp_port_in = 60304
5615 self.icmp_id_in = 60305
5616 pkts = self.create_stream_out(self.pg1,
5617 self.pg0.remote_ip4,
5618 use_inside_ports=True)
5619 self.pg1.add_stream(pkts)
5620 self.pg_enable_capture(self.pg_interfaces)
5622 capture = self.pg0.get_capture(len(pkts))
5623 self.verify_capture_in(capture, self.pg0)
5625 pkts = self.create_stream_in(self.pg0, self.pg1)
5626 self.pg0.add_stream(pkts)
5627 self.pg_enable_capture(self.pg_interfaces)
5629 capture = self.pg1.get_capture(len(pkts))
5630 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5633 def test_output_feature_and_service3(self):
5634 """ NAT44 interface output feature and DST NAT """
5635 external_addr = '1.2.3.4'
5639 self.vapi.nat44_forwarding_enable_disable(enable=1)
5640 self.nat44_add_address(self.nat_addr)
5641 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5642 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5643 local_port, external_port,
5644 proto=IP_PROTOS.tcp, flags=flags)
5645 flags = self.config_flags.NAT_IS_INSIDE
5646 self.vapi.nat44_interface_add_del_feature(
5647 sw_if_index=self.pg0.sw_if_index,
5649 self.vapi.nat44_interface_add_del_feature(
5650 sw_if_index=self.pg0.sw_if_index,
5651 flags=flags, is_add=1)
5652 self.vapi.nat44_interface_add_del_output_feature(
5654 sw_if_index=self.pg1.sw_if_index)
5656 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5657 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5658 TCP(sport=12345, dport=external_port))
5659 self.pg0.add_stream(p)
5660 self.pg_enable_capture(self.pg_interfaces)
5662 capture = self.pg1.get_capture(1)
5667 self.assertEqual(ip.src, self.pg0.remote_ip4)
5668 self.assertEqual(tcp.sport, 12345)
5669 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5670 self.assertEqual(tcp.dport, local_port)
5671 self.assert_packet_checksums_valid(p)
5673 self.logger.error(ppp("Unexpected or invalid packet:", p))
5676 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5677 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5678 TCP(sport=local_port, dport=12345))
5679 self.pg1.add_stream(p)
5680 self.pg_enable_capture(self.pg_interfaces)
5682 capture = self.pg0.get_capture(1)
5687 self.assertEqual(ip.src, external_addr)
5688 self.assertEqual(tcp.sport, external_port)
5689 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5690 self.assertEqual(tcp.dport, 12345)
5691 self.assert_packet_checksums_valid(p)
5693 self.logger.error(ppp("Unexpected or invalid packet:", p))
5696 def test_next_src_nat(self):
5697 """ On way back forward packet to nat44-in2out node. """
5698 twice_nat_addr = '10.0.1.3'
5701 post_twice_nat_port = 0
5703 self.vapi.nat44_forwarding_enable_disable(enable=1)
5704 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5705 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5706 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5707 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5708 local_port, external_port,
5709 proto=IP_PROTOS.tcp, vrf_id=1,
5711 self.vapi.nat44_interface_add_del_feature(
5712 sw_if_index=self.pg6.sw_if_index,
5715 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5716 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5717 TCP(sport=12345, dport=external_port))
5718 self.pg6.add_stream(p)
5719 self.pg_enable_capture(self.pg_interfaces)
5721 capture = self.pg6.get_capture(1)
5726 self.assertEqual(ip.src, twice_nat_addr)
5727 self.assertNotEqual(tcp.sport, 12345)
5728 post_twice_nat_port = tcp.sport
5729 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5730 self.assertEqual(tcp.dport, local_port)
5731 self.assert_packet_checksums_valid(p)
5733 self.logger.error(ppp("Unexpected or invalid packet:", p))
5736 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5737 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5738 TCP(sport=local_port, dport=post_twice_nat_port))
5739 self.pg6.add_stream(p)
5740 self.pg_enable_capture(self.pg_interfaces)
5742 capture = self.pg6.get_capture(1)
5747 self.assertEqual(ip.src, self.pg1.remote_ip4)
5748 self.assertEqual(tcp.sport, external_port)
5749 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5750 self.assertEqual(tcp.dport, 12345)
5751 self.assert_packet_checksums_valid(p)
5753 self.logger.error(ppp("Unexpected or invalid packet:", p))
5756 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5758 twice_nat_addr = '10.0.1.3'
5766 port_in1 = port_in + 1
5767 port_in2 = port_in + 2
5772 server1 = self.pg0.remote_hosts[0]
5773 server2 = self.pg0.remote_hosts[1]
5785 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5788 self.nat44_add_address(self.nat_addr)
5789 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5793 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5795 flags |= self.config_flags.NAT_IS_TWICE_NAT
5798 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5800 proto=IP_PROTOS.tcp,
5803 locals = [{'addr': server1.ip4,
5807 {'addr': server2.ip4,
5811 out_addr = self.nat_addr
5813 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5814 external_addr=out_addr,
5815 external_port=port_out,
5816 protocol=IP_PROTOS.tcp,
5817 local_num=len(locals),
5819 flags = self.config_flags.NAT_IS_INSIDE
5820 self.vapi.nat44_interface_add_del_feature(
5821 sw_if_index=pg0.sw_if_index,
5822 flags=flags, is_add=1)
5823 self.vapi.nat44_interface_add_del_feature(
5824 sw_if_index=pg1.sw_if_index,
5831 assert client_id is not None
5833 client = self.pg0.remote_hosts[0]
5834 elif client_id == 2:
5835 client = self.pg0.remote_hosts[1]
5837 client = pg1.remote_hosts[0]
5838 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5839 IP(src=client.ip4, dst=self.nat_addr) /
5840 TCP(sport=eh_port_out, dport=port_out))
5842 self.pg_enable_capture(self.pg_interfaces)
5844 capture = pg0.get_capture(1)
5850 if ip.dst == server1.ip4:
5856 self.assertEqual(ip.dst, server.ip4)
5858 self.assertIn(tcp.dport, [port_in1, port_in2])
5860 self.assertEqual(tcp.dport, port_in)
5862 self.assertEqual(ip.src, twice_nat_addr)
5863 self.assertNotEqual(tcp.sport, eh_port_out)
5865 self.assertEqual(ip.src, client.ip4)
5866 self.assertEqual(tcp.sport, eh_port_out)
5868 eh_port_in = tcp.sport
5869 saved_port_in = tcp.dport
5870 self.assert_packet_checksums_valid(p)
5872 self.logger.error(ppp("Unexpected or invalid packet:", p))
5875 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5876 IP(src=server.ip4, dst=eh_addr_in) /
5877 TCP(sport=saved_port_in, dport=eh_port_in))
5879 self.pg_enable_capture(self.pg_interfaces)
5881 capture = pg1.get_capture(1)
5886 self.assertEqual(ip.dst, client.ip4)
5887 self.assertEqual(ip.src, self.nat_addr)
5888 self.assertEqual(tcp.dport, eh_port_out)
5889 self.assertEqual(tcp.sport, port_out)
5890 self.assert_packet_checksums_valid(p)
5892 self.logger.error(ppp("Unexpected or invalid packet:", p))
5896 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5897 self.assertEqual(len(sessions), 1)
5898 self.assertTrue(sessions[0].flags &
5899 self.config_flags.NAT_IS_EXT_HOST_VALID)
5900 self.assertTrue(sessions[0].flags &
5901 self.config_flags.NAT_IS_TWICE_NAT)
5902 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5903 self.vapi.nat44_del_session(
5904 address=sessions[0].inside_ip_address,
5905 port=sessions[0].inside_port,
5906 protocol=sessions[0].protocol,
5907 flags=(self.config_flags.NAT_IS_INSIDE |
5908 self.config_flags.NAT_IS_EXT_HOST_VALID),
5909 ext_host_address=sessions[0].ext_host_nat_address,
5910 ext_host_port=sessions[0].ext_host_nat_port)
5911 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5912 self.assertEqual(len(sessions), 0)
5914 def test_twice_nat(self):
5916 self.twice_nat_common()
5918 def test_self_twice_nat_positive(self):
5919 """ Self Twice NAT44 (positive test) """
5920 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5922 def test_self_twice_nat_negative(self):
5923 """ Self Twice NAT44 (negative test) """
5924 self.twice_nat_common(self_twice_nat=True)
5926 def test_twice_nat_lb(self):
5927 """ Twice NAT44 local service load balancing """
5928 self.twice_nat_common(lb=True)
5930 def test_self_twice_nat_lb_positive(self):
5931 """ Self Twice NAT44 local service load balancing (positive test) """
5932 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5935 def test_self_twice_nat_lb_negative(self):
5936 """ Self Twice NAT44 local service load balancing (negative test) """
5937 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5940 def test_twice_nat_interface_addr(self):
5941 """ Acquire twice NAT44 addresses from interface """
5942 flags = self.config_flags.NAT_IS_TWICE_NAT
5943 self.vapi.nat44_add_del_interface_addr(
5945 sw_if_index=self.pg3.sw_if_index,
5948 # no address in NAT pool
5949 adresses = self.vapi.nat44_address_dump()
5950 self.assertEqual(0, len(adresses))
5952 # configure interface address and check NAT address pool
5953 self.pg3.config_ip4()
5954 adresses = self.vapi.nat44_address_dump()
5955 self.assertEqual(1, len(adresses))
5956 self.assertEqual(str(adresses[0].ip_address),
5958 self.assertEqual(adresses[0].flags, flags)
5960 # remove interface address and check NAT address pool
5961 self.pg3.unconfig_ip4()
5962 adresses = self.vapi.nat44_address_dump()
5963 self.assertEqual(0, len(adresses))
5965 def test_tcp_close(self):
5966 """ Close TCP session from inside network - output feature """
5967 self.vapi.nat44_forwarding_enable_disable(enable=1)
5968 self.nat44_add_address(self.pg1.local_ip4)
5969 twice_nat_addr = '10.0.1.3'
5970 service_ip = '192.168.16.150'
5971 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5972 flags = self.config_flags.NAT_IS_INSIDE
5973 self.vapi.nat44_interface_add_del_feature(
5974 sw_if_index=self.pg0.sw_if_index,
5976 self.vapi.nat44_interface_add_del_feature(
5977 sw_if_index=self.pg0.sw_if_index,
5978 flags=flags, is_add=1)
5979 self.vapi.nat44_interface_add_del_output_feature(
5981 sw_if_index=self.pg1.sw_if_index)
5982 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5983 self.config_flags.NAT_IS_TWICE_NAT)
5984 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5988 proto=IP_PROTOS.tcp,
5990 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
5991 start_sessnum = len(sessions)
5993 # SYN packet out->in
5994 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5995 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5996 TCP(sport=33898, dport=80, flags="S"))
5997 self.pg1.add_stream(p)
5998 self.pg_enable_capture(self.pg_interfaces)
6000 capture = self.pg0.get_capture(1)
6002 tcp_port = p[TCP].sport
6004 # SYN + ACK packet in->out
6005 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6006 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6007 TCP(sport=80, dport=tcp_port, flags="SA"))
6008 self.pg0.add_stream(p)
6009 self.pg_enable_capture(self.pg_interfaces)
6011 self.pg1.get_capture(1)
6013 # ACK packet out->in
6014 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6015 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6016 TCP(sport=33898, dport=80, flags="A"))
6017 self.pg1.add_stream(p)
6018 self.pg_enable_capture(self.pg_interfaces)
6020 self.pg0.get_capture(1)
6022 # FIN packet in -> out
6023 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6024 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6025 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6026 self.pg0.add_stream(p)
6027 self.pg_enable_capture(self.pg_interfaces)
6029 self.pg1.get_capture(1)
6031 # FIN+ACK packet out -> in
6032 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6033 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6034 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6035 self.pg1.add_stream(p)
6036 self.pg_enable_capture(self.pg_interfaces)
6038 self.pg0.get_capture(1)
6040 # ACK packet in -> out
6041 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6042 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6043 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6044 self.pg0.add_stream(p)
6045 self.pg_enable_capture(self.pg_interfaces)
6047 self.pg1.get_capture(1)
6049 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6051 self.assertEqual(len(sessions) - start_sessnum, 0)
6053 def test_tcp_session_close_in(self):
6054 """ Close TCP session from inside network """
6055 self.tcp_port_out = 10505
6056 self.nat44_add_address(self.nat_addr)
6057 flags = self.config_flags.NAT_IS_TWICE_NAT
6058 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6062 proto=IP_PROTOS.tcp,
6064 flags = self.config_flags.NAT_IS_INSIDE
6065 self.vapi.nat44_interface_add_del_feature(
6066 sw_if_index=self.pg0.sw_if_index,
6067 flags=flags, is_add=1)
6068 self.vapi.nat44_interface_add_del_feature(
6069 sw_if_index=self.pg1.sw_if_index,
6072 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6073 start_sessnum = len(sessions)
6075 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6076 tcp_transitory=2, icmp=5)
6078 self.initiate_tcp_session(self.pg0, self.pg1)
6080 # FIN packet in -> out
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="FA", seq=100, ack=300))
6085 self.pg0.add_stream(p)
6086 self.pg_enable_capture(self.pg_interfaces)
6088 self.pg1.get_capture(1)
6092 # ACK packet out -> in
6093 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6094 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6095 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6096 flags="A", seq=300, ack=101))
6099 # FIN packet out -> in
6100 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6101 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6102 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6103 flags="FA", seq=300, ack=101))
6106 self.pg1.add_stream(pkts)
6107 self.pg_enable_capture(self.pg_interfaces)
6109 self.pg0.get_capture(2)
6111 # ACK packet in -> out
6112 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6113 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6114 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6115 flags="A", seq=101, ack=301))
6116 self.pg0.add_stream(p)
6117 self.pg_enable_capture(self.pg_interfaces)
6119 self.pg1.get_capture(1)
6121 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6122 self.assertEqual(len(sessions) - start_sessnum, 1)
6124 stats = self.statistics.get_counter(
6125 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6126 out2in_drops = stats[0]
6127 stats = self.statistics.get_counter(
6128 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6129 in2out_drops = stats[0]
6131 # extra FIN packet out -> in - this should be dropped
6132 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6133 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6134 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6135 flags="FA", seq=300, ack=101))
6137 self.pg1.add_stream(p)
6138 self.pg_enable_capture(self.pg_interfaces)
6140 self.pg0.assert_nothing_captured()
6142 # extra ACK packet in -> out - this should be dropped
6143 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6144 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6145 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6146 flags="A", seq=101, ack=301))
6147 self.pg0.add_stream(p)
6148 self.pg_enable_capture(self.pg_interfaces)
6150 self.pg1.assert_nothing_captured()
6152 stats = self.statistics.get_counter(
6153 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6154 self.assertEqual(stats[0] - out2in_drops, 1)
6155 stats = self.statistics.get_counter(
6156 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6157 self.assertEqual(stats[0] - in2out_drops, 1)
6160 # extra ACK packet in -> out - this will cause session to be wiped
6161 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6162 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6163 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6164 flags="A", seq=101, ack=301))
6165 self.pg0.add_stream(p)
6166 self.pg_enable_capture(self.pg_interfaces)
6168 self.pg1.assert_nothing_captured()
6169 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6170 self.assertEqual(len(sessions) - start_sessnum, 0)
6172 def test_tcp_session_close_out(self):
6173 """ Close TCP session from outside network """
6174 self.tcp_port_out = 10505
6175 self.nat44_add_address(self.nat_addr)
6176 flags = self.config_flags.NAT_IS_TWICE_NAT
6177 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6181 proto=IP_PROTOS.tcp,
6183 flags = self.config_flags.NAT_IS_INSIDE
6184 self.vapi.nat44_interface_add_del_feature(
6185 sw_if_index=self.pg0.sw_if_index,
6186 flags=flags, is_add=1)
6187 self.vapi.nat44_interface_add_del_feature(
6188 sw_if_index=self.pg1.sw_if_index,
6191 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6192 start_sessnum = len(sessions)
6194 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6195 tcp_transitory=2, icmp=5)
6197 self.initiate_tcp_session(self.pg0, self.pg1)
6199 # FIN packet out -> in
6200 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6201 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6202 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6203 flags="FA", seq=100, ack=300))
6204 self.pg1.add_stream(p)
6205 self.pg_enable_capture(self.pg_interfaces)
6207 self.pg0.get_capture(1)
6209 # FIN+ACK packet in -> out
6210 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6211 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6212 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6213 flags="FA", seq=300, ack=101))
6215 self.pg0.add_stream(p)
6216 self.pg_enable_capture(self.pg_interfaces)
6218 self.pg1.get_capture(1)
6220 # ACK packet out -> in
6221 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6222 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6223 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6224 flags="A", seq=101, ack=301))
6225 self.pg1.add_stream(p)
6226 self.pg_enable_capture(self.pg_interfaces)
6228 self.pg0.get_capture(1)
6230 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6231 self.assertEqual(len(sessions) - start_sessnum, 1)
6233 stats = self.statistics.get_counter(
6234 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6235 out2in_drops = stats[0]
6236 stats = self.statistics.get_counter(
6237 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6238 in2out_drops = stats[0]
6240 # extra FIN packet out -> in - this should be dropped
6241 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6242 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6243 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6244 flags="FA", seq=300, ack=101))
6246 self.pg1.add_stream(p)
6247 self.pg_enable_capture(self.pg_interfaces)
6249 self.pg0.assert_nothing_captured()
6251 # extra ACK packet in -> out - this should be dropped
6252 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6253 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6254 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6255 flags="A", seq=101, ack=301))
6256 self.pg0.add_stream(p)
6257 self.pg_enable_capture(self.pg_interfaces)
6259 self.pg1.assert_nothing_captured()
6261 stats = self.statistics.get_counter(
6262 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6263 self.assertEqual(stats[0] - out2in_drops, 1)
6264 stats = self.statistics.get_counter(
6265 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6266 self.assertEqual(stats[0] - in2out_drops, 1)
6269 # extra ACK packet in -> out - this will cause session to be wiped
6270 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6271 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6272 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6273 flags="A", seq=101, ack=301))
6274 self.pg0.add_stream(p)
6275 self.pg_enable_capture(self.pg_interfaces)
6277 self.pg1.assert_nothing_captured()
6278 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6279 self.assertEqual(len(sessions) - start_sessnum, 0)
6281 def test_tcp_session_close_simultaneous(self):
6282 """ Close TCP session from inside network """
6283 self.tcp_port_out = 10505
6284 self.nat44_add_address(self.nat_addr)
6285 flags = self.config_flags.NAT_IS_TWICE_NAT
6286 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6290 proto=IP_PROTOS.tcp,
6292 flags = self.config_flags.NAT_IS_INSIDE
6293 self.vapi.nat44_interface_add_del_feature(
6294 sw_if_index=self.pg0.sw_if_index,
6295 flags=flags, is_add=1)
6296 self.vapi.nat44_interface_add_del_feature(
6297 sw_if_index=self.pg1.sw_if_index,
6300 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6301 start_sessnum = len(sessions)
6303 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6304 tcp_transitory=2, icmp=5)
6306 self.initiate_tcp_session(self.pg0, self.pg1)
6308 # FIN packet in -> out
6309 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6310 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6311 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6312 flags="FA", seq=100, ack=300))
6313 self.pg0.add_stream(p)
6314 self.pg_enable_capture(self.pg_interfaces)
6316 self.pg1.get_capture(1)
6318 # FIN packet out -> in
6319 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6320 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6321 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6322 flags="FA", seq=300, ack=100))
6323 self.pg1.add_stream(p)
6324 self.pg_enable_capture(self.pg_interfaces)
6326 self.pg0.get_capture(1)
6328 # ACK packet in -> out
6329 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6330 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6331 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6332 flags="A", seq=101, ack=301))
6333 self.pg0.add_stream(p)
6334 self.pg_enable_capture(self.pg_interfaces)
6336 self.pg1.get_capture(1)
6338 # ACK packet out -> in
6339 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6340 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6341 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6342 flags="A", seq=301, ack=101))
6343 self.pg1.add_stream(p)
6344 self.pg_enable_capture(self.pg_interfaces)
6346 self.pg0.get_capture(1)
6348 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6349 self.assertEqual(len(sessions) - start_sessnum, 1)
6351 stats = self.statistics.get_counter(
6352 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6353 out2in_drops = stats[0]
6354 stats = self.statistics.get_counter(
6355 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6356 in2out_drops = stats[0]
6358 # extra FIN packet out -> in - this should be dropped
6359 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6360 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6361 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6362 flags="FA", seq=300, ack=101))
6364 self.pg1.add_stream(p)
6365 self.pg_enable_capture(self.pg_interfaces)
6367 self.pg0.assert_nothing_captured()
6369 # extra ACK packet in -> out - this should be dropped
6370 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6371 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6372 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6373 flags="A", seq=101, ack=301))
6374 self.pg0.add_stream(p)
6375 self.pg_enable_capture(self.pg_interfaces)
6377 self.pg1.assert_nothing_captured()
6379 stats = self.statistics.get_counter(
6380 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6381 self.assertEqual(stats[0] - out2in_drops, 1)
6382 stats = self.statistics.get_counter(
6383 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6384 self.assertEqual(stats[0] - in2out_drops, 1)
6387 # extra ACK packet in -> out - this will cause session to be wiped
6388 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6389 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6390 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6391 flags="A", seq=101, ack=301))
6392 self.pg0.add_stream(p)
6393 self.pg_enable_capture(self.pg_interfaces)
6395 self.pg1.assert_nothing_captured()
6396 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6397 self.assertEqual(len(sessions) - start_sessnum, 0)
6399 def test_one_armed_nat44_static(self):
6400 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6401 remote_host = self.pg4.remote_hosts[0]
6402 local_host = self.pg4.remote_hosts[1]
6407 self.vapi.nat44_forwarding_enable_disable(enable=1)
6408 self.nat44_add_address(self.nat_addr, twice_nat=1)
6409 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6410 self.config_flags.NAT_IS_TWICE_NAT)
6411 self.nat44_add_static_mapping(local_host.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.pg4.sw_if_index,
6418 self.vapi.nat44_interface_add_del_feature(
6419 sw_if_index=self.pg4.sw_if_index,
6420 flags=flags, is_add=1)
6422 # from client to service
6423 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6424 IP(src=remote_host.ip4, dst=self.nat_addr) /
6425 TCP(sport=12345, dport=external_port))
6426 self.pg4.add_stream(p)
6427 self.pg_enable_capture(self.pg_interfaces)
6429 capture = self.pg4.get_capture(1)
6434 self.assertEqual(ip.dst, local_host.ip4)
6435 self.assertEqual(ip.src, self.nat_addr)
6436 self.assertEqual(tcp.dport, local_port)
6437 self.assertNotEqual(tcp.sport, 12345)
6438 eh_port_in = tcp.sport
6439 self.assert_packet_checksums_valid(p)
6441 self.logger.error(ppp("Unexpected or invalid packet:", p))
6444 # from service back to client
6445 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6446 IP(src=local_host.ip4, dst=self.nat_addr) /
6447 TCP(sport=local_port, dport=eh_port_in))
6448 self.pg4.add_stream(p)
6449 self.pg_enable_capture(self.pg_interfaces)
6451 capture = self.pg4.get_capture(1)
6456 self.assertEqual(ip.src, self.nat_addr)
6457 self.assertEqual(ip.dst, remote_host.ip4)
6458 self.assertEqual(tcp.sport, external_port)
6459 self.assertEqual(tcp.dport, 12345)
6460 self.assert_packet_checksums_valid(p)
6462 self.logger.error(ppp("Unexpected or invalid packet:", p))
6465 def test_static_with_port_out2(self):
6466 """ 1:1 NAPT asymmetrical rule """
6471 self.vapi.nat44_forwarding_enable_disable(enable=1)
6472 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6473 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6474 local_port, external_port,
6475 proto=IP_PROTOS.tcp, flags=flags)
6476 flags = self.config_flags.NAT_IS_INSIDE
6477 self.vapi.nat44_interface_add_del_feature(
6478 sw_if_index=self.pg0.sw_if_index,
6479 flags=flags, is_add=1)
6480 self.vapi.nat44_interface_add_del_feature(
6481 sw_if_index=self.pg1.sw_if_index,
6484 # from client to service
6485 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6486 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6487 TCP(sport=12345, dport=external_port))
6488 self.pg1.add_stream(p)
6489 self.pg_enable_capture(self.pg_interfaces)
6491 capture = self.pg0.get_capture(1)
6496 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6497 self.assertEqual(tcp.dport, local_port)
6498 self.assert_packet_checksums_valid(p)
6500 self.logger.error(ppp("Unexpected or invalid packet:", p))
6504 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6505 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6506 ICMP(type=11) / capture[0][IP])
6507 self.pg0.add_stream(p)
6508 self.pg_enable_capture(self.pg_interfaces)
6510 capture = self.pg1.get_capture(1)
6513 self.assertEqual(p[IP].src, self.nat_addr)
6515 self.assertEqual(inner.dst, self.nat_addr)
6516 self.assertEqual(inner[TCPerror].dport, external_port)
6518 self.logger.error(ppp("Unexpected or invalid packet:", p))
6521 # from service back to client
6522 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6523 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6524 TCP(sport=local_port, dport=12345))
6525 self.pg0.add_stream(p)
6526 self.pg_enable_capture(self.pg_interfaces)
6528 capture = self.pg1.get_capture(1)
6533 self.assertEqual(ip.src, self.nat_addr)
6534 self.assertEqual(tcp.sport, external_port)
6535 self.assert_packet_checksums_valid(p)
6537 self.logger.error(ppp("Unexpected or invalid packet:", p))
6541 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6542 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6543 ICMP(type=11) / capture[0][IP])
6544 self.pg1.add_stream(p)
6545 self.pg_enable_capture(self.pg_interfaces)
6547 capture = self.pg0.get_capture(1)
6550 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6552 self.assertEqual(inner.src, self.pg0.remote_ip4)
6553 self.assertEqual(inner[TCPerror].sport, local_port)
6555 self.logger.error(ppp("Unexpected or invalid packet:", p))
6558 # from client to server (no translation)
6559 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6560 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6561 TCP(sport=12346, dport=local_port))
6562 self.pg1.add_stream(p)
6563 self.pg_enable_capture(self.pg_interfaces)
6565 capture = self.pg0.get_capture(1)
6570 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6571 self.assertEqual(tcp.dport, local_port)
6572 self.assert_packet_checksums_valid(p)
6574 self.logger.error(ppp("Unexpected or invalid packet:", p))
6577 # from service back to client (no translation)
6578 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6579 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6580 TCP(sport=local_port, dport=12346))
6581 self.pg0.add_stream(p)
6582 self.pg_enable_capture(self.pg_interfaces)
6584 capture = self.pg1.get_capture(1)
6589 self.assertEqual(ip.src, self.pg0.remote_ip4)
6590 self.assertEqual(tcp.sport, local_port)
6591 self.assert_packet_checksums_valid(p)
6593 self.logger.error(ppp("Unexpected or invalid packet:", p))
6596 def test_output_feature(self):
6597 """ NAT44 interface output feature (in2out postrouting) """
6598 self.vapi.nat44_forwarding_enable_disable(enable=1)
6599 self.nat44_add_address(self.nat_addr)
6600 self.vapi.nat44_interface_add_del_feature(
6601 sw_if_index=self.pg0.sw_if_index,
6603 self.vapi.nat44_interface_add_del_output_feature(
6605 sw_if_index=self.pg1.sw_if_index)
6608 pkts = self.create_stream_in(self.pg0, self.pg1)
6609 self.pg0.add_stream(pkts)
6610 self.pg_enable_capture(self.pg_interfaces)
6612 capture = self.pg1.get_capture(len(pkts))
6613 self.verify_capture_out(capture, ignore_port=True)
6616 pkts = self.create_stream_out(self.pg1)
6617 self.pg1.add_stream(pkts)
6618 self.pg_enable_capture(self.pg_interfaces)
6620 capture = self.pg0.get_capture(len(pkts))
6621 self.verify_capture_in(capture, self.pg0)
6623 def test_output_feature_stateful_acl(self):
6624 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6625 self.nat44_add_address(self.nat_addr)
6626 self.vapi.nat44_interface_add_del_output_feature(
6627 sw_if_index=self.pg0.sw_if_index,
6628 flags=self.config_flags.NAT_IS_INSIDE,
6630 self.vapi.nat44_interface_add_del_output_feature(
6631 sw_if_index=self.pg1.sw_if_index,
6632 flags=self.config_flags.NAT_IS_OUTSIDE,
6635 # First ensure that the NAT is working sans ACL
6637 # send packets out2in, no sessions yet so packets should drop
6638 pkts_out2in = self.create_stream_out(self.pg1)
6639 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6641 # send packets into inside intf, ensure received via outside intf
6642 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6643 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6645 self.verify_capture_out(capture, ignore_port=True)
6647 # send out2in again, with sessions created it should work now
6648 pkts_out2in = self.create_stream_out(self.pg1)
6649 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6651 self.verify_capture_in(capture, self.pg0)
6653 # Create an ACL blocking everything
6654 out2in_deny_rule = AclRule(is_permit=0)
6655 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6656 out2in_acl.add_vpp_config()
6658 # create an ACL to permit/reflect everything
6659 in2out_reflect_rule = AclRule(is_permit=2)
6660 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6661 in2out_acl.add_vpp_config()
6663 # apply as input acl on interface and confirm it blocks everything
6664 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6665 n_input=1, acls=[out2in_acl])
6666 acl_if.add_vpp_config()
6667 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6670 acl_if.acls = [out2in_acl, in2out_acl]
6671 acl_if.add_vpp_config()
6672 # send in2out to generate ACL state (NAT state was created earlier)
6673 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6675 self.verify_capture_out(capture, ignore_port=True)
6677 # send out2in again. ACL state exists so it should work now.
6678 # TCP packets with the syn flag set also need the ack flag
6679 for p in pkts_out2in:
6680 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6681 p[TCP].flags |= 0x10
6682 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6684 self.verify_capture_in(capture, self.pg0)
6685 self.logger.info(self.vapi.cli("show trace"))
6687 def test_multiple_vrf(self):
6688 """ Multiple VRF setup """
6689 external_addr = '1.2.3.4'
6694 self.vapi.nat44_forwarding_enable_disable(enable=1)
6695 self.nat44_add_address(self.nat_addr)
6696 flags = self.config_flags.NAT_IS_INSIDE
6697 self.vapi.nat44_interface_add_del_feature(
6698 sw_if_index=self.pg0.sw_if_index,
6700 self.vapi.nat44_interface_add_del_feature(
6701 sw_if_index=self.pg0.sw_if_index,
6702 flags=flags, is_add=1)
6703 self.vapi.nat44_interface_add_del_output_feature(
6705 sw_if_index=self.pg1.sw_if_index)
6706 self.vapi.nat44_interface_add_del_feature(
6707 sw_if_index=self.pg5.sw_if_index,
6709 self.vapi.nat44_interface_add_del_feature(
6710 sw_if_index=self.pg5.sw_if_index,
6711 flags=flags, is_add=1)
6712 self.vapi.nat44_interface_add_del_feature(
6713 sw_if_index=self.pg6.sw_if_index,
6715 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6716 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6717 local_port, external_port, vrf_id=1,
6718 proto=IP_PROTOS.tcp, flags=flags)
6719 self.nat44_add_static_mapping(
6720 self.pg0.remote_ip4,
6721 external_sw_if_index=self.pg0.sw_if_index,
6722 local_port=local_port,
6724 external_port=external_port,
6725 proto=IP_PROTOS.tcp,
6729 # from client to service (both VRF1)
6730 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6731 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6732 TCP(sport=12345, dport=external_port))
6733 self.pg6.add_stream(p)
6734 self.pg_enable_capture(self.pg_interfaces)
6736 capture = self.pg5.get_capture(1)
6741 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6742 self.assertEqual(tcp.dport, local_port)
6743 self.assert_packet_checksums_valid(p)
6745 self.logger.error(ppp("Unexpected or invalid packet:", p))
6748 # from service back to client (both VRF1)
6749 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6750 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6751 TCP(sport=local_port, dport=12345))
6752 self.pg5.add_stream(p)
6753 self.pg_enable_capture(self.pg_interfaces)
6755 capture = self.pg6.get_capture(1)
6760 self.assertEqual(ip.src, external_addr)
6761 self.assertEqual(tcp.sport, external_port)
6762 self.assert_packet_checksums_valid(p)
6764 self.logger.error(ppp("Unexpected or invalid packet:", p))
6767 # dynamic NAT from VRF1 to VRF0 (output-feature)
6768 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6769 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6770 TCP(sport=2345, dport=22))
6771 self.pg5.add_stream(p)
6772 self.pg_enable_capture(self.pg_interfaces)
6774 capture = self.pg1.get_capture(1)
6779 self.assertEqual(ip.src, self.nat_addr)
6780 self.assert_packet_checksums_valid(p)
6783 self.logger.error(ppp("Unexpected or invalid packet:", p))
6786 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6787 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6788 TCP(sport=22, dport=port))
6789 self.pg1.add_stream(p)
6790 self.pg_enable_capture(self.pg_interfaces)
6792 capture = self.pg5.get_capture(1)
6797 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6798 self.assertEqual(tcp.dport, 2345)
6799 self.assert_packet_checksums_valid(p)
6801 self.logger.error(ppp("Unexpected or invalid packet:", p))
6804 # from client VRF1 to service VRF0
6805 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6806 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6807 TCP(sport=12346, dport=external_port))
6808 self.pg6.add_stream(p)
6809 self.pg_enable_capture(self.pg_interfaces)
6811 capture = self.pg0.get_capture(1)
6816 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6817 self.assertEqual(tcp.dport, local_port)
6818 self.assert_packet_checksums_valid(p)
6820 self.logger.error(ppp("Unexpected or invalid packet:", p))
6823 # from service VRF0 back to client VRF1
6824 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6825 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6826 TCP(sport=local_port, dport=12346))
6827 self.pg0.add_stream(p)
6828 self.pg_enable_capture(self.pg_interfaces)
6830 capture = self.pg6.get_capture(1)
6835 self.assertEqual(ip.src, self.pg0.local_ip4)
6836 self.assertEqual(tcp.sport, external_port)
6837 self.assert_packet_checksums_valid(p)
6839 self.logger.error(ppp("Unexpected or invalid packet:", p))
6842 # from client VRF0 to service VRF1
6843 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6844 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6845 TCP(sport=12347, dport=external_port))
6846 self.pg0.add_stream(p)
6847 self.pg_enable_capture(self.pg_interfaces)
6849 capture = self.pg5.get_capture(1)
6854 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6855 self.assertEqual(tcp.dport, local_port)
6856 self.assert_packet_checksums_valid(p)
6858 self.logger.error(ppp("Unexpected or invalid packet:", p))
6861 # from service VRF1 back to client VRF0
6862 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6863 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6864 TCP(sport=local_port, dport=12347))
6865 self.pg5.add_stream(p)
6866 self.pg_enable_capture(self.pg_interfaces)
6868 capture = self.pg0.get_capture(1)
6873 self.assertEqual(ip.src, external_addr)
6874 self.assertEqual(tcp.sport, external_port)
6875 self.assert_packet_checksums_valid(p)
6877 self.logger.error(ppp("Unexpected or invalid packet:", p))
6880 # from client to server (both VRF1, no translation)
6881 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6882 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6883 TCP(sport=12348, dport=local_port))
6884 self.pg6.add_stream(p)
6885 self.pg_enable_capture(self.pg_interfaces)
6887 capture = self.pg5.get_capture(1)
6892 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6893 self.assertEqual(tcp.dport, local_port)
6894 self.assert_packet_checksums_valid(p)
6896 self.logger.error(ppp("Unexpected or invalid packet:", p))
6899 # from server back to client (both VRF1, no translation)
6900 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6901 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6902 TCP(sport=local_port, dport=12348))
6903 self.pg5.add_stream(p)
6904 self.pg_enable_capture(self.pg_interfaces)
6906 capture = self.pg6.get_capture(1)
6911 self.assertEqual(ip.src, self.pg5.remote_ip4)
6912 self.assertEqual(tcp.sport, local_port)
6913 self.assert_packet_checksums_valid(p)
6915 self.logger.error(ppp("Unexpected or invalid packet:", p))
6918 # from client VRF1 to server VRF0 (no translation)
6919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6920 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6921 TCP(sport=local_port, dport=12349))
6922 self.pg0.add_stream(p)
6923 self.pg_enable_capture(self.pg_interfaces)
6925 capture = self.pg6.get_capture(1)
6930 self.assertEqual(ip.src, self.pg0.remote_ip4)
6931 self.assertEqual(tcp.sport, local_port)
6932 self.assert_packet_checksums_valid(p)
6934 self.logger.error(ppp("Unexpected or invalid packet:", p))
6937 # from server VRF0 back to client VRF1 (no translation)
6938 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6939 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6940 TCP(sport=local_port, dport=12349))
6941 self.pg0.add_stream(p)
6942 self.pg_enable_capture(self.pg_interfaces)
6944 capture = self.pg6.get_capture(1)
6949 self.assertEqual(ip.src, self.pg0.remote_ip4)
6950 self.assertEqual(tcp.sport, local_port)
6951 self.assert_packet_checksums_valid(p)
6953 self.logger.error(ppp("Unexpected or invalid packet:", p))
6956 # from client VRF0 to server VRF1 (no translation)
6957 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6958 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
6959 TCP(sport=12344, dport=local_port))
6960 self.pg0.add_stream(p)
6961 self.pg_enable_capture(self.pg_interfaces)
6963 capture = self.pg5.get_capture(1)
6968 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6969 self.assertEqual(tcp.dport, local_port)
6970 self.assert_packet_checksums_valid(p)
6972 self.logger.error(ppp("Unexpected or invalid packet:", p))
6975 # from server VRF1 back to client VRF0 (no translation)
6976 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6977 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6978 TCP(sport=local_port, dport=12344))
6979 self.pg5.add_stream(p)
6980 self.pg_enable_capture(self.pg_interfaces)
6982 capture = self.pg0.get_capture(1)
6987 self.assertEqual(ip.src, self.pg5.remote_ip4)
6988 self.assertEqual(tcp.sport, local_port)
6989 self.assert_packet_checksums_valid(p)
6991 self.logger.error(ppp("Unexpected or invalid packet:", p))
6994 @unittest.skipUnless(running_extended_tests, "part of extended tests")
6995 def test_session_timeout(self):
6996 """ NAT44 session timeouts """
6997 self.nat44_add_address(self.nat_addr)
6998 flags = self.config_flags.NAT_IS_INSIDE
6999 self.vapi.nat44_interface_add_del_feature(
7000 sw_if_index=self.pg0.sw_if_index,
7001 flags=flags, is_add=1)
7002 self.vapi.nat44_interface_add_del_feature(
7003 sw_if_index=self.pg1.sw_if_index,
7005 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7006 tcp_transitory=240, icmp=5)
7010 for i in range(0, max_sessions):
7011 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7012 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7013 IP(src=src, dst=self.pg1.remote_ip4) /
7014 ICMP(id=1025, type='echo-request'))
7016 self.pg0.add_stream(pkts)
7017 self.pg_enable_capture(self.pg_interfaces)
7019 self.pg1.get_capture(max_sessions)
7024 for i in range(0, max_sessions):
7025 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7026 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7027 IP(src=src, dst=self.pg1.remote_ip4) /
7028 ICMP(id=1026, type='echo-request'))
7030 self.pg0.add_stream(pkts)
7031 self.pg_enable_capture(self.pg_interfaces)
7033 self.pg1.get_capture(max_sessions)
7036 users = self.vapi.nat44_user_dump()
7038 nsessions = nsessions + user.nsessions
7039 self.assertLess(nsessions, 2 * max_sessions)
7041 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7042 def test_session_rst_timeout(self):
7043 """ NAT44 session RST timeouts """
7044 self.nat44_add_address(self.nat_addr)
7045 flags = self.config_flags.NAT_IS_INSIDE
7046 self.vapi.nat44_interface_add_del_feature(
7047 sw_if_index=self.pg0.sw_if_index,
7048 flags=flags, is_add=1)
7049 self.vapi.nat44_interface_add_del_feature(
7050 sw_if_index=self.pg1.sw_if_index,
7052 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7053 tcp_transitory=5, icmp=60)
7055 self.initiate_tcp_session(self.pg0, self.pg1)
7056 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7057 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7058 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7060 self.pg0.add_stream(p)
7061 self.pg_enable_capture(self.pg_interfaces)
7063 self.pg1.get_capture(1)
7067 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7068 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7069 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
7071 self.pg0.add_stream(p)
7072 self.pg_enable_capture(self.pg_interfaces)
7074 self.pg1.get_capture(1)
7076 def test_syslog_sess(self):
7077 """ Test syslog session creation and deletion """
7078 self.vapi.syslog_set_filter(
7079 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
7080 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
7081 self.nat44_add_address(self.nat_addr)
7082 flags = self.config_flags.NAT_IS_INSIDE
7083 self.vapi.nat44_interface_add_del_feature(
7084 sw_if_index=self.pg0.sw_if_index,
7085 flags=flags, is_add=1)
7086 self.vapi.nat44_interface_add_del_feature(
7087 sw_if_index=self.pg1.sw_if_index,
7090 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7091 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7092 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7093 self.pg0.add_stream(p)
7094 self.pg_enable_capture(self.pg_interfaces)
7096 capture = self.pg1.get_capture(1)
7097 self.tcp_port_out = capture[0][TCP].sport
7098 capture = self.pg2.get_capture(1)
7099 self.verify_syslog_sess(capture[0][Raw].load)
7101 self.pg_enable_capture(self.pg_interfaces)
7103 self.nat44_add_address(self.nat_addr, is_add=0)
7104 capture = self.pg2.get_capture(1)
7105 self.verify_syslog_sess(capture[0][Raw].load, False)
7107 def test_ed_users_dump(self):
7108 """ API test - nat44_user_dump """
7109 flags = self.config_flags.NAT_IS_INSIDE
7110 self.vapi.nat44_interface_add_del_feature(
7111 sw_if_index=self.pg0.sw_if_index,
7112 flags=flags, is_add=1)
7113 self.vapi.nat44_interface_add_del_feature(
7114 sw_if_index=self.pg1.sw_if_index,
7116 self.vapi.nat44_forwarding_enable_disable(enable=1)
7118 real_ip = self.pg0.remote_ip4
7119 alias_ip = self.nat_addr
7120 flags = self.config_flags.NAT_IS_ADDR_ONLY
7121 self.vapi.nat44_add_del_static_mapping(is_add=1,
7122 local_ip_address=real_ip,
7123 external_ip_address=alias_ip,
7124 external_sw_if_index=0xFFFFFFFF,
7127 users = self.vapi.nat44_user_dump()
7128 self.assertEqual(len(users), 0)
7130 # in2out - static mapping match
7132 pkts = self.create_stream_out(self.pg1)
7133 self.pg1.add_stream(pkts)
7134 self.pg_enable_capture(self.pg_interfaces)
7136 capture = self.pg0.get_capture(len(pkts))
7137 self.verify_capture_in(capture, self.pg0)
7139 pkts = self.create_stream_in(self.pg0, self.pg1)
7140 self.pg0.add_stream(pkts)
7141 self.pg_enable_capture(self.pg_interfaces)
7143 capture = self.pg1.get_capture(len(pkts))
7144 self.verify_capture_out(capture, same_port=True)
7146 users = self.vapi.nat44_user_dump()
7147 self.assertEqual(len(users), 1)
7148 static_user = users[0]
7149 self.assertEqual(static_user.nstaticsessions, 3)
7150 self.assertEqual(static_user.nsessions, 0)
7152 # in2out - no static mapping match
7154 host0 = self.pg0.remote_hosts[0]
7155 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
7157 pkts = self.create_stream_out(self.pg1,
7158 dst_ip=self.pg0.remote_ip4,
7159 use_inside_ports=True)
7160 self.pg1.add_stream(pkts)
7161 self.pg_enable_capture(self.pg_interfaces)
7163 capture = self.pg0.get_capture(len(pkts))
7164 self.verify_capture_in(capture, self.pg0)
7166 pkts = self.create_stream_in(self.pg0, self.pg1)
7167 self.pg0.add_stream(pkts)
7168 self.pg_enable_capture(self.pg_interfaces)
7170 capture = self.pg1.get_capture(len(pkts))
7171 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7174 self.pg0.remote_hosts[0] = host0
7176 users = self.vapi.nat44_user_dump()
7177 self.assertEqual(len(users), 2)
7178 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7179 non_static_user = users[1]
7180 static_user = users[0]
7182 non_static_user = users[0]
7183 static_user = users[1]
7184 self.assertEqual(static_user.nstaticsessions, 3)
7185 self.assertEqual(static_user.nsessions, 0)
7186 self.assertEqual(non_static_user.nstaticsessions, 0)
7187 self.assertEqual(non_static_user.nsessions, 3)
7189 users = self.vapi.nat44_user_dump()
7190 self.assertEqual(len(users), 2)
7191 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7192 non_static_user = users[1]
7193 static_user = users[0]
7195 non_static_user = users[0]
7196 static_user = users[1]
7197 self.assertEqual(static_user.nstaticsessions, 3)
7198 self.assertEqual(static_user.nsessions, 0)
7199 self.assertEqual(non_static_user.nstaticsessions, 0)
7200 self.assertEqual(non_static_user.nsessions, 3)
7203 self.vapi.nat44_forwarding_enable_disable(enable=0)
7204 flags = self.config_flags.NAT_IS_ADDR_ONLY
7205 self.vapi.nat44_add_del_static_mapping(
7207 local_ip_address=real_ip,
7208 external_ip_address=alias_ip,
7209 external_sw_if_index=0xFFFFFFFF,
7213 super(TestNAT44EndpointDependent, self).tearDown()
7214 if not self.vpp_dead:
7216 self.vapi.cli("clear logging")
7218 def show_commands_at_teardown(self):
7219 self.logger.info(self.vapi.cli("show nat44 addresses"))
7220 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7221 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7222 self.logger.info(self.vapi.cli("show nat44 interface address"))
7223 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7224 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7225 self.logger.info(self.vapi.cli("show nat timeouts"))
7228 class TestNAT44EndpointDependent3(MethodHolder):
7229 """ Endpoint-Dependent mapping and filtering extra test cases """
7231 max_translations = 50
7234 def setUpConstants(cls):
7235 super(TestNAT44EndpointDependent3, cls).setUpConstants()
7236 cls.vpp_cmdline.extend([
7237 "nat", "{", "endpoint-dependent",
7238 "max translations per thread %d" % cls.max_translations,
7243 def setUpClass(cls):
7244 super(TestNAT44EndpointDependent3, cls).setUpClass()
7245 cls.vapi.cli("set log class nat level debug")
7247 cls.nat_addr = '10.0.0.3'
7249 cls.create_pg_interfaces(range(2))
7251 for i in cls.pg_interfaces:
7257 super(TestNAT44EndpointDependent3, self).setUp()
7258 self.vapi.nat_set_timeouts(
7259 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7260 self.nat44_add_address(self.nat_addr)
7261 flags = self.config_flags.NAT_IS_INSIDE
7262 self.vapi.nat44_interface_add_del_feature(
7263 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7264 self.vapi.nat44_interface_add_del_feature(
7265 sw_if_index=self.pg1.sw_if_index, is_add=1)
7268 def tearDownClass(cls):
7269 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7271 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7272 # SYN packet in->out
7273 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7274 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7275 TCP(sport=sport, dport=ext_dport, flags="S"))
7277 self.pg_enable_capture(self.pg_interfaces)
7279 capture = out_if.get_capture(1)
7281 tcp_port_out = p[TCP].sport
7283 # SYN + ACK packet out->in
7284 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7285 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7286 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7287 out_if.add_stream(p)
7288 self.pg_enable_capture(self.pg_interfaces)
7290 in_if.get_capture(1)
7292 # ACK packet in->out
7293 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7294 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7295 TCP(sport=sport, dport=ext_dport, flags="A"))
7297 self.pg_enable_capture(self.pg_interfaces)
7299 out_if.get_capture(1)
7303 def test_lru_cleanup(self):
7304 """ LRU cleanup algorithm """
7305 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7307 for i in range(0, self.max_translations - 1):
7308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7309 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7310 UDP(sport=7000+i, dport=80))
7313 self.pg0.add_stream(pkts)
7314 self.pg_enable_capture(self.pg_interfaces)
7316 self.pg1.get_capture(len(pkts))
7317 self.sleep(1.5, "wait for timeouts")
7320 for i in range(0, self.max_translations - 1):
7321 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7322 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7323 ICMP(id=8000+i, type='echo-request'))
7326 self.pg0.add_stream(pkts)
7327 self.pg_enable_capture(self.pg_interfaces)
7329 self.pg1.get_capture(len(pkts))
7332 class TestNAT44Out2InDPO(MethodHolder):
7333 """ NAT44 Test Cases using out2in DPO """
7336 def setUpConstants(cls):
7337 super(TestNAT44Out2InDPO, cls).setUpConstants()
7338 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7341 def setUpClass(cls):
7342 super(TestNAT44Out2InDPO, cls).setUpClass()
7343 cls.vapi.cli("set log class nat level debug")
7345 cls.tcp_port_in = 6303
7346 cls.tcp_port_out = 6303
7347 cls.udp_port_in = 6304
7348 cls.udp_port_out = 6304
7349 cls.icmp_id_in = 6305
7350 cls.icmp_id_out = 6305
7351 cls.nat_addr = '10.0.0.3'
7352 cls.dst_ip4 = '192.168.70.1'
7354 cls.create_pg_interfaces(range(2))
7357 cls.pg0.config_ip4()
7358 cls.pg0.resolve_arp()
7361 cls.pg1.config_ip6()
7362 cls.pg1.resolve_ndp()
7364 r1 = VppIpRoute(cls, "::", 0,
7365 [VppRoutePath(cls.pg1.remote_ip6,
7366 cls.pg1.sw_if_index)],
7371 def tearDownClass(cls):
7372 super(TestNAT44Out2InDPO, cls).tearDownClass()
7374 def configure_xlat(self):
7375 self.dst_ip6_pfx = '1:2:3::'
7376 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7378 self.dst_ip6_pfx_len = 96
7379 self.src_ip6_pfx = '4:5:6::'
7380 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7382 self.src_ip6_pfx_len = 96
7383 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7384 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7385 '\x00\x00\x00\x00', 0)
7387 @unittest.skip('Temporary disabled')
7388 def test_464xlat_ce(self):
7389 """ Test 464XLAT CE with NAT44 """
7391 nat_config = self.vapi.nat_show_config()
7392 self.assertEqual(1, nat_config.out2in_dpo)
7394 self.configure_xlat()
7396 flags = self.config_flags.NAT_IS_INSIDE
7397 self.vapi.nat44_interface_add_del_feature(
7398 sw_if_index=self.pg0.sw_if_index,
7399 flags=flags, is_add=1)
7400 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7401 last_ip_address=self.nat_addr_n,
7402 vrf_id=0xFFFFFFFF, is_add=1)
7404 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7405 self.dst_ip6_pfx_len)
7406 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7407 self.src_ip6_pfx_len)
7410 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7411 self.pg0.add_stream(pkts)
7412 self.pg_enable_capture(self.pg_interfaces)
7414 capture = self.pg1.get_capture(len(pkts))
7415 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7418 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7420 self.pg1.add_stream(pkts)
7421 self.pg_enable_capture(self.pg_interfaces)
7423 capture = self.pg0.get_capture(len(pkts))
7424 self.verify_capture_in(capture, self.pg0)
7426 self.vapi.nat44_interface_add_del_feature(
7427 sw_if_index=self.pg0.sw_if_index,
7429 self.vapi.nat44_add_del_address_range(
7430 first_ip_address=self.nat_addr_n,
7431 last_ip_address=self.nat_addr_n,
7434 @unittest.skip('Temporary disabled')
7435 def test_464xlat_ce_no_nat(self):
7436 """ Test 464XLAT CE without NAT44 """
7438 self.configure_xlat()
7440 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7441 self.dst_ip6_pfx_len)
7442 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7443 self.src_ip6_pfx_len)
7445 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7446 self.pg0.add_stream(pkts)
7447 self.pg_enable_capture(self.pg_interfaces)
7449 capture = self.pg1.get_capture(len(pkts))
7450 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7451 nat_ip=out_dst_ip6, same_port=True)
7453 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7454 self.pg1.add_stream(pkts)
7455 self.pg_enable_capture(self.pg_interfaces)
7457 capture = self.pg0.get_capture(len(pkts))
7458 self.verify_capture_in(capture, self.pg0)
7461 class TestDeterministicNAT(MethodHolder):
7462 """ Deterministic NAT Test Cases """
7465 def setUpConstants(cls):
7466 super(TestDeterministicNAT, cls).setUpConstants()
7467 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
7470 def setUpClass(cls):
7471 super(TestDeterministicNAT, cls).setUpClass()
7472 cls.vapi.cli("set log class nat level debug")
7474 cls.tcp_port_in = 6303
7475 cls.tcp_external_port = 6303
7476 cls.udp_port_in = 6304
7477 cls.udp_external_port = 6304
7478 cls.icmp_id_in = 6305
7479 cls.nat_addr = '10.0.0.3'
7481 cls.create_pg_interfaces(range(3))
7482 cls.interfaces = list(cls.pg_interfaces)
7484 for i in cls.interfaces:
7489 cls.pg0.generate_remote_hosts(2)
7490 cls.pg0.configure_ipv4_neighbors()
7493 def tearDownClass(cls):
7494 super(TestDeterministicNAT, cls).tearDownClass()
7496 def create_stream_in(self, in_if, out_if, ttl=64):
7498 Create packet stream for inside network
7500 :param in_if: Inside interface
7501 :param out_if: Outside interface
7502 :param ttl: TTL of generated packets
7506 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7507 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7508 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7512 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7513 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7514 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
7518 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
7519 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
7520 ICMP(id=self.icmp_id_in, type='echo-request'))
7525 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
7527 Create packet stream for outside network
7529 :param out_if: Outside interface
7530 :param dst_ip: Destination IP address (Default use global NAT address)
7531 :param ttl: TTL of generated packets
7534 dst_ip = self.nat_addr
7537 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7538 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7539 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
7543 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7544 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7545 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
7549 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
7550 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
7551 ICMP(id=self.icmp_external_id, type='echo-reply'))
7556 def verify_capture_out(self, capture, nat_ip=None):
7558 Verify captured packets on outside network
7560 :param capture: Captured packets
7561 :param nat_ip: Translated IP address (Default use global NAT address)
7562 :param same_port: Source port number is not translated (Default False)
7565 nat_ip = self.nat_addr
7566 for packet in capture:
7568 self.assertEqual(packet[IP].src, nat_ip)
7569 if packet.haslayer(TCP):
7570 self.tcp_port_out = packet[TCP].sport
7571 elif packet.haslayer(UDP):
7572 self.udp_port_out = packet[UDP].sport
7574 self.icmp_external_id = packet[ICMP].id
7576 self.logger.error(ppp("Unexpected or invalid packet "
7577 "(outside network):", packet))
7580 def test_deterministic_mode(self):
7581 """ NAT plugin run deterministic mode """
7582 in_addr = '172.16.255.0'
7583 out_addr = '172.17.255.50'
7584 in_addr_t = '172.16.255.20'
7588 nat_config = self.vapi.nat_show_config()
7589 self.assertEqual(1, nat_config.deterministic)
7591 self.vapi.nat_det_add_del_map(is_add=1, in_addr=in_addr,
7592 in_plen=in_plen, out_addr=out_addr,
7595 rep1 = self.vapi.nat_det_forward(in_addr_t)
7596 self.assertEqual(str(rep1.out_addr), out_addr)
7597 rep2 = self.vapi.nat_det_reverse(rep1.out_port_hi, out_addr)
7599 self.assertEqual(str(rep2.in_addr), in_addr_t)
7601 deterministic_mappings = self.vapi.nat_det_map_dump()
7602 self.assertEqual(len(deterministic_mappings), 1)
7603 dsm = deterministic_mappings[0]
7604 self.assertEqual(in_addr, str(dsm.in_addr))
7605 self.assertEqual(in_plen, dsm.in_plen)
7606 self.assertEqual(out_addr, str(dsm.out_addr))
7607 self.assertEqual(out_plen, dsm.out_plen)
7609 self.clear_nat_det()
7610 deterministic_mappings = self.vapi.nat_det_map_dump()
7611 self.assertEqual(len(deterministic_mappings), 0)
7613 def test_set_timeouts(self):
7614 """ Set deterministic NAT timeouts """
7615 timeouts_before = self.vapi.nat_get_timeouts()
7617 self.vapi.nat_set_timeouts(
7618 udp=timeouts_before.udp + 10,
7619 tcp_established=timeouts_before.tcp_established + 10,
7620 tcp_transitory=timeouts_before.tcp_transitory + 10,
7621 icmp=timeouts_before.icmp + 10)
7623 timeouts_after = self.vapi.nat_get_timeouts()
7625 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
7626 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
7627 self.assertNotEqual(timeouts_before.tcp_established,
7628 timeouts_after.tcp_established)
7629 self.assertNotEqual(timeouts_before.tcp_transitory,
7630 timeouts_after.tcp_transitory)
7632 def test_det_in(self):
7633 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
7635 nat_ip = "10.0.0.10"
7637 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7639 out_addr=socket.inet_aton(nat_ip),
7642 flags = self.config_flags.NAT_IS_INSIDE
7643 self.vapi.nat44_interface_add_del_feature(
7644 sw_if_index=self.pg0.sw_if_index,
7645 flags=flags, is_add=1)
7646 self.vapi.nat44_interface_add_del_feature(
7647 sw_if_index=self.pg1.sw_if_index,
7651 pkts = self.create_stream_in(self.pg0, self.pg1)
7652 self.pg0.add_stream(pkts)
7653 self.pg_enable_capture(self.pg_interfaces)
7655 capture = self.pg1.get_capture(len(pkts))
7656 self.verify_capture_out(capture, nat_ip)
7659 pkts = self.create_stream_out(self.pg1, nat_ip)
7660 self.pg1.add_stream(pkts)
7661 self.pg_enable_capture(self.pg_interfaces)
7663 capture = self.pg0.get_capture(len(pkts))
7664 self.verify_capture_in(capture, self.pg0)
7667 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4)
7668 self.assertEqual(len(sessions), 3)
7672 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7673 self.assertEqual(s.in_port, self.tcp_port_in)
7674 self.assertEqual(s.out_port, self.tcp_port_out)
7675 self.assertEqual(s.ext_port, self.tcp_external_port)
7679 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7680 self.assertEqual(s.in_port, self.udp_port_in)
7681 self.assertEqual(s.out_port, self.udp_port_out)
7682 self.assertEqual(s.ext_port, self.udp_external_port)
7686 self.assertEqual(str(s.ext_addr), self.pg1.remote_ip4)
7687 self.assertEqual(s.in_port, self.icmp_id_in)
7688 self.assertEqual(s.out_port, self.icmp_external_id)
7690 def test_multiple_users(self):
7691 """ Deterministic NAT multiple users """
7693 nat_ip = "10.0.0.10"
7695 external_port = 6303
7697 host0 = self.pg0.remote_hosts[0]
7698 host1 = self.pg0.remote_hosts[1]
7700 self.vapi.nat_det_add_del_map(is_add=1, in_addr=host0.ip4, in_plen=24,
7701 out_addr=socket.inet_aton(nat_ip),
7703 flags = self.config_flags.NAT_IS_INSIDE
7704 self.vapi.nat44_interface_add_del_feature(
7705 sw_if_index=self.pg0.sw_if_index,
7706 flags=flags, is_add=1)
7707 self.vapi.nat44_interface_add_del_feature(
7708 sw_if_index=self.pg1.sw_if_index,
7712 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
7713 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
7714 TCP(sport=port_in, dport=external_port))
7715 self.pg0.add_stream(p)
7716 self.pg_enable_capture(self.pg_interfaces)
7718 capture = self.pg1.get_capture(1)
7723 self.assertEqual(ip.src, nat_ip)
7724 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7725 self.assertEqual(tcp.dport, external_port)
7726 port_out0 = tcp.sport
7728 self.logger.error(ppp("Unexpected or invalid packet:", p))
7732 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
7733 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
7734 TCP(sport=port_in, dport=external_port))
7735 self.pg0.add_stream(p)
7736 self.pg_enable_capture(self.pg_interfaces)
7738 capture = self.pg1.get_capture(1)
7743 self.assertEqual(ip.src, nat_ip)
7744 self.assertEqual(ip.dst, self.pg1.remote_ip4)
7745 self.assertEqual(tcp.dport, external_port)
7746 port_out1 = tcp.sport
7748 self.logger.error(ppp("Unexpected or invalid packet:", p))
7751 dms = self.vapi.nat_det_map_dump()
7752 self.assertEqual(1, len(dms))
7753 self.assertEqual(2, dms[0].ses_num)
7756 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7757 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7758 TCP(sport=external_port, dport=port_out0))
7759 self.pg1.add_stream(p)
7760 self.pg_enable_capture(self.pg_interfaces)
7762 capture = self.pg0.get_capture(1)
7767 self.assertEqual(ip.src, self.pg1.remote_ip4)
7768 self.assertEqual(ip.dst, host0.ip4)
7769 self.assertEqual(tcp.dport, port_in)
7770 self.assertEqual(tcp.sport, external_port)
7772 self.logger.error(ppp("Unexpected or invalid packet:", p))
7776 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7777 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
7778 TCP(sport=external_port, dport=port_out1))
7779 self.pg1.add_stream(p)
7780 self.pg_enable_capture(self.pg_interfaces)
7782 capture = self.pg0.get_capture(1)
7787 self.assertEqual(ip.src, self.pg1.remote_ip4)
7788 self.assertEqual(ip.dst, host1.ip4)
7789 self.assertEqual(tcp.dport, port_in)
7790 self.assertEqual(tcp.sport, external_port)
7792 self.logger.error(ppp("Unexpected or invalid packet", p))
7795 # session close api test
7796 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
7798 self.pg1.remote_ip4,
7800 dms = self.vapi.nat_det_map_dump()
7801 self.assertEqual(dms[0].ses_num, 1)
7803 self.vapi.nat_det_close_session_in(host0.ip4,
7805 self.pg1.remote_ip4,
7807 dms = self.vapi.nat_det_map_dump()
7808 self.assertEqual(dms[0].ses_num, 0)
7810 def test_tcp_session_close_detection_in(self):
7811 """ Deterministic NAT TCP session close from inside network """
7812 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7814 out_addr=socket.inet_aton(self.nat_addr),
7816 flags = self.config_flags.NAT_IS_INSIDE
7817 self.vapi.nat44_interface_add_del_feature(
7818 sw_if_index=self.pg0.sw_if_index,
7819 flags=flags, is_add=1)
7820 self.vapi.nat44_interface_add_del_feature(
7821 sw_if_index=self.pg1.sw_if_index,
7824 self.initiate_tcp_session(self.pg0, self.pg1)
7826 # close the session from inside
7828 # FIN packet in -> out
7829 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7830 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7831 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7833 self.pg0.add_stream(p)
7834 self.pg_enable_capture(self.pg_interfaces)
7836 self.pg1.get_capture(1)
7840 # ACK packet out -> in
7841 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7842 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7843 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7847 # FIN packet out -> in
7848 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7849 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7850 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7854 self.pg1.add_stream(pkts)
7855 self.pg_enable_capture(self.pg_interfaces)
7857 self.pg0.get_capture(2)
7859 # ACK packet in -> out
7860 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7861 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7862 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7864 self.pg0.add_stream(p)
7865 self.pg_enable_capture(self.pg_interfaces)
7867 self.pg1.get_capture(1)
7869 # Check if deterministic NAT44 closed the session
7870 dms = self.vapi.nat_det_map_dump()
7871 self.assertEqual(0, dms[0].ses_num)
7873 self.logger.error("TCP session termination failed")
7876 def test_tcp_session_close_detection_out(self):
7877 """ Deterministic NAT TCP session close from outside network """
7878 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7880 out_addr=socket.inet_aton(self.nat_addr),
7882 flags = self.config_flags.NAT_IS_INSIDE
7883 self.vapi.nat44_interface_add_del_feature(
7884 sw_if_index=self.pg0.sw_if_index,
7885 flags=flags, is_add=1)
7886 self.vapi.nat44_interface_add_del_feature(
7887 sw_if_index=self.pg1.sw_if_index,
7890 self.initiate_tcp_session(self.pg0, self.pg1)
7892 # close the session from outside
7894 # FIN packet out -> in
7895 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7896 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7897 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7899 self.pg1.add_stream(p)
7900 self.pg_enable_capture(self.pg_interfaces)
7902 self.pg0.get_capture(1)
7906 # ACK packet in -> out
7907 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7908 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7909 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7913 # ACK packet in -> out
7914 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7915 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7916 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7920 self.pg0.add_stream(pkts)
7921 self.pg_enable_capture(self.pg_interfaces)
7923 self.pg1.get_capture(2)
7925 # ACK packet out -> in
7926 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
7927 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7928 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
7930 self.pg1.add_stream(p)
7931 self.pg_enable_capture(self.pg_interfaces)
7933 self.pg0.get_capture(1)
7935 # Check if deterministic NAT44 closed the session
7936 dms = self.vapi.nat_det_map_dump()
7937 self.assertEqual(0, dms[0].ses_num)
7939 self.logger.error("TCP session termination failed")
7942 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7943 def test_session_timeout(self):
7944 """ Deterministic NAT session timeouts """
7945 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7947 out_addr=socket.inet_aton(self.nat_addr),
7949 flags = self.config_flags.NAT_IS_INSIDE
7950 self.vapi.nat44_interface_add_del_feature(
7951 sw_if_index=self.pg0.sw_if_index,
7952 flags=flags, is_add=1)
7953 self.vapi.nat44_interface_add_del_feature(
7954 sw_if_index=self.pg1.sw_if_index,
7957 self.initiate_tcp_session(self.pg0, self.pg1)
7958 self.vapi.nat_set_timeouts(udp=5, tcp_established=5, tcp_transitory=5,
7960 pkts = self.create_stream_in(self.pg0, self.pg1)
7961 self.pg0.add_stream(pkts)
7962 self.pg_enable_capture(self.pg_interfaces)
7964 capture = self.pg1.get_capture(len(pkts))
7967 dms = self.vapi.nat_det_map_dump()
7968 self.assertEqual(0, dms[0].ses_num)
7970 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7971 def test_session_limit_per_user(self):
7972 """ Deterministic NAT maximum sessions per user limit """
7973 self.vapi.nat_det_add_del_map(is_add=1, in_addr=self.pg0.remote_ip4,
7975 out_addr=socket.inet_aton(self.nat_addr),
7977 flags = self.config_flags.NAT_IS_INSIDE
7978 self.vapi.nat44_interface_add_del_feature(
7979 sw_if_index=self.pg0.sw_if_index,
7980 flags=flags, is_add=1)
7981 self.vapi.nat44_interface_add_del_feature(
7982 sw_if_index=self.pg1.sw_if_index,
7984 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4,
7985 src_address=self.pg2.local_ip4,
7987 template_interval=10)
7988 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
7992 for port in range(1025, 2025):
7993 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7994 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7995 UDP(sport=port, dport=port))
7998 self.pg0.add_stream(pkts)
7999 self.pg_enable_capture(self.pg_interfaces)
8001 capture = self.pg1.get_capture(len(pkts))
8003 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8004 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
8005 UDP(sport=3001, dport=3002))
8006 self.pg0.add_stream(p)
8007 self.pg_enable_capture(self.pg_interfaces)
8009 capture = self.pg1.assert_nothing_captured()
8011 # verify ICMP error packet
8012 capture = self.pg0.get_capture(1)
8014 self.assertTrue(p.haslayer(ICMP))
8016 self.assertEqual(icmp.type, 3)
8017 self.assertEqual(icmp.code, 1)
8018 self.assertTrue(icmp.haslayer(IPerror))
8019 inner_ip = icmp[IPerror]
8020 self.assertEqual(inner_ip[UDPerror].sport, 3001)
8021 self.assertEqual(inner_ip[UDPerror].dport, 3002)
8023 dms = self.vapi.nat_det_map_dump()
8025 self.assertEqual(1000, dms[0].ses_num)
8027 # verify IPFIX logging
8028 self.vapi.ipfix_flush()
8030 capture = self.pg2.get_capture(2)
8031 ipfix = IPFIXDecoder()
8032 # first load template
8034 self.assertTrue(p.haslayer(IPFIX))
8035 if p.haslayer(Template):
8036 ipfix.add_template(p.getlayer(Template))
8037 # verify events in data set
8039 if p.haslayer(Data):
8040 data = ipfix.decode_data_set(p.getlayer(Set))
8041 self.verify_ipfix_max_entries_per_user(data,
8043 self.pg0.remote_ip4)
8045 def clear_nat_det(self):
8047 Clear deterministic NAT configuration.
8049 self.vapi.nat_ipfix_enable_disable(domain_id=1, src_port=4739,
8051 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8052 tcp_transitory=240, icmp=60)
8053 deterministic_mappings = self.vapi.nat_det_map_dump()
8054 for dsm in deterministic_mappings:
8055 self.vapi.nat_det_add_del_map(is_add=0, in_addr=dsm.in_addr,
8056 in_plen=dsm.in_plen,
8057 out_addr=dsm.out_addr,
8058 out_plen=dsm.out_plen)
8060 interfaces = self.vapi.nat44_interface_dump()
8061 for intf in interfaces:
8062 self.vapi.nat44_interface_add_del_feature(
8063 sw_if_index=intf.sw_if_index,
8067 super(TestDeterministicNAT, self).tearDown()
8068 if not self.vpp_dead:
8069 self.clear_nat_det()
8071 def show_commands_at_teardown(self):
8072 self.logger.info(self.vapi.cli("show nat44 interfaces"))
8073 self.logger.info(self.vapi.cli("show nat timeouts"))
8075 self.vapi.cli("show nat44 deterministic mappings"))
8077 self.vapi.cli("show nat44 deterministic sessions"))
8080 class TestNAT64(MethodHolder):
8081 """ NAT64 Test Cases """
8084 def setUpConstants(cls):
8085 super(TestNAT64, cls).setUpConstants()
8086 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
8087 "nat64 st hash buckets 256", "}"])
8090 def setUpClass(cls):
8091 super(TestNAT64, cls).setUpClass()
8093 cls.tcp_port_in = 6303
8094 cls.tcp_port_out = 6303
8095 cls.udp_port_in = 6304
8096 cls.udp_port_out = 6304
8097 cls.icmp_id_in = 6305
8098 cls.icmp_id_out = 6305
8099 cls.tcp_external_port = 80
8100 cls.nat_addr = '10.0.0.3'
8101 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8103 cls.vrf1_nat_addr = '10.0.10.3'
8104 cls.ipfix_src_port = 4739
8105 cls.ipfix_domain_id = 1
8107 cls.create_pg_interfaces(range(6))
8108 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
8109 cls.ip6_interfaces.append(cls.pg_interfaces[2])
8110 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
8112 cls.vapi.ip_table_add_del(is_add=1,
8113 table={'table_id': cls.vrf1_id,
8116 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
8118 cls.pg0.generate_remote_hosts(2)
8120 for i in cls.ip6_interfaces:
8123 i.configure_ipv6_neighbors()
8125 for i in cls.ip4_interfaces:
8131 cls.pg3.config_ip4()
8132 cls.pg3.resolve_arp()
8133 cls.pg3.config_ip6()
8134 cls.pg3.configure_ipv6_neighbors()
8137 cls.pg5.config_ip6()
8140 def tearDownClass(cls):
8141 super(TestNAT64, cls).tearDownClass()
8143 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
8144 """ NAT64 inside interface handles Neighbor Advertisement """
8146 flags = self.config_flags.NAT_IS_INSIDE
8147 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8148 sw_if_index=self.pg5.sw_if_index)
8151 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8152 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8153 ICMPv6EchoRequest())
8155 self.pg5.add_stream(pkts)
8156 self.pg_enable_capture(self.pg_interfaces)
8159 # Wait for Neighbor Solicitation
8160 capture = self.pg5.get_capture(len(pkts))
8163 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8164 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
8165 tgt = packet[ICMPv6ND_NS].tgt
8167 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8170 # Send Neighbor Advertisement
8171 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
8172 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
8173 ICMPv6ND_NA(tgt=tgt) /
8174 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
8176 self.pg5.add_stream(pkts)
8177 self.pg_enable_capture(self.pg_interfaces)
8180 # Try to send ping again
8182 self.pg5.add_stream(pkts)
8183 self.pg_enable_capture(self.pg_interfaces)
8186 # Wait for ping reply
8187 capture = self.pg5.get_capture(len(pkts))
8190 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
8191 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
8192 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
8194 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8197 def test_pool(self):
8198 """ Add/delete address to NAT64 pool """
8199 nat_addr = '1.2.3.4'
8201 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8203 vrf_id=0xFFFFFFFF, is_add=1)
8205 addresses = self.vapi.nat64_pool_addr_dump()
8206 self.assertEqual(len(addresses), 1)
8207 self.assertEqual(str(addresses[0].address), nat_addr)
8209 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
8211 vrf_id=0xFFFFFFFF, is_add=0)
8213 addresses = self.vapi.nat64_pool_addr_dump()
8214 self.assertEqual(len(addresses), 0)
8216 def test_interface(self):
8217 """ Enable/disable NAT64 feature on the interface """
8218 flags = self.config_flags.NAT_IS_INSIDE
8219 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8220 sw_if_index=self.pg0.sw_if_index)
8221 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8222 sw_if_index=self.pg1.sw_if_index)
8224 interfaces = self.vapi.nat64_interface_dump()
8225 self.assertEqual(len(interfaces), 2)
8228 for intf in interfaces:
8229 if intf.sw_if_index == self.pg0.sw_if_index:
8230 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
8232 elif intf.sw_if_index == self.pg1.sw_if_index:
8233 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
8235 self.assertTrue(pg0_found)
8236 self.assertTrue(pg1_found)
8238 features = self.vapi.cli("show interface features pg0")
8239 self.assertIn('nat64-in2out', features)
8240 features = self.vapi.cli("show interface features pg1")
8241 self.assertIn('nat64-out2in', features)
8243 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8244 sw_if_index=self.pg0.sw_if_index)
8245 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
8246 sw_if_index=self.pg1.sw_if_index)
8248 interfaces = self.vapi.nat64_interface_dump()
8249 self.assertEqual(len(interfaces), 0)
8251 def test_static_bib(self):
8252 """ Add/delete static BIB entry """
8253 in_addr = '2001:db8:85a3::8a2e:370:7334'
8254 out_addr = '10.1.1.3'
8257 proto = IP_PROTOS.tcp
8259 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8260 i_port=in_port, o_port=out_port,
8261 proto=proto, vrf_id=0, is_add=1)
8262 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8265 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8267 self.assertEqual(str(bibe.i_addr), in_addr)
8268 self.assertEqual(str(bibe.o_addr), out_addr)
8269 self.assertEqual(bibe.i_port, in_port)
8270 self.assertEqual(bibe.o_port, out_port)
8271 self.assertEqual(static_bib_num, 1)
8272 bibs = self.statistics.get_counter('/nat64/total-bibs')
8273 self.assertEqual(bibs[0][0], 1)
8275 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
8276 i_port=in_port, o_port=out_port,
8277 proto=proto, vrf_id=0, is_add=0)
8278 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
8281 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8283 self.assertEqual(static_bib_num, 0)
8284 bibs = self.statistics.get_counter('/nat64/total-bibs')
8285 self.assertEqual(bibs[0][0], 0)
8287 def test_set_timeouts(self):
8288 """ Set NAT64 timeouts """
8289 # verify default values
8290 timeouts = self.vapi.nat_get_timeouts()
8291 self.assertEqual(timeouts.udp, 300)
8292 self.assertEqual(timeouts.icmp, 60)
8293 self.assertEqual(timeouts.tcp_transitory, 240)
8294 self.assertEqual(timeouts.tcp_established, 7440)
8296 # set and verify custom values
8297 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
8298 tcp_transitory=250, icmp=30)
8299 timeouts = self.vapi.nat_get_timeouts()
8300 self.assertEqual(timeouts.udp, 200)
8301 self.assertEqual(timeouts.icmp, 30)
8302 self.assertEqual(timeouts.tcp_transitory, 250)
8303 self.assertEqual(timeouts.tcp_established, 7450)
8305 def test_dynamic(self):
8306 """ NAT64 dynamic translation test """
8307 self.tcp_port_in = 6303
8308 self.udp_port_in = 6304
8309 self.icmp_id_in = 6305
8311 ses_num_start = self.nat64_get_ses_num()
8313 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8314 end_addr=self.nat_addr,
8317 flags = self.config_flags.NAT_IS_INSIDE
8318 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8319 sw_if_index=self.pg0.sw_if_index)
8320 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8321 sw_if_index=self.pg1.sw_if_index)
8324 tcpn = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8325 udpn = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8326 icmpn = self.statistics.get_err_counter(
8327 '/err/nat64-in2out/ICMP packets')
8328 totaln = self.statistics.get_err_counter(
8329 '/err/nat64-in2out/good in2out packets processed')
8331 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8332 self.pg0.add_stream(pkts)
8333 self.pg_enable_capture(self.pg_interfaces)
8335 capture = self.pg1.get_capture(len(pkts))
8336 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8337 dst_ip=self.pg1.remote_ip4)
8339 err = self.statistics.get_err_counter('/err/nat64-in2out/TCP packets')
8340 self.assertEqual(err - tcpn, 1)
8341 err = self.statistics.get_err_counter('/err/nat64-in2out/UDP packets')
8342 self.assertEqual(err - udpn, 1)
8343 err = self.statistics.get_err_counter('/err/nat64-in2out/ICMP packets')
8344 self.assertEqual(err - icmpn, 1)
8345 err = self.statistics.get_err_counter(
8346 '/err/nat64-in2out/good in2out packets processed')
8347 self.assertEqual(err - totaln, 3)
8350 tcpn = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8351 udpn = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8352 icmpn = self.statistics.get_err_counter(
8353 '/err/nat64-out2in/ICMP packets')
8354 totaln = self.statistics.get_err_counter(
8355 '/err/nat64-out2in/good out2in packets processed')
8357 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8358 self.pg1.add_stream(pkts)
8359 self.pg_enable_capture(self.pg_interfaces)
8361 capture = self.pg0.get_capture(len(pkts))
8362 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8363 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8365 err = self.statistics.get_err_counter('/err/nat64-out2in/TCP packets')
8366 self.assertEqual(err - tcpn, 2)
8367 err = self.statistics.get_err_counter('/err/nat64-out2in/UDP packets')
8368 self.assertEqual(err - udpn, 1)
8369 err = self.statistics.get_err_counter('/err/nat64-out2in/ICMP packets')
8370 self.assertEqual(err - icmpn, 1)
8371 err = self.statistics.get_err_counter(
8372 '/err/nat64-out2in/good out2in packets processed')
8373 self.assertEqual(err - totaln, 4)
8375 bibs = self.statistics.get_counter('/nat64/total-bibs')
8376 self.assertEqual(bibs[0][0], 3)
8377 sessions = self.statistics.get_counter('/nat64/total-sessions')
8378 self.assertEqual(sessions[0][0], 3)
8381 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8382 self.pg0.add_stream(pkts)
8383 self.pg_enable_capture(self.pg_interfaces)
8385 capture = self.pg1.get_capture(len(pkts))
8386 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8387 dst_ip=self.pg1.remote_ip4)
8390 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8391 self.pg1.add_stream(pkts)
8392 self.pg_enable_capture(self.pg_interfaces)
8394 capture = self.pg0.get_capture(len(pkts))
8395 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8397 ses_num_end = self.nat64_get_ses_num()
8399 self.assertEqual(ses_num_end - ses_num_start, 3)
8401 # tenant with specific VRF
8402 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8403 end_addr=self.vrf1_nat_addr,
8404 vrf_id=self.vrf1_id, is_add=1)
8405 flags = self.config_flags.NAT_IS_INSIDE
8406 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8407 sw_if_index=self.pg2.sw_if_index)
8409 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
8410 self.pg2.add_stream(pkts)
8411 self.pg_enable_capture(self.pg_interfaces)
8413 capture = self.pg1.get_capture(len(pkts))
8414 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8415 dst_ip=self.pg1.remote_ip4)
8417 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8418 self.pg1.add_stream(pkts)
8419 self.pg_enable_capture(self.pg_interfaces)
8421 capture = self.pg2.get_capture(len(pkts))
8422 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
8424 def test_static(self):
8425 """ NAT64 static translation test """
8426 self.tcp_port_in = 60303
8427 self.udp_port_in = 60304
8428 self.icmp_id_in = 60305
8429 self.tcp_port_out = 60303
8430 self.udp_port_out = 60304
8431 self.icmp_id_out = 60305
8433 ses_num_start = self.nat64_get_ses_num()
8435 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8436 end_addr=self.nat_addr,
8439 flags = self.config_flags.NAT_IS_INSIDE
8440 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8441 sw_if_index=self.pg0.sw_if_index)
8442 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8443 sw_if_index=self.pg1.sw_if_index)
8445 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8446 o_addr=self.nat_addr,
8447 i_port=self.tcp_port_in,
8448 o_port=self.tcp_port_out,
8449 proto=IP_PROTOS.tcp, vrf_id=0,
8451 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8452 o_addr=self.nat_addr,
8453 i_port=self.udp_port_in,
8454 o_port=self.udp_port_out,
8455 proto=IP_PROTOS.udp, vrf_id=0,
8457 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
8458 o_addr=self.nat_addr,
8459 i_port=self.icmp_id_in,
8460 o_port=self.icmp_id_out,
8461 proto=IP_PROTOS.icmp, vrf_id=0,
8465 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8466 self.pg0.add_stream(pkts)
8467 self.pg_enable_capture(self.pg_interfaces)
8469 capture = self.pg1.get_capture(len(pkts))
8470 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8471 dst_ip=self.pg1.remote_ip4, same_port=True)
8474 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8475 self.pg1.add_stream(pkts)
8476 self.pg_enable_capture(self.pg_interfaces)
8478 capture = self.pg0.get_capture(len(pkts))
8479 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8480 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
8482 ses_num_end = self.nat64_get_ses_num()
8484 self.assertEqual(ses_num_end - ses_num_start, 3)
8486 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8487 def test_session_timeout(self):
8488 """ NAT64 session timeout """
8489 self.icmp_id_in = 1234
8490 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8491 end_addr=self.nat_addr,
8494 flags = self.config_flags.NAT_IS_INSIDE
8495 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8496 sw_if_index=self.pg0.sw_if_index)
8497 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8498 sw_if_index=self.pg1.sw_if_index)
8499 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
8503 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8504 self.pg0.add_stream(pkts)
8505 self.pg_enable_capture(self.pg_interfaces)
8507 capture = self.pg1.get_capture(len(pkts))
8509 ses_num_before_timeout = self.nat64_get_ses_num()
8513 # ICMP and TCP session after timeout
8514 ses_num_after_timeout = self.nat64_get_ses_num()
8515 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
8517 def test_icmp_error(self):
8518 """ NAT64 ICMP Error message translation """
8519 self.tcp_port_in = 6303
8520 self.udp_port_in = 6304
8521 self.icmp_id_in = 6305
8523 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8524 end_addr=self.nat_addr,
8527 flags = self.config_flags.NAT_IS_INSIDE
8528 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8529 sw_if_index=self.pg0.sw_if_index)
8530 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8531 sw_if_index=self.pg1.sw_if_index)
8533 # send some packets to create sessions
8534 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
8535 self.pg0.add_stream(pkts)
8536 self.pg_enable_capture(self.pg_interfaces)
8538 capture_ip4 = self.pg1.get_capture(len(pkts))
8539 self.verify_capture_out(capture_ip4,
8540 nat_ip=self.nat_addr,
8541 dst_ip=self.pg1.remote_ip4)
8543 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8544 self.pg1.add_stream(pkts)
8545 self.pg_enable_capture(self.pg_interfaces)
8547 capture_ip6 = self.pg0.get_capture(len(pkts))
8548 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
8549 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
8550 self.pg0.remote_ip6)
8553 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8554 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
8555 ICMPv6DestUnreach(code=1) /
8556 packet[IPv6] for packet in capture_ip6]
8557 self.pg0.add_stream(pkts)
8558 self.pg_enable_capture(self.pg_interfaces)
8560 capture = self.pg1.get_capture(len(pkts))
8561 for packet in capture:
8563 self.assertEqual(packet[IP].src, self.nat_addr)
8564 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8565 self.assertEqual(packet[ICMP].type, 3)
8566 self.assertEqual(packet[ICMP].code, 13)
8567 inner = packet[IPerror]
8568 self.assertEqual(inner.src, self.pg1.remote_ip4)
8569 self.assertEqual(inner.dst, self.nat_addr)
8570 self.assert_packet_checksums_valid(packet)
8571 if inner.haslayer(TCPerror):
8572 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
8573 elif inner.haslayer(UDPerror):
8574 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8576 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8578 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8582 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8583 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8584 ICMP(type=3, code=13) /
8585 packet[IP] for packet in capture_ip4]
8586 self.pg1.add_stream(pkts)
8587 self.pg_enable_capture(self.pg_interfaces)
8589 capture = self.pg0.get_capture(len(pkts))
8590 for packet in capture:
8592 self.assertEqual(packet[IPv6].src, ip.src)
8593 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8594 icmp = packet[ICMPv6DestUnreach]
8595 self.assertEqual(icmp.code, 1)
8596 inner = icmp[IPerror6]
8597 self.assertEqual(inner.src, self.pg0.remote_ip6)
8598 self.assertEqual(inner.dst, ip.src)
8599 self.assert_icmpv6_checksum_valid(packet)
8600 if inner.haslayer(TCPerror):
8601 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8602 elif inner.haslayer(UDPerror):
8603 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8605 self.assertEqual(inner[ICMPv6EchoRequest].id,
8608 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8611 def test_hairpinning(self):
8612 """ NAT64 hairpinning """
8614 client = self.pg0.remote_hosts[0]
8615 server = self.pg0.remote_hosts[1]
8616 server_tcp_in_port = 22
8617 server_tcp_out_port = 4022
8618 server_udp_in_port = 23
8619 server_udp_out_port = 4023
8620 client_tcp_in_port = 1234
8621 client_udp_in_port = 1235
8622 client_tcp_out_port = 0
8623 client_udp_out_port = 0
8624 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8625 nat_addr_ip6 = ip.src
8627 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8628 end_addr=self.nat_addr,
8631 flags = self.config_flags.NAT_IS_INSIDE
8632 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8633 sw_if_index=self.pg0.sw_if_index)
8634 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8635 sw_if_index=self.pg1.sw_if_index)
8637 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8638 o_addr=self.nat_addr,
8639 i_port=server_tcp_in_port,
8640 o_port=server_tcp_out_port,
8641 proto=IP_PROTOS.tcp, vrf_id=0,
8643 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8644 o_addr=self.nat_addr,
8645 i_port=server_udp_in_port,
8646 o_port=server_udp_out_port,
8647 proto=IP_PROTOS.udp, vrf_id=0,
8652 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8653 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8654 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8656 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8657 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8658 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8660 self.pg0.add_stream(pkts)
8661 self.pg_enable_capture(self.pg_interfaces)
8663 capture = self.pg0.get_capture(len(pkts))
8664 for packet in capture:
8666 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8667 self.assertEqual(packet[IPv6].dst, server.ip6)
8668 self.assert_packet_checksums_valid(packet)
8669 if packet.haslayer(TCP):
8670 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8671 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8672 client_tcp_out_port = packet[TCP].sport
8674 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8675 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8676 client_udp_out_port = packet[UDP].sport
8678 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8683 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8684 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8685 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8687 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8688 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8689 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8691 self.pg0.add_stream(pkts)
8692 self.pg_enable_capture(self.pg_interfaces)
8694 capture = self.pg0.get_capture(len(pkts))
8695 for packet in capture:
8697 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8698 self.assertEqual(packet[IPv6].dst, client.ip6)
8699 self.assert_packet_checksums_valid(packet)
8700 if packet.haslayer(TCP):
8701 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8702 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8704 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8705 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8707 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8712 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8713 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8714 ICMPv6DestUnreach(code=1) /
8715 packet[IPv6] for packet in capture]
8716 self.pg0.add_stream(pkts)
8717 self.pg_enable_capture(self.pg_interfaces)
8719 capture = self.pg0.get_capture(len(pkts))
8720 for packet in capture:
8722 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8723 self.assertEqual(packet[IPv6].dst, server.ip6)
8724 icmp = packet[ICMPv6DestUnreach]
8725 self.assertEqual(icmp.code, 1)
8726 inner = icmp[IPerror6]
8727 self.assertEqual(inner.src, server.ip6)
8728 self.assertEqual(inner.dst, nat_addr_ip6)
8729 self.assert_packet_checksums_valid(packet)
8730 if inner.haslayer(TCPerror):
8731 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8732 self.assertEqual(inner[TCPerror].dport,
8733 client_tcp_out_port)
8735 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8736 self.assertEqual(inner[UDPerror].dport,
8737 client_udp_out_port)
8739 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8742 def test_prefix(self):
8743 """ NAT64 Network-Specific Prefix """
8745 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8746 end_addr=self.nat_addr,
8749 flags = self.config_flags.NAT_IS_INSIDE
8750 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8751 sw_if_index=self.pg0.sw_if_index)
8752 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8753 sw_if_index=self.pg1.sw_if_index)
8754 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8755 end_addr=self.vrf1_nat_addr,
8756 vrf_id=self.vrf1_id, is_add=1)
8757 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8758 sw_if_index=self.pg2.sw_if_index)
8761 global_pref64 = "2001:db8::"
8762 global_pref64_len = 32
8763 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8764 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8767 prefix = self.vapi.nat64_prefix_dump()
8768 self.assertEqual(len(prefix), 1)
8769 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8770 self.assertEqual(prefix[0].vrf_id, 0)
8772 # Add tenant specific prefix
8773 vrf1_pref64 = "2001:db8:122:300::"
8774 vrf1_pref64_len = 56
8775 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8776 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8777 vrf_id=self.vrf1_id, is_add=1)
8779 prefix = self.vapi.nat64_prefix_dump()
8780 self.assertEqual(len(prefix), 2)
8783 pkts = self.create_stream_in_ip6(self.pg0,
8786 plen=global_pref64_len)
8787 self.pg0.add_stream(pkts)
8788 self.pg_enable_capture(self.pg_interfaces)
8790 capture = self.pg1.get_capture(len(pkts))
8791 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8792 dst_ip=self.pg1.remote_ip4)
8794 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8795 self.pg1.add_stream(pkts)
8796 self.pg_enable_capture(self.pg_interfaces)
8798 capture = self.pg0.get_capture(len(pkts))
8799 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8802 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8804 # Tenant specific prefix
8805 pkts = self.create_stream_in_ip6(self.pg2,
8808 plen=vrf1_pref64_len)
8809 self.pg2.add_stream(pkts)
8810 self.pg_enable_capture(self.pg_interfaces)
8812 capture = self.pg1.get_capture(len(pkts))
8813 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8814 dst_ip=self.pg1.remote_ip4)
8816 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8817 self.pg1.add_stream(pkts)
8818 self.pg_enable_capture(self.pg_interfaces)
8820 capture = self.pg2.get_capture(len(pkts))
8821 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8824 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8826 def test_unknown_proto(self):
8827 """ NAT64 translate packet with unknown protocol """
8829 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8830 end_addr=self.nat_addr,
8833 flags = self.config_flags.NAT_IS_INSIDE
8834 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8835 sw_if_index=self.pg0.sw_if_index)
8836 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8837 sw_if_index=self.pg1.sw_if_index)
8838 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8841 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8842 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8843 TCP(sport=self.tcp_port_in, dport=20))
8844 self.pg0.add_stream(p)
8845 self.pg_enable_capture(self.pg_interfaces)
8847 p = self.pg1.get_capture(1)
8849 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8850 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8852 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8853 TCP(sport=1234, dport=1234))
8854 self.pg0.add_stream(p)
8855 self.pg_enable_capture(self.pg_interfaces)
8857 p = self.pg1.get_capture(1)
8860 self.assertEqual(packet[IP].src, self.nat_addr)
8861 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8862 self.assertEqual(packet.haslayer(GRE), 1)
8863 self.assert_packet_checksums_valid(packet)
8865 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8869 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8870 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8872 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8873 TCP(sport=1234, dport=1234))
8874 self.pg1.add_stream(p)
8875 self.pg_enable_capture(self.pg_interfaces)
8877 p = self.pg0.get_capture(1)
8880 self.assertEqual(packet[IPv6].src, remote_ip6)
8881 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8882 self.assertEqual(packet[IPv6].nh, 47)
8884 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8887 def test_hairpinning_unknown_proto(self):
8888 """ NAT64 translate packet with unknown protocol - hairpinning """
8890 client = self.pg0.remote_hosts[0]
8891 server = self.pg0.remote_hosts[1]
8892 server_tcp_in_port = 22
8893 server_tcp_out_port = 4022
8894 client_tcp_in_port = 1234
8895 client_tcp_out_port = 1235
8896 server_nat_ip = "10.0.0.100"
8897 client_nat_ip = "10.0.0.110"
8898 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8899 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8901 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8902 end_addr=client_nat_ip,
8905 flags = self.config_flags.NAT_IS_INSIDE
8906 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8907 sw_if_index=self.pg0.sw_if_index)
8908 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8909 sw_if_index=self.pg1.sw_if_index)
8911 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8912 o_addr=server_nat_ip,
8913 i_port=server_tcp_in_port,
8914 o_port=server_tcp_out_port,
8915 proto=IP_PROTOS.tcp, vrf_id=0,
8918 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8919 o_addr=server_nat_ip, i_port=0,
8921 proto=IP_PROTOS.gre, vrf_id=0,
8924 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8925 o_addr=client_nat_ip,
8926 i_port=client_tcp_in_port,
8927 o_port=client_tcp_out_port,
8928 proto=IP_PROTOS.tcp, vrf_id=0,
8932 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8933 IPv6(src=client.ip6, dst=server_nat_ip6) /
8934 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8935 self.pg0.add_stream(p)
8936 self.pg_enable_capture(self.pg_interfaces)
8938 p = self.pg0.get_capture(1)
8940 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8941 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8943 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8944 TCP(sport=1234, dport=1234))
8945 self.pg0.add_stream(p)
8946 self.pg_enable_capture(self.pg_interfaces)
8948 p = self.pg0.get_capture(1)
8951 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8952 self.assertEqual(packet[IPv6].dst, server.ip6)
8953 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8955 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8959 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8960 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8962 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8963 TCP(sport=1234, dport=1234))
8964 self.pg0.add_stream(p)
8965 self.pg_enable_capture(self.pg_interfaces)
8967 p = self.pg0.get_capture(1)
8970 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8971 self.assertEqual(packet[IPv6].dst, client.ip6)
8972 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8974 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8977 def test_one_armed_nat64(self):
8978 """ One armed NAT64 """
8980 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8984 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8985 end_addr=self.nat_addr,
8988 flags = self.config_flags.NAT_IS_INSIDE
8989 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8990 sw_if_index=self.pg3.sw_if_index)
8991 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8992 sw_if_index=self.pg3.sw_if_index)
8995 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8996 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8997 TCP(sport=12345, dport=80))
8998 self.pg3.add_stream(p)
8999 self.pg_enable_capture(self.pg_interfaces)
9001 capture = self.pg3.get_capture(1)
9006 self.assertEqual(ip.src, self.nat_addr)
9007 self.assertEqual(ip.dst, self.pg3.remote_ip4)
9008 self.assertNotEqual(tcp.sport, 12345)
9009 external_port = tcp.sport
9010 self.assertEqual(tcp.dport, 80)
9011 self.assert_packet_checksums_valid(p)
9013 self.logger.error(ppp("Unexpected or invalid packet:", p))
9017 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
9018 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
9019 TCP(sport=80, dport=external_port))
9020 self.pg3.add_stream(p)
9021 self.pg_enable_capture(self.pg_interfaces)
9023 capture = self.pg3.get_capture(1)
9028 self.assertEqual(ip.src, remote_host_ip6)
9029 self.assertEqual(ip.dst, self.pg3.remote_ip6)
9030 self.assertEqual(tcp.sport, 80)
9031 self.assertEqual(tcp.dport, 12345)
9032 self.assert_packet_checksums_valid(p)
9034 self.logger.error(ppp("Unexpected or invalid packet:", p))
9037 def test_frag_in_order(self):
9038 """ NAT64 translate fragments arriving in order """
9039 self.tcp_port_in = random.randint(1025, 65535)
9041 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9042 end_addr=self.nat_addr,
9045 flags = self.config_flags.NAT_IS_INSIDE
9046 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9047 sw_if_index=self.pg0.sw_if_index)
9048 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9049 sw_if_index=self.pg1.sw_if_index)
9053 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9054 self.tcp_port_in, 20, data)
9055 self.pg0.add_stream(pkts)
9056 self.pg_enable_capture(self.pg_interfaces)
9058 frags = self.pg1.get_capture(len(pkts))
9059 p = self.reass_frags_and_verify(frags,
9061 self.pg1.remote_ip4)
9062 self.assertEqual(p[TCP].dport, 20)
9063 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9064 self.tcp_port_out = p[TCP].sport
9065 self.assertEqual(data, p[Raw].load)
9068 data = b"A" * 4 + b"b" * 16 + b"C" * 3
9069 pkts = self.create_stream_frag(self.pg1,
9074 self.pg1.add_stream(pkts)
9075 self.pg_enable_capture(self.pg_interfaces)
9077 frags = self.pg0.get_capture(len(pkts))
9078 self.logger.debug(ppc("Captured:", frags))
9079 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9080 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9081 self.assertEqual(p[TCP].sport, 20)
9082 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9083 self.assertEqual(data, p[Raw].load)
9085 def test_reass_hairpinning(self):
9086 """ NAT64 fragments hairpinning """
9088 server = self.pg0.remote_hosts[1]
9089 server_in_port = random.randint(1025, 65535)
9090 server_out_port = random.randint(1025, 65535)
9091 client_in_port = random.randint(1025, 65535)
9092 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
9093 nat_addr_ip6 = ip.src
9095 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9096 end_addr=self.nat_addr,
9099 flags = self.config_flags.NAT_IS_INSIDE
9100 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9101 sw_if_index=self.pg0.sw_if_index)
9102 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9103 sw_if_index=self.pg1.sw_if_index)
9105 # add static BIB entry for server
9106 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
9107 o_addr=self.nat_addr,
9108 i_port=server_in_port,
9109 o_port=server_out_port,
9110 proto=IP_PROTOS.tcp, vrf_id=0,
9113 # send packet from host to server
9114 pkts = self.create_stream_frag_ip6(self.pg0,
9119 self.pg0.add_stream(pkts)
9120 self.pg_enable_capture(self.pg_interfaces)
9122 frags = self.pg0.get_capture(len(pkts))
9123 self.logger.debug(ppc("Captured:", frags))
9124 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
9125 self.assertNotEqual(p[TCP].sport, client_in_port)
9126 self.assertEqual(p[TCP].dport, server_in_port)
9127 self.assertEqual(data, p[Raw].load)
9129 def test_frag_out_of_order(self):
9130 """ NAT64 translate fragments arriving out of order """
9131 self.tcp_port_in = random.randint(1025, 65535)
9133 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9134 end_addr=self.nat_addr,
9137 flags = self.config_flags.NAT_IS_INSIDE
9138 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9139 sw_if_index=self.pg0.sw_if_index)
9140 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9141 sw_if_index=self.pg1.sw_if_index)
9145 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
9146 self.tcp_port_in, 20, data)
9148 self.pg0.add_stream(pkts)
9149 self.pg_enable_capture(self.pg_interfaces)
9151 frags = self.pg1.get_capture(len(pkts))
9152 p = self.reass_frags_and_verify(frags,
9154 self.pg1.remote_ip4)
9155 self.assertEqual(p[TCP].dport, 20)
9156 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
9157 self.tcp_port_out = p[TCP].sport
9158 self.assertEqual(data, p[Raw].load)
9161 data = b"A" * 4 + b"B" * 16 + b"C" * 3
9162 pkts = self.create_stream_frag(self.pg1,
9168 self.pg1.add_stream(pkts)
9169 self.pg_enable_capture(self.pg_interfaces)
9171 frags = self.pg0.get_capture(len(pkts))
9172 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
9173 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
9174 self.assertEqual(p[TCP].sport, 20)
9175 self.assertEqual(p[TCP].dport, self.tcp_port_in)
9176 self.assertEqual(data, p[Raw].load)
9178 def test_interface_addr(self):
9179 """ Acquire NAT64 pool addresses from interface """
9180 self.vapi.nat64_add_del_interface_addr(
9182 sw_if_index=self.pg4.sw_if_index)
9184 # no address in NAT64 pool
9185 addresses = self.vapi.nat44_address_dump()
9186 self.assertEqual(0, len(addresses))
9188 # configure interface address and check NAT64 address pool
9189 self.pg4.config_ip4()
9190 addresses = self.vapi.nat64_pool_addr_dump()
9191 self.assertEqual(len(addresses), 1)
9193 self.assertEqual(str(addresses[0].address),
9196 # remove interface address and check NAT64 address pool
9197 self.pg4.unconfig_ip4()
9198 addresses = self.vapi.nat64_pool_addr_dump()
9199 self.assertEqual(0, len(addresses))
9201 @unittest.skipUnless(running_extended_tests, "part of extended tests")
9202 def test_ipfix_max_bibs_sessions(self):
9203 """ IPFIX logging maximum session and BIB entries exceeded """
9206 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9210 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9211 end_addr=self.nat_addr,
9214 flags = self.config_flags.NAT_IS_INSIDE
9215 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9216 sw_if_index=self.pg0.sw_if_index)
9217 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9218 sw_if_index=self.pg1.sw_if_index)
9222 for i in range(0, max_bibs):
9223 src = "fd01:aa::%x" % (i)
9224 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9225 IPv6(src=src, dst=remote_host_ip6) /
9226 TCP(sport=12345, dport=80))
9228 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9229 IPv6(src=src, dst=remote_host_ip6) /
9230 TCP(sport=12345, dport=22))
9232 self.pg0.add_stream(pkts)
9233 self.pg_enable_capture(self.pg_interfaces)
9235 self.pg1.get_capture(max_sessions)
9237 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9238 src_address=self.pg3.local_ip4,
9240 template_interval=10)
9241 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9242 src_port=self.ipfix_src_port,
9245 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9246 IPv6(src=src, dst=remote_host_ip6) /
9247 TCP(sport=12345, dport=25))
9248 self.pg0.add_stream(p)
9249 self.pg_enable_capture(self.pg_interfaces)
9251 self.pg1.assert_nothing_captured()
9253 self.vapi.ipfix_flush()
9254 capture = self.pg3.get_capture(7)
9255 ipfix = IPFIXDecoder()
9256 # first load template
9258 self.assertTrue(p.haslayer(IPFIX))
9259 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9260 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9261 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9262 self.assertEqual(p[UDP].dport, 4739)
9263 self.assertEqual(p[IPFIX].observationDomainID,
9264 self.ipfix_domain_id)
9265 if p.haslayer(Template):
9266 ipfix.add_template(p.getlayer(Template))
9267 # verify events in data set
9269 if p.haslayer(Data):
9270 data = ipfix.decode_data_set(p.getlayer(Set))
9271 self.verify_ipfix_max_sessions(data, max_sessions)
9273 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9274 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9275 TCP(sport=12345, dport=80))
9276 self.pg0.add_stream(p)
9277 self.pg_enable_capture(self.pg_interfaces)
9279 self.pg1.assert_nothing_captured()
9281 self.vapi.ipfix_flush()
9282 capture = self.pg3.get_capture(1)
9283 # verify events in data set
9285 self.assertTrue(p.haslayer(IPFIX))
9286 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9287 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9288 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9289 self.assertEqual(p[UDP].dport, 4739)
9290 self.assertEqual(p[IPFIX].observationDomainID,
9291 self.ipfix_domain_id)
9292 if p.haslayer(Data):
9293 data = ipfix.decode_data_set(p.getlayer(Set))
9294 self.verify_ipfix_max_bibs(data, max_bibs)
9296 def test_ipfix_bib_ses(self):
9297 """ IPFIX logging NAT64 BIB/session create and delete events """
9298 self.tcp_port_in = random.randint(1025, 65535)
9299 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9303 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9304 end_addr=self.nat_addr,
9307 flags = self.config_flags.NAT_IS_INSIDE
9308 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9309 sw_if_index=self.pg0.sw_if_index)
9310 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9311 sw_if_index=self.pg1.sw_if_index)
9312 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
9313 src_address=self.pg3.local_ip4,
9315 template_interval=10)
9316 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9317 src_port=self.ipfix_src_port,
9321 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9322 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9323 TCP(sport=self.tcp_port_in, dport=25))
9324 self.pg0.add_stream(p)
9325 self.pg_enable_capture(self.pg_interfaces)
9327 p = self.pg1.get_capture(1)
9328 self.tcp_port_out = p[0][TCP].sport
9329 self.vapi.ipfix_flush()
9330 capture = self.pg3.get_capture(8)
9331 ipfix = IPFIXDecoder()
9332 # first load template
9334 self.assertTrue(p.haslayer(IPFIX))
9335 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9336 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9337 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9338 self.assertEqual(p[UDP].dport, 4739)
9339 self.assertEqual(p[IPFIX].observationDomainID,
9340 self.ipfix_domain_id)
9341 if p.haslayer(Template):
9342 ipfix.add_template(p.getlayer(Template))
9343 # verify events in data set
9345 if p.haslayer(Data):
9346 data = ipfix.decode_data_set(p.getlayer(Set))
9347 if scapy.compat.orb(data[0][230]) == 10:
9348 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
9349 elif scapy.compat.orb(data[0][230]) == 6:
9350 self.verify_ipfix_nat64_ses(data,
9352 self.pg0.remote_ip6,
9353 self.pg1.remote_ip4,
9356 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9359 self.pg_enable_capture(self.pg_interfaces)
9360 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9361 end_addr=self.nat_addr,
9364 self.vapi.ipfix_flush()
9365 capture = self.pg3.get_capture(2)
9366 # verify events in data set
9368 self.assertTrue(p.haslayer(IPFIX))
9369 self.assertEqual(p[IP].src, self.pg3.local_ip4)
9370 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
9371 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
9372 self.assertEqual(p[UDP].dport, 4739)
9373 self.assertEqual(p[IPFIX].observationDomainID,
9374 self.ipfix_domain_id)
9375 if p.haslayer(Data):
9376 data = ipfix.decode_data_set(p.getlayer(Set))
9377 if scapy.compat.orb(data[0][230]) == 11:
9378 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
9379 elif scapy.compat.orb(data[0][230]) == 7:
9380 self.verify_ipfix_nat64_ses(data,
9382 self.pg0.remote_ip6,
9383 self.pg1.remote_ip4,
9386 self.logger.error(ppp("Unexpected or invalid packet: ", p))
9388 def test_syslog_sess(self):
9389 """ Test syslog session creation and deletion """
9390 self.tcp_port_in = random.randint(1025, 65535)
9391 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
9395 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9396 end_addr=self.nat_addr,
9399 flags = self.config_flags.NAT_IS_INSIDE
9400 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
9401 sw_if_index=self.pg0.sw_if_index)
9402 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
9403 sw_if_index=self.pg1.sw_if_index)
9404 self.vapi.syslog_set_filter(
9405 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
9406 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
9408 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
9409 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
9410 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
9411 self.pg0.add_stream(p)
9412 self.pg_enable_capture(self.pg_interfaces)
9414 p = self.pg1.get_capture(1)
9415 self.tcp_port_out = p[0][TCP].sport
9416 capture = self.pg3.get_capture(1)
9417 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
9419 self.pg_enable_capture(self.pg_interfaces)
9421 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
9422 end_addr=self.nat_addr,
9425 capture = self.pg3.get_capture(1)
9426 self.verify_syslog_sess(capture[0][Raw].load, False, True)
9428 def nat64_get_ses_num(self):
9430 Return number of active NAT64 sessions.
9432 st = self.vapi.nat64_st_dump(proto=255)
9435 def clear_nat64(self):
9437 Clear NAT64 configuration.
9439 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
9440 src_port=self.ipfix_src_port,
9442 self.ipfix_src_port = 4739
9443 self.ipfix_domain_id = 1
9445 self.vapi.syslog_set_filter(
9446 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
9448 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
9449 tcp_transitory=240, icmp=60)
9451 interfaces = self.vapi.nat64_interface_dump()
9452 for intf in interfaces:
9453 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
9454 sw_if_index=intf.sw_if_index)
9456 bib = self.vapi.nat64_bib_dump(proto=255)
9458 if bibe.flags & self.config_flags.NAT_IS_STATIC:
9459 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
9467 adresses = self.vapi.nat64_pool_addr_dump()
9468 for addr in adresses:
9469 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
9470 end_addr=addr.address,
9474 prefixes = self.vapi.nat64_prefix_dump()
9475 for prefix in prefixes:
9476 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
9477 vrf_id=prefix.vrf_id, is_add=0)
9479 bibs = self.statistics.get_counter('/nat64/total-bibs')
9480 self.assertEqual(bibs[0][0], 0)
9481 sessions = self.statistics.get_counter('/nat64/total-sessions')
9482 self.assertEqual(sessions[0][0], 0)
9485 super(TestNAT64, self).tearDown()
9486 if not self.vpp_dead:
9489 def show_commands_at_teardown(self):
9490 self.logger.info(self.vapi.cli("show nat64 pool"))
9491 self.logger.info(self.vapi.cli("show nat64 interfaces"))
9492 self.logger.info(self.vapi.cli("show nat64 prefix"))
9493 self.logger.info(self.vapi.cli("show nat64 bib all"))
9494 self.logger.info(self.vapi.cli("show nat64 session table all"))
9497 class TestNAT66(MethodHolder):
9498 """ NAT66 Test Cases """
9501 def setUpClass(cls):
9502 super(TestNAT66, cls).setUpClass()
9504 cls.nat_addr = 'fd01:ff::2'
9506 cls.create_pg_interfaces(range(2))
9507 cls.interfaces = list(cls.pg_interfaces)
9509 for i in cls.interfaces:
9512 i.configure_ipv6_neighbors()
9515 def tearDownClass(cls):
9516 super(TestNAT66, cls).tearDownClass()
9518 def test_static(self):
9519 """ 1:1 NAT66 test """
9520 flags = self.config_flags.NAT_IS_INSIDE
9521 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9522 sw_if_index=self.pg0.sw_if_index)
9523 self.vapi.nat66_add_del_interface(is_add=1,
9524 sw_if_index=self.pg1.sw_if_index)
9525 self.vapi.nat66_add_del_static_mapping(
9526 local_ip_address=self.pg0.remote_ip6,
9527 external_ip_address=self.nat_addr,
9532 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9533 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9536 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9537 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9540 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9541 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9542 ICMPv6EchoRequest())
9544 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9545 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9546 GRE() / IP() / TCP())
9548 self.pg0.add_stream(pkts)
9549 self.pg_enable_capture(self.pg_interfaces)
9551 capture = self.pg1.get_capture(len(pkts))
9553 for packet in capture:
9555 self.assertEqual(packet[IPv6].src, self.nat_addr)
9556 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9557 self.assert_packet_checksums_valid(packet)
9559 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9564 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9565 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9568 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9569 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9572 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9573 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9576 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
9577 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
9578 GRE() / IP() / TCP())
9580 self.pg1.add_stream(pkts)
9581 self.pg_enable_capture(self.pg_interfaces)
9583 capture = self.pg0.get_capture(len(pkts))
9584 for packet in capture:
9586 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
9587 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
9588 self.assert_packet_checksums_valid(packet)
9590 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9593 sm = self.vapi.nat66_static_mapping_dump()
9594 self.assertEqual(len(sm), 1)
9595 self.assertEqual(sm[0].total_pkts, 8)
9597 def test_check_no_translate(self):
9598 """ NAT66 translate only when egress interface is outside interface """
9599 flags = self.config_flags.NAT_IS_INSIDE
9600 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9601 sw_if_index=self.pg0.sw_if_index)
9602 self.vapi.nat66_add_del_interface(is_add=1, flags=flags,
9603 sw_if_index=self.pg1.sw_if_index)
9604 self.vapi.nat66_add_del_static_mapping(
9605 local_ip_address=self.pg0.remote_ip6,
9606 external_ip_address=self.nat_addr,
9610 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
9611 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
9613 self.pg0.add_stream([p])
9614 self.pg_enable_capture(self.pg_interfaces)
9616 capture = self.pg1.get_capture(1)
9619 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
9620 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
9622 self.logger.error(ppp("Unexpected or invalid packet:", packet))
9625 def clear_nat66(self):
9627 Clear NAT66 configuration.
9629 interfaces = self.vapi.nat66_interface_dump()
9630 for intf in interfaces:
9631 self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags,
9632 sw_if_index=intf.sw_if_index)
9634 static_mappings = self.vapi.nat66_static_mapping_dump()
9635 for sm in static_mappings:
9636 self.vapi.nat66_add_del_static_mapping(
9637 local_ip_address=sm.local_ip_address,
9638 external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id,
9642 super(TestNAT66, self).tearDown()
9645 def show_commands_at_teardown(self):
9646 self.logger.info(self.vapi.cli("show nat66 interfaces"))
9647 self.logger.info(self.vapi.cli("show nat66 static mappings"))
9650 if __name__ == '__main__':
9651 unittest.main(testRunner=VppTestRunner)