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 TestNATMisc(MethodHolder):
1390 """ NAT misc Test Cases """
1392 max_translations = 10240
1396 def setUpConstants(cls):
1397 super(TestNATMisc, cls).setUpConstants()
1398 cls.vpp_cmdline.extend([
1400 "max translations per thread %d" % cls.max_translations,
1401 "max users per thread %d" % cls.max_users,
1406 def tearDownClass(cls):
1407 super(TestNATMisc, cls).tearDownClass()
1409 def test_show_config(self):
1410 """ NAT config translation memory """
1412 nat_config = self.vapi.nat_show_config()
1413 mem = nat_config.translation_memory_size
1414 self.assertTrue(mem > 0)
1415 self.logger.info("max translation memory: %d" % mem)
1417 def test_show_config_2(self):
1418 """ NAT config2 translation memory """
1420 nat_config = self.vapi.nat_show_config_2()
1421 mem = nat_config.translation_memory_size
1422 self.assertTrue(mem > 0)
1423 self.logger.info("max translation memory: %d" % mem)
1425 def test_show_max_translations(self):
1426 """ API test - max translations per thread """
1427 nat_config = self.vapi.nat_show_config_2()
1428 self.assertEqual(self.max_translations,
1429 nat_config.max_translations_per_thread)
1432 class TestNAT44(MethodHolder):
1433 """ NAT44 Test Cases """
1435 max_translations = 10240
1439 def setUpConstants(cls):
1440 super(TestNAT44, cls).setUpConstants()
1441 cls.vpp_cmdline.extend([
1443 "max translations per thread %d" % cls.max_translations,
1444 "max users per thread %d" % cls.max_users,
1449 def setUpClass(cls):
1450 super(TestNAT44, cls).setUpClass()
1451 cls.vapi.cli("set log class nat level debug")
1453 cls.tcp_port_in = 6303
1454 cls.tcp_port_out = 6303
1455 cls.udp_port_in = 6304
1456 cls.udp_port_out = 6304
1457 cls.icmp_id_in = 6305
1458 cls.icmp_id_out = 6305
1459 cls.nat_addr = '10.0.0.3'
1460 cls.ipfix_src_port = 4739
1461 cls.ipfix_domain_id = 1
1462 cls.tcp_external_port = 80
1463 cls.udp_external_port = 69
1465 cls.create_pg_interfaces(range(10))
1466 cls.interfaces = list(cls.pg_interfaces[0:4])
1468 for i in cls.interfaces:
1473 cls.pg0.generate_remote_hosts(3)
1474 cls.pg0.configure_ipv4_neighbors()
1476 cls.pg1.generate_remote_hosts(1)
1477 cls.pg1.configure_ipv4_neighbors()
1479 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
1480 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 10})
1481 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 20})
1483 cls.pg4._local_ip4 = "172.16.255.1"
1484 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1485 cls.pg4.set_table_ip4(10)
1486 cls.pg5._local_ip4 = "172.17.255.3"
1487 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
1488 cls.pg5.set_table_ip4(10)
1489 cls.pg6._local_ip4 = "172.16.255.1"
1490 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1491 cls.pg6.set_table_ip4(20)
1492 for i in cls.overlapping_interfaces:
1500 cls.pg9.generate_remote_hosts(2)
1501 cls.pg9.config_ip4()
1502 cls.vapi.sw_interface_add_del_address(
1503 sw_if_index=cls.pg9.sw_if_index,
1504 prefix="10.0.0.1/24")
1507 cls.pg9.resolve_arp()
1508 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1509 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1510 cls.pg9.resolve_arp()
1513 def tearDownClass(cls):
1514 super(TestNAT44, cls).tearDownClass()
1516 def test_clear_sessions(self):
1517 """ NAT44 session clearing test """
1519 self.nat44_add_address(self.nat_addr)
1520 flags = self.config_flags.NAT_IS_INSIDE
1521 self.vapi.nat44_interface_add_del_feature(
1522 sw_if_index=self.pg0.sw_if_index,
1523 flags=flags, is_add=1)
1524 self.vapi.nat44_interface_add_del_feature(
1525 sw_if_index=self.pg1.sw_if_index,
1528 nat_config = self.vapi.nat_show_config()
1529 self.assertEqual(0, nat_config.endpoint_dependent)
1531 pkts = self.create_stream_in(self.pg0, self.pg1)
1532 self.pg0.add_stream(pkts)
1533 self.pg_enable_capture(self.pg_interfaces)
1535 capture = self.pg1.get_capture(len(pkts))
1536 self.verify_capture_out(capture)
1538 sessions = self.statistics.get_counter('/nat44/total-sessions')
1539 self.assertTrue(sessions[0][0] > 0)
1540 self.logger.info("sessions before clearing: %s" % sessions[0][0])
1542 self.vapi.cli("clear nat44 sessions")
1544 sessions = self.statistics.get_counter('/nat44/total-sessions')
1545 self.assertEqual(sessions[0][0], 0)
1546 self.logger.info("sessions after clearing: %s" % sessions[0][0])
1548 def test_dynamic(self):
1549 """ NAT44 dynamic translation test """
1550 self.nat44_add_address(self.nat_addr)
1551 flags = self.config_flags.NAT_IS_INSIDE
1552 self.vapi.nat44_interface_add_del_feature(
1553 sw_if_index=self.pg0.sw_if_index,
1554 flags=flags, is_add=1)
1555 self.vapi.nat44_interface_add_del_feature(
1556 sw_if_index=self.pg1.sw_if_index,
1560 tcpn = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1561 udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1562 icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1563 drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1565 pkts = self.create_stream_in(self.pg0, self.pg1)
1566 self.pg0.add_stream(pkts)
1567 self.pg_enable_capture(self.pg_interfaces)
1569 capture = self.pg1.get_capture(len(pkts))
1570 self.verify_capture_out(capture)
1572 if_idx = self.pg0.sw_if_index
1573 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
1574 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1575 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
1576 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1577 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
1578 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1579 cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
1580 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1583 tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1584 udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1585 icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1586 drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1588 pkts = self.create_stream_out(self.pg1)
1589 self.pg1.add_stream(pkts)
1590 self.pg_enable_capture(self.pg_interfaces)
1592 capture = self.pg0.get_capture(len(pkts))
1593 self.verify_capture_in(capture, self.pg0)
1595 if_idx = self.pg1.sw_if_index
1596 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
1597 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
1598 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
1599 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
1600 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
1601 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
1602 cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
1603 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
1605 users = self.statistics.get_counter('/nat44/total-users')
1606 self.assertEqual(users[0][0], 1)
1607 sessions = self.statistics.get_counter('/nat44/total-sessions')
1608 self.assertEqual(sessions[0][0], 3)
1610 def test_dynamic_icmp_errors_in2out_ttl_1(self):
1611 """ NAT44 handling of client packets with TTL=1 """
1613 self.nat44_add_address(self.nat_addr)
1614 flags = self.config_flags.NAT_IS_INSIDE
1615 self.vapi.nat44_interface_add_del_feature(
1616 sw_if_index=self.pg0.sw_if_index,
1617 flags=flags, is_add=1)
1618 self.vapi.nat44_interface_add_del_feature(
1619 sw_if_index=self.pg1.sw_if_index,
1622 # Client side - generate traffic
1623 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1624 self.pg0.add_stream(pkts)
1625 self.pg_enable_capture(self.pg_interfaces)
1628 # Client side - verify ICMP type 11 packets
1629 capture = self.pg0.get_capture(len(pkts))
1630 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1632 def test_dynamic_icmp_errors_out2in_ttl_1(self):
1633 """ NAT44 handling of server packets with TTL=1 """
1635 self.nat44_add_address(self.nat_addr)
1636 flags = self.config_flags.NAT_IS_INSIDE
1637 self.vapi.nat44_interface_add_del_feature(
1638 sw_if_index=self.pg0.sw_if_index,
1639 flags=flags, is_add=1)
1640 self.vapi.nat44_interface_add_del_feature(
1641 sw_if_index=self.pg1.sw_if_index,
1644 # Client side - create sessions
1645 pkts = self.create_stream_in(self.pg0, self.pg1)
1646 self.pg0.add_stream(pkts)
1647 self.pg_enable_capture(self.pg_interfaces)
1650 # Server side - generate traffic
1651 capture = self.pg1.get_capture(len(pkts))
1652 self.verify_capture_out(capture)
1653 pkts = self.create_stream_out(self.pg1, ttl=1)
1654 self.pg1.add_stream(pkts)
1655 self.pg_enable_capture(self.pg_interfaces)
1658 # Server side - verify ICMP type 11 packets
1659 capture = self.pg1.get_capture(len(pkts))
1660 self.verify_capture_out_with_icmp_errors(capture,
1661 src_ip=self.pg1.local_ip4)
1663 def test_dynamic_icmp_errors_in2out_ttl_2(self):
1664 """ NAT44 handling of error responses to client packets with TTL=2 """
1666 self.nat44_add_address(self.nat_addr)
1667 flags = self.config_flags.NAT_IS_INSIDE
1668 self.vapi.nat44_interface_add_del_feature(
1669 sw_if_index=self.pg0.sw_if_index,
1670 flags=flags, is_add=1)
1671 self.vapi.nat44_interface_add_del_feature(
1672 sw_if_index=self.pg1.sw_if_index,
1675 # Client side - generate traffic
1676 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1677 self.pg0.add_stream(pkts)
1678 self.pg_enable_capture(self.pg_interfaces)
1681 # Server side - simulate ICMP type 11 response
1682 capture = self.pg1.get_capture(len(pkts))
1683 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1684 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
1685 ICMP(type=11) / packet[IP] for packet in capture]
1686 self.pg1.add_stream(pkts)
1687 self.pg_enable_capture(self.pg_interfaces)
1690 # Client side - verify ICMP type 11 packets
1691 capture = self.pg0.get_capture(len(pkts))
1692 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1694 def test_dynamic_icmp_errors_out2in_ttl_2(self):
1695 """ NAT44 handling of error responses to server packets with TTL=2 """
1697 self.nat44_add_address(self.nat_addr)
1698 flags = self.config_flags.NAT_IS_INSIDE
1699 self.vapi.nat44_interface_add_del_feature(
1700 sw_if_index=self.pg0.sw_if_index,
1701 flags=flags, is_add=1)
1702 self.vapi.nat44_interface_add_del_feature(
1703 sw_if_index=self.pg1.sw_if_index,
1706 # Client side - create sessions
1707 pkts = self.create_stream_in(self.pg0, self.pg1)
1708 self.pg0.add_stream(pkts)
1709 self.pg_enable_capture(self.pg_interfaces)
1712 # Server side - generate traffic
1713 capture = self.pg1.get_capture(len(pkts))
1714 self.verify_capture_out(capture)
1715 pkts = self.create_stream_out(self.pg1, ttl=2)
1716 self.pg1.add_stream(pkts)
1717 self.pg_enable_capture(self.pg_interfaces)
1720 # Client side - simulate ICMP type 11 response
1721 capture = self.pg0.get_capture(len(pkts))
1722 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1723 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1724 ICMP(type=11) / packet[IP] for packet in capture]
1725 self.pg0.add_stream(pkts)
1726 self.pg_enable_capture(self.pg_interfaces)
1729 # Server side - verify ICMP type 11 packets
1730 capture = self.pg1.get_capture(len(pkts))
1731 self.verify_capture_out_with_icmp_errors(capture)
1733 def test_ping_out_interface_from_outside(self):
1734 """ Ping NAT44 out interface from outside network """
1736 self.nat44_add_address(self.nat_addr)
1737 flags = self.config_flags.NAT_IS_INSIDE
1738 self.vapi.nat44_interface_add_del_feature(
1739 sw_if_index=self.pg0.sw_if_index,
1740 flags=flags, is_add=1)
1741 self.vapi.nat44_interface_add_del_feature(
1742 sw_if_index=self.pg1.sw_if_index,
1745 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1746 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1747 ICMP(id=self.icmp_id_out, type='echo-request'))
1749 self.pg1.add_stream(pkts)
1750 self.pg_enable_capture(self.pg_interfaces)
1752 capture = self.pg1.get_capture(len(pkts))
1755 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1756 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1757 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1758 self.assertEqual(packet[ICMP].type, 0) # echo reply
1760 self.logger.error(ppp("Unexpected or invalid packet "
1761 "(outside network):", packet))
1764 def test_ping_internal_host_from_outside(self):
1765 """ Ping internal host from outside network """
1767 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1768 flags = self.config_flags.NAT_IS_INSIDE
1769 self.vapi.nat44_interface_add_del_feature(
1770 sw_if_index=self.pg0.sw_if_index,
1771 flags=flags, is_add=1)
1772 self.vapi.nat44_interface_add_del_feature(
1773 sw_if_index=self.pg1.sw_if_index,
1777 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1778 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
1779 ICMP(id=self.icmp_id_out, type='echo-request'))
1780 self.pg1.add_stream(pkt)
1781 self.pg_enable_capture(self.pg_interfaces)
1783 capture = self.pg0.get_capture(1)
1784 self.verify_capture_in(capture, self.pg0)
1785 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1788 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1789 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1790 ICMP(id=self.icmp_id_in, type='echo-reply'))
1791 self.pg0.add_stream(pkt)
1792 self.pg_enable_capture(self.pg_interfaces)
1794 capture = self.pg1.get_capture(1)
1795 self.verify_capture_out(capture, same_port=True)
1796 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1798 def test_forwarding(self):
1799 """ NAT44 forwarding test """
1801 flags = self.config_flags.NAT_IS_INSIDE
1802 self.vapi.nat44_interface_add_del_feature(
1803 sw_if_index=self.pg0.sw_if_index,
1804 flags=flags, is_add=1)
1805 self.vapi.nat44_interface_add_del_feature(
1806 sw_if_index=self.pg1.sw_if_index,
1808 self.vapi.nat44_forwarding_enable_disable(enable=1)
1810 real_ip = self.pg0.remote_ip4
1811 alias_ip = self.nat_addr
1812 flags = self.config_flags.NAT_IS_ADDR_ONLY
1813 self.vapi.nat44_add_del_static_mapping(is_add=1,
1814 local_ip_address=real_ip,
1815 external_ip_address=alias_ip,
1816 external_sw_if_index=0xFFFFFFFF,
1820 # static mapping match
1822 pkts = self.create_stream_out(self.pg1)
1823 self.pg1.add_stream(pkts)
1824 self.pg_enable_capture(self.pg_interfaces)
1826 capture = self.pg0.get_capture(len(pkts))
1827 self.verify_capture_in(capture, self.pg0)
1829 pkts = self.create_stream_in(self.pg0, self.pg1)
1830 self.pg0.add_stream(pkts)
1831 self.pg_enable_capture(self.pg_interfaces)
1833 capture = self.pg1.get_capture(len(pkts))
1834 self.verify_capture_out(capture, same_port=True)
1836 # no static mapping match
1838 host0 = self.pg0.remote_hosts[0]
1839 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1841 pkts = self.create_stream_out(self.pg1,
1842 dst_ip=self.pg0.remote_ip4,
1843 use_inside_ports=True)
1844 self.pg1.add_stream(pkts)
1845 self.pg_enable_capture(self.pg_interfaces)
1847 capture = self.pg0.get_capture(len(pkts))
1848 self.verify_capture_in(capture, self.pg0)
1850 pkts = self.create_stream_in(self.pg0, self.pg1)
1851 self.pg0.add_stream(pkts)
1852 self.pg_enable_capture(self.pg_interfaces)
1854 capture = self.pg1.get_capture(len(pkts))
1855 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1858 self.pg0.remote_hosts[0] = host0
1861 self.vapi.nat44_forwarding_enable_disable(enable=0)
1862 flags = self.config_flags.NAT_IS_ADDR_ONLY
1863 self.vapi.nat44_add_del_static_mapping(
1865 local_ip_address=real_ip,
1866 external_ip_address=alias_ip,
1867 external_sw_if_index=0xFFFFFFFF,
1870 def test_static_in(self):
1871 """ 1:1 NAT initialized from inside network """
1873 nat_ip = "10.0.0.10"
1874 self.tcp_port_out = 6303
1875 self.udp_port_out = 6304
1876 self.icmp_id_out = 6305
1878 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1879 flags = self.config_flags.NAT_IS_INSIDE
1880 self.vapi.nat44_interface_add_del_feature(
1881 sw_if_index=self.pg0.sw_if_index,
1882 flags=flags, is_add=1)
1883 self.vapi.nat44_interface_add_del_feature(
1884 sw_if_index=self.pg1.sw_if_index,
1886 sm = self.vapi.nat44_static_mapping_dump()
1887 self.assertEqual(len(sm), 1)
1888 self.assertEqual(sm[0].tag, '')
1889 self.assertEqual(sm[0].protocol, 0)
1890 self.assertEqual(sm[0].local_port, 0)
1891 self.assertEqual(sm[0].external_port, 0)
1894 pkts = self.create_stream_in(self.pg0, self.pg1)
1895 self.pg0.add_stream(pkts)
1896 self.pg_enable_capture(self.pg_interfaces)
1898 capture = self.pg1.get_capture(len(pkts))
1899 self.verify_capture_out(capture, nat_ip, True)
1902 pkts = self.create_stream_out(self.pg1, nat_ip)
1903 self.pg1.add_stream(pkts)
1904 self.pg_enable_capture(self.pg_interfaces)
1906 capture = self.pg0.get_capture(len(pkts))
1907 self.verify_capture_in(capture, self.pg0)
1909 def test_static_out(self):
1910 """ 1:1 NAT initialized from outside network """
1912 nat_ip = "10.0.0.20"
1913 self.tcp_port_out = 6303
1914 self.udp_port_out = 6304
1915 self.icmp_id_out = 6305
1918 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
1919 flags = self.config_flags.NAT_IS_INSIDE
1920 self.vapi.nat44_interface_add_del_feature(
1921 sw_if_index=self.pg0.sw_if_index,
1922 flags=flags, is_add=1)
1923 self.vapi.nat44_interface_add_del_feature(
1924 sw_if_index=self.pg1.sw_if_index,
1926 sm = self.vapi.nat44_static_mapping_dump()
1927 self.assertEqual(len(sm), 1)
1928 self.assertEqual(sm[0].tag, tag)
1931 pkts = self.create_stream_out(self.pg1, nat_ip)
1932 self.pg1.add_stream(pkts)
1933 self.pg_enable_capture(self.pg_interfaces)
1935 capture = self.pg0.get_capture(len(pkts))
1936 self.verify_capture_in(capture, self.pg0)
1939 pkts = self.create_stream_in(self.pg0, self.pg1)
1940 self.pg0.add_stream(pkts)
1941 self.pg_enable_capture(self.pg_interfaces)
1943 capture = self.pg1.get_capture(len(pkts))
1944 self.verify_capture_out(capture, nat_ip, True)
1946 def test_static_with_port_in(self):
1947 """ 1:1 NAPT initialized from inside network """
1949 self.tcp_port_out = 3606
1950 self.udp_port_out = 3607
1951 self.icmp_id_out = 3608
1953 self.nat44_add_address(self.nat_addr)
1954 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1955 self.tcp_port_in, self.tcp_port_out,
1956 proto=IP_PROTOS.tcp)
1957 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1958 self.udp_port_in, self.udp_port_out,
1959 proto=IP_PROTOS.udp)
1960 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1961 self.icmp_id_in, self.icmp_id_out,
1962 proto=IP_PROTOS.icmp)
1963 flags = self.config_flags.NAT_IS_INSIDE
1964 self.vapi.nat44_interface_add_del_feature(
1965 sw_if_index=self.pg0.sw_if_index,
1966 flags=flags, is_add=1)
1967 self.vapi.nat44_interface_add_del_feature(
1968 sw_if_index=self.pg1.sw_if_index,
1972 pkts = self.create_stream_in(self.pg0, self.pg1)
1973 self.pg0.add_stream(pkts)
1974 self.pg_enable_capture(self.pg_interfaces)
1976 capture = self.pg1.get_capture(len(pkts))
1977 self.verify_capture_out(capture)
1980 pkts = self.create_stream_out(self.pg1)
1981 self.pg1.add_stream(pkts)
1982 self.pg_enable_capture(self.pg_interfaces)
1984 capture = self.pg0.get_capture(len(pkts))
1985 self.verify_capture_in(capture, self.pg0)
1987 def test_static_with_port_out(self):
1988 """ 1:1 NAPT initialized from outside network """
1990 self.tcp_port_out = 30606
1991 self.udp_port_out = 30607
1992 self.icmp_id_out = 30608
1994 self.nat44_add_address(self.nat_addr)
1995 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1996 self.tcp_port_in, self.tcp_port_out,
1997 proto=IP_PROTOS.tcp)
1998 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1999 self.udp_port_in, self.udp_port_out,
2000 proto=IP_PROTOS.udp)
2001 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2002 self.icmp_id_in, self.icmp_id_out,
2003 proto=IP_PROTOS.icmp)
2004 flags = self.config_flags.NAT_IS_INSIDE
2005 self.vapi.nat44_interface_add_del_feature(
2006 sw_if_index=self.pg0.sw_if_index,
2007 flags=flags, is_add=1)
2008 self.vapi.nat44_interface_add_del_feature(
2009 sw_if_index=self.pg1.sw_if_index,
2013 pkts = self.create_stream_out(self.pg1)
2014 self.pg1.add_stream(pkts)
2015 self.pg_enable_capture(self.pg_interfaces)
2017 capture = self.pg0.get_capture(len(pkts))
2018 self.verify_capture_in(capture, self.pg0)
2021 pkts = self.create_stream_in(self.pg0, self.pg1)
2022 self.pg0.add_stream(pkts)
2023 self.pg_enable_capture(self.pg_interfaces)
2025 capture = self.pg1.get_capture(len(pkts))
2026 self.verify_capture_out(capture)
2028 def test_static_vrf_aware(self):
2029 """ 1:1 NAT VRF awareness """
2031 nat_ip1 = "10.0.0.30"
2032 nat_ip2 = "10.0.0.40"
2033 self.tcp_port_out = 6303
2034 self.udp_port_out = 6304
2035 self.icmp_id_out = 6305
2037 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
2039 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
2041 flags = self.config_flags.NAT_IS_INSIDE
2042 self.vapi.nat44_interface_add_del_feature(
2043 sw_if_index=self.pg3.sw_if_index,
2045 self.vapi.nat44_interface_add_del_feature(
2046 sw_if_index=self.pg0.sw_if_index,
2047 flags=flags, is_add=1)
2048 self.vapi.nat44_interface_add_del_feature(
2049 sw_if_index=self.pg4.sw_if_index,
2050 flags=flags, is_add=1)
2052 # inside interface VRF match NAT44 static mapping VRF
2053 pkts = self.create_stream_in(self.pg4, self.pg3)
2054 self.pg4.add_stream(pkts)
2055 self.pg_enable_capture(self.pg_interfaces)
2057 capture = self.pg3.get_capture(len(pkts))
2058 self.verify_capture_out(capture, nat_ip1, True)
2060 # inside interface VRF don't match NAT44 static mapping VRF (packets
2062 pkts = self.create_stream_in(self.pg0, self.pg3)
2063 self.pg0.add_stream(pkts)
2064 self.pg_enable_capture(self.pg_interfaces)
2066 self.pg3.assert_nothing_captured()
2068 def test_dynamic_to_static(self):
2069 """ Switch from dynamic translation to 1:1NAT """
2070 nat_ip = "10.0.0.10"
2071 self.tcp_port_out = 6303
2072 self.udp_port_out = 6304
2073 self.icmp_id_out = 6305
2075 self.nat44_add_address(self.nat_addr)
2076 flags = self.config_flags.NAT_IS_INSIDE
2077 self.vapi.nat44_interface_add_del_feature(
2078 sw_if_index=self.pg0.sw_if_index,
2079 flags=flags, is_add=1)
2080 self.vapi.nat44_interface_add_del_feature(
2081 sw_if_index=self.pg1.sw_if_index,
2085 pkts = self.create_stream_in(self.pg0, self.pg1)
2086 self.pg0.add_stream(pkts)
2087 self.pg_enable_capture(self.pg_interfaces)
2089 capture = self.pg1.get_capture(len(pkts))
2090 self.verify_capture_out(capture)
2093 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2094 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2095 self.assertEqual(len(sessions), 0)
2096 pkts = self.create_stream_in(self.pg0, self.pg1)
2097 self.pg0.add_stream(pkts)
2098 self.pg_enable_capture(self.pg_interfaces)
2100 capture = self.pg1.get_capture(len(pkts))
2101 self.verify_capture_out(capture, nat_ip, True)
2103 def test_identity_nat(self):
2104 """ Identity NAT """
2105 flags = self.config_flags.NAT_IS_ADDR_ONLY
2106 self.vapi.nat44_add_del_identity_mapping(
2107 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2108 flags=flags, is_add=1)
2109 flags = self.config_flags.NAT_IS_INSIDE
2110 self.vapi.nat44_interface_add_del_feature(
2111 sw_if_index=self.pg0.sw_if_index,
2112 flags=flags, is_add=1)
2113 self.vapi.nat44_interface_add_del_feature(
2114 sw_if_index=self.pg1.sw_if_index,
2117 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2118 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2119 TCP(sport=12345, dport=56789))
2120 self.pg1.add_stream(p)
2121 self.pg_enable_capture(self.pg_interfaces)
2123 capture = self.pg0.get_capture(1)
2128 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2129 self.assertEqual(ip.src, self.pg1.remote_ip4)
2130 self.assertEqual(tcp.dport, 56789)
2131 self.assertEqual(tcp.sport, 12345)
2132 self.assert_packet_checksums_valid(p)
2134 self.logger.error(ppp("Unexpected or invalid packet:", p))
2137 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
2138 self.assertEqual(len(sessions), 0)
2139 flags = self.config_flags.NAT_IS_ADDR_ONLY
2140 self.vapi.nat44_add_del_identity_mapping(
2141 ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
2142 flags=flags, vrf_id=1, is_add=1)
2143 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2144 self.assertEqual(len(identity_mappings), 2)
2146 def test_multiple_inside_interfaces(self):
2147 """ NAT44 multiple non-overlapping address space inside interfaces """
2149 self.nat44_add_address(self.nat_addr)
2150 flags = self.config_flags.NAT_IS_INSIDE
2151 self.vapi.nat44_interface_add_del_feature(
2152 sw_if_index=self.pg0.sw_if_index,
2153 flags=flags, is_add=1)
2154 self.vapi.nat44_interface_add_del_feature(
2155 sw_if_index=self.pg1.sw_if_index,
2156 flags=flags, is_add=1)
2157 self.vapi.nat44_interface_add_del_feature(
2158 sw_if_index=self.pg3.sw_if_index,
2161 # between two NAT44 inside interfaces (no translation)
2162 pkts = self.create_stream_in(self.pg0, self.pg1)
2163 self.pg0.add_stream(pkts)
2164 self.pg_enable_capture(self.pg_interfaces)
2166 capture = self.pg1.get_capture(len(pkts))
2167 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2169 # from NAT44 inside to interface without NAT44 feature (no translation)
2170 pkts = self.create_stream_in(self.pg0, self.pg2)
2171 self.pg0.add_stream(pkts)
2172 self.pg_enable_capture(self.pg_interfaces)
2174 capture = self.pg2.get_capture(len(pkts))
2175 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2177 # in2out 1st interface
2178 pkts = self.create_stream_in(self.pg0, self.pg3)
2179 self.pg0.add_stream(pkts)
2180 self.pg_enable_capture(self.pg_interfaces)
2182 capture = self.pg3.get_capture(len(pkts))
2183 self.verify_capture_out(capture)
2185 # out2in 1st interface
2186 pkts = self.create_stream_out(self.pg3)
2187 self.pg3.add_stream(pkts)
2188 self.pg_enable_capture(self.pg_interfaces)
2190 capture = self.pg0.get_capture(len(pkts))
2191 self.verify_capture_in(capture, self.pg0)
2193 # in2out 2nd interface
2194 pkts = self.create_stream_in(self.pg1, self.pg3)
2195 self.pg1.add_stream(pkts)
2196 self.pg_enable_capture(self.pg_interfaces)
2198 capture = self.pg3.get_capture(len(pkts))
2199 self.verify_capture_out(capture)
2201 # out2in 2nd interface
2202 pkts = self.create_stream_out(self.pg3)
2203 self.pg3.add_stream(pkts)
2204 self.pg_enable_capture(self.pg_interfaces)
2206 capture = self.pg1.get_capture(len(pkts))
2207 self.verify_capture_in(capture, self.pg1)
2209 def test_inside_overlapping_interfaces(self):
2210 """ NAT44 multiple inside interfaces with overlapping address space """
2212 static_nat_ip = "10.0.0.10"
2213 self.nat44_add_address(self.nat_addr)
2214 flags = self.config_flags.NAT_IS_INSIDE
2215 self.vapi.nat44_interface_add_del_feature(
2216 sw_if_index=self.pg3.sw_if_index,
2218 self.vapi.nat44_interface_add_del_feature(
2219 sw_if_index=self.pg4.sw_if_index,
2220 flags=flags, is_add=1)
2221 self.vapi.nat44_interface_add_del_feature(
2222 sw_if_index=self.pg5.sw_if_index,
2223 flags=flags, is_add=1)
2224 self.vapi.nat44_interface_add_del_feature(
2225 sw_if_index=self.pg6.sw_if_index,
2226 flags=flags, is_add=1)
2227 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2230 # between NAT44 inside interfaces with same VRF (no translation)
2231 pkts = self.create_stream_in(self.pg4, self.pg5)
2232 self.pg4.add_stream(pkts)
2233 self.pg_enable_capture(self.pg_interfaces)
2235 capture = self.pg5.get_capture(len(pkts))
2236 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2238 # between NAT44 inside interfaces with different VRF (hairpinning)
2239 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2240 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2241 TCP(sport=1234, dport=5678))
2242 self.pg4.add_stream(p)
2243 self.pg_enable_capture(self.pg_interfaces)
2245 capture = self.pg6.get_capture(1)
2250 self.assertEqual(ip.src, self.nat_addr)
2251 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2252 self.assertNotEqual(tcp.sport, 1234)
2253 self.assertEqual(tcp.dport, 5678)
2255 self.logger.error(ppp("Unexpected or invalid packet:", p))
2258 # in2out 1st interface
2259 pkts = self.create_stream_in(self.pg4, self.pg3)
2260 self.pg4.add_stream(pkts)
2261 self.pg_enable_capture(self.pg_interfaces)
2263 capture = self.pg3.get_capture(len(pkts))
2264 self.verify_capture_out(capture)
2266 # out2in 1st interface
2267 pkts = self.create_stream_out(self.pg3)
2268 self.pg3.add_stream(pkts)
2269 self.pg_enable_capture(self.pg_interfaces)
2271 capture = self.pg4.get_capture(len(pkts))
2272 self.verify_capture_in(capture, self.pg4)
2274 # in2out 2nd interface
2275 pkts = self.create_stream_in(self.pg5, self.pg3)
2276 self.pg5.add_stream(pkts)
2277 self.pg_enable_capture(self.pg_interfaces)
2279 capture = self.pg3.get_capture(len(pkts))
2280 self.verify_capture_out(capture)
2282 # out2in 2nd interface
2283 pkts = self.create_stream_out(self.pg3)
2284 self.pg3.add_stream(pkts)
2285 self.pg_enable_capture(self.pg_interfaces)
2287 capture = self.pg5.get_capture(len(pkts))
2288 self.verify_capture_in(capture, self.pg5)
2291 addresses = self.vapi.nat44_address_dump()
2292 self.assertEqual(len(addresses), 1)
2293 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
2294 self.assertEqual(len(sessions), 3)
2295 for session in sessions:
2296 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2297 self.assertEqual(str(session.inside_ip_address),
2298 self.pg5.remote_ip4)
2299 self.assertEqual(session.outside_ip_address,
2300 addresses[0].ip_address)
2301 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2302 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2303 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2304 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2305 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2306 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2307 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2308 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2309 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2311 # in2out 3rd interface
2312 pkts = self.create_stream_in(self.pg6, self.pg3)
2313 self.pg6.add_stream(pkts)
2314 self.pg_enable_capture(self.pg_interfaces)
2316 capture = self.pg3.get_capture(len(pkts))
2317 self.verify_capture_out(capture, static_nat_ip, True)
2319 # out2in 3rd interface
2320 pkts = self.create_stream_out(self.pg3, static_nat_ip)
2321 self.pg3.add_stream(pkts)
2322 self.pg_enable_capture(self.pg_interfaces)
2324 capture = self.pg6.get_capture(len(pkts))
2325 self.verify_capture_in(capture, self.pg6)
2327 # general user and session dump verifications
2328 users = self.vapi.nat44_user_dump()
2329 self.assertGreaterEqual(len(users), 3)
2330 addresses = self.vapi.nat44_address_dump()
2331 self.assertEqual(len(addresses), 1)
2333 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2335 for session in sessions:
2336 self.assertEqual(user.ip_address, session.inside_ip_address)
2337 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2338 self.assertTrue(session.protocol in
2339 [IP_PROTOS.tcp, IP_PROTOS.udp,
2341 self.assertFalse(session.flags &
2342 self.config_flags.NAT_IS_EXT_HOST_VALID)
2345 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
2346 self.assertGreaterEqual(len(sessions), 4)
2347 for session in sessions:
2348 self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
2349 self.assertEqual(str(session.inside_ip_address),
2350 self.pg4.remote_ip4)
2351 self.assertEqual(session.outside_ip_address,
2352 addresses[0].ip_address)
2355 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
2356 self.assertGreaterEqual(len(sessions), 3)
2357 for session in sessions:
2358 self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
2359 self.assertEqual(str(session.inside_ip_address),
2360 self.pg6.remote_ip4)
2361 self.assertEqual(str(session.outside_ip_address),
2363 self.assertTrue(session.inside_port in
2364 [self.tcp_port_in, self.udp_port_in,
2367 def test_hairpinning(self):
2368 """ NAT44 hairpinning - 1:1 NAPT """
2370 host = self.pg0.remote_hosts[0]
2371 server = self.pg0.remote_hosts[1]
2374 server_in_port = 5678
2375 server_out_port = 8765
2377 self.nat44_add_address(self.nat_addr)
2378 flags = self.config_flags.NAT_IS_INSIDE
2379 self.vapi.nat44_interface_add_del_feature(
2380 sw_if_index=self.pg0.sw_if_index,
2381 flags=flags, is_add=1)
2382 self.vapi.nat44_interface_add_del_feature(
2383 sw_if_index=self.pg1.sw_if_index,
2386 # add static mapping for server
2387 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2388 server_in_port, server_out_port,
2389 proto=IP_PROTOS.tcp)
2391 cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
2392 # send packet from host to server
2393 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
2394 IP(src=host.ip4, dst=self.nat_addr) /
2395 TCP(sport=host_in_port, dport=server_out_port))
2396 self.pg0.add_stream(p)
2397 self.pg_enable_capture(self.pg_interfaces)
2399 capture = self.pg0.get_capture(1)
2404 self.assertEqual(ip.src, self.nat_addr)
2405 self.assertEqual(ip.dst, server.ip4)
2406 self.assertNotEqual(tcp.sport, host_in_port)
2407 self.assertEqual(tcp.dport, server_in_port)
2408 self.assert_packet_checksums_valid(p)
2409 host_out_port = tcp.sport
2411 self.logger.error(ppp("Unexpected or invalid packet:", p))
2414 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2415 if_idx = self.pg0.sw_if_index
2416 self.assertEqual(after[if_idx] - cnt[if_idx], 1)
2418 # send reply from server to host
2419 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
2420 IP(src=server.ip4, dst=self.nat_addr) /
2421 TCP(sport=server_in_port, dport=host_out_port))
2422 self.pg0.add_stream(p)
2423 self.pg_enable_capture(self.pg_interfaces)
2425 capture = self.pg0.get_capture(1)
2430 self.assertEqual(ip.src, self.nat_addr)
2431 self.assertEqual(ip.dst, host.ip4)
2432 self.assertEqual(tcp.sport, server_out_port)
2433 self.assertEqual(tcp.dport, host_in_port)
2434 self.assert_packet_checksums_valid(p)
2436 self.logger.error(ppp("Unexpected or invalid packet:", p))
2439 after = self.statistics.get_counter('/nat44/hairpinning')[0]
2440 if_idx = self.pg0.sw_if_index
2441 self.assertEqual(after[if_idx] - cnt[if_idx], 2)
2443 def test_hairpinning2(self):
2444 """ NAT44 hairpinning - 1:1 NAT"""
2446 server1_nat_ip = "10.0.0.10"
2447 server2_nat_ip = "10.0.0.11"
2448 host = self.pg0.remote_hosts[0]
2449 server1 = self.pg0.remote_hosts[1]
2450 server2 = self.pg0.remote_hosts[2]
2451 server_tcp_port = 22
2452 server_udp_port = 20
2454 self.nat44_add_address(self.nat_addr)
2455 flags = self.config_flags.NAT_IS_INSIDE
2456 self.vapi.nat44_interface_add_del_feature(
2457 sw_if_index=self.pg0.sw_if_index,
2458 flags=flags, is_add=1)
2459 self.vapi.nat44_interface_add_del_feature(
2460 sw_if_index=self.pg1.sw_if_index,
2463 # add static mapping for servers
2464 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2465 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
2469 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2470 IP(src=host.ip4, dst=server1_nat_ip) /
2471 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2473 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2474 IP(src=host.ip4, dst=server1_nat_ip) /
2475 UDP(sport=self.udp_port_in, dport=server_udp_port))
2477 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2478 IP(src=host.ip4, dst=server1_nat_ip) /
2479 ICMP(id=self.icmp_id_in, type='echo-request'))
2481 self.pg0.add_stream(pkts)
2482 self.pg_enable_capture(self.pg_interfaces)
2484 capture = self.pg0.get_capture(len(pkts))
2485 for packet in capture:
2487 self.assertEqual(packet[IP].src, self.nat_addr)
2488 self.assertEqual(packet[IP].dst, server1.ip4)
2489 if packet.haslayer(TCP):
2490 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2491 self.assertEqual(packet[TCP].dport, server_tcp_port)
2492 self.tcp_port_out = packet[TCP].sport
2493 self.assert_packet_checksums_valid(packet)
2494 elif packet.haslayer(UDP):
2495 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2496 self.assertEqual(packet[UDP].dport, server_udp_port)
2497 self.udp_port_out = packet[UDP].sport
2499 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2500 self.icmp_id_out = packet[ICMP].id
2502 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2507 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2508 IP(src=server1.ip4, dst=self.nat_addr) /
2509 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2511 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2512 IP(src=server1.ip4, dst=self.nat_addr) /
2513 UDP(sport=server_udp_port, dport=self.udp_port_out))
2515 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2516 IP(src=server1.ip4, dst=self.nat_addr) /
2517 ICMP(id=self.icmp_id_out, type='echo-reply'))
2519 self.pg0.add_stream(pkts)
2520 self.pg_enable_capture(self.pg_interfaces)
2522 capture = self.pg0.get_capture(len(pkts))
2523 for packet in capture:
2525 self.assertEqual(packet[IP].src, server1_nat_ip)
2526 self.assertEqual(packet[IP].dst, host.ip4)
2527 if packet.haslayer(TCP):
2528 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2529 self.assertEqual(packet[TCP].sport, server_tcp_port)
2530 self.assert_packet_checksums_valid(packet)
2531 elif packet.haslayer(UDP):
2532 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2533 self.assertEqual(packet[UDP].sport, server_udp_port)
2535 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2537 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2540 # server2 to server1
2542 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2543 IP(src=server2.ip4, dst=server1_nat_ip) /
2544 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2546 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2547 IP(src=server2.ip4, dst=server1_nat_ip) /
2548 UDP(sport=self.udp_port_in, dport=server_udp_port))
2550 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2551 IP(src=server2.ip4, dst=server1_nat_ip) /
2552 ICMP(id=self.icmp_id_in, type='echo-request'))
2554 self.pg0.add_stream(pkts)
2555 self.pg_enable_capture(self.pg_interfaces)
2557 capture = self.pg0.get_capture(len(pkts))
2558 for packet in capture:
2560 self.assertEqual(packet[IP].src, server2_nat_ip)
2561 self.assertEqual(packet[IP].dst, server1.ip4)
2562 if packet.haslayer(TCP):
2563 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2564 self.assertEqual(packet[TCP].dport, server_tcp_port)
2565 self.tcp_port_out = packet[TCP].sport
2566 self.assert_packet_checksums_valid(packet)
2567 elif packet.haslayer(UDP):
2568 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2569 self.assertEqual(packet[UDP].dport, server_udp_port)
2570 self.udp_port_out = packet[UDP].sport
2572 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2573 self.icmp_id_out = packet[ICMP].id
2575 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2578 # server1 to server2
2580 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2581 IP(src=server1.ip4, dst=server2_nat_ip) /
2582 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2584 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2585 IP(src=server1.ip4, dst=server2_nat_ip) /
2586 UDP(sport=server_udp_port, dport=self.udp_port_out))
2588 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2589 IP(src=server1.ip4, dst=server2_nat_ip) /
2590 ICMP(id=self.icmp_id_out, type='echo-reply'))
2592 self.pg0.add_stream(pkts)
2593 self.pg_enable_capture(self.pg_interfaces)
2595 capture = self.pg0.get_capture(len(pkts))
2596 for packet in capture:
2598 self.assertEqual(packet[IP].src, server1_nat_ip)
2599 self.assertEqual(packet[IP].dst, server2.ip4)
2600 if packet.haslayer(TCP):
2601 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2602 self.assertEqual(packet[TCP].sport, server_tcp_port)
2603 self.assert_packet_checksums_valid(packet)
2604 elif packet.haslayer(UDP):
2605 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2606 self.assertEqual(packet[UDP].sport, server_udp_port)
2608 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2610 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2613 def test_interface_addr(self):
2614 """ Acquire NAT44 addresses from interface """
2615 self.vapi.nat44_add_del_interface_addr(
2617 sw_if_index=self.pg7.sw_if_index)
2619 # no address in NAT pool
2620 addresses = self.vapi.nat44_address_dump()
2621 self.assertEqual(0, len(addresses))
2623 # configure interface address and check NAT address pool
2624 self.pg7.config_ip4()
2625 addresses = self.vapi.nat44_address_dump()
2626 self.assertEqual(1, len(addresses))
2627 self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
2629 # remove interface address and check NAT address pool
2630 self.pg7.unconfig_ip4()
2631 addresses = self.vapi.nat44_address_dump()
2632 self.assertEqual(0, len(addresses))
2634 def test_interface_addr_static_mapping(self):
2635 """ Static mapping with addresses from interface """
2638 self.vapi.nat44_add_del_interface_addr(
2640 sw_if_index=self.pg7.sw_if_index)
2641 self.nat44_add_static_mapping(
2643 external_sw_if_index=self.pg7.sw_if_index,
2646 # static mappings with external interface
2647 static_mappings = self.vapi.nat44_static_mapping_dump()
2648 self.assertEqual(1, len(static_mappings))
2649 self.assertEqual(self.pg7.sw_if_index,
2650 static_mappings[0].external_sw_if_index)
2651 self.assertEqual(static_mappings[0].tag, tag)
2653 # configure interface address and check static mappings
2654 self.pg7.config_ip4()
2655 static_mappings = self.vapi.nat44_static_mapping_dump()
2656 self.assertEqual(2, len(static_mappings))
2658 for sm in static_mappings:
2659 if sm.external_sw_if_index == 0xFFFFFFFF:
2660 self.assertEqual(str(sm.external_ip_address),
2662 self.assertEqual(sm.tag, tag)
2664 self.assertTrue(resolved)
2666 # remove interface address and check static mappings
2667 self.pg7.unconfig_ip4()
2668 static_mappings = self.vapi.nat44_static_mapping_dump()
2669 self.assertEqual(1, len(static_mappings))
2670 self.assertEqual(self.pg7.sw_if_index,
2671 static_mappings[0].external_sw_if_index)
2672 self.assertEqual(static_mappings[0].tag, tag)
2674 # configure interface address again and check static mappings
2675 self.pg7.config_ip4()
2676 static_mappings = self.vapi.nat44_static_mapping_dump()
2677 self.assertEqual(2, len(static_mappings))
2679 for sm in static_mappings:
2680 if sm.external_sw_if_index == 0xFFFFFFFF:
2681 self.assertEqual(str(sm.external_ip_address),
2683 self.assertEqual(sm.tag, tag)
2685 self.assertTrue(resolved)
2687 # remove static mapping
2688 self.nat44_add_static_mapping(
2690 external_sw_if_index=self.pg7.sw_if_index,
2693 static_mappings = self.vapi.nat44_static_mapping_dump()
2694 self.assertEqual(0, len(static_mappings))
2696 def test_interface_addr_identity_nat(self):
2697 """ Identity NAT with addresses from interface """
2700 self.vapi.nat44_add_del_interface_addr(
2702 sw_if_index=self.pg7.sw_if_index)
2703 self.vapi.nat44_add_del_identity_mapping(
2705 sw_if_index=self.pg7.sw_if_index,
2707 protocol=IP_PROTOS.tcp,
2710 # identity mappings with external interface
2711 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2712 self.assertEqual(1, len(identity_mappings))
2713 self.assertEqual(self.pg7.sw_if_index,
2714 identity_mappings[0].sw_if_index)
2716 # configure interface address and check identity mappings
2717 self.pg7.config_ip4()
2718 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2720 self.assertEqual(2, len(identity_mappings))
2721 for sm in identity_mappings:
2722 if sm.sw_if_index == 0xFFFFFFFF:
2723 self.assertEqual(str(identity_mappings[0].ip_address),
2725 self.assertEqual(port, identity_mappings[0].port)
2726 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2728 self.assertTrue(resolved)
2730 # remove interface address and check identity mappings
2731 self.pg7.unconfig_ip4()
2732 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2733 self.assertEqual(1, len(identity_mappings))
2734 self.assertEqual(self.pg7.sw_if_index,
2735 identity_mappings[0].sw_if_index)
2737 def test_ipfix_nat44_sess(self):
2738 """ IPFIX logging NAT44 session created/deleted """
2739 self.ipfix_domain_id = 10
2740 self.ipfix_src_port = 20202
2741 collector_port = 30303
2742 bind_layers(UDP, IPFIX, dport=30303)
2743 self.nat44_add_address(self.nat_addr)
2744 flags = self.config_flags.NAT_IS_INSIDE
2745 self.vapi.nat44_interface_add_del_feature(
2746 sw_if_index=self.pg0.sw_if_index,
2747 flags=flags, is_add=1)
2748 self.vapi.nat44_interface_add_del_feature(
2749 sw_if_index=self.pg1.sw_if_index,
2751 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2752 src_address=self.pg3.local_ip4,
2754 template_interval=10,
2755 collector_port=collector_port)
2756 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2757 src_port=self.ipfix_src_port,
2760 pkts = self.create_stream_in(self.pg0, self.pg1)
2761 self.pg0.add_stream(pkts)
2762 self.pg_enable_capture(self.pg_interfaces)
2764 capture = self.pg1.get_capture(len(pkts))
2765 self.verify_capture_out(capture)
2766 self.nat44_add_address(self.nat_addr, is_add=0)
2767 self.vapi.ipfix_flush()
2768 capture = self.pg3.get_capture(7)
2769 ipfix = IPFIXDecoder()
2770 # first load template
2772 self.assertTrue(p.haslayer(IPFIX))
2773 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2774 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2775 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2776 self.assertEqual(p[UDP].dport, collector_port)
2777 self.assertEqual(p[IPFIX].observationDomainID,
2778 self.ipfix_domain_id)
2779 if p.haslayer(Template):
2780 ipfix.add_template(p.getlayer(Template))
2781 # verify events in data set
2783 if p.haslayer(Data):
2784 data = ipfix.decode_data_set(p.getlayer(Set))
2785 self.verify_ipfix_nat44_ses(data)
2787 def test_ipfix_addr_exhausted(self):
2788 """ IPFIX logging NAT addresses exhausted """
2789 flags = self.config_flags.NAT_IS_INSIDE
2790 self.vapi.nat44_interface_add_del_feature(
2791 sw_if_index=self.pg0.sw_if_index,
2792 flags=flags, is_add=1)
2793 self.vapi.nat44_interface_add_del_feature(
2794 sw_if_index=self.pg1.sw_if_index,
2796 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2797 src_address=self.pg3.local_ip4,
2799 template_interval=10)
2800 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2801 src_port=self.ipfix_src_port,
2804 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2805 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2807 self.pg0.add_stream(p)
2808 self.pg_enable_capture(self.pg_interfaces)
2810 self.pg1.assert_nothing_captured()
2812 self.vapi.ipfix_flush()
2813 capture = self.pg3.get_capture(7)
2814 ipfix = IPFIXDecoder()
2815 # first load template
2817 self.assertTrue(p.haslayer(IPFIX))
2818 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2819 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2820 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2821 self.assertEqual(p[UDP].dport, 4739)
2822 self.assertEqual(p[IPFIX].observationDomainID,
2823 self.ipfix_domain_id)
2824 if p.haslayer(Template):
2825 ipfix.add_template(p.getlayer(Template))
2826 # verify events in data set
2828 if p.haslayer(Data):
2829 data = ipfix.decode_data_set(p.getlayer(Set))
2830 self.verify_ipfix_addr_exhausted(data)
2832 @unittest.skipUnless(running_extended_tests, "part of extended tests")
2833 def test_ipfix_max_sessions(self):
2834 """ IPFIX logging maximum session entries exceeded """
2835 self.nat44_add_address(self.nat_addr)
2836 flags = self.config_flags.NAT_IS_INSIDE
2837 self.vapi.nat44_interface_add_del_feature(
2838 sw_if_index=self.pg0.sw_if_index,
2839 flags=flags, is_add=1)
2840 self.vapi.nat44_interface_add_del_feature(
2841 sw_if_index=self.pg1.sw_if_index,
2844 max_sessions = self.max_translations
2847 for i in range(0, max_sessions):
2848 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2849 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2850 IP(src=src, dst=self.pg1.remote_ip4) /
2853 self.pg0.add_stream(pkts)
2854 self.pg_enable_capture(self.pg_interfaces)
2857 self.pg1.get_capture(max_sessions)
2858 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
2859 src_address=self.pg3.local_ip4,
2861 template_interval=10)
2862 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
2863 src_port=self.ipfix_src_port,
2866 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2867 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2869 self.pg0.add_stream(p)
2870 self.pg_enable_capture(self.pg_interfaces)
2872 self.pg1.assert_nothing_captured()
2874 self.vapi.ipfix_flush()
2875 capture = self.pg3.get_capture(7)
2876 ipfix = IPFIXDecoder()
2877 # first load template
2879 self.assertTrue(p.haslayer(IPFIX))
2880 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2881 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2882 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2883 self.assertEqual(p[UDP].dport, 4739)
2884 self.assertEqual(p[IPFIX].observationDomainID,
2885 self.ipfix_domain_id)
2886 if p.haslayer(Template):
2887 ipfix.add_template(p.getlayer(Template))
2888 # verify events in data set
2890 if p.haslayer(Data):
2891 data = ipfix.decode_data_set(p.getlayer(Set))
2892 self.verify_ipfix_max_sessions(data, max_sessions)
2894 def test_syslog_apmap(self):
2895 """ Test syslog address and port mapping creation and deletion """
2896 self.vapi.syslog_set_filter(
2897 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
2898 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
2899 self.nat44_add_address(self.nat_addr)
2900 flags = self.config_flags.NAT_IS_INSIDE
2901 self.vapi.nat44_interface_add_del_feature(
2902 sw_if_index=self.pg0.sw_if_index,
2903 flags=flags, is_add=1)
2904 self.vapi.nat44_interface_add_del_feature(
2905 sw_if_index=self.pg1.sw_if_index,
2908 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2909 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2910 TCP(sport=self.tcp_port_in, dport=20))
2911 self.pg0.add_stream(p)
2912 self.pg_enable_capture(self.pg_interfaces)
2914 capture = self.pg1.get_capture(1)
2915 self.tcp_port_out = capture[0][TCP].sport
2916 capture = self.pg3.get_capture(1)
2917 self.verify_syslog_apmap(capture[0][Raw].load)
2919 self.pg_enable_capture(self.pg_interfaces)
2921 self.nat44_add_address(self.nat_addr, is_add=0)
2922 capture = self.pg3.get_capture(1)
2923 self.verify_syslog_apmap(capture[0][Raw].load, False)
2925 def test_pool_addr_fib(self):
2926 """ NAT44 add pool addresses to FIB """
2927 static_addr = '10.0.0.10'
2928 self.nat44_add_address(self.nat_addr)
2929 flags = self.config_flags.NAT_IS_INSIDE
2930 self.vapi.nat44_interface_add_del_feature(
2931 sw_if_index=self.pg0.sw_if_index,
2932 flags=flags, is_add=1)
2933 self.vapi.nat44_interface_add_del_feature(
2934 sw_if_index=self.pg1.sw_if_index,
2936 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
2939 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2940 ARP(op=ARP.who_has, pdst=self.nat_addr,
2941 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2942 self.pg1.add_stream(p)
2943 self.pg_enable_capture(self.pg_interfaces)
2945 capture = self.pg1.get_capture(1)
2946 self.assertTrue(capture[0].haslayer(ARP))
2947 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2950 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2951 ARP(op=ARP.who_has, pdst=static_addr,
2952 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2953 self.pg1.add_stream(p)
2954 self.pg_enable_capture(self.pg_interfaces)
2956 capture = self.pg1.get_capture(1)
2957 self.assertTrue(capture[0].haslayer(ARP))
2958 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2960 # send ARP to non-NAT44 interface
2961 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2962 ARP(op=ARP.who_has, pdst=self.nat_addr,
2963 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2964 self.pg2.add_stream(p)
2965 self.pg_enable_capture(self.pg_interfaces)
2967 self.pg1.assert_nothing_captured()
2969 # remove addresses and verify
2970 self.nat44_add_address(self.nat_addr, is_add=0)
2971 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2974 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2975 ARP(op=ARP.who_has, pdst=self.nat_addr,
2976 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2977 self.pg1.add_stream(p)
2978 self.pg_enable_capture(self.pg_interfaces)
2980 self.pg1.assert_nothing_captured()
2982 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2983 ARP(op=ARP.who_has, pdst=static_addr,
2984 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2985 self.pg1.add_stream(p)
2986 self.pg_enable_capture(self.pg_interfaces)
2988 self.pg1.assert_nothing_captured()
2990 def test_vrf_mode(self):
2991 """ NAT44 tenant VRF aware address pool mode """
2995 nat_ip1 = "10.0.0.10"
2996 nat_ip2 = "10.0.0.11"
2998 self.pg0.unconfig_ip4()
2999 self.pg1.unconfig_ip4()
3000 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3001 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3002 self.pg0.set_table_ip4(vrf_id1)
3003 self.pg1.set_table_ip4(vrf_id2)
3004 self.pg0.config_ip4()
3005 self.pg1.config_ip4()
3006 self.pg0.resolve_arp()
3007 self.pg1.resolve_arp()
3009 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
3010 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
3011 flags = self.config_flags.NAT_IS_INSIDE
3012 self.vapi.nat44_interface_add_del_feature(
3013 sw_if_index=self.pg0.sw_if_index,
3014 flags=flags, is_add=1)
3015 self.vapi.nat44_interface_add_del_feature(
3016 sw_if_index=self.pg1.sw_if_index,
3017 flags=flags, is_add=1)
3018 self.vapi.nat44_interface_add_del_feature(
3019 sw_if_index=self.pg2.sw_if_index,
3024 pkts = self.create_stream_in(self.pg0, self.pg2)
3025 self.pg0.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)
3032 pkts = self.create_stream_in(self.pg1, self.pg2)
3033 self.pg1.add_stream(pkts)
3034 self.pg_enable_capture(self.pg_interfaces)
3036 capture = self.pg2.get_capture(len(pkts))
3037 self.verify_capture_out(capture, nat_ip2)
3040 self.pg0.unconfig_ip4()
3041 self.pg1.unconfig_ip4()
3042 self.pg0.set_table_ip4(0)
3043 self.pg1.set_table_ip4(0)
3044 self.pg0.config_ip4()
3045 self.pg1.config_ip4()
3046 self.pg0.resolve_arp()
3047 self.pg1.resolve_arp()
3048 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id1})
3049 self.vapi.ip_table_add_del(is_add=0, table={'table_id': vrf_id2})
3051 def test_vrf_feature_independent(self):
3052 """ NAT44 tenant VRF independent address pool mode """
3054 nat_ip1 = "10.0.0.10"
3055 nat_ip2 = "10.0.0.11"
3057 self.nat44_add_address(nat_ip1)
3058 self.nat44_add_address(nat_ip2, vrf_id=99)
3059 flags = self.config_flags.NAT_IS_INSIDE
3060 self.vapi.nat44_interface_add_del_feature(
3061 sw_if_index=self.pg0.sw_if_index,
3062 flags=flags, is_add=1)
3063 self.vapi.nat44_interface_add_del_feature(
3064 sw_if_index=self.pg1.sw_if_index,
3065 flags=flags, is_add=1)
3066 self.vapi.nat44_interface_add_del_feature(
3067 sw_if_index=self.pg2.sw_if_index,
3071 pkts = self.create_stream_in(self.pg0, self.pg2)
3072 self.pg0.add_stream(pkts)
3073 self.pg_enable_capture(self.pg_interfaces)
3075 capture = self.pg2.get_capture(len(pkts))
3076 self.verify_capture_out(capture, nat_ip1)
3079 pkts = self.create_stream_in(self.pg1, self.pg2)
3080 self.pg1.add_stream(pkts)
3081 self.pg_enable_capture(self.pg_interfaces)
3083 capture = self.pg2.get_capture(len(pkts))
3084 self.verify_capture_out(capture, nat_ip1)
3086 def create_routes_and_neigbors(self):
3087 r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
3088 [VppRoutePath(self.pg7.remote_ip4,
3089 self.pg7.sw_if_index)])
3090 r2 = VppIpRoute(self, self.pg8.remote_ip4, 32,
3091 [VppRoutePath(self.pg8.remote_ip4,
3092 self.pg8.sw_if_index)])
3096 n1 = VppNeighbor(self,
3097 self.pg7.sw_if_index,
3098 self.pg7.remote_mac,
3099 self.pg7.remote_ip4,
3101 n2 = VppNeighbor(self,
3102 self.pg8.sw_if_index,
3103 self.pg8.remote_mac,
3104 self.pg8.remote_ip4,
3109 def test_dynamic_ipless_interfaces(self):
3110 """ NAT44 interfaces without configured IP address """
3111 self.create_routes_and_neigbors()
3112 self.nat44_add_address(self.nat_addr)
3113 flags = self.config_flags.NAT_IS_INSIDE
3114 self.vapi.nat44_interface_add_del_feature(
3115 sw_if_index=self.pg7.sw_if_index,
3116 flags=flags, is_add=1)
3117 self.vapi.nat44_interface_add_del_feature(
3118 sw_if_index=self.pg8.sw_if_index,
3122 pkts = self.create_stream_in(self.pg7, self.pg8)
3123 self.pg7.add_stream(pkts)
3124 self.pg_enable_capture(self.pg_interfaces)
3126 capture = self.pg8.get_capture(len(pkts))
3127 self.verify_capture_out(capture)
3130 pkts = self.create_stream_out(self.pg8, self.nat_addr)
3131 self.pg8.add_stream(pkts)
3132 self.pg_enable_capture(self.pg_interfaces)
3134 capture = self.pg7.get_capture(len(pkts))
3135 self.verify_capture_in(capture, self.pg7)
3137 def test_static_ipless_interfaces(self):
3138 """ NAT44 interfaces without configured IP address - 1:1 NAT """
3140 self.create_routes_and_neigbors()
3141 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3142 flags = self.config_flags.NAT_IS_INSIDE
3143 self.vapi.nat44_interface_add_del_feature(
3144 sw_if_index=self.pg7.sw_if_index,
3145 flags=flags, is_add=1)
3146 self.vapi.nat44_interface_add_del_feature(
3147 sw_if_index=self.pg8.sw_if_index,
3151 pkts = self.create_stream_out(self.pg8)
3152 self.pg8.add_stream(pkts)
3153 self.pg_enable_capture(self.pg_interfaces)
3155 capture = self.pg7.get_capture(len(pkts))
3156 self.verify_capture_in(capture, self.pg7)
3159 pkts = self.create_stream_in(self.pg7, self.pg8)
3160 self.pg7.add_stream(pkts)
3161 self.pg_enable_capture(self.pg_interfaces)
3163 capture = self.pg8.get_capture(len(pkts))
3164 self.verify_capture_out(capture, self.nat_addr, True)
3166 def test_static_with_port_ipless_interfaces(self):
3167 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
3169 self.tcp_port_out = 30606
3170 self.udp_port_out = 30607
3171 self.icmp_id_out = 30608
3173 self.create_routes_and_neigbors()
3174 self.nat44_add_address(self.nat_addr)
3175 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3176 self.tcp_port_in, self.tcp_port_out,
3177 proto=IP_PROTOS.tcp)
3178 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3179 self.udp_port_in, self.udp_port_out,
3180 proto=IP_PROTOS.udp)
3181 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3182 self.icmp_id_in, self.icmp_id_out,
3183 proto=IP_PROTOS.icmp)
3184 flags = self.config_flags.NAT_IS_INSIDE
3185 self.vapi.nat44_interface_add_del_feature(
3186 sw_if_index=self.pg7.sw_if_index,
3187 flags=flags, is_add=1)
3188 self.vapi.nat44_interface_add_del_feature(
3189 sw_if_index=self.pg8.sw_if_index,
3193 pkts = self.create_stream_out(self.pg8)
3194 self.pg8.add_stream(pkts)
3195 self.pg_enable_capture(self.pg_interfaces)
3197 capture = self.pg7.get_capture(len(pkts))
3198 self.verify_capture_in(capture, self.pg7)
3201 pkts = self.create_stream_in(self.pg7, self.pg8)
3202 self.pg7.add_stream(pkts)
3203 self.pg_enable_capture(self.pg_interfaces)
3205 capture = self.pg8.get_capture(len(pkts))
3206 self.verify_capture_out(capture)
3208 def test_static_unknown_proto(self):
3209 """ 1:1 NAT translate packet with unknown protocol """
3210 nat_ip = "10.0.0.10"
3211 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3212 flags = self.config_flags.NAT_IS_INSIDE
3213 self.vapi.nat44_interface_add_del_feature(
3214 sw_if_index=self.pg0.sw_if_index,
3215 flags=flags, is_add=1)
3216 self.vapi.nat44_interface_add_del_feature(
3217 sw_if_index=self.pg1.sw_if_index,
3221 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3222 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3224 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3225 TCP(sport=1234, dport=1234))
3226 self.pg0.add_stream(p)
3227 self.pg_enable_capture(self.pg_interfaces)
3229 p = self.pg1.get_capture(1)
3232 self.assertEqual(packet[IP].src, nat_ip)
3233 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3234 self.assertEqual(packet.haslayer(GRE), 1)
3235 self.assert_packet_checksums_valid(packet)
3237 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3241 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3242 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3244 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3245 TCP(sport=1234, dport=1234))
3246 self.pg1.add_stream(p)
3247 self.pg_enable_capture(self.pg_interfaces)
3249 p = self.pg0.get_capture(1)
3252 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3253 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3254 self.assertEqual(packet.haslayer(GRE), 1)
3255 self.assert_packet_checksums_valid(packet)
3257 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3260 def test_hairpinning_static_unknown_proto(self):
3261 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3263 host = self.pg0.remote_hosts[0]
3264 server = self.pg0.remote_hosts[1]
3266 host_nat_ip = "10.0.0.10"
3267 server_nat_ip = "10.0.0.11"
3269 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3270 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3271 flags = self.config_flags.NAT_IS_INSIDE
3272 self.vapi.nat44_interface_add_del_feature(
3273 sw_if_index=self.pg0.sw_if_index,
3274 flags=flags, is_add=1)
3275 self.vapi.nat44_interface_add_del_feature(
3276 sw_if_index=self.pg1.sw_if_index,
3280 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3281 IP(src=host.ip4, dst=server_nat_ip) /
3283 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3284 TCP(sport=1234, dport=1234))
3285 self.pg0.add_stream(p)
3286 self.pg_enable_capture(self.pg_interfaces)
3288 p = self.pg0.get_capture(1)
3291 self.assertEqual(packet[IP].src, host_nat_ip)
3292 self.assertEqual(packet[IP].dst, server.ip4)
3293 self.assertEqual(packet.haslayer(GRE), 1)
3294 self.assert_packet_checksums_valid(packet)
3296 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3300 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3301 IP(src=server.ip4, dst=host_nat_ip) /
3303 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3304 TCP(sport=1234, dport=1234))
3305 self.pg0.add_stream(p)
3306 self.pg_enable_capture(self.pg_interfaces)
3308 p = self.pg0.get_capture(1)
3311 self.assertEqual(packet[IP].src, server_nat_ip)
3312 self.assertEqual(packet[IP].dst, host.ip4)
3313 self.assertEqual(packet.haslayer(GRE), 1)
3314 self.assert_packet_checksums_valid(packet)
3316 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3319 def test_output_feature(self):
3320 """ NAT44 interface output feature (in2out postrouting) """
3321 self.nat44_add_address(self.nat_addr)
3322 flags = self.config_flags.NAT_IS_INSIDE
3323 self.vapi.nat44_interface_add_del_output_feature(
3324 is_add=1, flags=flags,
3325 sw_if_index=self.pg0.sw_if_index)
3326 self.vapi.nat44_interface_add_del_output_feature(
3327 is_add=1, flags=flags,
3328 sw_if_index=self.pg1.sw_if_index)
3329 self.vapi.nat44_interface_add_del_output_feature(
3331 sw_if_index=self.pg3.sw_if_index)
3334 pkts = self.create_stream_in(self.pg0, self.pg3)
3335 self.pg0.add_stream(pkts)
3336 self.pg_enable_capture(self.pg_interfaces)
3338 capture = self.pg3.get_capture(len(pkts))
3339 self.verify_capture_out(capture)
3342 pkts = self.create_stream_out(self.pg3)
3343 self.pg3.add_stream(pkts)
3344 self.pg_enable_capture(self.pg_interfaces)
3346 capture = self.pg0.get_capture(len(pkts))
3347 self.verify_capture_in(capture, self.pg0)
3349 # from non-NAT interface to NAT inside interface
3350 pkts = self.create_stream_in(self.pg2, self.pg0)
3351 self.pg2.add_stream(pkts)
3352 self.pg_enable_capture(self.pg_interfaces)
3354 capture = self.pg0.get_capture(len(pkts))
3355 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3357 def test_output_feature_vrf_aware(self):
3358 """ NAT44 interface output feature VRF aware (in2out postrouting) """
3359 nat_ip_vrf10 = "10.0.0.10"
3360 nat_ip_vrf20 = "10.0.0.20"
3362 r1 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3363 [VppRoutePath(self.pg3.remote_ip4,
3364 self.pg3.sw_if_index)],
3366 r2 = VppIpRoute(self, self.pg3.remote_ip4, 32,
3367 [VppRoutePath(self.pg3.remote_ip4,
3368 self.pg3.sw_if_index)],
3373 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3374 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3375 flags = self.config_flags.NAT_IS_INSIDE
3376 self.vapi.nat44_interface_add_del_output_feature(
3377 is_add=1, flags=flags,
3378 sw_if_index=self.pg4.sw_if_index)
3379 self.vapi.nat44_interface_add_del_output_feature(
3380 is_add=1, flags=flags,
3381 sw_if_index=self.pg6.sw_if_index)
3382 self.vapi.nat44_interface_add_del_output_feature(
3384 sw_if_index=self.pg3.sw_if_index)
3387 pkts = self.create_stream_in(self.pg4, self.pg3)
3388 self.pg4.add_stream(pkts)
3389 self.pg_enable_capture(self.pg_interfaces)
3391 capture = self.pg3.get_capture(len(pkts))
3392 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3395 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3396 self.pg3.add_stream(pkts)
3397 self.pg_enable_capture(self.pg_interfaces)
3399 capture = self.pg4.get_capture(len(pkts))
3400 self.verify_capture_in(capture, self.pg4)
3403 pkts = self.create_stream_in(self.pg6, self.pg3)
3404 self.pg6.add_stream(pkts)
3405 self.pg_enable_capture(self.pg_interfaces)
3407 capture = self.pg3.get_capture(len(pkts))
3408 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3411 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3412 self.pg3.add_stream(pkts)
3413 self.pg_enable_capture(self.pg_interfaces)
3415 capture = self.pg6.get_capture(len(pkts))
3416 self.verify_capture_in(capture, self.pg6)
3418 def test_output_feature_hairpinning(self):
3419 """ NAT44 interface output feature hairpinning (in2out postrouting) """
3420 host = self.pg0.remote_hosts[0]
3421 server = self.pg0.remote_hosts[1]
3424 server_in_port = 5678
3425 server_out_port = 8765
3427 self.nat44_add_address(self.nat_addr)
3428 flags = self.config_flags.NAT_IS_INSIDE
3429 self.vapi.nat44_interface_add_del_output_feature(
3430 is_add=1, flags=flags,
3431 sw_if_index=self.pg0.sw_if_index)
3432 self.vapi.nat44_interface_add_del_output_feature(
3434 sw_if_index=self.pg1.sw_if_index)
3436 # add static mapping for server
3437 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3438 server_in_port, server_out_port,
3439 proto=IP_PROTOS.tcp)
3441 # send packet from host to server
3442 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3443 IP(src=host.ip4, dst=self.nat_addr) /
3444 TCP(sport=host_in_port, dport=server_out_port))
3445 self.pg0.add_stream(p)
3446 self.pg_enable_capture(self.pg_interfaces)
3448 capture = self.pg0.get_capture(1)
3453 self.assertEqual(ip.src, self.nat_addr)
3454 self.assertEqual(ip.dst, server.ip4)
3455 self.assertNotEqual(tcp.sport, host_in_port)
3456 self.assertEqual(tcp.dport, server_in_port)
3457 self.assert_packet_checksums_valid(p)
3458 host_out_port = tcp.sport
3460 self.logger.error(ppp("Unexpected or invalid packet:", p))
3463 # send reply from server to host
3464 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3465 IP(src=server.ip4, dst=self.nat_addr) /
3466 TCP(sport=server_in_port, dport=host_out_port))
3467 self.pg0.add_stream(p)
3468 self.pg_enable_capture(self.pg_interfaces)
3470 capture = self.pg0.get_capture(1)
3475 self.assertEqual(ip.src, self.nat_addr)
3476 self.assertEqual(ip.dst, host.ip4)
3477 self.assertEqual(tcp.sport, server_out_port)
3478 self.assertEqual(tcp.dport, host_in_port)
3479 self.assert_packet_checksums_valid(p)
3481 self.logger.error(ppp("Unexpected or invalid packet:", p))
3484 def test_one_armed_nat44(self):
3485 """ One armed NAT44 """
3486 remote_host = self.pg9.remote_hosts[0]
3487 local_host = self.pg9.remote_hosts[1]
3490 self.nat44_add_address(self.nat_addr)
3491 flags = self.config_flags.NAT_IS_INSIDE
3492 self.vapi.nat44_interface_add_del_feature(
3493 sw_if_index=self.pg9.sw_if_index,
3495 self.vapi.nat44_interface_add_del_feature(
3496 sw_if_index=self.pg9.sw_if_index,
3497 flags=flags, is_add=1)
3500 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3501 IP(src=local_host.ip4, dst=remote_host.ip4) /
3502 TCP(sport=12345, dport=80))
3503 self.pg9.add_stream(p)
3504 self.pg_enable_capture(self.pg_interfaces)
3506 capture = self.pg9.get_capture(1)
3511 self.assertEqual(ip.src, self.nat_addr)
3512 self.assertEqual(ip.dst, remote_host.ip4)
3513 self.assertNotEqual(tcp.sport, 12345)
3514 external_port = tcp.sport
3515 self.assertEqual(tcp.dport, 80)
3516 self.assert_packet_checksums_valid(p)
3518 self.logger.error(ppp("Unexpected or invalid packet:", p))
3522 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3523 IP(src=remote_host.ip4, dst=self.nat_addr) /
3524 TCP(sport=80, dport=external_port))
3525 self.pg9.add_stream(p)
3526 self.pg_enable_capture(self.pg_interfaces)
3528 capture = self.pg9.get_capture(1)
3533 self.assertEqual(ip.src, remote_host.ip4)
3534 self.assertEqual(ip.dst, local_host.ip4)
3535 self.assertEqual(tcp.sport, 80)
3536 self.assertEqual(tcp.dport, 12345)
3537 self.assert_packet_checksums_valid(p)
3539 self.logger.error(ppp("Unexpected or invalid packet:", p))
3542 err = self.statistics.get_err_counter(
3543 '/err/nat44-classify/next in2out')
3544 self.assertEqual(err, 1)
3545 err = self.statistics.get_err_counter(
3546 '/err/nat44-classify/next out2in')
3547 self.assertEqual(err, 1)
3549 def test_del_session(self):
3550 """ Delete NAT44 session """
3551 self.nat44_add_address(self.nat_addr)
3552 flags = self.config_flags.NAT_IS_INSIDE
3553 self.vapi.nat44_interface_add_del_feature(
3554 sw_if_index=self.pg0.sw_if_index,
3555 flags=flags, is_add=1)
3556 self.vapi.nat44_interface_add_del_feature(
3557 sw_if_index=self.pg1.sw_if_index,
3560 pkts = self.create_stream_in(self.pg0, self.pg1)
3561 self.pg0.add_stream(pkts)
3562 self.pg_enable_capture(self.pg_interfaces)
3564 self.pg1.get_capture(len(pkts))
3566 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3567 nsessions = len(sessions)
3569 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3570 port=sessions[0].inside_port,
3571 protocol=sessions[0].protocol,
3572 flags=self.config_flags.NAT_IS_INSIDE)
3573 self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
3574 port=sessions[1].outside_port,
3575 protocol=sessions[1].protocol)
3577 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
3578 self.assertEqual(nsessions - len(sessions), 2)
3580 self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
3581 port=sessions[0].inside_port,
3582 protocol=sessions[0].protocol,
3583 flags=self.config_flags.NAT_IS_INSIDE)
3585 self.verify_no_nat44_user()
3587 def test_frag_in_order(self):
3588 """ NAT44 translate fragments arriving in order """
3590 self.nat44_add_address(self.nat_addr)
3591 flags = self.config_flags.NAT_IS_INSIDE
3592 self.vapi.nat44_interface_add_del_feature(
3593 sw_if_index=self.pg0.sw_if_index,
3594 flags=flags, is_add=1)
3595 self.vapi.nat44_interface_add_del_feature(
3596 sw_if_index=self.pg1.sw_if_index,
3599 self.frag_in_order(proto=IP_PROTOS.tcp)
3600 self.frag_in_order(proto=IP_PROTOS.udp)
3601 self.frag_in_order(proto=IP_PROTOS.icmp)
3603 def test_frag_forwarding(self):
3604 """ NAT44 forwarding fragment test """
3605 self.vapi.nat44_add_del_interface_addr(
3607 sw_if_index=self.pg1.sw_if_index)
3608 flags = self.config_flags.NAT_IS_INSIDE
3609 self.vapi.nat44_interface_add_del_feature(
3610 sw_if_index=self.pg0.sw_if_index,
3611 flags=flags, is_add=1)
3612 self.vapi.nat44_interface_add_del_feature(
3613 sw_if_index=self.pg1.sw_if_index,
3615 self.vapi.nat44_forwarding_enable_disable(enable=1)
3617 data = b"A" * 16 + b"B" * 16 + b"C" * 3
3618 pkts = self.create_stream_frag(self.pg1,
3619 self.pg0.remote_ip4,
3623 proto=IP_PROTOS.udp)
3624 self.pg1.add_stream(pkts)
3625 self.pg_enable_capture(self.pg_interfaces)
3627 frags = self.pg0.get_capture(len(pkts))
3628 p = self.reass_frags_and_verify(frags,
3629 self.pg1.remote_ip4,
3630 self.pg0.remote_ip4)
3631 self.assertEqual(p[UDP].sport, 4789)
3632 self.assertEqual(p[UDP].dport, 4789)
3633 self.assertEqual(data, p[Raw].load)
3635 def test_reass_hairpinning(self):
3636 """ NAT44 fragments hairpinning """
3638 self.server = self.pg0.remote_hosts[1]
3639 self.host_in_port = random.randint(1025, 65535)
3640 self.server_in_port = random.randint(1025, 65535)
3641 self.server_out_port = random.randint(1025, 65535)
3643 self.nat44_add_address(self.nat_addr)
3644 flags = self.config_flags.NAT_IS_INSIDE
3645 self.vapi.nat44_interface_add_del_feature(
3646 sw_if_index=self.pg0.sw_if_index,
3647 flags=flags, is_add=1)
3648 self.vapi.nat44_interface_add_del_feature(
3649 sw_if_index=self.pg1.sw_if_index,
3651 # add static mapping for server
3652 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3653 self.server_in_port,
3654 self.server_out_port,
3655 proto=IP_PROTOS.tcp)
3656 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3657 self.server_in_port,
3658 self.server_out_port,
3659 proto=IP_PROTOS.udp)
3660 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
3662 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3663 self.reass_hairpinning(proto=IP_PROTOS.udp)
3664 self.reass_hairpinning(proto=IP_PROTOS.icmp)
3666 def test_frag_out_of_order(self):
3667 """ NAT44 translate fragments arriving out of order """
3669 self.nat44_add_address(self.nat_addr)
3670 flags = self.config_flags.NAT_IS_INSIDE
3671 self.vapi.nat44_interface_add_del_feature(
3672 sw_if_index=self.pg0.sw_if_index,
3673 flags=flags, is_add=1)
3674 self.vapi.nat44_interface_add_del_feature(
3675 sw_if_index=self.pg1.sw_if_index,
3678 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3679 self.frag_out_of_order(proto=IP_PROTOS.udp)
3680 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3682 def test_port_restricted(self):
3683 """ Port restricted NAT44 (MAP-E CE) """
3684 self.nat44_add_address(self.nat_addr)
3685 flags = self.config_flags.NAT_IS_INSIDE
3686 self.vapi.nat44_interface_add_del_feature(
3687 sw_if_index=self.pg0.sw_if_index,
3688 flags=flags, is_add=1)
3689 self.vapi.nat44_interface_add_del_feature(
3690 sw_if_index=self.pg1.sw_if_index,
3692 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3697 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3698 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3699 TCP(sport=4567, dport=22))
3700 self.pg0.add_stream(p)
3701 self.pg_enable_capture(self.pg_interfaces)
3703 capture = self.pg1.get_capture(1)
3708 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3709 self.assertEqual(ip.src, self.nat_addr)
3710 self.assertEqual(tcp.dport, 22)
3711 self.assertNotEqual(tcp.sport, 4567)
3712 self.assertEqual((tcp.sport >> 6) & 63, 10)
3713 self.assert_packet_checksums_valid(p)
3715 self.logger.error(ppp("Unexpected or invalid packet:", p))
3718 def test_port_range(self):
3719 """ External address port range """
3720 self.nat44_add_address(self.nat_addr)
3721 flags = self.config_flags.NAT_IS_INSIDE
3722 self.vapi.nat44_interface_add_del_feature(
3723 sw_if_index=self.pg0.sw_if_index,
3724 flags=flags, is_add=1)
3725 self.vapi.nat44_interface_add_del_feature(
3726 sw_if_index=self.pg1.sw_if_index,
3728 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3733 for port in range(0, 5):
3734 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3735 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3736 TCP(sport=1125 + port))
3738 self.pg0.add_stream(pkts)
3739 self.pg_enable_capture(self.pg_interfaces)
3741 capture = self.pg1.get_capture(3)
3744 self.assertGreaterEqual(tcp.sport, 1025)
3745 self.assertLessEqual(tcp.sport, 1027)
3747 def test_multiple_outside_vrf(self):
3748 """ Multiple outside VRF """
3752 self.pg1.unconfig_ip4()
3753 self.pg2.unconfig_ip4()
3754 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id1})
3755 self.vapi.ip_table_add_del(is_add=1, table={'table_id': vrf_id2})
3756 self.pg1.set_table_ip4(vrf_id1)
3757 self.pg2.set_table_ip4(vrf_id2)
3758 self.pg1.config_ip4()
3759 self.pg2.config_ip4()
3760 self.pg1.resolve_arp()
3761 self.pg2.resolve_arp()
3763 self.nat44_add_address(self.nat_addr)
3764 flags = self.config_flags.NAT_IS_INSIDE
3765 self.vapi.nat44_interface_add_del_feature(
3766 sw_if_index=self.pg0.sw_if_index,
3767 flags=flags, is_add=1)
3768 self.vapi.nat44_interface_add_del_feature(
3769 sw_if_index=self.pg1.sw_if_index,
3771 self.vapi.nat44_interface_add_del_feature(
3772 sw_if_index=self.pg2.sw_if_index,
3777 pkts = self.create_stream_in(self.pg0, self.pg1)
3778 self.pg0.add_stream(pkts)
3779 self.pg_enable_capture(self.pg_interfaces)
3781 capture = self.pg1.get_capture(len(pkts))
3782 self.verify_capture_out(capture, self.nat_addr)
3784 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3785 self.pg1.add_stream(pkts)
3786 self.pg_enable_capture(self.pg_interfaces)
3788 capture = self.pg0.get_capture(len(pkts))
3789 self.verify_capture_in(capture, self.pg0)
3791 self.tcp_port_in = 60303
3792 self.udp_port_in = 60304
3793 self.icmp_id_in = 60305
3796 pkts = self.create_stream_in(self.pg0, self.pg2)
3797 self.pg0.add_stream(pkts)
3798 self.pg_enable_capture(self.pg_interfaces)
3800 capture = self.pg2.get_capture(len(pkts))
3801 self.verify_capture_out(capture, self.nat_addr)
3803 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3804 self.pg2.add_stream(pkts)
3805 self.pg_enable_capture(self.pg_interfaces)
3807 capture = self.pg0.get_capture(len(pkts))
3808 self.verify_capture_in(capture, self.pg0)
3811 self.nat44_add_address(self.nat_addr, is_add=0)
3812 self.pg1.unconfig_ip4()
3813 self.pg2.unconfig_ip4()
3814 self.pg1.set_table_ip4(0)
3815 self.pg2.set_table_ip4(0)
3816 self.pg1.config_ip4()
3817 self.pg2.config_ip4()
3818 self.pg1.resolve_arp()
3819 self.pg2.resolve_arp()
3821 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3822 def test_session_timeout(self):
3823 """ NAT44 session timeouts """
3824 self.nat44_add_address(self.nat_addr)
3825 flags = self.config_flags.NAT_IS_INSIDE
3826 self.vapi.nat44_interface_add_del_feature(
3827 sw_if_index=self.pg0.sw_if_index,
3828 flags=flags, is_add=1)
3829 self.vapi.nat44_interface_add_del_feature(
3830 sw_if_index=self.pg1.sw_if_index,
3832 self.vapi.nat_set_timeouts(udp=5, tcp_established=7440,
3833 tcp_transitory=240, icmp=60)
3837 for i in range(0, max_sessions):
3838 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3839 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3840 IP(src=src, dst=self.pg1.remote_ip4) /
3841 UDP(sport=1025, dport=53))
3843 self.pg0.add_stream(pkts)
3844 self.pg_enable_capture(self.pg_interfaces)
3846 self.pg1.get_capture(max_sessions)
3851 for i in range(0, max_sessions):
3852 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3853 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3854 IP(src=src, dst=self.pg1.remote_ip4) /
3855 UDP(sport=1026, dport=53))
3857 self.pg0.add_stream(pkts)
3858 self.pg_enable_capture(self.pg_interfaces)
3860 self.pg1.get_capture(max_sessions)
3863 users = self.vapi.nat44_user_dump()
3865 nsessions = nsessions + user.nsessions
3866 self.assertLess(nsessions, 2 * max_sessions)
3868 def test_mss_clamping(self):
3869 """ TCP MSS clamping """
3870 self.nat44_add_address(self.nat_addr)
3871 flags = self.config_flags.NAT_IS_INSIDE
3872 self.vapi.nat44_interface_add_del_feature(
3873 sw_if_index=self.pg0.sw_if_index,
3874 flags=flags, is_add=1)
3875 self.vapi.nat44_interface_add_del_feature(
3876 sw_if_index=self.pg1.sw_if_index,
3879 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3880 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3881 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3882 flags="S", options=[('MSS', 1400)]))
3884 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3885 self.pg0.add_stream(p)
3886 self.pg_enable_capture(self.pg_interfaces)
3888 capture = self.pg1.get_capture(1)
3889 # Negotiated MSS value greater than configured - changed
3890 self.verify_mss_value(capture[0], 1000)
3892 self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
3893 self.pg0.add_stream(p)
3894 self.pg_enable_capture(self.pg_interfaces)
3896 capture = self.pg1.get_capture(1)
3897 # MSS clamping disabled - negotiated MSS unchanged
3898 self.verify_mss_value(capture[0], 1400)
3900 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3901 self.pg0.add_stream(p)
3902 self.pg_enable_capture(self.pg_interfaces)
3904 capture = self.pg1.get_capture(1)
3905 # Negotiated MSS value smaller than configured - unchanged
3906 self.verify_mss_value(capture[0], 1400)
3908 @unittest.skipUnless(running_extended_tests, "part of extended tests")
3909 def test_ha_send(self):
3910 """ Send HA session synchronization events (active) """
3911 self.nat44_add_address(self.nat_addr)
3912 flags = self.config_flags.NAT_IS_INSIDE
3913 self.vapi.nat44_interface_add_del_feature(
3914 sw_if_index=self.pg0.sw_if_index,
3915 flags=flags, is_add=1)
3916 self.vapi.nat44_interface_add_del_feature(
3917 sw_if_index=self.pg1.sw_if_index,
3919 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
3922 self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
3923 port=12346, session_refresh_interval=10)
3924 bind_layers(UDP, HANATStateSync, sport=12345)
3927 pkts = self.create_stream_in(self.pg0, self.pg1)
3928 self.pg0.add_stream(pkts)
3929 self.pg_enable_capture(self.pg_interfaces)
3931 capture = self.pg1.get_capture(len(pkts))
3932 self.verify_capture_out(capture)
3933 # active send HA events
3934 self.vapi.nat_ha_flush()
3935 stats = self.statistics.get_counter('/nat44/ha/add-event-send')
3936 self.assertEqual(stats[0][0], 3)
3937 capture = self.pg3.get_capture(1)
3939 self.assert_packet_checksums_valid(p)
3943 hanat = p[HANATStateSync]
3945 self.logger.error(ppp("Invalid packet:", p))
3948 self.assertEqual(ip.src, self.pg3.local_ip4)
3949 self.assertEqual(ip.dst, self.pg3.remote_ip4)
3950 self.assertEqual(udp.sport, 12345)
3951 self.assertEqual(udp.dport, 12346)
3952 self.assertEqual(hanat.version, 1)
3953 self.assertEqual(hanat.thread_index, 0)
3954 self.assertEqual(hanat.count, 3)
3955 seq = hanat.sequence_number
3956 for event in hanat.events:
3957 self.assertEqual(event.event_type, 1)
3958 self.assertEqual(event.in_addr, self.pg0.remote_ip4)
3959 self.assertEqual(event.out_addr, self.nat_addr)
3960 self.assertEqual(event.fib_index, 0)
3962 # ACK received events
3963 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
3964 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
3965 UDP(sport=12346, dport=12345) /
3966 HANATStateSync(sequence_number=seq, flags='ACK'))
3967 self.pg3.add_stream(ack)
3969 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
3970 self.assertEqual(stats[0][0], 1)
3972 # delete one session
3973 self.pg_enable_capture(self.pg_interfaces)
3974 self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
3975 port=self.tcp_port_in,
3976 protocol=IP_PROTOS.tcp,
3977 flags=self.config_flags.NAT_IS_INSIDE)
3978 self.vapi.nat_ha_flush()
3979 stats = self.statistics.get_counter('/nat44/ha/del-event-send')
3980 self.assertEqual(stats[0][0], 1)
3981 capture = self.pg3.get_capture(1)
3984 hanat = p[HANATStateSync]
3986 self.logger.error(ppp("Invalid packet:", p))
3989 self.assertGreater(hanat.sequence_number, seq)
3991 # do not send ACK, active retry send HA event again
3992 self.pg_enable_capture(self.pg_interfaces)
3994 stats = self.statistics.get_counter('/nat44/ha/retry-count')
3995 self.assertEqual(stats[0][0], 3)
3996 stats = self.statistics.get_counter('/nat44/ha/missed-count')
3997 self.assertEqual(stats[0][0], 1)
3998 capture = self.pg3.get_capture(3)
3999 for packet in capture:
4000 self.assertEqual(packet, p)
4002 # session counters refresh
4003 pkts = self.create_stream_out(self.pg1)
4004 self.pg1.add_stream(pkts)
4005 self.pg_enable_capture(self.pg_interfaces)
4007 self.pg0.get_capture(2)
4008 self.vapi.nat_ha_flush()
4009 stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
4010 self.assertEqual(stats[0][0], 2)
4011 capture = self.pg3.get_capture(1)
4013 self.assert_packet_checksums_valid(p)
4017 hanat = p[HANATStateSync]
4019 self.logger.error(ppp("Invalid packet:", p))
4022 self.assertEqual(ip.src, self.pg3.local_ip4)
4023 self.assertEqual(ip.dst, self.pg3.remote_ip4)
4024 self.assertEqual(udp.sport, 12345)
4025 self.assertEqual(udp.dport, 12346)
4026 self.assertEqual(hanat.version, 1)
4027 self.assertEqual(hanat.count, 2)
4028 seq = hanat.sequence_number
4029 for event in hanat.events:
4030 self.assertEqual(event.event_type, 3)
4031 self.assertEqual(event.out_addr, self.nat_addr)
4032 self.assertEqual(event.fib_index, 0)
4033 self.assertEqual(event.total_pkts, 2)
4034 self.assertGreater(event.total_bytes, 0)
4036 ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4037 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4038 UDP(sport=12346, dport=12345) /
4039 HANATStateSync(sequence_number=seq, flags='ACK'))
4040 self.pg3.add_stream(ack)
4042 stats = self.statistics.get_counter('/nat44/ha/ack-recv')
4043 self.assertEqual(stats[0][0], 2)
4045 def test_ha_recv(self):
4046 """ Receive HA session synchronization events (passive) """
4047 self.nat44_add_address(self.nat_addr)
4048 flags = self.config_flags.NAT_IS_INSIDE
4049 self.vapi.nat44_interface_add_del_feature(
4050 sw_if_index=self.pg0.sw_if_index,
4051 flags=flags, is_add=1)
4052 self.vapi.nat44_interface_add_del_feature(
4053 sw_if_index=self.pg1.sw_if_index,
4055 self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
4058 bind_layers(UDP, HANATStateSync, sport=12345)
4060 self.tcp_port_out = random.randint(1025, 65535)
4061 self.udp_port_out = random.randint(1025, 65535)
4063 # send HA session add events to failover/passive
4064 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4065 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4066 UDP(sport=12346, dport=12345) /
4067 HANATStateSync(sequence_number=1, events=[
4068 Event(event_type='add', protocol='tcp',
4069 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4070 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4071 eh_addr=self.pg1.remote_ip4,
4072 ehn_addr=self.pg1.remote_ip4,
4073 eh_port=self.tcp_external_port,
4074 ehn_port=self.tcp_external_port, fib_index=0),
4075 Event(event_type='add', protocol='udp',
4076 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4077 in_port=self.udp_port_in, out_port=self.udp_port_out,
4078 eh_addr=self.pg1.remote_ip4,
4079 ehn_addr=self.pg1.remote_ip4,
4080 eh_port=self.udp_external_port,
4081 ehn_port=self.udp_external_port, fib_index=0)]))
4083 self.pg3.add_stream(p)
4084 self.pg_enable_capture(self.pg_interfaces)
4087 capture = self.pg3.get_capture(1)
4090 hanat = p[HANATStateSync]
4092 self.logger.error(ppp("Invalid packet:", p))
4095 self.assertEqual(hanat.sequence_number, 1)
4096 self.assertEqual(hanat.flags, 'ACK')
4097 self.assertEqual(hanat.version, 1)
4098 self.assertEqual(hanat.thread_index, 0)
4099 stats = self.statistics.get_counter('/nat44/ha/ack-send')
4100 self.assertEqual(stats[0][0], 1)
4101 stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
4102 self.assertEqual(stats[0][0], 2)
4103 users = self.statistics.get_counter('/nat44/total-users')
4104 self.assertEqual(users[0][0], 1)
4105 sessions = self.statistics.get_counter('/nat44/total-sessions')
4106 self.assertEqual(sessions[0][0], 2)
4107 users = self.vapi.nat44_user_dump()
4108 self.assertEqual(len(users), 1)
4109 self.assertEqual(str(users[0].ip_address),
4110 self.pg0.remote_ip4)
4111 # there should be 2 sessions created by HA
4112 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4114 self.assertEqual(len(sessions), 2)
4115 for session in sessions:
4116 self.assertEqual(str(session.inside_ip_address),
4117 self.pg0.remote_ip4)
4118 self.assertEqual(str(session.outside_ip_address),
4120 self.assertIn(session.inside_port,
4121 [self.tcp_port_in, self.udp_port_in])
4122 self.assertIn(session.outside_port,
4123 [self.tcp_port_out, self.udp_port_out])
4124 self.assertIn(session.protocol, [IP_PROTOS.tcp, IP_PROTOS.udp])
4126 # send HA session delete event to failover/passive
4127 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4128 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4129 UDP(sport=12346, dport=12345) /
4130 HANATStateSync(sequence_number=2, events=[
4131 Event(event_type='del', protocol='udp',
4132 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4133 in_port=self.udp_port_in, out_port=self.udp_port_out,
4134 eh_addr=self.pg1.remote_ip4,
4135 ehn_addr=self.pg1.remote_ip4,
4136 eh_port=self.udp_external_port,
4137 ehn_port=self.udp_external_port, fib_index=0)]))
4139 self.pg3.add_stream(p)
4140 self.pg_enable_capture(self.pg_interfaces)
4143 capture = self.pg3.get_capture(1)
4146 hanat = p[HANATStateSync]
4148 self.logger.error(ppp("Invalid packet:", p))
4151 self.assertEqual(hanat.sequence_number, 2)
4152 self.assertEqual(hanat.flags, 'ACK')
4153 self.assertEqual(hanat.version, 1)
4154 users = self.vapi.nat44_user_dump()
4155 self.assertEqual(len(users), 1)
4156 self.assertEqual(str(users[0].ip_address),
4157 self.pg0.remote_ip4)
4158 # now we should have only 1 session, 1 deleted by HA
4159 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4161 self.assertEqual(len(sessions), 1)
4162 stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
4163 self.assertEqual(stats[0][0], 1)
4165 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4166 self.assertEqual(stats, 2)
4168 # send HA session refresh event to failover/passive
4169 p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
4170 IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
4171 UDP(sport=12346, dport=12345) /
4172 HANATStateSync(sequence_number=3, events=[
4173 Event(event_type='refresh', protocol='tcp',
4174 in_addr=self.pg0.remote_ip4, out_addr=self.nat_addr,
4175 in_port=self.tcp_port_in, out_port=self.tcp_port_out,
4176 eh_addr=self.pg1.remote_ip4,
4177 ehn_addr=self.pg1.remote_ip4,
4178 eh_port=self.tcp_external_port,
4179 ehn_port=self.tcp_external_port, fib_index=0,
4180 total_bytes=1024, total_pkts=2)]))
4181 self.pg3.add_stream(p)
4182 self.pg_enable_capture(self.pg_interfaces)
4185 capture = self.pg3.get_capture(1)
4188 hanat = p[HANATStateSync]
4190 self.logger.error(ppp("Invalid packet:", p))
4193 self.assertEqual(hanat.sequence_number, 3)
4194 self.assertEqual(hanat.flags, 'ACK')
4195 self.assertEqual(hanat.version, 1)
4196 users = self.vapi.nat44_user_dump()
4197 self.assertEqual(len(users), 1)
4198 self.assertEqual(str(users[0].ip_address),
4199 self.pg0.remote_ip4)
4200 sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
4202 self.assertEqual(len(sessions), 1)
4203 session = sessions[0]
4204 self.assertEqual(session.total_bytes, 1024)
4205 self.assertEqual(session.total_pkts, 2)
4206 stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
4207 self.assertEqual(stats[0][0], 1)
4209 stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
4210 self.assertEqual(stats, 3)
4212 # send packet to test session created by HA
4213 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4214 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4215 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out))
4216 self.pg1.add_stream(p)
4217 self.pg_enable_capture(self.pg_interfaces)
4219 capture = self.pg0.get_capture(1)
4225 self.logger.error(ppp("Invalid packet:", p))
4228 self.assertEqual(ip.src, self.pg1.remote_ip4)
4229 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4230 self.assertEqual(tcp.sport, self.tcp_external_port)
4231 self.assertEqual(tcp.dport, self.tcp_port_in)
4234 super(TestNAT44, self).tearDown()
4236 self.vapi.cli("clear logging")
4238 def show_commands_at_teardown(self):
4239 self.logger.info(self.vapi.cli("show nat44 addresses"))
4240 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4241 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4242 self.logger.info(self.vapi.cli("show nat44 interface address"))
4243 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
4244 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
4245 self.logger.info(self.vapi.cli("show nat timeouts"))
4247 self.vapi.cli("show nat addr-port-assignment-alg"))
4248 self.logger.info(self.vapi.cli("show nat ha"))
4251 class TestNAT44EndpointDependent2(MethodHolder):
4252 """ Endpoint-Dependent mapping and filtering test cases """
4255 def setUpConstants(cls):
4256 super(TestNAT44EndpointDependent2, cls).setUpConstants()
4257 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4260 def tearDownClass(cls):
4261 super(TestNAT44EndpointDependent2, cls).tearDownClass()
4264 super(TestNAT44EndpointDependent2, self).tearDown()
4267 def create_and_add_ip4_table(cls, i, table_id):
4268 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': table_id})
4269 i.set_table_ip4(table_id)
4272 def setUpClass(cls):
4273 super(TestNAT44EndpointDependent2, cls).setUpClass()
4275 cls.create_pg_interfaces(range(3))
4276 cls.interfaces = list(cls.pg_interfaces)
4278 cls.create_and_add_ip4_table(cls.pg1, 10)
4280 for i in cls.interfaces:
4285 i.generate_remote_hosts(1)
4286 i.configure_ipv4_neighbors()
4289 super(TestNAT44EndpointDependent2, self).setUp()
4291 nat_config = self.vapi.nat_show_config()
4292 self.assertEqual(1, nat_config.endpoint_dependent)
4294 def nat_add_inside_interface(self, i):
4295 self.vapi.nat44_interface_add_del_feature(
4296 flags=self.config_flags.NAT_IS_INSIDE,
4297 sw_if_index=i.sw_if_index, is_add=1)
4299 def nat_add_outside_interface(self, i):
4300 self.vapi.nat44_interface_add_del_feature(
4301 flags=self.config_flags.NAT_IS_OUTSIDE,
4302 sw_if_index=i.sw_if_index, is_add=1)
4304 def nat_add_interface_address(self, i):
4305 self.nat_addr = i.local_ip4
4306 self.vapi.nat44_add_del_interface_addr(
4307 sw_if_index=i.sw_if_index, is_add=1)
4309 def nat_add_address(self, address, vrf_id=0xFFFFFFFF):
4310 self.nat_addr = address
4311 self.nat44_add_address(address, vrf_id=vrf_id)
4313 def cli(self, command):
4314 result = self.vapi.cli(command)
4315 self.logger.info(result)
4318 def show_configuration(self):
4319 self.cli("show interface")
4320 self.cli("show interface address")
4321 self.cli("show nat44 addresses")
4322 self.cli("show nat44 interfaces")
4324 def create_tcp_stream(self, in_if, out_if, count):
4326 Create tcp packet stream
4328 :param in_if: Inside interface
4329 :param out_if: Outside interface
4330 :param count: count of packets to generate
4335 for i in range(count):
4336 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4337 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=64) /
4338 TCP(sport=port + i, dport=20))
4343 def test_session_limit_per_vrf(self):
4346 inside_vrf10 = self.pg1
4351 # 2 interfaces pg0, pg1 (vrf10, limit 1 tcp session)
4352 # non existing vrf_id makes process core dump
4353 self.vapi.nat44_set_session_limit(session_limit=limit, vrf_id=10)
4355 self.nat_add_inside_interface(inside)
4356 self.nat_add_inside_interface(inside_vrf10)
4357 self.nat_add_outside_interface(outside)
4360 self.nat_add_interface_address(outside)
4362 # BUG: causing core dump - when bad vrf_id is specified
4363 # self.nat44_add_address(outside.local_ip4, vrf_id=20)
4365 self.show_configuration()
4367 stream = self.create_tcp_stream(inside_vrf10, outside, limit * 2)
4368 inside_vrf10.add_stream(stream)
4370 self.pg_enable_capture(self.pg_interfaces)
4373 capture = outside.get_capture(limit)
4375 stream = self.create_tcp_stream(inside, outside, limit * 2)
4376 inside.add_stream(stream)
4378 self.pg_enable_capture(self.pg_interfaces)
4381 capture = outside.get_capture(len(stream))
4384 class TestNAT44EndpointDependent(MethodHolder):
4385 """ Endpoint-Dependent mapping and filtering test cases """
4388 def setUpConstants(cls):
4389 super(TestNAT44EndpointDependent, cls).setUpConstants()
4390 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
4393 def setUpClass(cls):
4394 super(TestNAT44EndpointDependent, cls).setUpClass()
4395 cls.vapi.cli("set log class nat level debug")
4397 cls.tcp_port_in = 6303
4398 cls.tcp_port_out = 6303
4399 cls.udp_port_in = 6304
4400 cls.udp_port_out = 6304
4401 cls.icmp_id_in = 6305
4402 cls.icmp_id_out = 6305
4403 cls.nat_addr = '10.0.0.3'
4404 cls.ipfix_src_port = 4739
4405 cls.ipfix_domain_id = 1
4406 cls.tcp_external_port = 80
4408 cls.create_pg_interfaces(range(9))
4409 cls.interfaces = list(cls.pg_interfaces[0:3])
4411 for i in cls.interfaces:
4416 cls.pg0.generate_remote_hosts(3)
4417 cls.pg0.configure_ipv4_neighbors()
4421 cls.pg4.generate_remote_hosts(2)
4422 cls.pg4.config_ip4()
4423 cls.vapi.sw_interface_add_del_address(
4424 sw_if_index=cls.pg4.sw_if_index,
4425 prefix="10.0.0.1/24")
4428 cls.pg4.resolve_arp()
4429 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
4430 cls.pg4.resolve_arp()
4432 zero_ip4 = socket.inet_pton(socket.AF_INET, "0.0.0.0")
4433 cls.vapi.ip_table_add_del(is_add=1, table={'table_id': 1})
4435 cls.pg5._local_ip4 = "10.1.1.1"
4436 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
4437 cls.pg5.set_table_ip4(1)
4438 cls.pg5.config_ip4()
4440 r1 = VppIpRoute(cls, cls.pg5.remote_ip4, 32,
4441 [VppRoutePath("0.0.0.0",
4442 cls.pg5.sw_if_index)],
4447 cls.pg6._local_ip4 = "10.1.2.1"
4448 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
4449 cls.pg6.set_table_ip4(1)
4450 cls.pg6.config_ip4()
4453 r2 = VppIpRoute(cls, cls.pg6.remote_ip4, 32,
4454 [VppRoutePath("0.0.0.0",
4455 cls.pg6.sw_if_index)],
4458 r3 = VppIpRoute(cls, cls.pg6.remote_ip4, 16,
4459 [VppRoutePath("0.0.0.0",
4464 r4 = VppIpRoute(cls, "0.0.0.0", 0,
4465 [VppRoutePath("0.0.0.0", 0xffffffff,
4469 r5 = VppIpRoute(cls, "0.0.0.0", 0,
4470 [VppRoutePath(cls.pg1.local_ip4,
4471 cls.pg1.sw_if_index)],
4478 cls.pg5.resolve_arp()
4479 cls.pg6.resolve_arp()
4482 cls.pg7.config_ip4()
4483 cls.pg7.resolve_arp()
4484 cls.pg7.generate_remote_hosts(3)
4485 cls.pg7.configure_ipv4_neighbors()
4488 cls.pg8.config_ip4()
4489 cls.pg8.resolve_arp()
4492 super(TestNAT44EndpointDependent, self).setUp()
4493 self.vapi.nat_set_timeouts(
4494 udp=300, tcp_established=7440, tcp_transitory=240, icmp=60)
4497 def tearDownClass(cls):
4498 super(TestNAT44EndpointDependent, cls).tearDownClass()
4500 def test_frag_in_order(self):
4501 """ NAT44 translate fragments arriving in order """
4502 self.nat44_add_address(self.nat_addr)
4503 flags = self.config_flags.NAT_IS_INSIDE
4504 self.vapi.nat44_interface_add_del_feature(
4505 sw_if_index=self.pg0.sw_if_index,
4506 flags=flags, is_add=1)
4507 self.vapi.nat44_interface_add_del_feature(
4508 sw_if_index=self.pg1.sw_if_index,
4510 self.frag_in_order(proto=IP_PROTOS.tcp, ignore_port=True)
4511 self.frag_in_order(proto=IP_PROTOS.udp, ignore_port=True)
4512 self.frag_in_order(proto=IP_PROTOS.icmp, ignore_port=True)
4514 def test_frag_in_order_dont_translate(self):
4515 """ NAT44 don't translate fragments arriving in order """
4516 flags = self.config_flags.NAT_IS_INSIDE
4517 self.vapi.nat44_interface_add_del_feature(
4518 sw_if_index=self.pg0.sw_if_index,
4519 flags=flags, is_add=1)
4520 self.vapi.nat44_interface_add_del_feature(
4521 sw_if_index=self.pg1.sw_if_index,
4523 self.vapi.nat44_forwarding_enable_disable(enable=True)
4524 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
4526 def test_frag_out_of_order(self):
4527 """ NAT44 translate fragments arriving out of order """
4528 self.nat44_add_address(self.nat_addr)
4529 flags = self.config_flags.NAT_IS_INSIDE
4530 self.vapi.nat44_interface_add_del_feature(
4531 sw_if_index=self.pg0.sw_if_index,
4532 flags=flags, is_add=1)
4533 self.vapi.nat44_interface_add_del_feature(
4534 sw_if_index=self.pg1.sw_if_index,
4536 self.frag_out_of_order(proto=IP_PROTOS.tcp, ignore_port=True)
4537 self.frag_out_of_order(proto=IP_PROTOS.udp, ignore_port=True)
4538 self.frag_out_of_order(proto=IP_PROTOS.icmp, ignore_port=True)
4540 def test_frag_out_of_order_dont_translate(self):
4541 """ NAT44 don't translate fragments arriving out of order """
4542 flags = self.config_flags.NAT_IS_INSIDE
4543 self.vapi.nat44_interface_add_del_feature(
4544 sw_if_index=self.pg0.sw_if_index,
4545 flags=flags, is_add=1)
4546 self.vapi.nat44_interface_add_del_feature(
4547 sw_if_index=self.pg1.sw_if_index,
4549 self.vapi.nat44_forwarding_enable_disable(enable=True)
4550 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
4552 def test_frag_in_order_in_plus_out(self):
4553 """ in+out interface fragments in order """
4554 flags = self.config_flags.NAT_IS_INSIDE
4555 self.vapi.nat44_interface_add_del_feature(
4556 sw_if_index=self.pg0.sw_if_index,
4558 self.vapi.nat44_interface_add_del_feature(
4559 sw_if_index=self.pg0.sw_if_index,
4560 flags=flags, is_add=1)
4561 self.vapi.nat44_interface_add_del_feature(
4562 sw_if_index=self.pg1.sw_if_index,
4564 self.vapi.nat44_interface_add_del_feature(
4565 sw_if_index=self.pg1.sw_if_index,
4566 flags=flags, is_add=1)
4568 self.server = self.pg1.remote_hosts[0]
4570 self.server_in_addr = self.server.ip4
4571 self.server_out_addr = '11.11.11.11'
4572 self.server_in_port = random.randint(1025, 65535)
4573 self.server_out_port = random.randint(1025, 65535)
4575 self.nat44_add_address(self.server_out_addr)
4577 # add static mappings for server
4578 self.nat44_add_static_mapping(self.server_in_addr,
4579 self.server_out_addr,
4580 self.server_in_port,
4581 self.server_out_port,
4582 proto=IP_PROTOS.tcp)
4583 self.nat44_add_static_mapping(self.server_in_addr,
4584 self.server_out_addr,
4585 self.server_in_port,
4586 self.server_out_port,
4587 proto=IP_PROTOS.udp)
4588 self.nat44_add_static_mapping(self.server_in_addr,
4589 self.server_out_addr,
4590 proto=IP_PROTOS.icmp)
4592 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
4593 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
4594 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
4596 def test_frag_out_of_order_in_plus_out(self):
4597 """ in+out interface fragments out of order """
4598 flags = self.config_flags.NAT_IS_INSIDE
4599 self.vapi.nat44_interface_add_del_feature(
4600 sw_if_index=self.pg0.sw_if_index,
4602 self.vapi.nat44_interface_add_del_feature(
4603 sw_if_index=self.pg0.sw_if_index,
4604 flags=flags, is_add=1)
4605 self.vapi.nat44_interface_add_del_feature(
4606 sw_if_index=self.pg1.sw_if_index,
4608 self.vapi.nat44_interface_add_del_feature(
4609 sw_if_index=self.pg1.sw_if_index,
4610 flags=flags, is_add=1)
4612 self.server = self.pg1.remote_hosts[0]
4614 self.server_in_addr = self.server.ip4
4615 self.server_out_addr = '11.11.11.11'
4616 self.server_in_port = random.randint(1025, 65535)
4617 self.server_out_port = random.randint(1025, 65535)
4619 self.nat44_add_address(self.server_out_addr)
4621 # add static mappings for server
4622 self.nat44_add_static_mapping(self.server_in_addr,
4623 self.server_out_addr,
4624 self.server_in_port,
4625 self.server_out_port,
4626 proto=IP_PROTOS.tcp)
4627 self.nat44_add_static_mapping(self.server_in_addr,
4628 self.server_out_addr,
4629 self.server_in_port,
4630 self.server_out_port,
4631 proto=IP_PROTOS.udp)
4632 self.nat44_add_static_mapping(self.server_in_addr,
4633 self.server_out_addr,
4634 proto=IP_PROTOS.icmp)
4636 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4637 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4638 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4640 def test_reass_hairpinning(self):
4641 """ NAT44 fragments hairpinning """
4642 self.server = self.pg0.remote_hosts[1]
4643 self.host_in_port = random.randint(1025, 65535)
4644 self.server_in_port = random.randint(1025, 65535)
4645 self.server_out_port = random.randint(1025, 65535)
4647 self.nat44_add_address(self.nat_addr)
4648 flags = self.config_flags.NAT_IS_INSIDE
4649 self.vapi.nat44_interface_add_del_feature(
4650 sw_if_index=self.pg0.sw_if_index,
4651 flags=flags, is_add=1)
4652 self.vapi.nat44_interface_add_del_feature(
4653 sw_if_index=self.pg1.sw_if_index,
4655 # add static mapping for server
4656 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4657 self.server_in_port,
4658 self.server_out_port,
4659 proto=IP_PROTOS.tcp)
4660 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4661 self.server_in_port,
4662 self.server_out_port,
4663 proto=IP_PROTOS.udp)
4664 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
4666 self.reass_hairpinning(proto=IP_PROTOS.tcp, ignore_port=True)
4667 self.reass_hairpinning(proto=IP_PROTOS.udp, ignore_port=True)
4668 self.reass_hairpinning(proto=IP_PROTOS.icmp, ignore_port=True)
4670 def test_clear_sessions(self):
4671 """ NAT44 ED session clearing test """
4673 self.nat44_add_address(self.nat_addr)
4674 flags = self.config_flags.NAT_IS_INSIDE
4675 self.vapi.nat44_interface_add_del_feature(
4676 sw_if_index=self.pg0.sw_if_index,
4677 flags=flags, is_add=1)
4678 self.vapi.nat44_interface_add_del_feature(
4679 sw_if_index=self.pg1.sw_if_index,
4682 nat_config = self.vapi.nat_show_config()
4683 self.assertEqual(1, nat_config.endpoint_dependent)
4685 pkts = self.create_stream_in(self.pg0, self.pg1)
4686 self.pg0.add_stream(pkts)
4687 self.pg_enable_capture(self.pg_interfaces)
4689 capture = self.pg1.get_capture(len(pkts))
4690 self.verify_capture_out(capture, ignore_port=True)
4692 sessions = self.statistics.get_counter('/nat44/total-sessions')
4693 self.assertTrue(sessions[0][0] > 0)
4694 self.logger.info("sessions before clearing: %s" % sessions[0][0])
4696 # just for testing purposes
4697 self.logger.info(self.vapi.cli("show nat44 summary"))
4699 self.vapi.cli("clear nat44 sessions")
4701 self.logger.info(self.vapi.cli("show nat44 summary"))
4703 sessions = self.statistics.get_counter('/nat44/total-sessions')
4704 self.assertEqual(sessions[0][0], 0)
4705 self.logger.info("sessions after clearing: %s" % sessions[0][0])
4707 def test_dynamic(self):
4708 """ NAT44 dynamic translation test """
4710 self.nat44_add_address(self.nat_addr)
4711 flags = self.config_flags.NAT_IS_INSIDE
4712 self.vapi.nat44_interface_add_del_feature(
4713 sw_if_index=self.pg0.sw_if_index,
4714 flags=flags, is_add=1)
4715 self.vapi.nat44_interface_add_del_feature(
4716 sw_if_index=self.pg1.sw_if_index,
4719 nat_config = self.vapi.nat_show_config()
4720 self.assertEqual(1, nat_config.endpoint_dependent)
4723 tcpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4724 udpn = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4725 icmpn = self.statistics.get_counter(
4726 '/nat44/ed/in2out/slowpath/icmp')[0]
4727 drops = self.statistics.get_counter(
4728 '/nat44/ed/in2out/slowpath/drops')[0]
4730 pkts = self.create_stream_in(self.pg0, self.pg1)
4731 self.pg0.add_stream(pkts)
4732 self.pg_enable_capture(self.pg_interfaces)
4734 capture = self.pg1.get_capture(len(pkts))
4735 self.verify_capture_out(capture, ignore_port=True)
4737 if_idx = self.pg0.sw_if_index
4738 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/tcp')[0]
4739 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4740 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/udp')[0]
4741 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4742 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/icmp')[0]
4743 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4744 cnt = self.statistics.get_counter('/nat44/ed/in2out/slowpath/drops')[0]
4745 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4748 tcpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4749 udpn = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4750 icmpn = self.statistics.get_counter(
4751 '/nat44/ed/out2in/slowpath/icmp')[0]
4752 drops = self.statistics.get_counter(
4753 '/nat44/ed/out2in/fastpath/drops')[0]
4755 pkts = self.create_stream_out(self.pg1)
4756 self.pg1.add_stream(pkts)
4757 self.pg_enable_capture(self.pg_interfaces)
4759 capture = self.pg0.get_capture(len(pkts))
4760 self.verify_capture_in(capture, self.pg0)
4762 if_idx = self.pg1.sw_if_index
4763 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/tcp')[0]
4764 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4765 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/udp')[0]
4766 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4767 cnt = self.statistics.get_counter('/nat44/ed/out2in/slowpath/icmp')[0]
4768 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4769 cnt = self.statistics.get_counter('/nat44/ed/out2in/fastpath/drops')[0]
4770 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4772 sessions = self.statistics.get_counter('/nat44/total-sessions')
4773 self.assertEqual(sessions[0][0], 3)
4775 def test_dynamic_out_of_ports(self):
4776 """ NAT44 dynamic translation test: out of ports """
4778 flags = self.config_flags.NAT_IS_INSIDE
4779 self.vapi.nat44_interface_add_del_feature(
4780 sw_if_index=self.pg0.sw_if_index,
4781 flags=flags, is_add=1)
4782 self.vapi.nat44_interface_add_del_feature(
4783 sw_if_index=self.pg1.sw_if_index,
4786 nat_config = self.vapi.nat_show_config()
4787 self.assertEqual(1, nat_config.endpoint_dependent)
4789 # in2out and no NAT addresses added
4790 err_old = self.statistics.get_err_counter(
4791 '/err/nat44-ed-in2out-slowpath/out of ports')
4793 pkts = self.create_stream_in(self.pg0, self.pg1)
4794 self.pg0.add_stream(pkts)
4795 self.pg_enable_capture(self.pg_interfaces)
4797 self.pg1.get_capture(0, timeout=1)
4799 err_new = self.statistics.get_err_counter(
4800 '/err/nat44-ed-in2out-slowpath/out of ports')
4802 self.assertEqual(err_new - err_old, len(pkts))
4804 # in2out after NAT addresses added
4805 self.nat44_add_address(self.nat_addr)
4807 err_old = self.statistics.get_err_counter(
4808 '/err/nat44-ed-in2out-slowpath/out of ports')
4810 pkts = self.create_stream_in(self.pg0, self.pg1)
4811 self.pg0.add_stream(pkts)
4812 self.pg_enable_capture(self.pg_interfaces)
4814 capture = self.pg1.get_capture(len(pkts))
4815 self.verify_capture_out(capture, ignore_port=True)
4817 err_new = self.statistics.get_err_counter(
4818 '/err/nat44-ed-in2out-slowpath/out of ports')
4820 self.assertEqual(err_new, err_old)
4822 def test_dynamic_output_feature_vrf(self):
4823 """ NAT44 dynamic translation test: output-feature, VRF"""
4825 # other then default (0)
4828 self.nat44_add_address(self.nat_addr)
4829 flags = self.config_flags.NAT_IS_INSIDE
4830 self.vapi.nat44_interface_add_del_output_feature(
4831 sw_if_index=self.pg7.sw_if_index,
4832 flags=flags, is_add=1)
4833 self.vapi.nat44_interface_add_del_output_feature(
4834 sw_if_index=self.pg8.sw_if_index,
4838 self.vapi.ip_table_add_del(is_add=1,
4839 table={'table_id': new_vrf_id})
4841 self.pg7.unconfig_ip4()
4842 self.pg7.set_table_ip4(new_vrf_id)
4843 self.pg7.config_ip4()
4844 self.pg7.resolve_arp()
4846 self.pg8.unconfig_ip4()
4847 self.pg8.set_table_ip4(new_vrf_id)
4848 self.pg8.config_ip4()
4849 self.pg8.resolve_arp()
4851 nat_config = self.vapi.nat_show_config()
4852 self.assertEqual(1, nat_config.endpoint_dependent)
4855 tcpn = self.statistics.get_counter(
4856 '/nat44/ed/in2out/slowpath/tcp')[0]
4857 udpn = self.statistics.get_counter(
4858 '/nat44/ed/in2out/slowpath/udp')[0]
4859 icmpn = self.statistics.get_counter(
4860 '/nat44/ed/in2out/slowpath/icmp')[0]
4861 drops = self.statistics.get_counter(
4862 '/nat44/ed/in2out/slowpath/drops')[0]
4864 pkts = self.create_stream_in(self.pg7, self.pg8)
4865 self.pg7.add_stream(pkts)
4866 self.pg_enable_capture(self.pg_interfaces)
4868 capture = self.pg8.get_capture(len(pkts))
4869 self.verify_capture_out(capture, ignore_port=True)
4871 if_idx = self.pg7.sw_if_index
4872 cnt = self.statistics.get_counter(
4873 '/nat44/ed/in2out/slowpath/tcp')[0]
4874 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4875 cnt = self.statistics.get_counter(
4876 '/nat44/ed/in2out/slowpath/udp')[0]
4877 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4878 cnt = self.statistics.get_counter(
4879 '/nat44/ed/in2out/slowpath/icmp')[0]
4880 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4881 cnt = self.statistics.get_counter(
4882 '/nat44/ed/in2out/slowpath/drops')[0]
4883 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4886 tcpn = self.statistics.get_counter(
4887 '/nat44/ed/out2in/fastpath/tcp')[0]
4888 udpn = self.statistics.get_counter(
4889 '/nat44/ed/out2in/fastpath/udp')[0]
4890 icmpn = self.statistics.get_counter(
4891 '/nat44/ed/out2in/slowpath/icmp')[0]
4892 drops = self.statistics.get_counter(
4893 '/nat44/ed/out2in/fastpath/drops')[0]
4895 pkts = self.create_stream_out(self.pg8)
4896 self.pg8.add_stream(pkts)
4897 self.pg_enable_capture(self.pg_interfaces)
4899 capture = self.pg7.get_capture(len(pkts))
4900 self.verify_capture_in(capture, self.pg7)
4902 if_idx = self.pg8.sw_if_index
4903 cnt = self.statistics.get_counter(
4904 '/nat44/ed/out2in/fastpath/tcp')[0]
4905 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
4906 cnt = self.statistics.get_counter(
4907 '/nat44/ed/out2in/fastpath/udp')[0]
4908 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
4909 cnt = self.statistics.get_counter(
4910 '/nat44/ed/out2in/slowpath/icmp')[0]
4911 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
4912 cnt = self.statistics.get_counter(
4913 '/nat44/ed/out2in/fastpath/drops')[0]
4914 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
4916 sessions = self.statistics.get_counter('/nat44/total-sessions')
4917 self.assertEqual(sessions[0][0], 3)
4920 self.pg7.unconfig_ip4()
4921 self.pg7.set_table_ip4(1)
4922 self.pg7.config_ip4()
4923 self.pg7.resolve_arp()
4925 self.pg8.unconfig_ip4()
4926 self.pg8.set_table_ip4(1)
4927 self.pg8.config_ip4()
4928 self.pg8.resolve_arp()
4930 self.vapi.ip_table_add_del(is_add=0,
4931 table={'table_id': new_vrf_id})
4933 def test_forwarding(self):
4934 """ NAT44 forwarding test """
4936 flags = self.config_flags.NAT_IS_INSIDE
4937 self.vapi.nat44_interface_add_del_feature(
4938 sw_if_index=self.pg0.sw_if_index,
4939 flags=flags, is_add=1)
4940 self.vapi.nat44_interface_add_del_feature(
4941 sw_if_index=self.pg1.sw_if_index,
4943 self.vapi.nat44_forwarding_enable_disable(enable=1)
4945 real_ip = self.pg0.remote_ip4
4946 alias_ip = self.nat_addr
4947 flags = self.config_flags.NAT_IS_ADDR_ONLY
4948 self.vapi.nat44_add_del_static_mapping(is_add=1,
4949 local_ip_address=real_ip,
4950 external_ip_address=alias_ip,
4951 external_sw_if_index=0xFFFFFFFF,
4955 # in2out - static mapping match
4957 pkts = self.create_stream_out(self.pg1)
4958 self.pg1.add_stream(pkts)
4959 self.pg_enable_capture(self.pg_interfaces)
4961 capture = self.pg0.get_capture(len(pkts))
4962 self.verify_capture_in(capture, self.pg0)
4964 pkts = self.create_stream_in(self.pg0, self.pg1)
4965 self.pg0.add_stream(pkts)
4966 self.pg_enable_capture(self.pg_interfaces)
4968 capture = self.pg1.get_capture(len(pkts))
4969 self.verify_capture_out(capture, same_port=True)
4971 # in2out - no static mapping match
4973 host0 = self.pg0.remote_hosts[0]
4974 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4976 pkts = self.create_stream_out(self.pg1,
4977 dst_ip=self.pg0.remote_ip4,
4978 use_inside_ports=True)
4979 self.pg1.add_stream(pkts)
4980 self.pg_enable_capture(self.pg_interfaces)
4982 capture = self.pg0.get_capture(len(pkts))
4983 self.verify_capture_in(capture, self.pg0)
4985 pkts = self.create_stream_in(self.pg0, self.pg1)
4986 self.pg0.add_stream(pkts)
4987 self.pg_enable_capture(self.pg_interfaces)
4989 capture = self.pg1.get_capture(len(pkts))
4990 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4993 self.pg0.remote_hosts[0] = host0
4995 user = self.pg0.remote_hosts[1]
4996 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
4997 self.assertEqual(len(sessions), 3)
4998 self.assertTrue(sessions[0].flags &
4999 self.config_flags.NAT_IS_EXT_HOST_VALID)
5000 self.vapi.nat44_del_session(
5001 address=sessions[0].inside_ip_address,
5002 port=sessions[0].inside_port,
5003 protocol=sessions[0].protocol,
5004 flags=(self.config_flags.NAT_IS_INSIDE |
5005 self.config_flags.NAT_IS_EXT_HOST_VALID),
5006 ext_host_address=sessions[0].ext_host_address,
5007 ext_host_port=sessions[0].ext_host_port)
5008 sessions = self.vapi.nat44_user_session_dump(user.ip4, 0)
5009 self.assertEqual(len(sessions), 2)
5012 self.vapi.nat44_forwarding_enable_disable(enable=0)
5013 flags = self.config_flags.NAT_IS_ADDR_ONLY
5014 self.vapi.nat44_add_del_static_mapping(
5016 local_ip_address=real_ip,
5017 external_ip_address=alias_ip,
5018 external_sw_if_index=0xFFFFFFFF,
5021 def test_static_lb(self):
5022 """ NAT44 local service load balancing """
5023 external_addr_n = self.nat_addr
5026 server1 = self.pg0.remote_hosts[0]
5027 server2 = self.pg0.remote_hosts[1]
5029 locals = [{'addr': server1.ip4,
5033 {'addr': server2.ip4,
5038 self.nat44_add_address(self.nat_addr)
5039 self.vapi.nat44_add_del_lb_static_mapping(
5041 external_addr=external_addr_n,
5042 external_port=external_port,
5043 protocol=IP_PROTOS.tcp,
5044 local_num=len(locals),
5046 flags = self.config_flags.NAT_IS_INSIDE
5047 self.vapi.nat44_interface_add_del_feature(
5048 sw_if_index=self.pg0.sw_if_index,
5049 flags=flags, is_add=1)
5050 self.vapi.nat44_interface_add_del_feature(
5051 sw_if_index=self.pg1.sw_if_index,
5054 # from client to service
5055 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5056 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5057 TCP(sport=12345, dport=external_port))
5058 self.pg1.add_stream(p)
5059 self.pg_enable_capture(self.pg_interfaces)
5061 capture = self.pg0.get_capture(1)
5067 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5068 if ip.dst == server1.ip4:
5072 self.assertEqual(tcp.dport, local_port)
5073 self.assert_packet_checksums_valid(p)
5075 self.logger.error(ppp("Unexpected or invalid packet:", p))
5078 # from service back to client
5079 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5080 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5081 TCP(sport=local_port, dport=12345))
5082 self.pg0.add_stream(p)
5083 self.pg_enable_capture(self.pg_interfaces)
5085 capture = self.pg1.get_capture(1)
5090 self.assertEqual(ip.src, self.nat_addr)
5091 self.assertEqual(tcp.sport, external_port)
5092 self.assert_packet_checksums_valid(p)
5094 self.logger.error(ppp("Unexpected or invalid packet:", p))
5097 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5098 self.assertEqual(len(sessions), 1)
5099 self.assertTrue(sessions[0].flags &
5100 self.config_flags.NAT_IS_EXT_HOST_VALID)
5101 self.vapi.nat44_del_session(
5102 address=sessions[0].inside_ip_address,
5103 port=sessions[0].inside_port,
5104 protocol=sessions[0].protocol,
5105 flags=(self.config_flags.NAT_IS_INSIDE |
5106 self.config_flags.NAT_IS_EXT_HOST_VALID),
5107 ext_host_address=sessions[0].ext_host_address,
5108 ext_host_port=sessions[0].ext_host_port)
5109 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5110 self.assertEqual(len(sessions), 0)
5112 @unittest.skipUnless(running_extended_tests, "part of extended tests")
5113 def test_static_lb_multi_clients(self):
5114 """ NAT44 local service load balancing - multiple clients"""
5116 external_addr = self.nat_addr
5119 server1 = self.pg0.remote_hosts[0]
5120 server2 = self.pg0.remote_hosts[1]
5121 server3 = self.pg0.remote_hosts[2]
5123 locals = [{'addr': server1.ip4,
5127 {'addr': server2.ip4,
5132 self.nat44_add_address(self.nat_addr)
5133 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5134 external_addr=external_addr,
5135 external_port=external_port,
5136 protocol=IP_PROTOS.tcp,
5137 local_num=len(locals),
5139 flags = self.config_flags.NAT_IS_INSIDE
5140 self.vapi.nat44_interface_add_del_feature(
5141 sw_if_index=self.pg0.sw_if_index,
5142 flags=flags, is_add=1)
5143 self.vapi.nat44_interface_add_del_feature(
5144 sw_if_index=self.pg1.sw_if_index,
5149 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
5151 for client in clients:
5152 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5153 IP(src=client, dst=self.nat_addr) /
5154 TCP(sport=12345, dport=external_port))
5156 self.pg1.add_stream(pkts)
5157 self.pg_enable_capture(self.pg_interfaces)
5159 capture = self.pg0.get_capture(len(pkts))
5161 if p[IP].dst == server1.ip4:
5165 self.assertGreater(server1_n, server2_n)
5168 'addr': server3.ip4,
5175 self.vapi.nat44_lb_static_mapping_add_del_local(
5177 external_addr=external_addr,
5178 external_port=external_port,
5180 protocol=IP_PROTOS.tcp)
5184 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
5186 for client in clients:
5187 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5188 IP(src=client, dst=self.nat_addr) /
5189 TCP(sport=12346, dport=external_port))
5191 self.assertGreater(len(pkts), 0)
5192 self.pg1.add_stream(pkts)
5193 self.pg_enable_capture(self.pg_interfaces)
5195 capture = self.pg0.get_capture(len(pkts))
5197 if p[IP].dst == server1.ip4:
5199 elif p[IP].dst == server2.ip4:
5203 self.assertGreater(server1_n, 0)
5204 self.assertGreater(server2_n, 0)
5205 self.assertGreater(server3_n, 0)
5208 'addr': server2.ip4,
5214 # remove one back-end
5215 self.vapi.nat44_lb_static_mapping_add_del_local(
5217 external_addr=external_addr,
5218 external_port=external_port,
5220 protocol=IP_PROTOS.tcp)
5224 self.pg1.add_stream(pkts)
5225 self.pg_enable_capture(self.pg_interfaces)
5227 capture = self.pg0.get_capture(len(pkts))
5229 if p[IP].dst == server1.ip4:
5231 elif p[IP].dst == server2.ip4:
5235 self.assertGreater(server1_n, 0)
5236 self.assertEqual(server2_n, 0)
5237 self.assertGreater(server3_n, 0)
5239 def test_static_lb_2(self):
5240 """ NAT44 local service load balancing (asymmetrical rule) """
5241 external_addr = self.nat_addr
5244 server1 = self.pg0.remote_hosts[0]
5245 server2 = self.pg0.remote_hosts[1]
5247 locals = [{'addr': server1.ip4,
5251 {'addr': server2.ip4,
5256 self.vapi.nat44_forwarding_enable_disable(enable=1)
5257 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5258 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5259 external_addr=external_addr,
5260 external_port=external_port,
5261 protocol=IP_PROTOS.tcp,
5262 local_num=len(locals),
5264 flags = self.config_flags.NAT_IS_INSIDE
5265 self.vapi.nat44_interface_add_del_feature(
5266 sw_if_index=self.pg0.sw_if_index,
5267 flags=flags, is_add=1)
5268 self.vapi.nat44_interface_add_del_feature(
5269 sw_if_index=self.pg1.sw_if_index,
5272 # from client to service
5273 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5274 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5275 TCP(sport=12345, dport=external_port))
5276 self.pg1.add_stream(p)
5277 self.pg_enable_capture(self.pg_interfaces)
5279 capture = self.pg0.get_capture(1)
5285 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
5286 if ip.dst == server1.ip4:
5290 self.assertEqual(tcp.dport, local_port)
5291 self.assert_packet_checksums_valid(p)
5293 self.logger.error(ppp("Unexpected or invalid packet:", p))
5296 # from service back to client
5297 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
5298 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
5299 TCP(sport=local_port, dport=12345))
5300 self.pg0.add_stream(p)
5301 self.pg_enable_capture(self.pg_interfaces)
5303 capture = self.pg1.get_capture(1)
5308 self.assertEqual(ip.src, self.nat_addr)
5309 self.assertEqual(tcp.sport, external_port)
5310 self.assert_packet_checksums_valid(p)
5312 self.logger.error(ppp("Unexpected or invalid packet:", p))
5315 # from client to server (no translation)
5316 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5317 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
5318 TCP(sport=12346, dport=local_port))
5319 self.pg1.add_stream(p)
5320 self.pg_enable_capture(self.pg_interfaces)
5322 capture = self.pg0.get_capture(1)
5328 self.assertEqual(ip.dst, server1.ip4)
5329 self.assertEqual(tcp.dport, local_port)
5330 self.assert_packet_checksums_valid(p)
5332 self.logger.error(ppp("Unexpected or invalid packet:", p))
5335 # from service back to client (no translation)
5336 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
5337 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
5338 TCP(sport=local_port, dport=12346))
5339 self.pg0.add_stream(p)
5340 self.pg_enable_capture(self.pg_interfaces)
5342 capture = self.pg1.get_capture(1)
5347 self.assertEqual(ip.src, server1.ip4)
5348 self.assertEqual(tcp.sport, local_port)
5349 self.assert_packet_checksums_valid(p)
5351 self.logger.error(ppp("Unexpected or invalid packet:", p))
5354 def test_lb_affinity(self):
5355 """ NAT44 local service load balancing affinity """
5356 external_addr = self.nat_addr
5359 server1 = self.pg0.remote_hosts[0]
5360 server2 = self.pg0.remote_hosts[1]
5362 locals = [{'addr': server1.ip4,
5366 {'addr': server2.ip4,
5371 self.nat44_add_address(self.nat_addr)
5372 self.vapi.nat44_add_del_lb_static_mapping(is_add=1,
5373 external_addr=external_addr,
5374 external_port=external_port,
5375 protocol=IP_PROTOS.tcp,
5377 local_num=len(locals),
5379 flags = self.config_flags.NAT_IS_INSIDE
5380 self.vapi.nat44_interface_add_del_feature(
5381 sw_if_index=self.pg0.sw_if_index,
5382 flags=flags, is_add=1)
5383 self.vapi.nat44_interface_add_del_feature(
5384 sw_if_index=self.pg1.sw_if_index,
5387 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5388 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5389 TCP(sport=1025, dport=external_port))
5390 self.pg1.add_stream(p)
5391 self.pg_enable_capture(self.pg_interfaces)
5393 capture = self.pg0.get_capture(1)
5394 backend = capture[0][IP].dst
5396 sessions = self.vapi.nat44_user_session_dump(backend, 0)
5397 self.assertEqual(len(sessions), 1)
5398 self.assertTrue(sessions[0].flags &
5399 self.config_flags.NAT_IS_EXT_HOST_VALID)
5400 self.vapi.nat44_del_session(
5401 address=sessions[0].inside_ip_address,
5402 port=sessions[0].inside_port,
5403 protocol=sessions[0].protocol,
5404 flags=(self.config_flags.NAT_IS_INSIDE |
5405 self.config_flags.NAT_IS_EXT_HOST_VALID),
5406 ext_host_address=sessions[0].ext_host_address,
5407 ext_host_port=sessions[0].ext_host_port)
5410 for port in range(1030, 1100):
5411 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5412 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5413 TCP(sport=port, dport=external_port))
5415 self.pg1.add_stream(pkts)
5416 self.pg_enable_capture(self.pg_interfaces)
5418 capture = self.pg0.get_capture(len(pkts))
5420 self.assertEqual(p[IP].dst, backend)
5422 def test_unknown_proto(self):
5423 """ NAT44 translate packet with unknown protocol """
5424 self.nat44_add_address(self.nat_addr)
5425 flags = self.config_flags.NAT_IS_INSIDE
5426 self.vapi.nat44_interface_add_del_feature(
5427 sw_if_index=self.pg0.sw_if_index,
5428 flags=flags, is_add=1)
5429 self.vapi.nat44_interface_add_del_feature(
5430 sw_if_index=self.pg1.sw_if_index,
5434 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5435 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5436 TCP(sport=self.tcp_port_in, dport=20))
5437 self.pg0.add_stream(p)
5438 self.pg_enable_capture(self.pg_interfaces)
5440 p = self.pg1.get_capture(1)
5442 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5443 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5445 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5446 TCP(sport=1234, dport=1234))
5447 self.pg0.add_stream(p)
5448 self.pg_enable_capture(self.pg_interfaces)
5450 p = self.pg1.get_capture(1)
5453 self.assertEqual(packet[IP].src, self.nat_addr)
5454 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5455 self.assertEqual(packet.haslayer(GRE), 1)
5456 self.assert_packet_checksums_valid(packet)
5458 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5462 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5463 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5465 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5466 TCP(sport=1234, dport=1234))
5467 self.pg1.add_stream(p)
5468 self.pg_enable_capture(self.pg_interfaces)
5470 p = self.pg0.get_capture(1)
5473 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
5474 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
5475 self.assertEqual(packet.haslayer(GRE), 1)
5476 self.assert_packet_checksums_valid(packet)
5478 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5481 def test_hairpinning_unknown_proto(self):
5482 """ NAT44 translate packet with unknown protocol - hairpinning """
5483 host = self.pg0.remote_hosts[0]
5484 server = self.pg0.remote_hosts[1]
5486 server_out_port = 8765
5487 server_nat_ip = "10.0.0.11"
5489 self.nat44_add_address(self.nat_addr)
5490 flags = self.config_flags.NAT_IS_INSIDE
5491 self.vapi.nat44_interface_add_del_feature(
5492 sw_if_index=self.pg0.sw_if_index,
5493 flags=flags, is_add=1)
5494 self.vapi.nat44_interface_add_del_feature(
5495 sw_if_index=self.pg1.sw_if_index,
5498 # add static mapping for server
5499 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
5502 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
5503 IP(src=host.ip4, dst=server_nat_ip) /
5504 TCP(sport=host_in_port, dport=server_out_port))
5505 self.pg0.add_stream(p)
5506 self.pg_enable_capture(self.pg_interfaces)
5508 self.pg0.get_capture(1)
5510 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
5511 IP(src=host.ip4, dst=server_nat_ip) /
5513 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5514 TCP(sport=1234, dport=1234))
5515 self.pg0.add_stream(p)
5516 self.pg_enable_capture(self.pg_interfaces)
5518 p = self.pg0.get_capture(1)
5521 self.assertEqual(packet[IP].src, self.nat_addr)
5522 self.assertEqual(packet[IP].dst, server.ip4)
5523 self.assertEqual(packet.haslayer(GRE), 1)
5524 self.assert_packet_checksums_valid(packet)
5526 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5530 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
5531 IP(src=server.ip4, dst=self.nat_addr) /
5533 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
5534 TCP(sport=1234, dport=1234))
5535 self.pg0.add_stream(p)
5536 self.pg_enable_capture(self.pg_interfaces)
5538 p = self.pg0.get_capture(1)
5541 self.assertEqual(packet[IP].src, server_nat_ip)
5542 self.assertEqual(packet[IP].dst, host.ip4)
5543 self.assertEqual(packet.haslayer(GRE), 1)
5544 self.assert_packet_checksums_valid(packet)
5546 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5549 def test_output_feature_and_service(self):
5550 """ NAT44 interface output feature and services """
5551 external_addr = '1.2.3.4'
5555 self.vapi.nat44_forwarding_enable_disable(enable=1)
5556 self.nat44_add_address(self.nat_addr)
5557 flags = self.config_flags.NAT_IS_ADDR_ONLY
5558 self.vapi.nat44_add_del_identity_mapping(
5559 ip_address=self.pg1.remote_ip4, sw_if_index=0xFFFFFFFF,
5560 flags=flags, is_add=1)
5561 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5562 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
5563 local_port, external_port,
5564 proto=IP_PROTOS.tcp, flags=flags)
5565 flags = self.config_flags.NAT_IS_INSIDE
5566 self.vapi.nat44_interface_add_del_feature(
5567 sw_if_index=self.pg0.sw_if_index,
5569 self.vapi.nat44_interface_add_del_feature(
5570 sw_if_index=self.pg0.sw_if_index,
5571 flags=flags, is_add=1)
5572 self.vapi.nat44_interface_add_del_output_feature(
5574 sw_if_index=self.pg1.sw_if_index)
5576 # from client to service
5577 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5578 IP(src=self.pg1.remote_ip4, dst=external_addr) /
5579 TCP(sport=12345, dport=external_port))
5580 self.pg1.add_stream(p)
5581 self.pg_enable_capture(self.pg_interfaces)
5583 capture = self.pg0.get_capture(1)
5588 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5589 self.assertEqual(tcp.dport, local_port)
5590 self.assert_packet_checksums_valid(p)
5592 self.logger.error(ppp("Unexpected or invalid packet:", p))
5595 # from service back to client
5596 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5597 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5598 TCP(sport=local_port, dport=12345))
5599 self.pg0.add_stream(p)
5600 self.pg_enable_capture(self.pg_interfaces)
5602 capture = self.pg1.get_capture(1)
5607 self.assertEqual(ip.src, external_addr)
5608 self.assertEqual(tcp.sport, external_port)
5609 self.assert_packet_checksums_valid(p)
5611 self.logger.error(ppp("Unexpected or invalid packet:", p))
5614 # from local network host to external network
5615 pkts = self.create_stream_in(self.pg0, self.pg1)
5616 self.pg0.add_stream(pkts)
5617 self.pg_enable_capture(self.pg_interfaces)
5619 capture = self.pg1.get_capture(len(pkts))
5620 self.verify_capture_out(capture, ignore_port=True)
5621 pkts = self.create_stream_in(self.pg0, self.pg1)
5622 self.pg0.add_stream(pkts)
5623 self.pg_enable_capture(self.pg_interfaces)
5625 capture = self.pg1.get_capture(len(pkts))
5626 self.verify_capture_out(capture, ignore_port=True)
5628 # from external network back to local network host
5629 pkts = self.create_stream_out(self.pg1)
5630 self.pg1.add_stream(pkts)
5631 self.pg_enable_capture(self.pg_interfaces)
5633 capture = self.pg0.get_capture(len(pkts))
5634 self.verify_capture_in(capture, self.pg0)
5636 def test_output_feature_and_service2(self):
5637 """ NAT44 interface output feature and service host direct access """
5638 self.vapi.nat44_forwarding_enable_disable(enable=1)
5639 self.nat44_add_address(self.nat_addr)
5640 self.vapi.nat44_interface_add_del_output_feature(
5642 sw_if_index=self.pg1.sw_if_index)
5644 # session initiated from service host - translate
5645 pkts = self.create_stream_in(self.pg0, self.pg1)
5646 self.pg0.add_stream(pkts)
5647 self.pg_enable_capture(self.pg_interfaces)
5649 capture = self.pg1.get_capture(len(pkts))
5650 self.verify_capture_out(capture, ignore_port=True)
5652 pkts = self.create_stream_out(self.pg1)
5653 self.pg1.add_stream(pkts)
5654 self.pg_enable_capture(self.pg_interfaces)
5656 capture = self.pg0.get_capture(len(pkts))
5657 self.verify_capture_in(capture, self.pg0)
5659 # session initiated from remote host - do not translate
5660 self.tcp_port_in = 60303
5661 self.udp_port_in = 60304
5662 self.icmp_id_in = 60305
5663 pkts = self.create_stream_out(self.pg1,
5664 self.pg0.remote_ip4,
5665 use_inside_ports=True)
5666 self.pg1.add_stream(pkts)
5667 self.pg_enable_capture(self.pg_interfaces)
5669 capture = self.pg0.get_capture(len(pkts))
5670 self.verify_capture_in(capture, self.pg0)
5672 pkts = self.create_stream_in(self.pg0, self.pg1)
5673 self.pg0.add_stream(pkts)
5674 self.pg_enable_capture(self.pg_interfaces)
5676 capture = self.pg1.get_capture(len(pkts))
5677 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
5680 def test_output_feature_and_service3(self):
5681 """ NAT44 interface output feature and DST NAT """
5682 external_addr = '1.2.3.4'
5686 self.vapi.nat44_forwarding_enable_disable(enable=1)
5687 self.nat44_add_address(self.nat_addr)
5688 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
5689 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
5690 local_port, external_port,
5691 proto=IP_PROTOS.tcp, flags=flags)
5692 flags = self.config_flags.NAT_IS_INSIDE
5693 self.vapi.nat44_interface_add_del_feature(
5694 sw_if_index=self.pg0.sw_if_index,
5696 self.vapi.nat44_interface_add_del_feature(
5697 sw_if_index=self.pg0.sw_if_index,
5698 flags=flags, is_add=1)
5699 self.vapi.nat44_interface_add_del_output_feature(
5701 sw_if_index=self.pg1.sw_if_index)
5703 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5704 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5705 TCP(sport=12345, dport=external_port))
5706 self.pg0.add_stream(p)
5707 self.pg_enable_capture(self.pg_interfaces)
5709 capture = self.pg1.get_capture(1)
5714 self.assertEqual(ip.src, self.pg0.remote_ip4)
5715 self.assertEqual(tcp.sport, 12345)
5716 self.assertEqual(ip.dst, self.pg1.remote_ip4)
5717 self.assertEqual(tcp.dport, local_port)
5718 self.assert_packet_checksums_valid(p)
5720 self.logger.error(ppp("Unexpected or invalid packet:", p))
5723 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5724 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5725 TCP(sport=local_port, dport=12345))
5726 self.pg1.add_stream(p)
5727 self.pg_enable_capture(self.pg_interfaces)
5729 capture = self.pg0.get_capture(1)
5734 self.assertEqual(ip.src, external_addr)
5735 self.assertEqual(tcp.sport, external_port)
5736 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5737 self.assertEqual(tcp.dport, 12345)
5738 self.assert_packet_checksums_valid(p)
5740 self.logger.error(ppp("Unexpected or invalid packet:", p))
5743 def test_next_src_nat(self):
5744 """ On way back forward packet to nat44-in2out node. """
5745 twice_nat_addr = '10.0.1.3'
5748 post_twice_nat_port = 0
5750 self.vapi.nat44_forwarding_enable_disable(enable=1)
5751 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5752 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
5753 self.config_flags.NAT_IS_SELF_TWICE_NAT)
5754 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
5755 local_port, external_port,
5756 proto=IP_PROTOS.tcp, vrf_id=1,
5758 self.vapi.nat44_interface_add_del_feature(
5759 sw_if_index=self.pg6.sw_if_index,
5762 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5763 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
5764 TCP(sport=12345, dport=external_port))
5765 self.pg6.add_stream(p)
5766 self.pg_enable_capture(self.pg_interfaces)
5768 capture = self.pg6.get_capture(1)
5773 self.assertEqual(ip.src, twice_nat_addr)
5774 self.assertNotEqual(tcp.sport, 12345)
5775 post_twice_nat_port = tcp.sport
5776 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5777 self.assertEqual(tcp.dport, local_port)
5778 self.assert_packet_checksums_valid(p)
5780 self.logger.error(ppp("Unexpected or invalid packet:", p))
5783 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5784 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
5785 TCP(sport=local_port, dport=post_twice_nat_port))
5786 self.pg6.add_stream(p)
5787 self.pg_enable_capture(self.pg_interfaces)
5789 capture = self.pg6.get_capture(1)
5794 self.assertEqual(ip.src, self.pg1.remote_ip4)
5795 self.assertEqual(tcp.sport, external_port)
5796 self.assertEqual(ip.dst, self.pg6.remote_ip4)
5797 self.assertEqual(tcp.dport, 12345)
5798 self.assert_packet_checksums_valid(p)
5800 self.logger.error(ppp("Unexpected or invalid packet:", p))
5803 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
5805 twice_nat_addr = '10.0.1.3'
5813 port_in1 = port_in + 1
5814 port_in2 = port_in + 2
5819 server1 = self.pg0.remote_hosts[0]
5820 server2 = self.pg0.remote_hosts[1]
5832 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
5835 self.nat44_add_address(self.nat_addr)
5836 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5840 flags |= self.config_flags.NAT_IS_SELF_TWICE_NAT
5842 flags |= self.config_flags.NAT_IS_TWICE_NAT
5845 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
5847 proto=IP_PROTOS.tcp,
5850 locals = [{'addr': server1.ip4,
5854 {'addr': server2.ip4,
5858 out_addr = self.nat_addr
5860 self.vapi.nat44_add_del_lb_static_mapping(is_add=1, flags=flags,
5861 external_addr=out_addr,
5862 external_port=port_out,
5863 protocol=IP_PROTOS.tcp,
5864 local_num=len(locals),
5866 flags = self.config_flags.NAT_IS_INSIDE
5867 self.vapi.nat44_interface_add_del_feature(
5868 sw_if_index=pg0.sw_if_index,
5869 flags=flags, is_add=1)
5870 self.vapi.nat44_interface_add_del_feature(
5871 sw_if_index=pg1.sw_if_index,
5878 assert client_id is not None
5880 client = self.pg0.remote_hosts[0]
5881 elif client_id == 2:
5882 client = self.pg0.remote_hosts[1]
5884 client = pg1.remote_hosts[0]
5885 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
5886 IP(src=client.ip4, dst=self.nat_addr) /
5887 TCP(sport=eh_port_out, dport=port_out))
5889 self.pg_enable_capture(self.pg_interfaces)
5891 capture = pg0.get_capture(1)
5897 if ip.dst == server1.ip4:
5903 self.assertEqual(ip.dst, server.ip4)
5905 self.assertIn(tcp.dport, [port_in1, port_in2])
5907 self.assertEqual(tcp.dport, port_in)
5909 self.assertEqual(ip.src, twice_nat_addr)
5910 self.assertNotEqual(tcp.sport, eh_port_out)
5912 self.assertEqual(ip.src, client.ip4)
5913 self.assertEqual(tcp.sport, eh_port_out)
5915 eh_port_in = tcp.sport
5916 saved_port_in = tcp.dport
5917 self.assert_packet_checksums_valid(p)
5919 self.logger.error(ppp("Unexpected or invalid packet:", p))
5922 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5923 IP(src=server.ip4, dst=eh_addr_in) /
5924 TCP(sport=saved_port_in, dport=eh_port_in))
5926 self.pg_enable_capture(self.pg_interfaces)
5928 capture = pg1.get_capture(1)
5933 self.assertEqual(ip.dst, client.ip4)
5934 self.assertEqual(ip.src, self.nat_addr)
5935 self.assertEqual(tcp.dport, eh_port_out)
5936 self.assertEqual(tcp.sport, port_out)
5937 self.assert_packet_checksums_valid(p)
5939 self.logger.error(ppp("Unexpected or invalid packet:", p))
5943 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5944 self.assertEqual(len(sessions), 1)
5945 self.assertTrue(sessions[0].flags &
5946 self.config_flags.NAT_IS_EXT_HOST_VALID)
5947 self.assertTrue(sessions[0].flags &
5948 self.config_flags.NAT_IS_TWICE_NAT)
5949 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
5950 self.vapi.nat44_del_session(
5951 address=sessions[0].inside_ip_address,
5952 port=sessions[0].inside_port,
5953 protocol=sessions[0].protocol,
5954 flags=(self.config_flags.NAT_IS_INSIDE |
5955 self.config_flags.NAT_IS_EXT_HOST_VALID),
5956 ext_host_address=sessions[0].ext_host_nat_address,
5957 ext_host_port=sessions[0].ext_host_nat_port)
5958 sessions = self.vapi.nat44_user_session_dump(server.ip4, 0)
5959 self.assertEqual(len(sessions), 0)
5961 def test_twice_nat(self):
5963 self.twice_nat_common()
5965 def test_self_twice_nat_positive(self):
5966 """ Self Twice NAT44 (positive test) """
5967 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5969 def test_self_twice_nat_negative(self):
5970 """ Self Twice NAT44 (negative test) """
5971 self.twice_nat_common(self_twice_nat=True)
5973 def test_twice_nat_lb(self):
5974 """ Twice NAT44 local service load balancing """
5975 self.twice_nat_common(lb=True)
5977 def test_self_twice_nat_lb_positive(self):
5978 """ Self Twice NAT44 local service load balancing (positive test) """
5979 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5982 def test_self_twice_nat_lb_negative(self):
5983 """ Self Twice NAT44 local service load balancing (negative test) """
5984 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5987 def test_twice_nat_interface_addr(self):
5988 """ Acquire twice NAT44 addresses from interface """
5989 flags = self.config_flags.NAT_IS_TWICE_NAT
5990 self.vapi.nat44_add_del_interface_addr(
5992 sw_if_index=self.pg3.sw_if_index,
5995 # no address in NAT pool
5996 adresses = self.vapi.nat44_address_dump()
5997 self.assertEqual(0, len(adresses))
5999 # configure interface address and check NAT address pool
6000 self.pg3.config_ip4()
6001 adresses = self.vapi.nat44_address_dump()
6002 self.assertEqual(1, len(adresses))
6003 self.assertEqual(str(adresses[0].ip_address),
6005 self.assertEqual(adresses[0].flags, flags)
6007 # remove interface address and check NAT address pool
6008 self.pg3.unconfig_ip4()
6009 adresses = self.vapi.nat44_address_dump()
6010 self.assertEqual(0, len(adresses))
6012 def test_tcp_close(self):
6013 """ Close TCP session from inside network - output feature """
6014 self.vapi.nat44_forwarding_enable_disable(enable=1)
6015 self.nat44_add_address(self.pg1.local_ip4)
6016 twice_nat_addr = '10.0.1.3'
6017 service_ip = '192.168.16.150'
6018 self.nat44_add_address(twice_nat_addr, twice_nat=1)
6019 flags = self.config_flags.NAT_IS_INSIDE
6020 self.vapi.nat44_interface_add_del_feature(
6021 sw_if_index=self.pg0.sw_if_index,
6023 self.vapi.nat44_interface_add_del_feature(
6024 sw_if_index=self.pg0.sw_if_index,
6025 flags=flags, is_add=1)
6026 self.vapi.nat44_interface_add_del_output_feature(
6028 sw_if_index=self.pg1.sw_if_index)
6029 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6030 self.config_flags.NAT_IS_TWICE_NAT)
6031 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6035 proto=IP_PROTOS.tcp,
6037 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6038 start_sessnum = len(sessions)
6040 # SYN packet out->in
6041 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6042 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6043 TCP(sport=33898, dport=80, flags="S"))
6044 self.pg1.add_stream(p)
6045 self.pg_enable_capture(self.pg_interfaces)
6047 capture = self.pg0.get_capture(1)
6049 tcp_port = p[TCP].sport
6051 # SYN + ACK packet in->out
6052 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6053 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6054 TCP(sport=80, dport=tcp_port, flags="SA"))
6055 self.pg0.add_stream(p)
6056 self.pg_enable_capture(self.pg_interfaces)
6058 self.pg1.get_capture(1)
6060 # ACK packet out->in
6061 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6062 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6063 TCP(sport=33898, dport=80, flags="A"))
6064 self.pg1.add_stream(p)
6065 self.pg_enable_capture(self.pg_interfaces)
6067 self.pg0.get_capture(1)
6069 # FIN packet in -> out
6070 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6071 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6072 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
6073 self.pg0.add_stream(p)
6074 self.pg_enable_capture(self.pg_interfaces)
6076 self.pg1.get_capture(1)
6078 # FIN+ACK packet out -> in
6079 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6080 IP(src=self.pg1.remote_ip4, dst=service_ip) /
6081 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
6082 self.pg1.add_stream(p)
6083 self.pg_enable_capture(self.pg_interfaces)
6085 self.pg0.get_capture(1)
6087 # ACK packet in -> out
6088 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6089 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
6090 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
6091 self.pg0.add_stream(p)
6092 self.pg_enable_capture(self.pg_interfaces)
6094 self.pg1.get_capture(1)
6096 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4,
6098 self.assertEqual(len(sessions) - start_sessnum, 0)
6100 def test_tcp_session_close_in(self):
6101 """ Close TCP session from inside network """
6102 self.tcp_port_out = 10505
6103 self.nat44_add_address(self.nat_addr)
6104 flags = self.config_flags.NAT_IS_TWICE_NAT
6105 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6109 proto=IP_PROTOS.tcp,
6111 flags = self.config_flags.NAT_IS_INSIDE
6112 self.vapi.nat44_interface_add_del_feature(
6113 sw_if_index=self.pg0.sw_if_index,
6114 flags=flags, is_add=1)
6115 self.vapi.nat44_interface_add_del_feature(
6116 sw_if_index=self.pg1.sw_if_index,
6119 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6120 start_sessnum = len(sessions)
6122 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6123 tcp_transitory=2, icmp=5)
6125 self.initiate_tcp_session(self.pg0, self.pg1)
6127 # FIN packet in -> out
6128 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6129 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6130 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6131 flags="FA", seq=100, ack=300))
6132 self.pg0.add_stream(p)
6133 self.pg_enable_capture(self.pg_interfaces)
6135 self.pg1.get_capture(1)
6139 # ACK packet out -> in
6140 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6141 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6142 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6143 flags="A", seq=300, ack=101))
6146 # FIN packet out -> in
6147 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6148 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6149 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6150 flags="FA", seq=300, ack=101))
6153 self.pg1.add_stream(pkts)
6154 self.pg_enable_capture(self.pg_interfaces)
6156 self.pg0.get_capture(2)
6158 # ACK packet in -> out
6159 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6160 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6161 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6162 flags="A", seq=101, ack=301))
6163 self.pg0.add_stream(p)
6164 self.pg_enable_capture(self.pg_interfaces)
6166 self.pg1.get_capture(1)
6168 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6169 self.assertEqual(len(sessions) - start_sessnum, 1)
6171 stats = self.statistics.get_counter(
6172 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6173 out2in_drops = stats[0]
6174 stats = self.statistics.get_counter(
6175 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6176 in2out_drops = stats[0]
6178 # extra FIN packet out -> in - this should be dropped
6179 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6180 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6181 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6182 flags="FA", seq=300, ack=101))
6184 self.pg1.add_stream(p)
6185 self.pg_enable_capture(self.pg_interfaces)
6187 self.pg0.assert_nothing_captured()
6189 # extra ACK packet in -> out - this should be dropped
6190 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6191 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6192 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6193 flags="A", seq=101, ack=301))
6194 self.pg0.add_stream(p)
6195 self.pg_enable_capture(self.pg_interfaces)
6197 self.pg1.assert_nothing_captured()
6199 stats = self.statistics.get_counter(
6200 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6201 self.assertEqual(stats[0] - out2in_drops, 1)
6202 stats = self.statistics.get_counter(
6203 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6204 self.assertEqual(stats[0] - in2out_drops, 1)
6207 # extra ACK packet in -> out - this will cause session to be wiped
6208 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6209 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6210 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6211 flags="A", seq=101, ack=301))
6212 self.pg0.add_stream(p)
6213 self.pg_enable_capture(self.pg_interfaces)
6215 self.pg1.assert_nothing_captured()
6216 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6217 self.assertEqual(len(sessions) - start_sessnum, 0)
6219 def test_tcp_session_close_out(self):
6220 """ Close TCP session from outside network """
6221 self.tcp_port_out = 10505
6222 self.nat44_add_address(self.nat_addr)
6223 flags = self.config_flags.NAT_IS_TWICE_NAT
6224 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6228 proto=IP_PROTOS.tcp,
6230 flags = self.config_flags.NAT_IS_INSIDE
6231 self.vapi.nat44_interface_add_del_feature(
6232 sw_if_index=self.pg0.sw_if_index,
6233 flags=flags, is_add=1)
6234 self.vapi.nat44_interface_add_del_feature(
6235 sw_if_index=self.pg1.sw_if_index,
6238 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6239 start_sessnum = len(sessions)
6241 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6242 tcp_transitory=2, icmp=5)
6244 self.initiate_tcp_session(self.pg0, self.pg1)
6246 # FIN packet out -> in
6247 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6248 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6249 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6250 flags="FA", seq=100, ack=300))
6251 self.pg1.add_stream(p)
6252 self.pg_enable_capture(self.pg_interfaces)
6254 self.pg0.get_capture(1)
6256 # FIN+ACK packet in -> out
6257 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6258 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6259 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6260 flags="FA", seq=300, ack=101))
6262 self.pg0.add_stream(p)
6263 self.pg_enable_capture(self.pg_interfaces)
6265 self.pg1.get_capture(1)
6267 # ACK packet out -> in
6268 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6269 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6270 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6271 flags="A", seq=101, ack=301))
6272 self.pg1.add_stream(p)
6273 self.pg_enable_capture(self.pg_interfaces)
6275 self.pg0.get_capture(1)
6277 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6278 self.assertEqual(len(sessions) - start_sessnum, 1)
6280 stats = self.statistics.get_counter(
6281 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6282 out2in_drops = stats[0]
6283 stats = self.statistics.get_counter(
6284 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6285 in2out_drops = stats[0]
6287 # extra FIN packet out -> in - this should be dropped
6288 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6289 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6290 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6291 flags="FA", seq=300, ack=101))
6293 self.pg1.add_stream(p)
6294 self.pg_enable_capture(self.pg_interfaces)
6296 self.pg0.assert_nothing_captured()
6298 # extra ACK packet in -> out - this should be dropped
6299 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6300 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6301 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6302 flags="A", seq=101, ack=301))
6303 self.pg0.add_stream(p)
6304 self.pg_enable_capture(self.pg_interfaces)
6306 self.pg1.assert_nothing_captured()
6308 stats = self.statistics.get_counter(
6309 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6310 self.assertEqual(stats[0] - out2in_drops, 1)
6311 stats = self.statistics.get_counter(
6312 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6313 self.assertEqual(stats[0] - in2out_drops, 1)
6316 # extra ACK packet in -> out - this will cause session to be wiped
6317 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6318 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6319 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6320 flags="A", seq=101, ack=301))
6321 self.pg0.add_stream(p)
6322 self.pg_enable_capture(self.pg_interfaces)
6324 self.pg1.assert_nothing_captured()
6325 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6326 self.assertEqual(len(sessions) - start_sessnum, 0)
6328 def test_tcp_session_close_simultaneous(self):
6329 """ Close TCP session from inside network """
6330 self.tcp_port_out = 10505
6331 self.nat44_add_address(self.nat_addr)
6332 flags = self.config_flags.NAT_IS_TWICE_NAT
6333 self.nat44_add_static_mapping(self.pg0.remote_ip4,
6337 proto=IP_PROTOS.tcp,
6339 flags = self.config_flags.NAT_IS_INSIDE
6340 self.vapi.nat44_interface_add_del_feature(
6341 sw_if_index=self.pg0.sw_if_index,
6342 flags=flags, is_add=1)
6343 self.vapi.nat44_interface_add_del_feature(
6344 sw_if_index=self.pg1.sw_if_index,
6347 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6348 start_sessnum = len(sessions)
6350 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
6351 tcp_transitory=2, icmp=5)
6353 self.initiate_tcp_session(self.pg0, self.pg1)
6355 # FIN packet in -> out
6356 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6357 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6358 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6359 flags="FA", seq=100, ack=300))
6360 self.pg0.add_stream(p)
6361 self.pg_enable_capture(self.pg_interfaces)
6363 self.pg1.get_capture(1)
6365 # FIN packet out -> in
6366 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6367 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6368 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6369 flags="FA", seq=300, ack=100))
6370 self.pg1.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6373 self.pg0.get_capture(1)
6375 # ACK packet in -> out
6376 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6377 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6378 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6379 flags="A", seq=101, ack=301))
6380 self.pg0.add_stream(p)
6381 self.pg_enable_capture(self.pg_interfaces)
6383 self.pg1.get_capture(1)
6385 # ACK packet out -> in
6386 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6387 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6388 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6389 flags="A", seq=301, ack=101))
6390 self.pg1.add_stream(p)
6391 self.pg_enable_capture(self.pg_interfaces)
6393 self.pg0.get_capture(1)
6395 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6396 self.assertEqual(len(sessions) - start_sessnum, 1)
6398 stats = self.statistics.get_counter(
6399 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6400 out2in_drops = stats[0]
6401 stats = self.statistics.get_counter(
6402 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6403 in2out_drops = stats[0]
6405 # extra FIN packet out -> in - this should be dropped
6406 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6407 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6408 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
6409 flags="FA", seq=300, ack=101))
6411 self.pg1.add_stream(p)
6412 self.pg_enable_capture(self.pg_interfaces)
6414 self.pg0.assert_nothing_captured()
6416 # extra ACK packet in -> out - this should be dropped
6417 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6418 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6419 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6420 flags="A", seq=101, ack=301))
6421 self.pg0.add_stream(p)
6422 self.pg_enable_capture(self.pg_interfaces)
6424 self.pg1.assert_nothing_captured()
6426 stats = self.statistics.get_counter(
6427 '/err/nat44-ed-out2in/drops due to TCP in transitory timeout')
6428 self.assertEqual(stats[0] - out2in_drops, 1)
6429 stats = self.statistics.get_counter(
6430 '/err/nat44-ed-in2out/drops due to TCP in transitory timeout')
6431 self.assertEqual(stats[0] - in2out_drops, 1)
6434 # extra ACK packet in -> out - this will cause session to be wiped
6435 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6436 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6437 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
6438 flags="A", seq=101, ack=301))
6439 self.pg0.add_stream(p)
6440 self.pg_enable_capture(self.pg_interfaces)
6442 self.pg1.assert_nothing_captured()
6443 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
6444 self.assertEqual(len(sessions) - start_sessnum, 0)
6446 def test_one_armed_nat44_static(self):
6447 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
6448 remote_host = self.pg4.remote_hosts[0]
6449 local_host = self.pg4.remote_hosts[1]
6454 self.vapi.nat44_forwarding_enable_disable(enable=1)
6455 self.nat44_add_address(self.nat_addr, twice_nat=1)
6456 flags = (self.config_flags.NAT_IS_OUT2IN_ONLY |
6457 self.config_flags.NAT_IS_TWICE_NAT)
6458 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
6459 local_port, external_port,
6460 proto=IP_PROTOS.tcp, flags=flags)
6461 flags = self.config_flags.NAT_IS_INSIDE
6462 self.vapi.nat44_interface_add_del_feature(
6463 sw_if_index=self.pg4.sw_if_index,
6465 self.vapi.nat44_interface_add_del_feature(
6466 sw_if_index=self.pg4.sw_if_index,
6467 flags=flags, is_add=1)
6469 # from client to service
6470 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6471 IP(src=remote_host.ip4, dst=self.nat_addr) /
6472 TCP(sport=12345, dport=external_port))
6473 self.pg4.add_stream(p)
6474 self.pg_enable_capture(self.pg_interfaces)
6476 capture = self.pg4.get_capture(1)
6481 self.assertEqual(ip.dst, local_host.ip4)
6482 self.assertEqual(ip.src, self.nat_addr)
6483 self.assertEqual(tcp.dport, local_port)
6484 self.assertNotEqual(tcp.sport, 12345)
6485 eh_port_in = tcp.sport
6486 self.assert_packet_checksums_valid(p)
6488 self.logger.error(ppp("Unexpected or invalid packet:", p))
6491 # from service back to client
6492 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
6493 IP(src=local_host.ip4, dst=self.nat_addr) /
6494 TCP(sport=local_port, dport=eh_port_in))
6495 self.pg4.add_stream(p)
6496 self.pg_enable_capture(self.pg_interfaces)
6498 capture = self.pg4.get_capture(1)
6503 self.assertEqual(ip.src, self.nat_addr)
6504 self.assertEqual(ip.dst, remote_host.ip4)
6505 self.assertEqual(tcp.sport, external_port)
6506 self.assertEqual(tcp.dport, 12345)
6507 self.assert_packet_checksums_valid(p)
6509 self.logger.error(ppp("Unexpected or invalid packet:", p))
6512 def test_static_with_port_out2(self):
6513 """ 1:1 NAPT asymmetrical rule """
6518 self.vapi.nat44_forwarding_enable_disable(enable=1)
6519 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6520 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
6521 local_port, external_port,
6522 proto=IP_PROTOS.tcp, flags=flags)
6523 flags = self.config_flags.NAT_IS_INSIDE
6524 self.vapi.nat44_interface_add_del_feature(
6525 sw_if_index=self.pg0.sw_if_index,
6526 flags=flags, is_add=1)
6527 self.vapi.nat44_interface_add_del_feature(
6528 sw_if_index=self.pg1.sw_if_index,
6531 # from client to service
6532 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6533 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6534 TCP(sport=12345, dport=external_port))
6535 self.pg1.add_stream(p)
6536 self.pg_enable_capture(self.pg_interfaces)
6538 capture = self.pg0.get_capture(1)
6543 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6544 self.assertEqual(tcp.dport, local_port)
6545 self.assert_packet_checksums_valid(p)
6547 self.logger.error(ppp("Unexpected or invalid packet:", p))
6551 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6552 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6553 ICMP(type=11) / capture[0][IP])
6554 self.pg0.add_stream(p)
6555 self.pg_enable_capture(self.pg_interfaces)
6557 capture = self.pg1.get_capture(1)
6560 self.assertEqual(p[IP].src, self.nat_addr)
6562 self.assertEqual(inner.dst, self.nat_addr)
6563 self.assertEqual(inner[TCPerror].dport, external_port)
6565 self.logger.error(ppp("Unexpected or invalid packet:", p))
6568 # from service back to client
6569 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6570 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6571 TCP(sport=local_port, dport=12345))
6572 self.pg0.add_stream(p)
6573 self.pg_enable_capture(self.pg_interfaces)
6575 capture = self.pg1.get_capture(1)
6580 self.assertEqual(ip.src, self.nat_addr)
6581 self.assertEqual(tcp.sport, external_port)
6582 self.assert_packet_checksums_valid(p)
6584 self.logger.error(ppp("Unexpected or invalid packet:", p))
6588 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6589 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6590 ICMP(type=11) / capture[0][IP])
6591 self.pg1.add_stream(p)
6592 self.pg_enable_capture(self.pg_interfaces)
6594 capture = self.pg0.get_capture(1)
6597 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
6599 self.assertEqual(inner.src, self.pg0.remote_ip4)
6600 self.assertEqual(inner[TCPerror].sport, local_port)
6602 self.logger.error(ppp("Unexpected or invalid packet:", p))
6605 # from client to server (no translation)
6606 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6607 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
6608 TCP(sport=12346, dport=local_port))
6609 self.pg1.add_stream(p)
6610 self.pg_enable_capture(self.pg_interfaces)
6612 capture = self.pg0.get_capture(1)
6617 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6618 self.assertEqual(tcp.dport, local_port)
6619 self.assert_packet_checksums_valid(p)
6621 self.logger.error(ppp("Unexpected or invalid packet:", p))
6624 # from service back to client (no translation)
6625 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6626 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6627 TCP(sport=local_port, dport=12346))
6628 self.pg0.add_stream(p)
6629 self.pg_enable_capture(self.pg_interfaces)
6631 capture = self.pg1.get_capture(1)
6636 self.assertEqual(ip.src, self.pg0.remote_ip4)
6637 self.assertEqual(tcp.sport, local_port)
6638 self.assert_packet_checksums_valid(p)
6640 self.logger.error(ppp("Unexpected or invalid packet:", p))
6643 def test_output_feature(self):
6644 """ NAT44 interface output feature (in2out postrouting) """
6645 self.vapi.nat44_forwarding_enable_disable(enable=1)
6646 self.nat44_add_address(self.nat_addr)
6647 self.vapi.nat44_interface_add_del_feature(
6648 sw_if_index=self.pg0.sw_if_index,
6650 self.vapi.nat44_interface_add_del_output_feature(
6652 sw_if_index=self.pg1.sw_if_index)
6655 pkts = self.create_stream_in(self.pg0, self.pg1)
6656 self.pg0.add_stream(pkts)
6657 self.pg_enable_capture(self.pg_interfaces)
6659 capture = self.pg1.get_capture(len(pkts))
6660 self.verify_capture_out(capture, ignore_port=True)
6663 pkts = self.create_stream_out(self.pg1)
6664 self.pg1.add_stream(pkts)
6665 self.pg_enable_capture(self.pg_interfaces)
6667 capture = self.pg0.get_capture(len(pkts))
6668 self.verify_capture_in(capture, self.pg0)
6670 def test_output_feature_stateful_acl(self):
6671 """ NAT44 endpoint-dependent output feature works with stateful ACL """
6672 self.nat44_add_address(self.nat_addr)
6673 self.vapi.nat44_interface_add_del_output_feature(
6674 sw_if_index=self.pg0.sw_if_index,
6675 flags=self.config_flags.NAT_IS_INSIDE,
6677 self.vapi.nat44_interface_add_del_output_feature(
6678 sw_if_index=self.pg1.sw_if_index,
6679 flags=self.config_flags.NAT_IS_OUTSIDE,
6682 # First ensure that the NAT is working sans ACL
6684 # send packets out2in, no sessions yet so packets should drop
6685 pkts_out2in = self.create_stream_out(self.pg1)
6686 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6688 # send packets into inside intf, ensure received via outside intf
6689 pkts_in2out = self.create_stream_in(self.pg0, self.pg1)
6690 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6692 self.verify_capture_out(capture, ignore_port=True)
6694 # send out2in again, with sessions created it should work now
6695 pkts_out2in = self.create_stream_out(self.pg1)
6696 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6698 self.verify_capture_in(capture, self.pg0)
6700 # Create an ACL blocking everything
6701 out2in_deny_rule = AclRule(is_permit=0)
6702 out2in_acl = VppAcl(self, rules=[out2in_deny_rule])
6703 out2in_acl.add_vpp_config()
6705 # create an ACL to permit/reflect everything
6706 in2out_reflect_rule = AclRule(is_permit=2)
6707 in2out_acl = VppAcl(self, rules=[in2out_reflect_rule])
6708 in2out_acl.add_vpp_config()
6710 # apply as input acl on interface and confirm it blocks everything
6711 acl_if = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
6712 n_input=1, acls=[out2in_acl])
6713 acl_if.add_vpp_config()
6714 self.send_and_assert_no_replies(self.pg1, pkts_out2in)
6717 acl_if.acls = [out2in_acl, in2out_acl]
6718 acl_if.add_vpp_config()
6719 # send in2out to generate ACL state (NAT state was created earlier)
6720 capture = self.send_and_expect(self.pg0, pkts_in2out, self.pg1,
6722 self.verify_capture_out(capture, ignore_port=True)
6724 # send out2in again. ACL state exists so it should work now.
6725 # TCP packets with the syn flag set also need the ack flag
6726 for p in pkts_out2in:
6727 if p.haslayer(TCP) and p[TCP].flags & 0x02:
6728 p[TCP].flags |= 0x10
6729 capture = self.send_and_expect(self.pg1, pkts_out2in, self.pg0,
6731 self.verify_capture_in(capture, self.pg0)
6732 self.logger.info(self.vapi.cli("show trace"))
6734 def test_multiple_vrf(self):
6735 """ Multiple VRF setup """
6736 external_addr = '1.2.3.4'
6741 self.vapi.nat44_forwarding_enable_disable(enable=1)
6742 self.nat44_add_address(self.nat_addr)
6743 flags = self.config_flags.NAT_IS_INSIDE
6744 self.vapi.nat44_interface_add_del_feature(
6745 sw_if_index=self.pg0.sw_if_index,
6747 self.vapi.nat44_interface_add_del_feature(
6748 sw_if_index=self.pg0.sw_if_index,
6749 is_add=1, flags=flags)
6750 self.vapi.nat44_interface_add_del_output_feature(
6751 sw_if_index=self.pg1.sw_if_index,
6753 self.vapi.nat44_interface_add_del_feature(
6754 sw_if_index=self.pg5.sw_if_index,
6756 self.vapi.nat44_interface_add_del_feature(
6757 sw_if_index=self.pg5.sw_if_index,
6758 is_add=1, flags=flags)
6759 self.vapi.nat44_interface_add_del_feature(
6760 sw_if_index=self.pg6.sw_if_index,
6762 flags = self.config_flags.NAT_IS_OUT2IN_ONLY
6763 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
6764 local_port, external_port, vrf_id=1,
6765 proto=IP_PROTOS.tcp, flags=flags)
6766 self.nat44_add_static_mapping(
6767 self.pg0.remote_ip4,
6768 external_sw_if_index=self.pg0.sw_if_index,
6769 local_port=local_port,
6771 external_port=external_port,
6772 proto=IP_PROTOS.tcp,
6776 # from client to service (both VRF1)
6777 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6778 IP(src=self.pg6.remote_ip4, dst=external_addr) /
6779 TCP(sport=12345, dport=external_port))
6780 self.pg6.add_stream(p)
6781 self.pg_enable_capture(self.pg_interfaces)
6783 capture = self.pg5.get_capture(1)
6788 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6789 self.assertEqual(tcp.dport, local_port)
6790 self.assert_packet_checksums_valid(p)
6792 self.logger.error(ppp("Unexpected or invalid packet:", p))
6795 # from service back to client (both VRF1)
6796 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6797 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6798 TCP(sport=local_port, dport=12345))
6799 self.pg5.add_stream(p)
6800 self.pg_enable_capture(self.pg_interfaces)
6802 capture = self.pg6.get_capture(1)
6807 self.assertEqual(ip.src, external_addr)
6808 self.assertEqual(tcp.sport, external_port)
6809 self.assert_packet_checksums_valid(p)
6811 self.logger.error(ppp("Unexpected or invalid packet:", p))
6814 # dynamic NAT from VRF1 to VRF0 (output-feature)
6815 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6816 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
6817 TCP(sport=2345, dport=22))
6818 self.pg5.add_stream(p)
6819 self.pg_enable_capture(self.pg_interfaces)
6821 capture = self.pg1.get_capture(1)
6826 self.assertEqual(ip.src, self.nat_addr)
6827 self.assert_packet_checksums_valid(p)
6830 self.logger.error(ppp("Unexpected or invalid packet:", p))
6833 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6834 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6835 TCP(sport=22, dport=port))
6836 self.pg1.add_stream(p)
6837 self.pg_enable_capture(self.pg_interfaces)
6839 capture = self.pg5.get_capture(1)
6844 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6845 self.assertEqual(tcp.dport, 2345)
6846 self.assert_packet_checksums_valid(p)
6848 self.logger.error(ppp("Unexpected or invalid packet:", p))
6851 # from client VRF1 to service VRF0
6852 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6853 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
6854 TCP(sport=12346, dport=external_port))
6855 self.pg6.add_stream(p)
6856 self.pg_enable_capture(self.pg_interfaces)
6858 capture = self.pg0.get_capture(1)
6863 self.assertEqual(ip.dst, self.pg0.remote_ip4)
6864 self.assertEqual(tcp.dport, local_port)
6865 self.assert_packet_checksums_valid(p)
6867 self.logger.error(ppp("Unexpected or invalid packet:", p))
6870 # from service VRF0 back to client VRF1
6871 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6872 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6873 TCP(sport=local_port, dport=12346))
6874 self.pg0.add_stream(p)
6875 self.pg_enable_capture(self.pg_interfaces)
6877 capture = self.pg6.get_capture(1)
6882 self.assertEqual(ip.src, self.pg0.local_ip4)
6883 self.assertEqual(tcp.sport, external_port)
6884 self.assert_packet_checksums_valid(p)
6886 self.logger.error(ppp("Unexpected or invalid packet:", p))
6889 # from client VRF0 to service VRF1
6890 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6891 IP(src=self.pg0.remote_ip4, dst=external_addr) /
6892 TCP(sport=12347, dport=external_port))
6893 self.pg0.add_stream(p)
6894 self.pg_enable_capture(self.pg_interfaces)
6896 capture = self.pg5.get_capture(1)
6901 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6902 self.assertEqual(tcp.dport, local_port)
6903 self.assert_packet_checksums_valid(p)
6905 self.logger.error(ppp("Unexpected or invalid packet:", p))
6908 # from service VRF1 back to client VRF0
6909 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6910 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
6911 TCP(sport=local_port, dport=12347))
6912 self.pg5.add_stream(p)
6913 self.pg_enable_capture(self.pg_interfaces)
6915 capture = self.pg0.get_capture(1)
6920 self.assertEqual(ip.src, external_addr)
6921 self.assertEqual(tcp.sport, external_port)
6922 self.assert_packet_checksums_valid(p)
6924 self.logger.error(ppp("Unexpected or invalid packet:", p))
6927 # from client to server (both VRF1, no translation)
6928 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
6929 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
6930 TCP(sport=12348, dport=local_port))
6931 self.pg6.add_stream(p)
6932 self.pg_enable_capture(self.pg_interfaces)
6934 capture = self.pg5.get_capture(1)
6939 self.assertEqual(ip.dst, self.pg5.remote_ip4)
6940 self.assertEqual(tcp.dport, local_port)
6941 self.assert_packet_checksums_valid(p)
6943 self.logger.error(ppp("Unexpected or invalid packet:", p))
6946 # from server back to client (both VRF1, no translation)
6947 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
6948 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
6949 TCP(sport=local_port, dport=12348))
6950 self.pg5.add_stream(p)
6951 self.pg_enable_capture(self.pg_interfaces)
6953 capture = self.pg6.get_capture(1)
6958 self.assertEqual(ip.src, self.pg5.remote_ip4)
6959 self.assertEqual(tcp.sport, local_port)
6960 self.assert_packet_checksums_valid(p)
6962 self.logger.error(ppp("Unexpected or invalid packet:", p))
6965 # from client VRF1 to server VRF0 (no translation)
6966 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6967 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6968 TCP(sport=local_port, dport=12349))
6969 self.pg0.add_stream(p)
6970 self.pg_enable_capture(self.pg_interfaces)
6972 capture = self.pg6.get_capture(1)
6977 self.assertEqual(ip.src, self.pg0.remote_ip4)
6978 self.assertEqual(tcp.sport, local_port)
6979 self.assert_packet_checksums_valid(p)
6981 self.logger.error(ppp("Unexpected or invalid packet:", p))
6984 # from server VRF0 back to client VRF1 (no translation)
6985 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6986 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
6987 TCP(sport=local_port, dport=12349))
6988 self.pg0.add_stream(p)
6989 self.pg_enable_capture(self.pg_interfaces)
6991 capture = self.pg6.get_capture(1)
6996 self.assertEqual(ip.src, self.pg0.remote_ip4)
6997 self.assertEqual(tcp.sport, local_port)
6998 self.assert_packet_checksums_valid(p)
7000 self.logger.error(ppp("Unexpected or invalid packet:", p))
7003 # from client VRF0 to server VRF1 (no translation)
7004 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7005 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
7006 TCP(sport=12344, dport=local_port))
7007 self.pg0.add_stream(p)
7008 self.pg_enable_capture(self.pg_interfaces)
7010 capture = self.pg5.get_capture(1)
7015 self.assertEqual(ip.dst, self.pg5.remote_ip4)
7016 self.assertEqual(tcp.dport, local_port)
7017 self.assert_packet_checksums_valid(p)
7019 self.logger.error(ppp("Unexpected or invalid packet:", p))
7022 # from server VRF1 back to client VRF0 (no translation)
7023 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
7024 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
7025 TCP(sport=local_port, dport=12344))
7026 self.pg5.add_stream(p)
7027 self.pg_enable_capture(self.pg_interfaces)
7029 capture = self.pg0.get_capture(1)
7034 self.assertEqual(ip.src, self.pg5.remote_ip4)
7035 self.assertEqual(tcp.sport, local_port)
7036 self.assert_packet_checksums_valid(p)
7038 self.logger.error(ppp("Unexpected or invalid packet:", p))
7041 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7042 def test_session_timeout(self):
7043 """ NAT44 session 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=240, icmp=5)
7057 for i in range(0, max_sessions):
7058 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7059 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7060 IP(src=src, dst=self.pg1.remote_ip4) /
7061 ICMP(id=1025, type='echo-request'))
7063 self.pg0.add_stream(pkts)
7064 self.pg_enable_capture(self.pg_interfaces)
7066 self.pg1.get_capture(max_sessions)
7071 for i in range(0, max_sessions):
7072 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
7073 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7074 IP(src=src, dst=self.pg1.remote_ip4) /
7075 ICMP(id=1026, type='echo-request'))
7077 self.pg0.add_stream(pkts)
7078 self.pg_enable_capture(self.pg_interfaces)
7080 self.pg1.get_capture(max_sessions)
7083 users = self.vapi.nat44_user_dump()
7085 nsessions = nsessions + user.nsessions
7086 self.assertLess(nsessions, 2 * max_sessions)
7088 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7089 def test_session_rst_timeout(self):
7090 """ NAT44 session RST timeouts """
7091 self.nat44_add_address(self.nat_addr)
7092 flags = self.config_flags.NAT_IS_INSIDE
7093 self.vapi.nat44_interface_add_del_feature(
7094 sw_if_index=self.pg0.sw_if_index,
7095 flags=flags, is_add=1)
7096 self.vapi.nat44_interface_add_del_feature(
7097 sw_if_index=self.pg1.sw_if_index,
7099 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
7100 tcp_transitory=5, icmp=60)
7102 self.initiate_tcp_session(self.pg0, self.pg1)
7103 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7104 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7105 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
7107 self.pg0.add_stream(p)
7108 self.pg_enable_capture(self.pg_interfaces)
7110 self.pg1.get_capture(1)
7114 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7115 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7116 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
7118 self.pg0.add_stream(p)
7119 self.pg_enable_capture(self.pg_interfaces)
7121 self.pg1.get_capture(1)
7123 def test_syslog_sess(self):
7124 """ Test syslog session creation and deletion """
7125 self.vapi.syslog_set_filter(
7126 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
7127 self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)
7128 self.nat44_add_address(self.nat_addr)
7129 flags = self.config_flags.NAT_IS_INSIDE
7130 self.vapi.nat44_interface_add_del_feature(
7131 sw_if_index=self.pg0.sw_if_index,
7132 flags=flags, is_add=1)
7133 self.vapi.nat44_interface_add_del_feature(
7134 sw_if_index=self.pg1.sw_if_index,
7137 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7138 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
7139 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7140 self.pg0.add_stream(p)
7141 self.pg_enable_capture(self.pg_interfaces)
7143 capture = self.pg1.get_capture(1)
7144 self.tcp_port_out = capture[0][TCP].sport
7145 capture = self.pg2.get_capture(1)
7146 self.verify_syslog_sess(capture[0][Raw].load)
7148 self.pg_enable_capture(self.pg_interfaces)
7150 self.nat44_add_address(self.nat_addr, is_add=0)
7151 capture = self.pg2.get_capture(1)
7152 self.verify_syslog_sess(capture[0][Raw].load, False)
7154 def test_ed_users_dump(self):
7155 """ API test - nat44_user_dump """
7156 flags = self.config_flags.NAT_IS_INSIDE
7157 self.vapi.nat44_interface_add_del_feature(
7158 sw_if_index=self.pg0.sw_if_index,
7159 flags=flags, is_add=1)
7160 self.vapi.nat44_interface_add_del_feature(
7161 sw_if_index=self.pg1.sw_if_index,
7163 self.vapi.nat44_forwarding_enable_disable(enable=1)
7165 real_ip = self.pg0.remote_ip4
7166 alias_ip = self.nat_addr
7167 flags = self.config_flags.NAT_IS_ADDR_ONLY
7168 self.vapi.nat44_add_del_static_mapping(is_add=1,
7169 local_ip_address=real_ip,
7170 external_ip_address=alias_ip,
7171 external_sw_if_index=0xFFFFFFFF,
7174 users = self.vapi.nat44_user_dump()
7175 self.assertEqual(len(users), 0)
7177 # in2out - static mapping match
7179 pkts = self.create_stream_out(self.pg1)
7180 self.pg1.add_stream(pkts)
7181 self.pg_enable_capture(self.pg_interfaces)
7183 capture = self.pg0.get_capture(len(pkts))
7184 self.verify_capture_in(capture, self.pg0)
7186 pkts = self.create_stream_in(self.pg0, self.pg1)
7187 self.pg0.add_stream(pkts)
7188 self.pg_enable_capture(self.pg_interfaces)
7190 capture = self.pg1.get_capture(len(pkts))
7191 self.verify_capture_out(capture, same_port=True)
7193 users = self.vapi.nat44_user_dump()
7194 self.assertEqual(len(users), 1)
7195 static_user = users[0]
7196 self.assertEqual(static_user.nstaticsessions, 3)
7197 self.assertEqual(static_user.nsessions, 0)
7199 # in2out - no static mapping match
7201 host0 = self.pg0.remote_hosts[0]
7202 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
7204 pkts = self.create_stream_out(self.pg1,
7205 dst_ip=self.pg0.remote_ip4,
7206 use_inside_ports=True)
7207 self.pg1.add_stream(pkts)
7208 self.pg_enable_capture(self.pg_interfaces)
7210 capture = self.pg0.get_capture(len(pkts))
7211 self.verify_capture_in(capture, self.pg0)
7213 pkts = self.create_stream_in(self.pg0, self.pg1)
7214 self.pg0.add_stream(pkts)
7215 self.pg_enable_capture(self.pg_interfaces)
7217 capture = self.pg1.get_capture(len(pkts))
7218 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
7221 self.pg0.remote_hosts[0] = host0
7223 users = self.vapi.nat44_user_dump()
7224 self.assertEqual(len(users), 2)
7225 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7226 non_static_user = users[1]
7227 static_user = users[0]
7229 non_static_user = users[0]
7230 static_user = users[1]
7231 self.assertEqual(static_user.nstaticsessions, 3)
7232 self.assertEqual(static_user.nsessions, 0)
7233 self.assertEqual(non_static_user.nstaticsessions, 0)
7234 self.assertEqual(non_static_user.nsessions, 3)
7236 users = self.vapi.nat44_user_dump()
7237 self.assertEqual(len(users), 2)
7238 if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
7239 non_static_user = users[1]
7240 static_user = users[0]
7242 non_static_user = users[0]
7243 static_user = users[1]
7244 self.assertEqual(static_user.nstaticsessions, 3)
7245 self.assertEqual(static_user.nsessions, 0)
7246 self.assertEqual(non_static_user.nstaticsessions, 0)
7247 self.assertEqual(non_static_user.nsessions, 3)
7250 self.vapi.nat44_forwarding_enable_disable(enable=0)
7251 flags = self.config_flags.NAT_IS_ADDR_ONLY
7252 self.vapi.nat44_add_del_static_mapping(
7254 local_ip_address=real_ip,
7255 external_ip_address=alias_ip,
7256 external_sw_if_index=0xFFFFFFFF,
7260 super(TestNAT44EndpointDependent, self).tearDown()
7261 if not self.vpp_dead:
7263 self.vapi.cli("clear logging")
7265 def show_commands_at_teardown(self):
7266 self.logger.info(self.vapi.cli("show errors"))
7267 self.logger.info(self.vapi.cli("show nat44 addresses"))
7268 self.logger.info(self.vapi.cli("show nat44 interfaces"))
7269 self.logger.info(self.vapi.cli("show nat44 static mappings"))
7270 self.logger.info(self.vapi.cli("show nat44 interface address"))
7271 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
7272 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
7273 self.logger.info(self.vapi.cli("show nat timeouts"))
7274 self.logger.info(self.vapi.cli("debug nat44 fib registration"))
7277 class TestNAT44EndpointDependent3(MethodHolder):
7278 """ Endpoint-Dependent mapping and filtering extra test cases """
7280 max_translations = 50
7283 def setUpConstants(cls):
7284 super(TestNAT44EndpointDependent3, cls).setUpConstants()
7285 cls.vpp_cmdline.extend([
7286 "nat", "{", "endpoint-dependent",
7287 "max translations per thread %d" % cls.max_translations,
7292 def setUpClass(cls):
7293 super(TestNAT44EndpointDependent3, cls).setUpClass()
7294 cls.vapi.cli("set log class nat level debug")
7296 cls.nat_addr = '10.0.0.3'
7298 cls.create_pg_interfaces(range(2))
7300 for i in cls.pg_interfaces:
7306 super(TestNAT44EndpointDependent3, self).setUp()
7307 self.vapi.nat_set_timeouts(
7308 udp=1, tcp_established=7440, tcp_transitory=30, icmp=1)
7309 self.nat44_add_address(self.nat_addr)
7310 flags = self.config_flags.NAT_IS_INSIDE
7311 self.vapi.nat44_interface_add_del_feature(
7312 sw_if_index=self.pg0.sw_if_index, flags=flags, is_add=1)
7313 self.vapi.nat44_interface_add_del_feature(
7314 sw_if_index=self.pg1.sw_if_index, is_add=1)
7317 def tearDownClass(cls):
7318 super(TestNAT44EndpointDependent3, cls).tearDownClass()
7320 def init_tcp_session(self, in_if, out_if, sport, ext_dport):
7321 # SYN packet in->out
7322 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7323 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7324 TCP(sport=sport, dport=ext_dport, flags="S"))
7326 self.pg_enable_capture(self.pg_interfaces)
7328 capture = out_if.get_capture(1)
7330 tcp_port_out = p[TCP].sport
7332 # SYN + ACK packet out->in
7333 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
7334 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
7335 TCP(sport=ext_dport, dport=tcp_port_out, flags="SA"))
7336 out_if.add_stream(p)
7337 self.pg_enable_capture(self.pg_interfaces)
7339 in_if.get_capture(1)
7341 # ACK packet in->out
7342 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
7343 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
7344 TCP(sport=sport, dport=ext_dport, flags="A"))
7346 self.pg_enable_capture(self.pg_interfaces)
7348 out_if.get_capture(1)
7352 def test_lru_cleanup(self):
7353 """ LRU cleanup algorithm """
7354 tcp_port_out = self.init_tcp_session(self.pg0, self.pg1, 2000, 80)
7356 for i in range(0, self.max_translations - 1):
7357 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7358 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7359 UDP(sport=7000+i, dport=80))
7362 self.pg0.add_stream(pkts)
7363 self.pg_enable_capture(self.pg_interfaces)
7365 self.pg1.get_capture(len(pkts))
7366 self.sleep(1.5, "wait for timeouts")
7369 for i in range(0, self.max_translations - 1):
7370 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7371 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
7372 ICMP(id=8000+i, type='echo-request'))
7375 self.pg0.add_stream(pkts)
7376 self.pg_enable_capture(self.pg_interfaces)
7378 self.pg1.get_capture(len(pkts))
7381 class TestNAT44Out2InDPO(MethodHolder):
7382 """ NAT44 Test Cases using out2in DPO """
7385 def setUpConstants(cls):
7386 super(TestNAT44Out2InDPO, cls).setUpConstants()
7387 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
7390 def setUpClass(cls):
7391 super(TestNAT44Out2InDPO, cls).setUpClass()
7392 cls.vapi.cli("set log class nat level debug")
7394 cls.tcp_port_in = 6303
7395 cls.tcp_port_out = 6303
7396 cls.udp_port_in = 6304
7397 cls.udp_port_out = 6304
7398 cls.icmp_id_in = 6305
7399 cls.icmp_id_out = 6305
7400 cls.nat_addr = '10.0.0.3'
7401 cls.dst_ip4 = '192.168.70.1'
7403 cls.create_pg_interfaces(range(2))
7406 cls.pg0.config_ip4()
7407 cls.pg0.resolve_arp()
7410 cls.pg1.config_ip6()
7411 cls.pg1.resolve_ndp()
7413 r1 = VppIpRoute(cls, "::", 0,
7414 [VppRoutePath(cls.pg1.remote_ip6,
7415 cls.pg1.sw_if_index)],
7420 def tearDownClass(cls):
7421 super(TestNAT44Out2InDPO, cls).tearDownClass()
7423 def configure_xlat(self):
7424 self.dst_ip6_pfx = '1:2:3::'
7425 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7427 self.dst_ip6_pfx_len = 96
7428 self.src_ip6_pfx = '4:5:6::'
7429 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
7431 self.src_ip6_pfx_len = 96
7432 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
7433 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
7434 '\x00\x00\x00\x00', 0)
7436 @unittest.skip('Temporary disabled')
7437 def test_464xlat_ce(self):
7438 """ Test 464XLAT CE with NAT44 """
7440 nat_config = self.vapi.nat_show_config()
7441 self.assertEqual(1, nat_config.out2in_dpo)
7443 self.configure_xlat()
7445 flags = self.config_flags.NAT_IS_INSIDE
7446 self.vapi.nat44_interface_add_del_feature(
7447 sw_if_index=self.pg0.sw_if_index,
7448 flags=flags, is_add=1)
7449 self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
7450 last_ip_address=self.nat_addr_n,
7451 vrf_id=0xFFFFFFFF, is_add=1)
7453 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7454 self.dst_ip6_pfx_len)
7455 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
7456 self.src_ip6_pfx_len)
7459 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7460 self.pg0.add_stream(pkts)
7461 self.pg_enable_capture(self.pg_interfaces)
7463 capture = self.pg1.get_capture(len(pkts))
7464 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
7467 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
7469 self.pg1.add_stream(pkts)
7470 self.pg_enable_capture(self.pg_interfaces)
7472 capture = self.pg0.get_capture(len(pkts))
7473 self.verify_capture_in(capture, self.pg0)
7475 self.vapi.nat44_interface_add_del_feature(
7476 sw_if_index=self.pg0.sw_if_index,
7478 self.vapi.nat44_add_del_address_range(
7479 first_ip_address=self.nat_addr_n,
7480 last_ip_address=self.nat_addr_n,
7483 @unittest.skip('Temporary disabled')
7484 def test_464xlat_ce_no_nat(self):
7485 """ Test 464XLAT CE without NAT44 """
7487 self.configure_xlat()
7489 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
7490 self.dst_ip6_pfx_len)
7491 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
7492 self.src_ip6_pfx_len)
7494 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
7495 self.pg0.add_stream(pkts)
7496 self.pg_enable_capture(self.pg_interfaces)
7498 capture = self.pg1.get_capture(len(pkts))
7499 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
7500 nat_ip=out_dst_ip6, same_port=True)
7502 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
7503 self.pg1.add_stream(pkts)
7504 self.pg_enable_capture(self.pg_interfaces)
7506 capture = self.pg0.get_capture(len(pkts))
7507 self.verify_capture_in(capture, self.pg0)
7510 class TestNAT64(MethodHolder):
7511 """ NAT64 Test Cases """
7514 def setUpConstants(cls):
7515 super(TestNAT64, cls).setUpConstants()
7516 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
7517 "nat64 st hash buckets 256", "}"])
7520 def setUpClass(cls):
7521 super(TestNAT64, cls).setUpClass()
7523 cls.tcp_port_in = 6303
7524 cls.tcp_port_out = 6303
7525 cls.udp_port_in = 6304
7526 cls.udp_port_out = 6304
7527 cls.icmp_id_in = 6305
7528 cls.icmp_id_out = 6305
7529 cls.tcp_external_port = 80
7530 cls.nat_addr = '10.0.0.3'
7531 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
7533 cls.vrf1_nat_addr = '10.0.10.3'
7534 cls.ipfix_src_port = 4739
7535 cls.ipfix_domain_id = 1
7537 cls.create_pg_interfaces(range(6))
7538 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
7539 cls.ip6_interfaces.append(cls.pg_interfaces[2])
7540 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
7542 cls.vapi.ip_table_add_del(is_add=1,
7543 table={'table_id': cls.vrf1_id,
7546 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
7548 cls.pg0.generate_remote_hosts(2)
7550 for i in cls.ip6_interfaces:
7553 i.configure_ipv6_neighbors()
7555 for i in cls.ip4_interfaces:
7561 cls.pg3.config_ip4()
7562 cls.pg3.resolve_arp()
7563 cls.pg3.config_ip6()
7564 cls.pg3.configure_ipv6_neighbors()
7567 cls.pg5.config_ip6()
7570 def tearDownClass(cls):
7571 super(TestNAT64, cls).tearDownClass()
7573 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
7574 """ NAT64 inside interface handles Neighbor Advertisement """
7576 flags = self.config_flags.NAT_IS_INSIDE
7577 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7578 sw_if_index=self.pg5.sw_if_index)
7581 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7582 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7583 ICMPv6EchoRequest())
7585 self.pg5.add_stream(pkts)
7586 self.pg_enable_capture(self.pg_interfaces)
7589 # Wait for Neighbor Solicitation
7590 capture = self.pg5.get_capture(len(pkts))
7593 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7594 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
7595 tgt = packet[ICMPv6ND_NS].tgt
7597 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7600 # Send Neighbor Advertisement
7601 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
7602 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
7603 ICMPv6ND_NA(tgt=tgt) /
7604 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
7606 self.pg5.add_stream(pkts)
7607 self.pg_enable_capture(self.pg_interfaces)
7610 # Try to send ping again
7612 self.pg5.add_stream(pkts)
7613 self.pg_enable_capture(self.pg_interfaces)
7616 # Wait for ping reply
7617 capture = self.pg5.get_capture(len(pkts))
7620 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
7621 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
7622 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
7624 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7627 def test_pool(self):
7628 """ Add/delete address to NAT64 pool """
7629 nat_addr = '1.2.3.4'
7631 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7633 vrf_id=0xFFFFFFFF, is_add=1)
7635 addresses = self.vapi.nat64_pool_addr_dump()
7636 self.assertEqual(len(addresses), 1)
7637 self.assertEqual(str(addresses[0].address), nat_addr)
7639 self.vapi.nat64_add_del_pool_addr_range(start_addr=nat_addr,
7641 vrf_id=0xFFFFFFFF, is_add=0)
7643 addresses = self.vapi.nat64_pool_addr_dump()
7644 self.assertEqual(len(addresses), 0)
7646 def test_interface(self):
7647 """ Enable/disable NAT64 feature on the interface """
7648 flags = self.config_flags.NAT_IS_INSIDE
7649 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7650 sw_if_index=self.pg0.sw_if_index)
7651 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7652 sw_if_index=self.pg1.sw_if_index)
7654 interfaces = self.vapi.nat64_interface_dump()
7655 self.assertEqual(len(interfaces), 2)
7658 for intf in interfaces:
7659 if intf.sw_if_index == self.pg0.sw_if_index:
7660 self.assertEqual(intf.flags, self.config_flags.NAT_IS_INSIDE)
7662 elif intf.sw_if_index == self.pg1.sw_if_index:
7663 self.assertEqual(intf.flags, self.config_flags.NAT_IS_OUTSIDE)
7665 self.assertTrue(pg0_found)
7666 self.assertTrue(pg1_found)
7668 features = self.vapi.cli("show interface features pg0")
7669 self.assertIn('nat64-in2out', features)
7670 features = self.vapi.cli("show interface features pg1")
7671 self.assertIn('nat64-out2in', features)
7673 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7674 sw_if_index=self.pg0.sw_if_index)
7675 self.vapi.nat64_add_del_interface(is_add=0, flags=flags,
7676 sw_if_index=self.pg1.sw_if_index)
7678 interfaces = self.vapi.nat64_interface_dump()
7679 self.assertEqual(len(interfaces), 0)
7681 def test_static_bib(self):
7682 """ Add/delete static BIB entry """
7683 in_addr = '2001:db8:85a3::8a2e:370:7334'
7684 out_addr = '10.1.1.3'
7687 proto = IP_PROTOS.tcp
7689 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7690 i_port=in_port, o_port=out_port,
7691 proto=proto, vrf_id=0, is_add=1)
7692 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7695 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7697 self.assertEqual(str(bibe.i_addr), in_addr)
7698 self.assertEqual(str(bibe.o_addr), out_addr)
7699 self.assertEqual(bibe.i_port, in_port)
7700 self.assertEqual(bibe.o_port, out_port)
7701 self.assertEqual(static_bib_num, 1)
7702 bibs = self.statistics.get_counter('/nat64/total-bibs')
7703 self.assertEqual(bibs[0][0], 1)
7705 self.vapi.nat64_add_del_static_bib(i_addr=in_addr, o_addr=out_addr,
7706 i_port=in_port, o_port=out_port,
7707 proto=proto, vrf_id=0, is_add=0)
7708 bib = self.vapi.nat64_bib_dump(proto=IP_PROTOS.tcp)
7711 if bibe.flags & self.config_flags.NAT_IS_STATIC:
7713 self.assertEqual(static_bib_num, 0)
7714 bibs = self.statistics.get_counter('/nat64/total-bibs')
7715 self.assertEqual(bibs[0][0], 0)
7717 def test_set_timeouts(self):
7718 """ Set NAT64 timeouts """
7719 # verify default values
7720 timeouts = self.vapi.nat_get_timeouts()
7721 self.assertEqual(timeouts.udp, 300)
7722 self.assertEqual(timeouts.icmp, 60)
7723 self.assertEqual(timeouts.tcp_transitory, 240)
7724 self.assertEqual(timeouts.tcp_established, 7440)
7726 # set and verify custom values
7727 self.vapi.nat_set_timeouts(udp=200, tcp_established=7450,
7728 tcp_transitory=250, icmp=30)
7729 timeouts = self.vapi.nat_get_timeouts()
7730 self.assertEqual(timeouts.udp, 200)
7731 self.assertEqual(timeouts.icmp, 30)
7732 self.assertEqual(timeouts.tcp_transitory, 250)
7733 self.assertEqual(timeouts.tcp_established, 7450)
7735 def test_dynamic(self):
7736 """ NAT64 dynamic translation test """
7737 self.tcp_port_in = 6303
7738 self.udp_port_in = 6304
7739 self.icmp_id_in = 6305
7741 ses_num_start = self.nat64_get_ses_num()
7743 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7744 end_addr=self.nat_addr,
7747 flags = self.config_flags.NAT_IS_INSIDE
7748 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7749 sw_if_index=self.pg0.sw_if_index)
7750 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7751 sw_if_index=self.pg1.sw_if_index)
7754 tcpn = self.statistics.get_counter('/nat64/in2out/tcp')[0]
7755 udpn = self.statistics.get_counter('/nat64/in2out/udp')[0]
7756 icmpn = self.statistics.get_counter('/nat64/in2out/icmp')[0]
7757 drops = self.statistics.get_counter('/nat64/in2out/drops')[0]
7759 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7760 self.pg0.add_stream(pkts)
7761 self.pg_enable_capture(self.pg_interfaces)
7763 capture = self.pg1.get_capture(len(pkts))
7764 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7765 dst_ip=self.pg1.remote_ip4)
7767 if_idx = self.pg0.sw_if_index
7768 cnt = self.statistics.get_counter('/nat64/in2out/tcp')[0]
7769 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 1)
7770 cnt = self.statistics.get_counter('/nat64/in2out/udp')[0]
7771 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
7772 cnt = self.statistics.get_counter('/nat64/in2out/icmp')[0]
7773 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
7774 cnt = self.statistics.get_counter('/nat64/in2out/drops')[0]
7775 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
7778 tcpn = self.statistics.get_counter('/nat64/out2in/tcp')[0]
7779 udpn = self.statistics.get_counter('/nat64/out2in/udp')[0]
7780 icmpn = self.statistics.get_counter('/nat64/out2in/icmp')[0]
7781 drops = self.statistics.get_counter('/nat64/out2in/drops')[0]
7783 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7784 self.pg1.add_stream(pkts)
7785 self.pg_enable_capture(self.pg_interfaces)
7787 capture = self.pg0.get_capture(len(pkts))
7788 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7789 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7791 if_idx = self.pg1.sw_if_index
7792 cnt = self.statistics.get_counter('/nat64/out2in/tcp')[0]
7793 self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
7794 cnt = self.statistics.get_counter('/nat64/out2in/udp')[0]
7795 self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
7796 cnt = self.statistics.get_counter('/nat64/out2in/icmp')[0]
7797 self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
7798 cnt = self.statistics.get_counter('/nat64/out2in/drops')[0]
7799 self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
7801 bibs = self.statistics.get_counter('/nat64/total-bibs')
7802 self.assertEqual(bibs[0][0], 3)
7803 sessions = self.statistics.get_counter('/nat64/total-sessions')
7804 self.assertEqual(sessions[0][0], 3)
7807 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7808 self.pg0.add_stream(pkts)
7809 self.pg_enable_capture(self.pg_interfaces)
7811 capture = self.pg1.get_capture(len(pkts))
7812 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7813 dst_ip=self.pg1.remote_ip4)
7816 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7817 self.pg1.add_stream(pkts)
7818 self.pg_enable_capture(self.pg_interfaces)
7820 capture = self.pg0.get_capture(len(pkts))
7821 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7823 ses_num_end = self.nat64_get_ses_num()
7825 self.assertEqual(ses_num_end - ses_num_start, 3)
7827 # tenant with specific VRF
7828 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
7829 end_addr=self.vrf1_nat_addr,
7830 vrf_id=self.vrf1_id, is_add=1)
7831 flags = self.config_flags.NAT_IS_INSIDE
7832 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7833 sw_if_index=self.pg2.sw_if_index)
7835 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7836 self.pg2.add_stream(pkts)
7837 self.pg_enable_capture(self.pg_interfaces)
7839 capture = self.pg1.get_capture(len(pkts))
7840 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7841 dst_ip=self.pg1.remote_ip4)
7843 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7844 self.pg1.add_stream(pkts)
7845 self.pg_enable_capture(self.pg_interfaces)
7847 capture = self.pg2.get_capture(len(pkts))
7848 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7850 def test_static(self):
7851 """ NAT64 static translation test """
7852 self.tcp_port_in = 60303
7853 self.udp_port_in = 60304
7854 self.icmp_id_in = 60305
7855 self.tcp_port_out = 60303
7856 self.udp_port_out = 60304
7857 self.icmp_id_out = 60305
7859 ses_num_start = self.nat64_get_ses_num()
7861 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7862 end_addr=self.nat_addr,
7865 flags = self.config_flags.NAT_IS_INSIDE
7866 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7867 sw_if_index=self.pg0.sw_if_index)
7868 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7869 sw_if_index=self.pg1.sw_if_index)
7871 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7872 o_addr=self.nat_addr,
7873 i_port=self.tcp_port_in,
7874 o_port=self.tcp_port_out,
7875 proto=IP_PROTOS.tcp, vrf_id=0,
7877 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7878 o_addr=self.nat_addr,
7879 i_port=self.udp_port_in,
7880 o_port=self.udp_port_out,
7881 proto=IP_PROTOS.udp, vrf_id=0,
7883 self.vapi.nat64_add_del_static_bib(i_addr=self.pg0.remote_ip6,
7884 o_addr=self.nat_addr,
7885 i_port=self.icmp_id_in,
7886 o_port=self.icmp_id_out,
7887 proto=IP_PROTOS.icmp, vrf_id=0,
7891 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7892 self.pg0.add_stream(pkts)
7893 self.pg_enable_capture(self.pg_interfaces)
7895 capture = self.pg1.get_capture(len(pkts))
7896 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7897 dst_ip=self.pg1.remote_ip4, same_port=True)
7900 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7901 self.pg1.add_stream(pkts)
7902 self.pg_enable_capture(self.pg_interfaces)
7904 capture = self.pg0.get_capture(len(pkts))
7905 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7906 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7908 ses_num_end = self.nat64_get_ses_num()
7910 self.assertEqual(ses_num_end - ses_num_start, 3)
7912 @unittest.skipUnless(running_extended_tests, "part of extended tests")
7913 def test_session_timeout(self):
7914 """ NAT64 session timeout """
7915 self.icmp_id_in = 1234
7916 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7917 end_addr=self.nat_addr,
7920 flags = self.config_flags.NAT_IS_INSIDE
7921 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7922 sw_if_index=self.pg0.sw_if_index)
7923 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7924 sw_if_index=self.pg1.sw_if_index)
7925 self.vapi.nat_set_timeouts(udp=300, tcp_established=5,
7929 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7930 self.pg0.add_stream(pkts)
7931 self.pg_enable_capture(self.pg_interfaces)
7933 capture = self.pg1.get_capture(len(pkts))
7935 ses_num_before_timeout = self.nat64_get_ses_num()
7939 # ICMP and TCP session after timeout
7940 ses_num_after_timeout = self.nat64_get_ses_num()
7941 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
7943 def test_icmp_error(self):
7944 """ NAT64 ICMP Error message translation """
7945 self.tcp_port_in = 6303
7946 self.udp_port_in = 6304
7947 self.icmp_id_in = 6305
7949 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
7950 end_addr=self.nat_addr,
7953 flags = self.config_flags.NAT_IS_INSIDE
7954 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
7955 sw_if_index=self.pg0.sw_if_index)
7956 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
7957 sw_if_index=self.pg1.sw_if_index)
7959 # send some packets to create sessions
7960 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7961 self.pg0.add_stream(pkts)
7962 self.pg_enable_capture(self.pg_interfaces)
7964 capture_ip4 = self.pg1.get_capture(len(pkts))
7965 self.verify_capture_out(capture_ip4,
7966 nat_ip=self.nat_addr,
7967 dst_ip=self.pg1.remote_ip4)
7969 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7970 self.pg1.add_stream(pkts)
7971 self.pg_enable_capture(self.pg_interfaces)
7973 capture_ip6 = self.pg0.get_capture(len(pkts))
7974 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7975 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7976 self.pg0.remote_ip6)
7979 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7980 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7981 ICMPv6DestUnreach(code=1) /
7982 packet[IPv6] for packet in capture_ip6]
7983 self.pg0.add_stream(pkts)
7984 self.pg_enable_capture(self.pg_interfaces)
7986 capture = self.pg1.get_capture(len(pkts))
7987 for packet in capture:
7989 self.assertEqual(packet[IP].src, self.nat_addr)
7990 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7991 self.assertEqual(packet[ICMP].type, 3)
7992 self.assertEqual(packet[ICMP].code, 13)
7993 inner = packet[IPerror]
7994 self.assertEqual(inner.src, self.pg1.remote_ip4)
7995 self.assertEqual(inner.dst, self.nat_addr)
7996 self.assert_packet_checksums_valid(packet)
7997 if inner.haslayer(TCPerror):
7998 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7999 elif inner.haslayer(UDPerror):
8000 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
8002 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
8004 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8008 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8009 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8010 ICMP(type=3, code=13) /
8011 packet[IP] for packet in capture_ip4]
8012 self.pg1.add_stream(pkts)
8013 self.pg_enable_capture(self.pg_interfaces)
8015 capture = self.pg0.get_capture(len(pkts))
8016 for packet in capture:
8018 self.assertEqual(packet[IPv6].src, ip.src)
8019 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8020 icmp = packet[ICMPv6DestUnreach]
8021 self.assertEqual(icmp.code, 1)
8022 inner = icmp[IPerror6]
8023 self.assertEqual(inner.src, self.pg0.remote_ip6)
8024 self.assertEqual(inner.dst, ip.src)
8025 self.assert_icmpv6_checksum_valid(packet)
8026 if inner.haslayer(TCPerror):
8027 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
8028 elif inner.haslayer(UDPerror):
8029 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
8031 self.assertEqual(inner[ICMPv6EchoRequest].id,
8034 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8037 def test_hairpinning(self):
8038 """ NAT64 hairpinning """
8040 client = self.pg0.remote_hosts[0]
8041 server = self.pg0.remote_hosts[1]
8042 server_tcp_in_port = 22
8043 server_tcp_out_port = 4022
8044 server_udp_in_port = 23
8045 server_udp_out_port = 4023
8046 client_tcp_in_port = 1234
8047 client_udp_in_port = 1235
8048 client_tcp_out_port = 0
8049 client_udp_out_port = 0
8050 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8051 nat_addr_ip6 = ip.src
8053 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8054 end_addr=self.nat_addr,
8057 flags = self.config_flags.NAT_IS_INSIDE
8058 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8059 sw_if_index=self.pg0.sw_if_index)
8060 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8061 sw_if_index=self.pg1.sw_if_index)
8063 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8064 o_addr=self.nat_addr,
8065 i_port=server_tcp_in_port,
8066 o_port=server_tcp_out_port,
8067 proto=IP_PROTOS.tcp, vrf_id=0,
8069 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8070 o_addr=self.nat_addr,
8071 i_port=server_udp_in_port,
8072 o_port=server_udp_out_port,
8073 proto=IP_PROTOS.udp, vrf_id=0,
8078 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8079 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8080 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8082 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8083 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8084 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
8086 self.pg0.add_stream(pkts)
8087 self.pg_enable_capture(self.pg_interfaces)
8089 capture = self.pg0.get_capture(len(pkts))
8090 for packet in capture:
8092 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8093 self.assertEqual(packet[IPv6].dst, server.ip6)
8094 self.assert_packet_checksums_valid(packet)
8095 if packet.haslayer(TCP):
8096 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
8097 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
8098 client_tcp_out_port = packet[TCP].sport
8100 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
8101 self.assertEqual(packet[UDP].dport, server_udp_in_port)
8102 client_udp_out_port = packet[UDP].sport
8104 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8109 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8110 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8111 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
8113 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8114 IPv6(src=server.ip6, dst=nat_addr_ip6) /
8115 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
8117 self.pg0.add_stream(pkts)
8118 self.pg_enable_capture(self.pg_interfaces)
8120 capture = self.pg0.get_capture(len(pkts))
8121 for packet in capture:
8123 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8124 self.assertEqual(packet[IPv6].dst, client.ip6)
8125 self.assert_packet_checksums_valid(packet)
8126 if packet.haslayer(TCP):
8127 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
8128 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
8130 self.assertEqual(packet[UDP].sport, server_udp_out_port)
8131 self.assertEqual(packet[UDP].dport, client_udp_in_port)
8133 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8138 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8139 IPv6(src=client.ip6, dst=nat_addr_ip6) /
8140 ICMPv6DestUnreach(code=1) /
8141 packet[IPv6] for packet in capture]
8142 self.pg0.add_stream(pkts)
8143 self.pg_enable_capture(self.pg_interfaces)
8145 capture = self.pg0.get_capture(len(pkts))
8146 for packet in capture:
8148 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
8149 self.assertEqual(packet[IPv6].dst, server.ip6)
8150 icmp = packet[ICMPv6DestUnreach]
8151 self.assertEqual(icmp.code, 1)
8152 inner = icmp[IPerror6]
8153 self.assertEqual(inner.src, server.ip6)
8154 self.assertEqual(inner.dst, nat_addr_ip6)
8155 self.assert_packet_checksums_valid(packet)
8156 if inner.haslayer(TCPerror):
8157 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
8158 self.assertEqual(inner[TCPerror].dport,
8159 client_tcp_out_port)
8161 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
8162 self.assertEqual(inner[UDPerror].dport,
8163 client_udp_out_port)
8165 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8168 def test_prefix(self):
8169 """ NAT64 Network-Specific Prefix """
8171 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8172 end_addr=self.nat_addr,
8175 flags = self.config_flags.NAT_IS_INSIDE
8176 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8177 sw_if_index=self.pg0.sw_if_index)
8178 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8179 sw_if_index=self.pg1.sw_if_index)
8180 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.vrf1_nat_addr,
8181 end_addr=self.vrf1_nat_addr,
8182 vrf_id=self.vrf1_id, is_add=1)
8183 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8184 sw_if_index=self.pg2.sw_if_index)
8187 global_pref64 = "2001:db8::"
8188 global_pref64_len = 32
8189 global_pref64_str = "{}/{}".format(global_pref64, global_pref64_len)
8190 self.vapi.nat64_add_del_prefix(prefix=global_pref64_str, vrf_id=0,
8193 prefix = self.vapi.nat64_prefix_dump()
8194 self.assertEqual(len(prefix), 1)
8195 self.assertEqual(str(prefix[0].prefix), global_pref64_str)
8196 self.assertEqual(prefix[0].vrf_id, 0)
8198 # Add tenant specific prefix
8199 vrf1_pref64 = "2001:db8:122:300::"
8200 vrf1_pref64_len = 56
8201 vrf1_pref64_str = "{}/{}".format(vrf1_pref64, vrf1_pref64_len)
8202 self.vapi.nat64_add_del_prefix(prefix=vrf1_pref64_str,
8203 vrf_id=self.vrf1_id, is_add=1)
8205 prefix = self.vapi.nat64_prefix_dump()
8206 self.assertEqual(len(prefix), 2)
8209 pkts = self.create_stream_in_ip6(self.pg0,
8212 plen=global_pref64_len)
8213 self.pg0.add_stream(pkts)
8214 self.pg_enable_capture(self.pg_interfaces)
8216 capture = self.pg1.get_capture(len(pkts))
8217 self.verify_capture_out(capture, nat_ip=self.nat_addr,
8218 dst_ip=self.pg1.remote_ip4)
8220 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
8221 self.pg1.add_stream(pkts)
8222 self.pg_enable_capture(self.pg_interfaces)
8224 capture = self.pg0.get_capture(len(pkts))
8225 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8228 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
8230 # Tenant specific prefix
8231 pkts = self.create_stream_in_ip6(self.pg2,
8234 plen=vrf1_pref64_len)
8235 self.pg2.add_stream(pkts)
8236 self.pg_enable_capture(self.pg_interfaces)
8238 capture = self.pg1.get_capture(len(pkts))
8239 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
8240 dst_ip=self.pg1.remote_ip4)
8242 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
8243 self.pg1.add_stream(pkts)
8244 self.pg_enable_capture(self.pg_interfaces)
8246 capture = self.pg2.get_capture(len(pkts))
8247 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
8250 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
8252 def test_unknown_proto(self):
8253 """ NAT64 translate packet with unknown protocol """
8255 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8256 end_addr=self.nat_addr,
8259 flags = self.config_flags.NAT_IS_INSIDE
8260 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8261 sw_if_index=self.pg0.sw_if_index)
8262 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8263 sw_if_index=self.pg1.sw_if_index)
8264 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8267 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8268 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
8269 TCP(sport=self.tcp_port_in, dport=20))
8270 self.pg0.add_stream(p)
8271 self.pg_enable_capture(self.pg_interfaces)
8273 p = self.pg1.get_capture(1)
8275 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8276 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
8278 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8279 TCP(sport=1234, dport=1234))
8280 self.pg0.add_stream(p)
8281 self.pg_enable_capture(self.pg_interfaces)
8283 p = self.pg1.get_capture(1)
8286 self.assertEqual(packet[IP].src, self.nat_addr)
8287 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
8288 self.assertEqual(packet.haslayer(GRE), 1)
8289 self.assert_packet_checksums_valid(packet)
8291 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8295 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8296 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
8298 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8299 TCP(sport=1234, dport=1234))
8300 self.pg1.add_stream(p)
8301 self.pg_enable_capture(self.pg_interfaces)
8303 p = self.pg0.get_capture(1)
8306 self.assertEqual(packet[IPv6].src, remote_ip6)
8307 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
8308 self.assertEqual(packet[IPv6].nh, 47)
8310 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8313 def test_hairpinning_unknown_proto(self):
8314 """ NAT64 translate packet with unknown protocol - hairpinning """
8316 client = self.pg0.remote_hosts[0]
8317 server = self.pg0.remote_hosts[1]
8318 server_tcp_in_port = 22
8319 server_tcp_out_port = 4022
8320 client_tcp_in_port = 1234
8321 client_tcp_out_port = 1235
8322 server_nat_ip = "10.0.0.100"
8323 client_nat_ip = "10.0.0.110"
8324 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
8325 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
8327 self.vapi.nat64_add_del_pool_addr_range(start_addr=server_nat_ip,
8328 end_addr=client_nat_ip,
8331 flags = self.config_flags.NAT_IS_INSIDE
8332 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8333 sw_if_index=self.pg0.sw_if_index)
8334 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8335 sw_if_index=self.pg1.sw_if_index)
8337 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8338 o_addr=server_nat_ip,
8339 i_port=server_tcp_in_port,
8340 o_port=server_tcp_out_port,
8341 proto=IP_PROTOS.tcp, vrf_id=0,
8344 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8345 o_addr=server_nat_ip, i_port=0,
8347 proto=IP_PROTOS.gre, vrf_id=0,
8350 self.vapi.nat64_add_del_static_bib(i_addr=client.ip6n,
8351 o_addr=client_nat_ip,
8352 i_port=client_tcp_in_port,
8353 o_port=client_tcp_out_port,
8354 proto=IP_PROTOS.tcp, vrf_id=0,
8358 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8359 IPv6(src=client.ip6, dst=server_nat_ip6) /
8360 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
8361 self.pg0.add_stream(p)
8362 self.pg_enable_capture(self.pg_interfaces)
8364 p = self.pg0.get_capture(1)
8366 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8367 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
8369 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
8370 TCP(sport=1234, dport=1234))
8371 self.pg0.add_stream(p)
8372 self.pg_enable_capture(self.pg_interfaces)
8374 p = self.pg0.get_capture(1)
8377 self.assertEqual(packet[IPv6].src, client_nat_ip6)
8378 self.assertEqual(packet[IPv6].dst, server.ip6)
8379 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8381 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8385 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8386 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
8388 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
8389 TCP(sport=1234, dport=1234))
8390 self.pg0.add_stream(p)
8391 self.pg_enable_capture(self.pg_interfaces)
8393 p = self.pg0.get_capture(1)
8396 self.assertEqual(packet[IPv6].src, server_nat_ip6)
8397 self.assertEqual(packet[IPv6].dst, client.ip6)
8398 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
8400 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8403 def test_one_armed_nat64(self):
8404 """ One armed NAT64 """
8406 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
8410 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8411 end_addr=self.nat_addr,
8414 flags = self.config_flags.NAT_IS_INSIDE
8415 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8416 sw_if_index=self.pg3.sw_if_index)
8417 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8418 sw_if_index=self.pg3.sw_if_index)
8421 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8422 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
8423 TCP(sport=12345, dport=80))
8424 self.pg3.add_stream(p)
8425 self.pg_enable_capture(self.pg_interfaces)
8427 capture = self.pg3.get_capture(1)
8432 self.assertEqual(ip.src, self.nat_addr)
8433 self.assertEqual(ip.dst, self.pg3.remote_ip4)
8434 self.assertNotEqual(tcp.sport, 12345)
8435 external_port = tcp.sport
8436 self.assertEqual(tcp.dport, 80)
8437 self.assert_packet_checksums_valid(p)
8439 self.logger.error(ppp("Unexpected or invalid packet:", p))
8443 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
8444 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
8445 TCP(sport=80, dport=external_port))
8446 self.pg3.add_stream(p)
8447 self.pg_enable_capture(self.pg_interfaces)
8449 capture = self.pg3.get_capture(1)
8454 self.assertEqual(ip.src, remote_host_ip6)
8455 self.assertEqual(ip.dst, self.pg3.remote_ip6)
8456 self.assertEqual(tcp.sport, 80)
8457 self.assertEqual(tcp.dport, 12345)
8458 self.assert_packet_checksums_valid(p)
8460 self.logger.error(ppp("Unexpected or invalid packet:", p))
8463 def test_frag_in_order(self):
8464 """ NAT64 translate fragments arriving in order """
8465 self.tcp_port_in = random.randint(1025, 65535)
8467 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8468 end_addr=self.nat_addr,
8471 flags = self.config_flags.NAT_IS_INSIDE
8472 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8473 sw_if_index=self.pg0.sw_if_index)
8474 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8475 sw_if_index=self.pg1.sw_if_index)
8479 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8480 self.tcp_port_in, 20, data)
8481 self.pg0.add_stream(pkts)
8482 self.pg_enable_capture(self.pg_interfaces)
8484 frags = self.pg1.get_capture(len(pkts))
8485 p = self.reass_frags_and_verify(frags,
8487 self.pg1.remote_ip4)
8488 self.assertEqual(p[TCP].dport, 20)
8489 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8490 self.tcp_port_out = p[TCP].sport
8491 self.assertEqual(data, p[Raw].load)
8494 data = b"A" * 4 + b"b" * 16 + b"C" * 3
8495 pkts = self.create_stream_frag(self.pg1,
8500 self.pg1.add_stream(pkts)
8501 self.pg_enable_capture(self.pg_interfaces)
8503 frags = self.pg0.get_capture(len(pkts))
8504 self.logger.debug(ppc("Captured:", frags))
8505 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8506 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8507 self.assertEqual(p[TCP].sport, 20)
8508 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8509 self.assertEqual(data, p[Raw].load)
8511 def test_reass_hairpinning(self):
8512 """ NAT64 fragments hairpinning """
8514 server = self.pg0.remote_hosts[1]
8515 server_in_port = random.randint(1025, 65535)
8516 server_out_port = random.randint(1025, 65535)
8517 client_in_port = random.randint(1025, 65535)
8518 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
8519 nat_addr_ip6 = ip.src
8521 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8522 end_addr=self.nat_addr,
8525 flags = self.config_flags.NAT_IS_INSIDE
8526 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8527 sw_if_index=self.pg0.sw_if_index)
8528 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8529 sw_if_index=self.pg1.sw_if_index)
8531 # add static BIB entry for server
8532 self.vapi.nat64_add_del_static_bib(i_addr=server.ip6n,
8533 o_addr=self.nat_addr,
8534 i_port=server_in_port,
8535 o_port=server_out_port,
8536 proto=IP_PROTOS.tcp, vrf_id=0,
8539 # send packet from host to server
8540 pkts = self.create_stream_frag_ip6(self.pg0,
8545 self.pg0.add_stream(pkts)
8546 self.pg_enable_capture(self.pg_interfaces)
8548 frags = self.pg0.get_capture(len(pkts))
8549 self.logger.debug(ppc("Captured:", frags))
8550 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
8551 self.assertNotEqual(p[TCP].sport, client_in_port)
8552 self.assertEqual(p[TCP].dport, server_in_port)
8553 self.assertEqual(data, p[Raw].load)
8555 def test_frag_out_of_order(self):
8556 """ NAT64 translate fragments arriving out of order """
8557 self.tcp_port_in = random.randint(1025, 65535)
8559 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8560 end_addr=self.nat_addr,
8563 flags = self.config_flags.NAT_IS_INSIDE
8564 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8565 sw_if_index=self.pg0.sw_if_index)
8566 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8567 sw_if_index=self.pg1.sw_if_index)
8571 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
8572 self.tcp_port_in, 20, data)
8574 self.pg0.add_stream(pkts)
8575 self.pg_enable_capture(self.pg_interfaces)
8577 frags = self.pg1.get_capture(len(pkts))
8578 p = self.reass_frags_and_verify(frags,
8580 self.pg1.remote_ip4)
8581 self.assertEqual(p[TCP].dport, 20)
8582 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
8583 self.tcp_port_out = p[TCP].sport
8584 self.assertEqual(data, p[Raw].load)
8587 data = b"A" * 4 + b"B" * 16 + b"C" * 3
8588 pkts = self.create_stream_frag(self.pg1,
8594 self.pg1.add_stream(pkts)
8595 self.pg_enable_capture(self.pg_interfaces)
8597 frags = self.pg0.get_capture(len(pkts))
8598 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
8599 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
8600 self.assertEqual(p[TCP].sport, 20)
8601 self.assertEqual(p[TCP].dport, self.tcp_port_in)
8602 self.assertEqual(data, p[Raw].load)
8604 def test_interface_addr(self):
8605 """ Acquire NAT64 pool addresses from interface """
8606 self.vapi.nat64_add_del_interface_addr(
8608 sw_if_index=self.pg4.sw_if_index)
8610 # no address in NAT64 pool
8611 addresses = self.vapi.nat44_address_dump()
8612 self.assertEqual(0, len(addresses))
8614 # configure interface address and check NAT64 address pool
8615 self.pg4.config_ip4()
8616 addresses = self.vapi.nat64_pool_addr_dump()
8617 self.assertEqual(len(addresses), 1)
8619 self.assertEqual(str(addresses[0].address),
8622 # remove interface address and check NAT64 address pool
8623 self.pg4.unconfig_ip4()
8624 addresses = self.vapi.nat64_pool_addr_dump()
8625 self.assertEqual(0, len(addresses))
8627 @unittest.skipUnless(running_extended_tests, "part of extended tests")
8628 def test_ipfix_max_bibs_sessions(self):
8629 """ IPFIX logging maximum session and BIB entries exceeded """
8632 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8636 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8637 end_addr=self.nat_addr,
8640 flags = self.config_flags.NAT_IS_INSIDE
8641 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8642 sw_if_index=self.pg0.sw_if_index)
8643 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8644 sw_if_index=self.pg1.sw_if_index)
8648 for i in range(0, max_bibs):
8649 src = "fd01:aa::%x" % (i)
8650 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8651 IPv6(src=src, dst=remote_host_ip6) /
8652 TCP(sport=12345, dport=80))
8654 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8655 IPv6(src=src, dst=remote_host_ip6) /
8656 TCP(sport=12345, dport=22))
8658 self.pg0.add_stream(pkts)
8659 self.pg_enable_capture(self.pg_interfaces)
8661 self.pg1.get_capture(max_sessions)
8663 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8664 src_address=self.pg3.local_ip4,
8666 template_interval=10)
8667 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8668 src_port=self.ipfix_src_port,
8671 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8672 IPv6(src=src, dst=remote_host_ip6) /
8673 TCP(sport=12345, dport=25))
8674 self.pg0.add_stream(p)
8675 self.pg_enable_capture(self.pg_interfaces)
8677 self.pg1.assert_nothing_captured()
8679 self.vapi.ipfix_flush()
8680 capture = self.pg3.get_capture(7)
8681 ipfix = IPFIXDecoder()
8682 # first load template
8684 self.assertTrue(p.haslayer(IPFIX))
8685 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8686 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8687 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8688 self.assertEqual(p[UDP].dport, 4739)
8689 self.assertEqual(p[IPFIX].observationDomainID,
8690 self.ipfix_domain_id)
8691 if p.haslayer(Template):
8692 ipfix.add_template(p.getlayer(Template))
8693 # verify events in data set
8695 if p.haslayer(Data):
8696 data = ipfix.decode_data_set(p.getlayer(Set))
8697 self.verify_ipfix_max_sessions(data, max_sessions)
8699 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8700 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8701 TCP(sport=12345, dport=80))
8702 self.pg0.add_stream(p)
8703 self.pg_enable_capture(self.pg_interfaces)
8705 self.pg1.assert_nothing_captured()
8707 self.vapi.ipfix_flush()
8708 capture = self.pg3.get_capture(1)
8709 # verify events in data set
8711 self.assertTrue(p.haslayer(IPFIX))
8712 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8713 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8714 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8715 self.assertEqual(p[UDP].dport, 4739)
8716 self.assertEqual(p[IPFIX].observationDomainID,
8717 self.ipfix_domain_id)
8718 if p.haslayer(Data):
8719 data = ipfix.decode_data_set(p.getlayer(Set))
8720 self.verify_ipfix_max_bibs(data, max_bibs)
8722 def test_ipfix_bib_ses(self):
8723 """ IPFIX logging NAT64 BIB/session create and delete events """
8724 self.tcp_port_in = random.randint(1025, 65535)
8725 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8729 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8730 end_addr=self.nat_addr,
8733 flags = self.config_flags.NAT_IS_INSIDE
8734 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8735 sw_if_index=self.pg0.sw_if_index)
8736 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8737 sw_if_index=self.pg1.sw_if_index)
8738 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
8739 src_address=self.pg3.local_ip4,
8741 template_interval=10)
8742 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8743 src_port=self.ipfix_src_port,
8747 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8748 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8749 TCP(sport=self.tcp_port_in, dport=25))
8750 self.pg0.add_stream(p)
8751 self.pg_enable_capture(self.pg_interfaces)
8753 p = self.pg1.get_capture(1)
8754 self.tcp_port_out = p[0][TCP].sport
8755 self.vapi.ipfix_flush()
8756 capture = self.pg3.get_capture(8)
8757 ipfix = IPFIXDecoder()
8758 # first load template
8760 self.assertTrue(p.haslayer(IPFIX))
8761 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8762 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8763 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8764 self.assertEqual(p[UDP].dport, 4739)
8765 self.assertEqual(p[IPFIX].observationDomainID,
8766 self.ipfix_domain_id)
8767 if p.haslayer(Template):
8768 ipfix.add_template(p.getlayer(Template))
8769 # verify events in data set
8771 if p.haslayer(Data):
8772 data = ipfix.decode_data_set(p.getlayer(Set))
8773 if scapy.compat.orb(data[0][230]) == 10:
8774 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6)
8775 elif scapy.compat.orb(data[0][230]) == 6:
8776 self.verify_ipfix_nat64_ses(data,
8778 self.pg0.remote_ip6,
8779 self.pg1.remote_ip4,
8782 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8785 self.pg_enable_capture(self.pg_interfaces)
8786 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8787 end_addr=self.nat_addr,
8790 self.vapi.ipfix_flush()
8791 capture = self.pg3.get_capture(2)
8792 # verify events in data set
8794 self.assertTrue(p.haslayer(IPFIX))
8795 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8796 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8797 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8798 self.assertEqual(p[UDP].dport, 4739)
8799 self.assertEqual(p[IPFIX].observationDomainID,
8800 self.ipfix_domain_id)
8801 if p.haslayer(Data):
8802 data = ipfix.decode_data_set(p.getlayer(Set))
8803 if scapy.compat.orb(data[0][230]) == 11:
8804 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6)
8805 elif scapy.compat.orb(data[0][230]) == 7:
8806 self.verify_ipfix_nat64_ses(data,
8808 self.pg0.remote_ip6,
8809 self.pg1.remote_ip4,
8812 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8814 def test_syslog_sess(self):
8815 """ Test syslog session creation and deletion """
8816 self.tcp_port_in = random.randint(1025, 65535)
8817 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8821 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8822 end_addr=self.nat_addr,
8825 flags = self.config_flags.NAT_IS_INSIDE
8826 self.vapi.nat64_add_del_interface(is_add=1, flags=flags,
8827 sw_if_index=self.pg0.sw_if_index)
8828 self.vapi.nat64_add_del_interface(is_add=1, flags=0,
8829 sw_if_index=self.pg1.sw_if_index)
8830 self.vapi.syslog_set_filter(
8831 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
8832 self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
8834 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8835 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8836 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8837 self.pg0.add_stream(p)
8838 self.pg_enable_capture(self.pg_interfaces)
8840 p = self.pg1.get_capture(1)
8841 self.tcp_port_out = p[0][TCP].sport
8842 capture = self.pg3.get_capture(1)
8843 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8845 self.pg_enable_capture(self.pg_interfaces)
8847 self.vapi.nat64_add_del_pool_addr_range(start_addr=self.nat_addr,
8848 end_addr=self.nat_addr,
8851 capture = self.pg3.get_capture(1)
8852 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8854 def nat64_get_ses_num(self):
8856 Return number of active NAT64 sessions.
8858 st = self.vapi.nat64_st_dump(proto=255)
8861 def clear_nat64(self):
8863 Clear NAT64 configuration.
8865 self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
8866 src_port=self.ipfix_src_port,
8868 self.ipfix_src_port = 4739
8869 self.ipfix_domain_id = 1
8871 self.vapi.syslog_set_filter(
8872 self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_EMERG)
8874 self.vapi.nat_set_timeouts(udp=300, tcp_established=7440,
8875 tcp_transitory=240, icmp=60)
8877 interfaces = self.vapi.nat64_interface_dump()
8878 for intf in interfaces:
8879 self.vapi.nat64_add_del_interface(is_add=0, flags=intf.flags,
8880 sw_if_index=intf.sw_if_index)
8882 bib = self.vapi.nat64_bib_dump(proto=255)
8884 if bibe.flags & self.config_flags.NAT_IS_STATIC:
8885 self.vapi.nat64_add_del_static_bib(i_addr=bibe.i_addr,
8893 adresses = self.vapi.nat64_pool_addr_dump()
8894 for addr in adresses:
8895 self.vapi.nat64_add_del_pool_addr_range(start_addr=addr.address,
8896 end_addr=addr.address,
8900 prefixes = self.vapi.nat64_prefix_dump()
8901 for prefix in prefixes:
8902 self.vapi.nat64_add_del_prefix(prefix=str(prefix.prefix),
8903 vrf_id=prefix.vrf_id, is_add=0)
8905 bibs = self.statistics.get_counter('/nat64/total-bibs')
8906 self.assertEqual(bibs[0][0], 0)
8907 sessions = self.statistics.get_counter('/nat64/total-sessions')
8908 self.assertEqual(sessions[0][0], 0)
8911 super(TestNAT64, self).tearDown()
8912 if not self.vpp_dead:
8915 def show_commands_at_teardown(self):
8916 self.logger.info(self.vapi.cli("show nat64 pool"))
8917 self.logger.info(self.vapi.cli("show nat64 interfaces"))
8918 self.logger.info(self.vapi.cli("show nat64 prefix"))
8919 self.logger.info(self.vapi.cli("show nat64 bib all"))
8920 self.logger.info(self.vapi.cli("show nat64 session table all"))
8923 if __name__ == '__main__':
8924 unittest.main(testRunner=VppTestRunner)